§拦截 HTTP 请求
Play 的 Java API 提供了两种拦截操作调用的方法。第一种称为 ActionCreator
,它提供了一个 createAction
方法,用于创建操作组合中使用的初始操作。它处理调用操作的实际方法,允许您拦截请求。
第二种方法是实现您自己的 HttpRequestHandler
,它是 Play 中所有 HTTP 请求的主要入口点。这包括来自 Java 和 Scala 操作的请求。
§操作创建者
The ActionCreator
接口有两个可以实现的方法
createAction
: 接受请求和与传递的请求关联的控制器的操作方法。操作可以是第一个或最后一个操作,具体取决于配置设置play.http.actionComposition.executeActionCreatorActionFirst
。wrapAction
: 接收要运行的动作,并允许添加最终的全局拦截器。此方法已弃用,因为可以使用createAction
和上述设置实现相同的功能。
还有一个 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
。它接收要获取处理程序的请求,并返回一个包含 RequestHeader
和 Handler
的 HandlerForRequest
实例。
返回请求头的原因是为了在请求中添加信息,例如路由信息。这样,路由器就可以用路由信息标记请求,例如哪个路由匹配了请求,这对于监控甚至注入跨切面功能很有用。
一个非常简单的请求处理程序,它只是委托给路由器,可能看起来像这样
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 编程
在此文档中发现错误?此页面的源代码可以在 此处 找到。在阅读 文档指南 后,请随时贡献拉取请求。有疑问或建议要分享?转到 我们的社区论坛 与社区开始对话。