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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package com.johnson.example;

import java.io.IOException;
import java.net.http.*;
import java.net.URI;

/**
* HttpClient Example
*
* @author johnson lin
* @date 2026/4/27 01:08
*/
public class HttpClientExample {
static void main() throws IOException, InterruptedException {
var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder(URI.create("https://openjdk.org/"))
.GET()
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
assert response.statusCode() == 200;
String htmlText = response.body();

System.out.printf(htmlText);
}
}

这段代码中没有任何地方显式依赖 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
2
3
4
5
// 为 HttpClient 指定 HTTP/3 作为首选协议版本
// 此后通过该 client 发送的所有请求都将优先尝试 HTTP/3
var client = HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_3) // 显式启用 HTTP/3
.build();

方式二:在单个 HttpRequest 层面设置

1
2
3
4
5
// 仅为本次请求指定 HTTP/3 作为首选协议版本
var request = HttpRequest.newBuilder(URI.create("https://openjdk.org/"))
.version(HttpClient.Version.HTTP_3) // 仅此请求使用 HTTP/3
.GET()
.build();

无论采用哪种方式,设置完成后发送请求的代码保持不变,无需额外改动。

协议版本协商机制

一个关键问题是:客户端无法提前知晓目标服务器是否支持 HTTP/3。此外,由于 HTTP/1.1 和 HTTP/2 基于 TCP 流,而 HTTP/3 基于 UDP 数据报,因此无法将已有的 HTTP/1.1 或 HTTP/2 连接直接升级为 HTTP/3 连接。

JEP 517 设计了四种协议协商策略:

  1. 先用 HTTP/3 尝试:发送首个请求时优先尝试建立 HTTP/3 连接。若在合理时间内无法建立连接,则自动降级到 HTTP/2 或 HTTP/1.1。这是当 HttpRequest 单独指定 HTTP_3 时的行为。
  2. 并行竞速:同时尝试建立 HTTP/3 连接和 HTTP/2/HTTP/1.1 连接,谁先成功就用谁。这是当 HttpClient 全局指定 HTTP_3HttpRequest 未单独指定时的行为。
  3. Alt-Svc 服务端宣告:先用 HTTP/2 或 HTTP/1.1 发送首个请求,如果服务器在响应头中通过 Alt-Svc 字段告知支持 HTTP/3,则后续请求切换至 HTTP/3。通过设置 HttpOption.H3_DISCOVERYHttp3DiscoveryMode.ALT_SVC 即可启用此模式。
  4. 强制仅使用 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,或在现有项目中按需升级,而无需担心兼容性风险。