文档

§HTTP 请求处理程序

Play 提供了一系列抽象来将请求路由到操作,提供路由器和过滤器以满足最常见的需求。但是,应用程序有时会有更高级的需求,而 Play 的抽象无法满足这些需求。在这种情况下,应用程序可以提供 Play 最低级 HTTP 管道 API 的自定义实现,即 HttpRequestHandler

提供自定义 HttpRequestHandler 应该是最后的手段。大多数自定义需求可以通过实现自定义路由器或 过滤器 来满足。

§实现自定义请求处理程序

HttpRequestHandler 特性有一个要实现的方法,handlerForRequest。它接受要获取处理程序的请求,并返回一个包含 RequestHeaderHandler 的元组。

返回请求标头的原因为了能够向请求添加信息,例如路由信息。这样,路由器就可以用路由信息标记请求,例如哪个路由匹配了请求,这对于监控甚至注入横切功能非常有用。

一个非常简单的请求处理程序,它只是委托给路由器,可能看起来像这样

import javax.inject.Inject

import play.api.http._
import play.api.mvc._
import play.api.routing.Router

class SimpleHttpRequestHandler @Inject() (router: Router, action: DefaultActionBuilder) extends HttpRequestHandler {
  def handlerForRequest(request: RequestHeader) = {
    router.routes.lift(request) match {
      case Some(handler) => (request, handler)
      case None          => (request, action(Results.NotFound))
    }
  }
}

§扩展默认请求处理程序

在大多数情况下,您可能不想从头开始创建一个新的请求处理程序,而是想在默认请求处理程序的基础上进行构建。这可以通过扩展 DefaultHttpRequestHandler 来实现。默认请求处理程序提供了一些可以覆盖的方法,这使您能够实现自定义功能,而无需重新实现标记请求、处理错误等的代码。

自定义请求处理程序的一个用例可能是,您希望根据请求的目标主机委托给不同的路由器。以下是如何实现此操作的示例。

import javax.inject.Inject
import javax.inject.Provider

import play.api.http._
import play.api.mvc.RequestHeader

class VirtualHostRequestHandler @Inject() (
    webCommands: WebCommands,
    optionalDevContext: OptionalDevContext,
    errorHandler: HttpErrorHandler,
    configuration: HttpConfiguration,
    filters: HttpFilters,
    fooRouter: Provider[foo.Routes],
    barRouter: Provider[bar.Routes]
) extends DefaultHttpRequestHandler(
      webCommands,
      optionalDevContext,
      fooRouter,
      errorHandler,
      configuration,
      filters
    ) {
  override def routeRequest(request: RequestHeader): Option[Handler] = {
    request.host match {
      case "foo.example.com" => fooRouter.get.routes.lift(request)
      case "bar.example.com" => barRouter.get.routes.lift(request)
      case _                 => super.routeRequest(request)
    }
  }
}

§配置 HTTP 请求处理程序

如果您使用 BuiltInComponents 来构建您的应用程序,请覆盖 httpRequestHandler 方法以返回自定义处理程序的实例。

如果您使用运行时依赖项注入(例如 Guice),则可以在运行时动态加载请求处理程序。最简单的方法是在根包中创建一个名为 RequestHandler 的类,该类实现 HttpRequestHandler

如果您不想将请求处理程序放在根包中,或者您希望能够为不同的环境配置不同的请求处理程序,则可以通过在 application.conf 中配置 play.http.requestHandler 配置属性来实现。

play.http.requestHandler = "com.example.RequestHandler"

下一步:基本操作


发现此文档中的错误?此页面的源代码可以在 此处 找到。阅读完 文档指南 后,请随时贡献拉取请求。有疑问或建议要分享?请访问 我们的社区论坛 与社区开始对话。