文档

§Play HTTP API 简介

§什么是 EssentialAction?

EssentialAction 是 Play HTTP API 使用的底层函数类型。这与 Java 中的 Action 类型不同,Action 类型是更高层的类型,它接受一个 Request 并返回一个 CompletionStage<Result>。在大多数情况下,您不需要在 Java 应用程序中直接使用 EssentialAction,但它在编写过滤器或与其他低级 Play API 交互时可能很有用。

要理解 EssentialAction,我们需要了解 Play 架构。

Play 的核心非常小,周围环绕着大量的有用 API、服务和结构,使 Web 编程任务更容易。

基本上,Play 的 action API 抽象地具有以下类型

RequestHeader -> byte[] -> Result 

以上代码接受请求头 RequestHeader,然后将请求主体作为 byte[] 接收,并生成一个 Result

现在,此类型假定将请求主体完全放入内存(或磁盘)中,即使您只想从中计算一个值,或者更好地将其转发到像 Amazon S3 这样的存储服务。

我们更希望将请求主体块作为流接收,并在必要时逐步处理它们。

我们需要更改的是第二个箭头,使其以块的形式接收输入,并最终生成结果。有一个类型可以完全做到这一点,它被称为 Accumulator,并接受两个类型参数。

Accumulator<E,R> 是一种 箭头 类型,它将以 E 类型的块形式接收输入,并最终返回 R。对于我们的 API,我们需要一个 Accumulator,它接收 ByteString 块(本质上是字节数组的更高效包装器),并最终返回一个 Result。因此,我们稍微修改了类型,使其成为

RequestHeader -> Accumulator<ByteString, Result>

最终,我们的 Java 类型看起来像

Function<RequestHeader, Accumulator<ByteString, Result>>

这应该读作:获取请求头,获取代表请求体的 ByteString 块,最终返回一个 Result。这正是 EssentialAction 的 apply 方法的定义方式

public abstract Accumulator<ByteString, Result> apply(RequestHeader requestHeader);

另一方面,Result 类型可以抽象地认为是响应头和响应体

Result(ResponseHeader header, ByteString body)

但是,如果我们想逐步将响应体发送到客户端,而无需将其完全填充到内存中,该怎么办?我们需要改进我们的类型。我们需要将主体类型从 ByteString 替换为生成 ByteString 块的内容。

我们已经为此类型,称为 Source<E, ?>,这意味着它能够生成 E 块,在我们的例子中是 Source<ByteString, ?>

Result(ResponseHeader header, Source<ByteString, ?> body)

如果我们不必逐步发送响应,我们仍然可以将整个主体作为单个块发送。在实际的 API 中,Play 使用 HttpEntity 包装类型支持不同类型的实体,该类型支持流式、分块和严格实体。

§底线

基本的 Play HTTP API 非常简单

RequestHeader -> Accumulator<ByteString, Result>

它读作:获取 RequestHeader,然后获取 ByteString 块,并返回一个响应。响应包含 ResponseHeaders 和一个主体,该主体是可转换为 ByteString 的值的块,将写入 Source<E, ?> 类型中表示的套接字。

下一步:HTTP 过滤器


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