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