应用全局设置
全局对象
在你的项目中定义一个 Global
对象,它为你处理应用的全局设置. 这个对象必须定义在默认包中(即不带 package 声明的包).
1 2 3 4 5 |
import play.api._ object Global extends GlobalSettings { } |
小贴士: 你也可使用
application.global
key 值在在配置中指定自己的GlobalSettings
实现类名称.
Unmi 注: GlobalSettings.scala 放在 app 目录比较合适,Scala 的 package 层次与目录并不存在严格的对应关系。
要说呢,不带 package 声明的写法确实不是什么好习惯,因为其他带 package 声明的类无法使用它。见:为何Java的有包名的类不能引用默认包中的类。这就对了,本来这个全局对象就不是给别的类用的 - Don't call me, I'll call you。
勾住应用启动和停止事件
你可以覆盖方法 onStart
和 onStop
,它们会在应用的生命周期启动,停止时得到通知:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
import play.api._ object Global extends GlobalSettings { override def onStart(app: Application) { Logger.info("Application has started") } override def onStop(app: Application) { Logger.info("Application shutdown...") } } |
Unmi 注: Play 1.x 时代要实现这样的 Bootstrap,必须实现自己的 Job,@OnApplicationStart 标注类,它的 doJob() 方法就会在应用启动时执行,@OnApplicationStop 标注的 Job 会在应用停止时执行。参考:http://www.playframework.org/documentation/1.2.5/jobs。但是 Play 1.x 这样做可以让你用 @OnApplicationStart 或 @OnApplicationStop 标注多个类或启动多个 Job。
不管是原来的 @OnApplicationStart,还是现在的 onStart,其实是在第一个请求进来时执行的。
提供应用的错误页面
当你的应用出现一个异常时, onError
方法将会得到执行. 它默认时被用作内部框架错误页面:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
import play.api._ import play.api.mvc._ import play.api.mvc.Results._ object Global extends GlobalSettings { override def onError(request: RequestHeader, ex: Throwable) = { InternalServerError( views.html.errorPage(ex) ) } } |
处理找不到 Action 和绑定错误
If the framework doesn’t find an Action
for a request, the onHandlerNotFound
operation will be called:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
import play.api._ import play.api.mvc._ import play.api.mvc.Results._ object Global extends GlobalSettings { override def onHandlerNotFound(request: RequestHeader): Result = { NotFound( views.html.notFoundPage(request.path) ) } } |
在找到了 Route 但现代派定请求参数时出现问题时,onBadRequest
方法就会被调用(Unmi 注: Play 1.x 是否有这样的机制呢?):
1 2 3 4 5 6 7 8 9 10 11 |
import play.api._ import play.api.mvc._ import play.api.mvc.Results._ object Global extends GlobalSettings { override def onBadRequest(request: RequestHeader, error: String) = { BadRequest("Bad Request: " + error) } } |
拦截请求
覆盖 onRouteRequest 方法
Global
对象的另一个重要的方面是它还提供了一种方式去拦截请求,并在请求派发给 Action 之前执行业务逻辑.
小贴士 这个勾也可用于劫持请求, 允许开发者插入他们自己的请求路由机制.
让我们来看它实际是怎么工作的:
1 2 3 4 5 6 7 8 9 10 11 12 |
import play.api._ import play.api.mvc._ // Note: this is in the default package. object Global extends GlobalSettings { override def onRouteRequest(request: RequestHeader): Option[Handler] = { println("executed before every request:" + request.toString) super.onRouteRequest(request) } } |
使用 Action 组合 还可以去拦截特定的 Action 方法。