Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 生成Play 2'的不太冗长的方式;s javascript路由器_Scala_Playframework 2.0 - Fatal编程技术网

Scala 生成Play 2'的不太冗长的方式;s javascript路由器

Scala 生成Play 2'的不太冗长的方式;s javascript路由器,scala,playframework-2.0,Scala,Playframework 2.0,目前,我以相当详细的方式定义了我的应用程序的javascript路由器 def javascriptRoutes = Action { implicit request => import routes.javascript._ Ok(Routes.javascriptRouter("jsRoutes")( Login.method1,Login.Method2, OtherController.method1,OtherController.method2,

目前,我以相当详细的方式定义了我的应用程序的javascript路由器

def javascriptRoutes = Action { implicit request =>
  import routes.javascript._
  Ok(Routes.javascriptRouter("jsRoutes")(
    Login.method1,Login.Method2,
    OtherController.method1,OtherController.method2,
    //[...]
  )).as("text/javascript")
}
我真正想做的是创建一个
javascriptRouter
,其中包含
routes
文件中的所有路由,这样我就不必在每次添加新的控制器方法时手动更新
javascriptRoutes
定义


有没有一种方法可以完成这项任务,或者有没有一种定义
javascriptRouter
的方法稍微简单一点?

您可以通过反射这样做:

val routeCache = {
    import routes._
    val jsRoutesClass = classOf[routes.javascript]
    val controllers = jsRoutesClass.getFields().map(_.get(null))
    controllers.flatMap { controller =>
        controller.getClass().getDeclaredMethods().map { action =>
            action.invoke(controller).asInstanceOf[play.core.Router.JavascriptReverseRoute]
        }
    }
}

def javascriptRoutes = Action { implicit request =>
    Ok(Routes.javascriptRouter("jsRoutes")(routeCache:_*)).as("text/javascript")
}
这是从target/scala-2.x.x/src_managed中生成的源文件派生的。实际上,您可以添加自己的源代码生成器并自己解析routes文件,但我发现通过反射进行解析更容易


您可能还需要做的一件事是过滤掉您不想要的方法,因为这将为您提供所有路由(包括javascriptRouter本身)。

这是一个非常好的解决方案。如果在其他子包下有JavaScript路由,则需要像下面这样声明routeCache

val routeCache = {
  val jsRoutesClass = classOf[controllers.api.routes.javascript]
  val controllerArray = jsRoutesClass.getFields().map(_.get(null))
  controllerArray.flatMap { controller =>
    controller.getClass().getDeclaredMethods().map { action =>
    action.invoke(controller).asInstanceOf[play.core.Router.JavascriptReverseRoute]
  }
 }
}

我需要用java语言。在这里复制,以防对某人有用

public static Result javascriptRoutes() throws IllegalAccessException, IllegalArgumentException,
        InvocationTargetException {

    // use reflection to get the fields of controllers.routes.javascript
    Set<Object> reverseRoutes = new HashSet<Object>();
    for (Field f : controllers.routes.javascript.class.getFields()) {
        // get its methods
        for (Method m : getAllMethods(f.getType(), withReturnType(JavascriptReverseRoute.class))) {
            // for each method, add its result to the reverseRoutes
            reverseRoutes.add(m.invoke(f.get(null)));
        }
    }

    // return the reverse routes
    response().setContentType("text/javascript");
    return ok(Routes.javascriptRouter("jsRoutes",
            reverseRoutes.toArray(new JavascriptReverseRoute[reverseRoutes.size()])));
}
public静态结果javascriptRoutes()抛出IllegalAccessException、IllegalArgumentException、,
调用目标异常{
//使用反射获取controllers.routes.javascript的字段
Set reverseRoutes=new HashSet();
for(字段f:controllers.routes.javascript.class.getFields()){
//得到它的方法
对于(方法m:getAllMethods(f.getType(),withReturnType(JavascriptReverseRoute.class))){
//对于每个方法,将其结果添加到反向输出
add(m.invoke(f.get(null));
}
}
//返回反向路线
response().setContentType(“text/javascript”);
返回ok(Routes.javascriptRouter(“jsRoutes”),
toArray(新的JavascriptReverseRoute[reverseRoutes.size()]);
}

扩展@rochb对Play 2.4 Java的回答,其中包名略有不同,支持多个控制器包

public Result javascriptRoutes() throws IllegalAccessException, IllegalArgumentException,
        InvocationTargetException {

    // use reflection to get the fields of controllers.routes.javascript and other controller packages
    Set<Object> reverseRoutes = new HashSet<Object>();
    Class[] routeClasses = {controllers.routes.javascript.class, com.example.package1.routes.javascript.class, com.example.package2.routes.javascript.class};
    for (int i = 0; i < routeClasses.length; i++) {
        for (Field f : routeClasses[i].getFields()) {
            // get its methods
            for (Method m : getAllMethods(f.getType(), withReturnType(play.api.routing.JavaScriptReverseRoute.class))) {
                // for each method, add its result to the reverseRoutes
                reverseRoutes.add(m.invoke(f.get(null)));
            }
        }
    }
    // return the reverse routes
    response().setContentType("text/javascript");
    return ok(Routes.javascriptRouter("jsRoutes",
            reverseRoutes.toArray(new play.api.routing.JavaScriptReverseRoute[reverseRoutes.size()])));
}
public Result javascriptRoutes()抛出IllegalAccessException、IllegalArgumentException、,
调用目标异常{
//使用反射获取controllers.routes.javascript和其他控制器包的字段
Set reverseRoutes=new HashSet();
Class[]RouteClass={controllers.routes.javascript.Class,com.example.package1.routes.javascript.Class,com.example.package2.routes.javascript.Class};
对于(int i=0;i
此外,如果您使用的是Play 2.4,则某些类/包已更改:

def javascriptRoutes = Action { implicit request =>
  Ok(play.api.routing.JavaScriptReverseRouter("jsRoutes")(routeCache:_*)).as("text/javascript")
}

val routeCache: Array[JavaScriptReverseRoute] = {
  import routes._
  val jsRoutesClass: Class[javascript] = classOf[routes.javascript]
  val controllers = jsRoutesClass.getFields.map(_.get(null))
  val met = for (
    controller <- controllers;
    method <- controller.getClass.getDeclaredMethods if method.getReturnType == classOf[play.api.routing.JavaScriptReverseRoute]
  ) yield method.invoke(controller).asInstanceOf[play.api.routing.JavaScriptReverseRoute]
  met
}
def javascriptRoutes=Action{implicit request=>
Ok(play.api.routing.JavaScriptReverseRouter(“jsRoutes”)(routeCache:*).as(“text/javascript”)
}
val routeCache:Array[JavaScriptReverseRoute]={
进口路线_
val jsrouteClass:Class[javascript]=classOf[routes.javascript]
val controllers=JSRouteClass.getFields.map(uq.get(null))
val met=for(

控制器反射是不可能的吗?@那做反射是可以接受的谢谢!这正是我想要的。使用反射与手动列出方法相比,在运行时性能方面有什么缺点吗?每当服务器启动/重新加载时,一次性成本很小,但除此之外,没有其他成本记住。在实践中,我发现它并没有感觉到任何减慢。它是由游戏产生的