文档

§拦截 HTTP 请求

Play 的 Java API 提供了两种拦截操作调用的方法。第一种称为 ActionCreator,它提供了一个 createAction 方法,用于创建操作组合中使用的初始操作。它处理调用操作的实际方法,允许您拦截请求。

第二种方法是实现您自己的 HttpRequestHandler,它是 Play 中所有 HTTP 请求的主要入口点。这包括来自 Java 和 Scala 操作的请求。

§操作创建者

The ActionCreator 接口有两个可以实现的方法

还有一个 DefaultActionCreator 接口,您可以使用默认实现扩展它。

注意:如果您正在实现自定义 ActionCreator,因为您需要在执行动作之前对动作应用跨领域关注点,那么创建 过滤器 是实现相同目标的更惯用的方法。

可以通过在根包中创建一个实现 play.http.ActionCreator 的名为 ActionCreator 的类来提供自定义动作创建器,例如

import java.lang.reflect.Method;
import java.util.concurrent.CompletionStage;
import play.mvc.Action;
import play.mvc.Http;
import play.mvc.Result;

public class ActionCreator implements play.http.ActionCreator {
  @Override
  public Action createAction(Http.Request request, Method actionMethod) {
    return new Action.Simple() {
      @Override
      public CompletionStage<Result> call(Http.Request req) {
        return delegate.call(req);
      }
    };
  }
}

如果您不想将此类放在根包中,或者您希望能够为不同的环境配置不同的动作处理程序,您可以在 application.conf 中配置 play.http.actionCreator 配置属性。

play.http.actionCreator = "com.example.MyActionCreator"

注意:如果您也使用 动作组合,则默认情况下,createAction 方法返回的动作将在动作组合动作之后执行。如果您想更改此顺序,请在 application.conf 中设置 play.http.actionComposition.executeActionCreatorActionFirst = true

§HTTP 请求处理程序

有时应用程序会有更高级的需求,Play 的抽象无法满足。在这种情况下,应用程序可以提供 Play 最低级别 HTTP 管道 API 的自定义实现,即 HttpRequestHandler

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

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

HttpRequestHandler 接口有一个要实现的方法,handlerForRequest。它接收要获取处理程序的请求,并返回一个包含 RequestHeaderHandlerHandlerForRequest 实例。

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

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

import javax.inject.Inject;
import play.api.mvc.Handler;
import play.core.j.JavaHandler;
import play.core.j.JavaHandlerComponents;
import play.http.*;
import play.libs.streams.Accumulator;
import play.mvc.*;
import play.routing.Router;

public class SimpleHttpRequestHandler implements HttpRequestHandler {
  private final Router router;
  private final JavaHandlerComponents handlerComponents;

  @Inject
  public SimpleHttpRequestHandler(Router router, JavaHandlerComponents components) {
    this.router = router;
    this.handlerComponents = components;
  }

  public HandlerForRequest handlerForRequest(Http.RequestHeader request) {
    Handler handler =
        router
            .route(request)
            .orElseGet(() -> EssentialAction.of(req -> Accumulator.done(Results.notFound())));
    if (handler instanceof JavaHandler) {
      handler = ((JavaHandler) handler).withComponents(handlerComponents);
    }
    return new HandlerForRequest(request, handler);
  }
}

请注意,我们需要注入 JavaHandlerComponents 并调用 handler.withComponents 用于 Java 处理程序。这是 Java 操作正常工作所必需的。如果您扩展 DefaultHttpRequestHandler 并调用 super.handlerForRequest(),这也会自动为您处理。

请注意,HttpRequestHandler 目前有两个具有默认实现的遗留方法,这些方法已移至 ActionCreator

§配置 HTTP 请求处理程序

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

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

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

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

下一步: 异步 HTTP 编程


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