JEP 321:HTTP 客户端
概括
通过JEP 110标准化JDK 9 中引入的孵化HTTP 客户端 API,并在 JDK 10 中更新。
目标
除了JEP 110 的目标之外,该 JEP 将:
- 考虑到在孵化的 API 上收到的反馈,
java.net.http
基于孵化的API,在包中提供标准化的API ,并且- 移除已孵化的 API。
动机
描述
此 JEP 提议标准化 HTTP 客户端 API,该 API 在 JDK 9 中作为孵化 API 引入,并在 JDK 10 中更新。孵化 API 已收到多轮反馈,这些反馈带来了重大改进,但在较高水平上仍然存在大致相同。 API 通过 s 提供非阻塞请求和响应语义CompletableFuture
,可以将其链接起来以触发相关操作。请求和响应主体的背压和流量控制是通过 API 中平台的反应流支持提供的java.util.concurrent.Flow
。
在 JDK 9 和 JDK 10 中孵化时,实现几乎被完全重写。现在的实现是完全异步的(之前的 HTTP/1.1 实现是阻塞的)。 RX Flow 概念的使用已被推进到实现中,这消除了支持 HTTP/2 所需的许多原始自定义概念。现在可以更轻松地跟踪数据流,从用户级请求发布者和响应订阅者一直到底层套接字。这显着减少了代码中的 概念数量和复杂性,并最大限度地提高了 HTTP/1.1 和 HTTP/2 之间重用的可能性。
标准 API 的模块名称和包名称将为java.net.http
.
JDK 10 中孵化内容的变化
-
BodyPublisher
通过静态工厂方法创建的、BodyHandler
和 的预定义实现BodySubscriber
已移出到单独的不可实例化实用程序工厂类,遵循复数命名约定。这提高了这些相对较小的界面的可读性。 -
静态工厂方法的名称也按照以下大类进行了更新:
-
fromXxx
:来自标准订阅服务器的适配器,例如接受 aFlow.Subscriber
返回 aBodySubscriber
。 -
ofXxx
:创建新的预定义的工厂Body[Publisher|Handler|Subscriber]
,执行有用的常见任务,例如将响应正文作为字符串处理,或将正文流式传输到文件。 -
other:组合器(接受 a
BodySubscriber
返回 aBodySubscriber
)和其他有用的操作。
- 添加了一些
BodyHandler
和相应的,以提高常见场景下的可用性:BodySubscriber
-
discard(Object replacement)
结合丢弃/忽略响应主体并允许给定的替换。反馈表明这可能显得令人困惑。它已被删除并替换为两个单独的处理程序: 1)discarding()
和 2)replacing(Object replacement)
。 -
添加了
ofLines()
返回BodyHandler<Stream<String>>
, 以支持将响应正文作为Stream
一行一行地进行流式传输。提供与 类似的语义BufferedReader.lines()
。 -
添加了
fromLineSubscriber
,支持响应正文适应Flow.Subscriber
多String
行。 -
添加
BodySubscriber.mapping
用于从一种响应正文类型到另一种响应正文类型的通用映射。
-
推送承诺支持已重新设计,以减少其对 API 的影响并使其更符合常规请求/响应。具体来说,
MultiSubscriber
和MultiResultMap
已被删除。推送承诺现在通过功能接口 来处理,PushPromiseHandler
该接口可以在发送操作期间选择性地给出。 -
通过将和策略替换为 ,该
HttpClient.Redirect
策略已得到简化。据观察,之前的命名并不真正合适,应该重命名为,因为它可能适合大多数正常情况。考虑到新命名的上述名称,看起来很奇怪,可能会令人困惑,并且不太可能被使用。SAME_PROTOCOL``SECURE``NORMAL``SECURE``NORMAL``NORMAL``SAME_PROTOCOL
-
WebSocket.MessagePart
已被删除。该枚举用于接收方来指示消息的传递是否完成。它与发送方不对称,发送方使用简单的布尔值来实现此目的。此外,据观察,使用简单的布尔值处理接收到的消息可以显着减少和简化接收代码逻辑。确定所传递的消息是WHOLE
上述的好处和主要目的之一MessagePart
,已被证明没有其自身的重要性。
有关 API 的更多详细信息可以在JEP 110、最新的 API javadoc或网络组的JDK HTTP Client页面中找到。
测试
孵化 API 的现有测试将更新以使用新的标准 API。将添加额外的测试以涵盖所有支持的场景,特别是 HTTP/1.1 和 HTTP/2 之间的升级和降级。
风险和假设
当前依赖于孵化的 HTTP 客户端 API 的代码将需要更新,至少要更改其包导入。这与任何其他孵化功能没有什么不同。依赖于孵化模块的代码已经在编译时和运行时收到适当的警告。