java.net.http.HttpClient API 允许 Java 应用创建可重用的 HTTP 客户端实例,构建 HTTP 请求,并同步或异步处理响应。自 JDK 11 起,你可以在 HttpClient 或 HttpRequest 层设置首选的 HTTP 协议版本,如 HTTP/1.1 或 HTTP/2。
JEP 517 在 JDK 26 中引入了对 HTTP/3( HttpClient.Version.HTTP_3 )的支持,使应用能够为请求优先选择或强制使用 HTTP/3。虽然 HTTP/3 在协议级别提供了与 HTTP/2 类似的功能,但其关键区别在于它使用 UDP 基于 QUIC 协议运行,而 HTTP/2 基于 TCP 运行。以下是一个代码片段,展示了如何优先选择或强制使用 HTTP/3:
java
// prefer HTTP/3
HttpClient client = HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_3)
.build();
// if target server support HTTP/3, add this to enforce it
HttpRequest req = HttpRequest.newBuilder()
.uri(new URI("https://www.google.com/"))
.setOption(HttpOption.H3_DISCOVERY, Http3DiscoveryMode.HTTP_3_URI_ONLY)
.build();
HttpResponse<String> resp = client.send(req, BodyHandlers.ofString(StandardCharsets.UTF_8));
System.out.println("status code: " + resp.statusCode() + " HTTP protocol version: " + resp.version());
如果你设置了 HTTP/3 但它不可用,客户端将自动降级到 HTTP/2 或 HTTP/1.1。如果你配置为严格要求 HTTP/3,失败尝试将导致异常而不是降级。
然而,将 HTTP/3 设为首选版本并不能保证其使用,因为客户端无法事先知道服务器是否支持它。对于首次向服务器发起请求时,客户端会尝试 TCP(HTTP/2)和 UDP(HTTP/3)两种连接,并使用第一个成功的连接。随着时间的推移,客户端可以通过使用"Alt-Svc"机制(根据 RFC 7838 的"HTTP Alternative Services"标准)来"学习"服务器支持的 HTTP 版本。支持"Alt-Svc"的服务器会宣传替代支持的协议,如 HTTP/3。这允许后续请求在服务器支持时使用 HTTP/3。