JDK 17 异步 http request get

发布于:2025-06-11 ⋅ 阅读:(41) ⋅ 点赞:(0)

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); // 等待异步结果(实际项目无需)
    }
}

}


网站公告

今日签到

点亮在社区的每一天
去签到