我正在编写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()""")
}
我唯一的问题是:如何在运行时访问此问题?
此答案偶然地表明,使用的路由可以通过Play.maybeApplication.get.routes
获得,但现在已弃用。如何在运行时获得Routes
对象?
播放实际上使Routes
通过其Router
对象的依赖项注入(DI)可用。如果您已经在应用程序中设置了DI,则只需要将其注入构造函数:
import play.api.routing.Router
class YourFilter(router: Router) extends EssentialFilter { ... }
如果您尚未设置DI,则建议您阅读有关该主题的官方参考。这篇第三方博客文章还详细介绍了一些有用的现代图书馆。
但是,如果您想查看哪个控制器处理特定的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
)
}
,也可以从请求的attrs
中获得HandlerDef
:
val handlerDef: Option[HandlerDef] = request.attrs.get(Router.Attrs.HandlerDef)