java.net.http 包详解

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();

最佳实践

  1. 重用 HttpClient:HttpClient 是线程安全的,应该重用而不是为每个请求创建新实例

  2. 处理超时:总是设置合理的连接和请求超时

  3. 错误处理:正确处理 HTTP 错误状态码和异常

  4. 资源管理:确保关闭响应体和输入流

  5. 性能考虑:对于大量请求,考虑使用异步模式

java.net.http 包提供了现代 HTTP 客户端所需的所有功能,是 Java 应用程序中进行 HTTP 通信的首选方式。

相关推荐
小Ti客栈7 小时前
Spring Boot 集成 Springdoc-OpenAPI 与 Knife4j实现接口文档与可视化调试
java·spring boot·后端
Ai拆代码的曹操8 小时前
Spring 事务 REQUIRES_NEW 嵌套调用:连接池翻倍的秘密
java·后端·spring
动恰客流统计9 小时前
ReID边缘计算视觉统计:餐饮店客流增长的数字化破局路径
java·大数据·运维·人工智能
Ivanqhz9 小时前
Rust &‘static str浅析
java·前端·javascript·rust
iReachers11 小时前
.NET项目集成混淆加密:自动化保护DLL和EXE
.net·代码保护·自动构建·msbuild·c#混淆
weixin_4196583112 小时前
Docker 搭建 Jenkins 服务
java·docker·jenkins
会编程的土豆12 小时前
MySQL 入门:库、表、行、主键是什么
linux·数据库·网络协议·http
captain37612 小时前
多线程线程安全问题
java·java-ee
CoderYanger13 小时前
A.每日一题:1979. 找出数组的最大公约数
java·程序人生·算法·leetcode·面试·职场和发展·学习方法
灵极海13 小时前
LangChain4j RAG 实战完整指南:从入门到踩坑
java·langchain