拆分 Playframework 2 的 routes 为多个文件

我们用 Playframework 2 时,当 routes 中太多的路由配置时,我们可能会考虑把它们归类分布到多个文件中去。比如按 API 或用途分,有些是 RESTful API,有些是 Web 页面的,对于这种情景,我们可以由以下几个文件来组织:

1. routes 文件,这个仍然是充当入口

这里穿插着来解释下,-> 是固定写法,表示要去别外寻找了,紧接着的 /, /api, 和 /web 是分类路由的上下文了,例如,访问 api.routes 中定义的 /customers 的完整 API 路径就是 /test/customers。最后一部分是全类名,并非指别的路由文件的名称,像文件 general.routes 编译后会生成 general 包下生成  Routes.scala 文件,即类为 general.Routes.

2. general.routes

像前面在 routes 文件中是直接用 -> / general.Routes 来引用 general.routes 文件的,上下文 / 并不会改变 general.routes 中路由的访问方式,所以我们可以把 general.routes 中的内容搬移到 routes 文件中。

3. api.routes

4. web.routes

路由文件全分配到位,我们运行 activator compile 看下生成了什么,就是下面这张图

play2_routes

从上面那张图我们明明白白的知道,general.routes, api.routes 和 web.routes 都产生出相应的包名,类都是 Routes。

如果上面做下来你没有遇到编译错误的话,那你算是幸运的,我所遇到的错误是

[error] /Users/yanbin/Desktop/playtest/app/views/main.scala.html:8: value Assets is not a member of object controllers.routes
[error]         <link rel="stylesheet" media="screen" href="@routes.Assets.versioned("stylesheets/main.css")">
[error]                                                             ^
[error] /Users/yanbin/Desktop/playtest/app/views/main.scala.html:9: value Assets is not a member of object controllers.routes
[error]         <link rel="shortcut icon" type="image/png" href="@routes.Assets.versioned("images/favicon.png")">
[error]                                                                  ^
[error] /Users/yanbin/Desktop/playtest/app/views/main.scala.html:10: value Assets is not a member of object controllers.routes
[error]         <script src="@routes.Assets.versioned("javascripts/hello.js")" type="text/javascript"></script>
[error]                              ^

我当时也是半天摸不着头脑,后来发现错误中的 @routes.Assets 本该是定义在 target/scala-2.11/routes/main/controllers/routes.java 中的

public static final controllers.ReverseAssets Assets .....

这个文件注释中也告诉了我们该文件怎么产生的,例如本例中是

// @GENERATOR:play-routes-compiler
// @SOURCE:/Users/yanbin/Desktop/playtest/conf/web.routes
// @DATE:Mon Feb 22 23:05:47 CST 2016

如果不拆分 routes 文件的话,上面指示的 @SOURCE 应该就是 /Users/yanbin/Desktop/playtest/conf/routes, 而 routes.java 中的 Assets 常量是由下面这行生成的

因此我们必须把这行写一份到 web.routes 文件中,重新编译就可以通过了。

类似的,如果我们编译时碰到  @javascript.Assets........ 引用资源时的错误,解决方法也是一样的。

Playframework 的一位开发人员对此的解释是 https://github.com/playframework/playframework/issues/4430:

Does api.routes contain any routes to any controllers in the controllers package? If so, then that's the reason, the reverse router from api.routes for the controllers package is overwriting the reverse router from routes for the controllers package, different routes files must address controllers in different packages.

其次,不妨留意下 @routes.Assets.versioned("stylesheets/main.css") 在不同情况下产生的全路径也是有有差异,但不影响使用。如可能是

/public/stylesheets/main.css      或   /web/public/stylesheets/main.css

Play 2 支持这样简单的把 routes 拆到多个文件中的做法好像是 2.3 开始提供的。记得我们刚开始升级到 Play 2 的时候,如果在 routes 文件中要写成

->  /web   web.Routes

那还得为 web 建立一个 sbt 子项目,web.Routes  中用到的类都必须放在 web 子项目中,于是子项目之间,或子项目与主项目之间类相互间访问就成了一个大问题,这也就是为什么我们当时不得不把所有的东西堆在一个 routes 文件中。

参考:1. https://groups.google.com/d/msg/play-framework/dxDRml0khdY/92Sf48Fhs4MJ

 

类别: PlayFramework. 标签: . 阅读(157). 订阅评论. TrackBack.

Leave a Reply

4 Comments on "拆分 Playframework 2 的 routes 为多个文件"

avatar
Anonymous
Guest
Anonymous

博主,那个是vim吗?配色看着很好看。

liuhaihua.cn
Guest
liuhaihua.cn

原来独立博客了

wpDiscuz