访问播放框架路由器路由器在运行时



我正在编写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,则建议完全忽略Routerdocumentation对象,并使用方便的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)

最新更新