我正在写一个EssentialFilter
,因此我可以对每个请求执行一个操作。但是,筛选器收到的只是一个RequestHeader
对象,我需要了解稍后将处理此请求的实际控制器的信息。
此信息在routes.conf
中是简单明了的:
GET /foobar controllers.MyController.foobar()
GET /bashbaz controllers.MyController.bashbaz()
我什至可以看到,在我的target
文件夹中,生成的路由表非常整洁地放在documentation
对象中:
// This example greatly simplified for clarity
class Routes() {
def documentation = List(
("""GET""", prefix + """foobar""", """controllers.MyController.foobar()"""),
("""GET""", prefix + """bashbaz""", """controllers.MyController.bashbaz()""")
}
我唯一的问题是:我如何在运行时访问它?
This answer巧合地表明,已通过Play.maybeApplication.get.routes
使用 路由,但现在已弃用。如何在运行时获取Routes
对象?
答案 0 :(得分:0)
播放实际上通过其Routes
对象的依赖项注入(DI)使Router
可用。如果您已经在应用程序中设置了DI,则只需将其注入到构造函数中即可:
import play.api.routing.Router
class YourFilter(router: Router) extends EssentialFilter { ... }
如果您尚未设置DI,那么我建议您阅读the official reference。 This third-party blog post还详细介绍了一些有用的现代库。
但是,如果要查看哪个控制器处理特定的RequestHeader
,则建议完全忽略Router
和documentation
对象,并使用方便的handlerDef
隐式:
import play.api.routing.Router.RequestImplicits.WithHandlerDef
override def apply(next: EssentialAction) = { request: RequestHeader =>
val handlerDefOpt = request.handlerDef
handlerDefOpt.map(handlerDef =>
// Would be "controllers.MyController" in your example
handlerDef.controller
// Would be "foobar" or "bashbaz" in your example
handlerDef.method
// Would be "GET" in your example
handlerDef.verb
// Would be "/foobar" or "/bashbaz" in your example
handlerDef.path
)
}
或者您也可以从请求的HandlerDef
中获取attrs
:
val handlerDef: Option[HandlerDef] = request.attrs.get(Router.Attrs.HandlerDef)