Java HttpClient使用手册
在 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));// 拼接完整URLString 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
处理异步操作,避免阻塞主线程。