在运行时访问Play Framework Router路由表

时间:2019-03-22 02:06:02

标签: scala playframework routes

我正在写一个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对象?

1 个答案:

答案 0 :(得分:0)

播放实际上通过其Routes对象的依赖项注入(DI)使Router可用。如果您已经在应用程序中设置了DI,则只需将其注入到构造函数中即可:

import play.api.routing.Router

class YourFilter(router: Router) extends EssentialFilter { ... }

如果您尚未设置DI,那么我建议您阅读the official referenceThis third-party blog post还详细介绍了一些有用的现代库。

但是,如果要查看哪个控制器处理特定的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

  )
}

或者您也可以从请求的HandlerDef中获取attrs

val handlerDef: Option[HandlerDef] = request.attrs.get(Router.Attrs.HandlerDef)