新的 HTTP 客户端 API - Java 细品
Billy Korando 于 2022 年 6 月 27 日
需要通过 HTTP 发送或接收来自远程服务的数据吗?JDK 11 中添加的 HTTP 客户端改进了并替换了 HttpUrlConnection
API。在本文中,我们将探讨如何使用新的 HttpClient 以及它提供的一些 HttpUrlConnection
不具备的新功能。
HttpClient 概述
HTTP 客户端是在 JDK 11 中添加的,之前作为 JDK 9 中的孵化器功能引入。HTTP 客户端的目标是替换 HttpUrlConnection
,它不仅 API 难以使用,而且不支持 HTTP/2 和 WebSocket 等协议。
HTTP 客户端通过提供对 HTTP/2 和 WebSocket 的支持、更易于使用的 API 以及添加异步调用和响应式流等新功能来解决这些缺点。
创建客户端
通过其构建器 API 创建 HttpClient
的新实例
HttpClient client = HttpClient.newBuilder()
.version(Version.HTTP_1_1)
.followRedirects(Redirect.NORMAL)
.connectTimeout(Duration.ofSeconds(20))
.proxy(ProxySelector.of(...))
.authenticator(Authenticator.getDefault())
.build();
newBuilder()
有用于设置属性的方法,例如:HTTP 版本、重定向行为、代理、超时、身份验证器等等。创建后,HttpClient 是不可变的。
创建请求
与 HttpClient
一样,HttpRequest
也是通过其构建器 API 创建的
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://openjdk.org/"))
.timeout(Duration.ofSeconds(10))
.header("Content-Type",
"application/json")
.GET()
.build()
newBuilder()
提供用于设置属性的方法,例如:URI、超时、标头、HTTP 方法等等。与 HttpClient 一样,HttpRequest 是不可变的;但是,请求可以多次使用。
## 发送请求
请求可以作为同步阻塞调用或异步非阻塞调用发送。
同步请求
HttpResponse<String> response =
client.send(request,
BodyHandlers.ofString());
System.out.println(response.statusCode());
System.out.println(response.body());
异步请求
client.sendAsync(request,
BodyHandlers.ofString())
.thenApply(response ->
{ System.out.println
(response.statusCode());
return response;
} )
.thenApply(HttpResponse::body)
.thenAccept(System.out::println);
响应式流
异步请求也可以用作响应式流。作为响应式流,HttpRequest
充当发布者,HttpResponse
充当订阅者,其类中包含用于处理流的相应方法
public abstract class HttpRequest {
...
public interface BodyPublisher
extends Flow.Publisher<ByteBuffer>
{ ... }
}
public abstract class HttpResponse<T> {
...
public interface BodyHandler<T> {
BodySubscriber<T>
apply(int statusCode,
HttpHeaders responseHeaders);
}
public interface BodySubscriber<T>
extends
Flow.Subscriber<List<ByteBuffer>>
{ ... }
}
其他阅读资料
编码愉快!