package org.example.newFeatures.HttpClient;
import java.net.URI;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import java.util.concurrent.CompletableFuture;
public class HttpClient {
private final java.net.http.HttpClient client = java.net.http.HttpClient.newHttpClient();
public static void main(String[] args) throws Exception {
HttpClient httpClint = new HttpClient();
// httpClint.httpGet();
httpClint.httpSendAsync();
}
public void httpGet() throws Exception {
// 1. 创建 HttpClient 实例(线程安全,建议复用)
java.net.http.HttpClient client = java.net.http.HttpClient.newHttpClient(); // [1](@ref)
// 2. 构建 GET 请求
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://www.sina.1com.1cn/")) // 目标 URL
.GET() // 默认为 GET,可省略
.build(); // [1,3](@ref)
// 3. 发送同步请求,将响应体解析为字符串
HttpResponse<String> response = client.send(
request,
HttpResponse.BodyHandlers.ofString()
);
// 4. 输出结果
System.out.println("状态码: " + response.statusCode());
System.out.println("响应体: " + response.body());
}
public void httpSendAsync() throws InterruptedException {
// 1. 创建HTTP客户端(支持HTTP/2和HTTP/3)
java.net.http.HttpClient client = java.net.http.HttpClient.newBuilder()
.version(java.net.http.HttpClient.Version.HTTP_2) // 启用HTTP/2协议[3,6](@ref)
.connectTimeout(Duration.ofSeconds(10)) // 连接超时设置
.build();
// 2. 构建请求对象
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://www.sina.com.cn/"))
.timeout(Duration.ofSeconds(15)) // 请求超时设置[1](@ref)
.header("User-Agent", "JDK17-AsyncClient") // 自定义请求头
.GET() // GET请求方法
.build();
System.out.println("▶ 开始异步请求,主线程继续执行...");
// 3. 发送异步请求并处理响应
CompletableFuture<Void> future = client.sendAsync(
request,
HttpResponse.BodyHandlers.ofString() // 响应体转为字符串
).thenApply(response -> {
// 状态码检查(非200系列抛出异常)
if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new RuntimeException("HTTP错误: " + response.statusCode());
}
return response;
}).thenApply(HttpResponse::body) // 提取响应体[3](@ref)
.thenAccept(body -> {
// 4. 打印响应结果(截取前100字符示例)
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("\n▼ 响应内容 (前100字符):\n"
+ body.substring(0, Math.min(100, body.length())) + "...");
}).exceptionally(e -> {
// 5. 异常处理(提取根本原因)
Throwable root = e;
while (root.getCause() != null) root = root.getCause();
System.err.println("❌ 请求失败: " + root.getMessage());
return null;
});
// 6. 非阻塞完成通知
future.whenComplete((res, ex) -> {
if (ex == null) {
try {
Thread.sleep(6000); // 阻塞当前线程3000毫秒
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("✅ 异步操作已完成");
}
});
// 主线程继续执行(演示用)
for (int i=1; i<=100; i++) {
System.out.println("▶ 主线程执行其他任务..." + i);
Thread.sleep(1000); // 等待异步结果(实际项目无需)
}
}
}