在 Java 中,java.net.http.HttpClient
是一个现代化的 HTTP 客户端,自 Java 11 起引入,用于替代旧的 HttpURLConnection
。它支持 HTTP/1.1 和 HTTP/2,提供异步非阻塞 API,并支持流式处理请求和响应。
1. 创建 HttpClient 实例
import java.net.http.HttpClient;
import java.time.Duration;
// 创建默认配置的HttpClient
HttpClient client = HttpClient.newHttpClient();
// 自定义配置的HttpClient
HttpClient customClient = HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_2) // 使用HTTP/2
.followRedirects(HttpClient.Redirect.NORMAL) // 自动重定向
.connectTimeout(Duration.ofSeconds(10)) // 连接超时
.build();
2. 发送 GET 请求(同步)
import java.net.URI;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
// 构建GET请求
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.example.com/data"))
.header("User-Agent", "Java HttpClient")
.build();
// 发送请求并获取响应
try {
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println("状态码: " + response.statusCode());
System.out.println("响应体: " + response.body());
} catch (Exception e) {
e.printStackTrace();
}
带参数的HTTP GET请求示例如下:
将参数键值对编码后用&
连接,添加到 URL 的?
后面:
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
public class HttpClientGetExample {
public static void main(String[] args) throws Exception {
// 参数键值对
String param1 = "value1";
String param2 = "特殊字符!@#$";
// 构建查询字符串(手动编码参数)
String query = String.format("param1=%s¶m2=%s",
URLEncoder.encode(param1, StandardCharsets.UTF_8),
URLEncoder.encode(param2, StandardCharsets.UTF_8)
);
// 拼接完整URL
String url = "https://api.example.com/data?" + query;
// 创建HTTP请求
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.GET() // 可省略,默认是GET
.build();
// 发送请求
client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
.thenApply(HttpResponse::body)
.thenAccept(System.out::println)
.join();
}
}
3. 发送 POST 请求(带 JSON)
import java.net.URI;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
// 请求JSON数据
String jsonBody = """
{
"name": "John",
"age": 30
}
""";
// 构建POST请求
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.example.com/submit"))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(jsonBody, StandardCharsets.UTF_8))
.build();
// 发送请求
try {
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println("状态码: " + response.statusCode());
System.out.println("响应体: " + response.body());
} catch (Exception e) {
e.printStackTrace();
}
4. 处理响应体为文件
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Path;
import java.nio.file.Paths;
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://example.com/file.zip"))
.build();
try {
Path filePath = Paths.get("downloaded_file.zip");
HttpResponse<Path> response = client.send(
request,
HttpResponse.BodyHandlers.ofFile(filePath)
);
System.out.println("文件下载完成: " + filePath);
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
5. 异步请求处理
import java.net.URI;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.concurrent.CompletableFuture;
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.example.com/large-data"))
.build();
// 异步发送请求
CompletableFuture<HttpResponse<String>> future = client.sendAsync(
request,
HttpResponse.BodyHandlers.ofString()
);
// 处理完成后的回调
future.thenApply(HttpResponse::body)
.thenAccept(body -> System.out.println("异步响应: " + body))
.exceptionally(ex -> {
System.err.println("请求失败: " + ex.getMessage());
return null;
});
// 主线程可以继续执行其他任务
System.out.println("主线程继续执行...");
关键类说明:
- HttpClient:用于构建和配置 HTTP 客户端实例。
- HttpRequest:用于构建 HTTP 请求,支持链式调用设置 URL、方法、头信息和请求体。
- HttpResponse:表示 HTTP 响应,包含状态码、头信息和响应体。
- BodyHandlers:用于处理响应体的静态工厂方法(如
ofString()
、ofFile()
、ofByteArray()
等)。 - BodyPublishers:用于构建请求体的静态工厂方法(如
ofString()
、ofFile()
等)。
注意事项:
- 异常处理:同步请求需处理
IOException
和InterruptedException
,异步请求通过exceptionally()
处理异常。 - HTTP/2 支持:默认启用 HTTP/2,但服务器需支持才能使用。
- 异步编程:使用
CompletableFuture
处理异步操作,避免阻塞主线程。