Java 26前瞻:JEP 517终落地,原生HTTP Client API完美支持HTTP/3
JEP 517 为 Java 标准库中的 HTTP Client API(自 JDK 11 引入)增加了对 HTTP/3 协议的支持,使 Java 应用能够以最小的代码改动与 HTTP/3 服务器交互,从而获得更快握手、避免队头阻塞、更可靠传输等一系列协议层面的性能收益。该特性已于 JDK 26 正式交付。
基本信息卡片
| 项目 | 内容 |
|---|---|
| JEP 编号 | 517 |
| 标题 | HTTP/3 for the HTTP Client API |
| 负责人 | Daniel Fuchs |
| 所属版本 | JDK 26 |
| 状态 | Closed / Delivered |
| 组件 | core-libs / java.net |
| 关联 JEP | JEP 321(HTTP Client API) |
| Issue | JDK-8291976 |
背景与动机
HTTP Client API 的前世今生
JDK 11 通过 JEP 321 引入了一套现代化的 HTTP Client API,用于取代老旧的 java.net.HttpURLConnection。这套 API 设计之初就支持 HTTP/1.1 和 HTTP/2,并预留了未来扩展更多协议版本的能力。默认情况下,HTTP Client 会优先使用 HTTP/2,如果目标服务器不支持,则透明降级到 HTTP/1.1。
使用 HTTP Client API 的代码非常简洁,并且完全与底层协议版本无关——开发者无需关心最终走的是 HTTP/1.1 还是 HTTP/2。例如,发送一个 GET 请求并获取响应内容:
1 | package com.johnson.example; |
这段代码中没有任何地方显式依赖 HTTP 协议版本,应用代码天然具备协议无关性。
当前的短板:缺少 HTTP/3 支持
HTTP/3 是 HTTP/2 的下一代协议,由 IETF 于 2022 年正式标准化。与 HTTP/1.1 和 HTTP/2 基于 TCP 不同,HTTP/3 构建于 QUIC 协议之上。QUIC 是一种基于 UDP 数据报的可靠传输层协议,并使用 TLS 1.3 进行安全加密。
HTTP/3 带来了多项显著改进:
- 更快的握手速度:QUIC 将传输握手与 TLS 加密握手合并,减少了建立连接所需的往返次数。
- 消除队头阻塞:HTTP/2 虽然支持多路复用,但底层 TCP 的可靠传输机制仍会导致队头阻塞(一个丢失的数据包会阻塞同一 TCP 连接上的所有请求)。QUIC 在传输层实现了独立的数据流,从根本上解决了这一问题。
- 更可靠的传输表现:在高丢包率网络环境下(如移动网络),QUIC 的表现明显优于 TCP。
截至 JEP 517 提出之时,HTTP/3 已被主流浏览器广泛支持,约三分之一的网站已部署了该协议。Java 平台作为服务端和客户端开发的重要基础设施,应当跟上这一趋势。
核心变更详解
显式选择加入(Opt-in)
JEP 517 的一个重要设计原则是不改变默认行为。升级到 JDK 26 后,现有代码的 HTTP Client 仍会继续使用 HTTP/2 作为默认协议,不会自动切换到 HTTP/3。开发者需要显式声明使用 HTTP/3,这确保了向后兼容性,降低了升级风险。
有两种方式可以启用 HTTP/3:
方式一:在 HttpClient 层面设置
1 | // 为 HttpClient 指定 HTTP/3 作为首选协议版本 |
方式二:在单个 HttpRequest 层面设置
1 | // 仅为本次请求指定 HTTP/3 作为首选协议版本 |
无论采用哪种方式,设置完成后发送请求的代码保持不变,无需额外改动。
协议版本协商机制
一个关键问题是:客户端无法提前知晓目标服务器是否支持 HTTP/3。此外,由于 HTTP/1.1 和 HTTP/2 基于 TCP 流,而 HTTP/3 基于 UDP 数据报,因此无法将已有的 HTTP/1.1 或 HTTP/2 连接直接升级为 HTTP/3 连接。
JEP 517 设计了四种协议协商策略:
- 先用 HTTP/3 尝试:发送首个请求时优先尝试建立 HTTP/3 连接。若在合理时间内无法建立连接,则自动降级到 HTTP/2 或 HTTP/1.1。这是当
HttpRequest单独指定HTTP_3时的行为。 - 并行竞速:同时尝试建立 HTTP/3 连接和 HTTP/2/HTTP/1.1 连接,谁先成功就用谁。这是当
HttpClient全局指定HTTP_3而HttpRequest未单独指定时的行为。 - Alt-Svc 服务端宣告:先用 HTTP/2 或 HTTP/1.1 发送首个请求,如果服务器在响应头中通过
Alt-Svc字段告知支持 HTTP/3,则后续请求切换至 HTTP/3。通过设置HttpOption.H3_DISCOVERY为Http3DiscoveryMode.ALT_SVC即可启用此模式。 - 强制仅使用 HTTP/3:只发送 HTTP/3 请求。若服务器不支持 HTTP/3,请求直接失败。
非目标(Non-Goals)
JEP 517 明确排除了以下几项工作:
- 不提供 QUIC 协议的公开 API:QUIC 作为 HTTP/3 的底层传输协议,其实现是 JDK 内部的、不对外暴露的。开发者无法通过 HTTP Client API 直接操作 QUIC 连接。
- 不支持第三方安全套接字提供者:HTTP/3 的 TLS 实现依赖于 JDK 内置的 SunJSSE 提供者,暂不支持第三方 JSSE 实现。
- 不提供服务端 HTTP/3 实现:此 JEP 仅面向客户端场景,不涉及服务端对 HTTP/3 的支持。
- 不更新传统的
java.net.URL协议处理器:遗留的URL类及其相关 API 仍然只支持 HTTP/1.1,不会获得 HTTP/3 能力。
与历史版本的关联
JEP 517 直接构建于 JEP 321(HTTP Client API) 之上。JEP 321 在 JDK 11 中引入 HTTP Client API 时,其架构设计就已经为未来协议扩展留好了接口。JEP 517 正是这一设计前瞻性的体现——新增 HTTP/3 支持几乎不需要改动 API 表面,开发者只需添加一行 .version(HTTP_3) 即可享受新协议带来的性能红利。
该特性已于 2026 年 3 月随 JDK 26 GA 版本正式交付。
兼容性与影响
JEP 517 对现有 Java 应用的兼容性影响极小:
- 默认行为不变:未显式设置
HTTP_3的代码行为与升级前完全一致,继续使用 HTTP/2。 - 透明降级:即使设置了
HTTP_3,当服务器不支持 HTTP/3 时,客户端会自动回退到 HTTP/2 或 HTTP/1.1,不会导致请求失败。 - API 纯增量扩展:仅新增了
HttpClient.Version.HTTP_3枚举值和Http3DiscoveryMode等少量配置选项,不影响已有 API 的使用。
对于希望利用 HTTP/3 优势的开发者来说,迁移成本极低——通常只需在 HttpClient.newBuilder() 后追加一行 .version(HttpClient.Version.HTTP_3),其余代码无需任何改动。
小结与展望
JEP 517 以极小的 API 改动成本,为 Java HTTP Client 带来了对 HTTP/3 协议的支持。这是 Java 平台在现代化网络协议方面迈出的重要一步,使 Java 应用得以享受 QUIC 带来的低延迟、抗丢包等网络优化收益。
值得一提的是,HTTP/3 的底层实现基于 DatagramChannel 和 SunJSSE,完全由 JDK 内部提供,无需引入第三方依赖。对于微服务架构、移动端后台、物联网等对网络延迟敏感的场景,这一特性具有直接的实用价值。
随着 HTTP/3 在互联网上的部署率持续攀升,Java 应用现在已具备了“原生”适配的能力,开发者可以放心地在新项目中启用 HTTP/3,或在现有项目中按需升级,而无需担心兼容性风险。




