java.net.http 包是 Java 11 引入的 HTTP 客户端 API,提供了现代、灵活且功能强大的 HTTP 客户端功能,替代了传统的 HttpURLConnection。
核心类
1. HttpClient
HTTP 客户端的主要入口点,用于发送请求和接收响应。
主要特性:
-
支持 HTTP/1.1 和 HTTP/2
-
同步和异步请求
-
WebSocket 支持
-
连接池管理
-
重定向处理
-
认证支持
创建 HttpClient 示例:
java
HttpClient client = HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_2) // 使用HTTP/2
.followRedirects(HttpClient.Redirect.NORMAL) // 跟随重定向
.connectTimeout(Duration.ofSeconds(20)) // 连接超时
.proxy(ProxySelector.of(new InetSocketAddress("proxy.example.com", 80))) // 代理
.authenticator(Authenticator.getDefault()) // 认证
.build();
2. HttpRequest
表示要发送的 HTTP 请求。
构建请求示例:
java
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://example.com/api"))
.header("Content-Type", "application/json")
.timeout(Duration.ofMinutes(2))
.POST(HttpRequest.BodyPublishers.ofString("{\"key\":\"value\"}"))
.build();
BodyPublishers 类型:
-
ofString()- 从字符串创建请求体 -
ofByteArray()- 从字节数组创建请求体 -
ofFile()- 从文件创建请求体 -
noBody()- 无请求体
3. HttpResponse
表示接收到的 HTTP 响应。
处理响应体:
-
body()- 获取响应体 -
BodyHandlers用于处理响应体:-
ofString()- 将响应体作为字符串 -
ofByteArray()- 将响应体作为字节数组 -
ofFile()- 将响应体写入文件 -
discarding()- 丢弃响应体
-
同步请求示例
java
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://example.com"))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println("Status code: " + response.statusCode());
System.out.println("Response body: " + response.body());
异步请求示例
java
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://example.com"))
.build();
client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
.thenApply(HttpResponse::body)
.thenAccept(System.out::println)
.join(); // 等待完成
WebSocket 支持
java
HttpClient client = HttpClient.newHttpClient();
WebSocket webSocket = client.newWebSocketBuilder()
.buildAsync(URI.create("ws://example.com/chat"), new WebSocket.Listener() {
@Override
public void onOpen(WebSocket webSocket) {
System.out.println("WebSocket opened");
webSocket.sendText("Hello", true);
WebSocket.Listener.super.onOpen(webSocket);
}
@Override
public CompletionStage<?> onText(WebSocket webSocket, CharSequence data, boolean last) {
System.out.println("Received message: " + data);
return WebSocket.Listener.super.onText(webSocket, data, last);
}
}).join();
高级特性
1. 多部分请求
java
String boundary = "boundary";
HttpRequest request = HttpRequest.newBuilder()
.header("Content-Type", "multipart/form-data; boundary=" + boundary)
.POST(HttpRequest.BodyPublishers.ofByteArrays(Arrays.asList(
"--boundary\r\nContent-Disposition: form-data; name=\"field1\"\r\n\r\nvalue1\r\n".getBytes(),
"--boundary\r\nContent-Disposition: form-data; name=\"file\"; filename=\"test.txt\"\r\nContent-Type: text/plain\r\n\r\nFile content\r\n".getBytes(),
"--boundary--\r\n".getBytes()
)))
.build();
2. 处理响应流
java
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://example.com/large-file"))
.build();
HttpResponse<InputStream> response = client.send(request, HttpResponse.BodyHandlers.ofInputStream());
try (InputStream is = response.body()) {
// 处理输入流
byte[] buffer = new byte[8192];
int bytesRead;
while ((bytesRead = is.read(buffer)) != -1) {
// 处理数据块
}
}
3. 请求拦截器
java
HttpClient client = HttpClient.newBuilder()
.executor(Executors.newFixedThreadPool(5))
.authenticator(new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("user", "password".toCharArray());
}
})
.build();
最佳实践
-
重用 HttpClient:HttpClient 是线程安全的,应该重用而不是为每个请求创建新实例
-
处理超时:总是设置合理的连接和请求超时
-
错误处理:正确处理 HTTP 错误状态码和异常
-
资源管理:确保关闭响应体和输入流
-
性能考虑:对于大量请求,考虑使用异步模式
java.net.http 包提供了现代 HTTP 客户端所需的所有功能,是 Java 应用程序中进行 HTTP 通信的首选方式。