探索 Java 中的新 HTTP 客户端

探索 Java 中的新 HTTP 客户端
(java.net.http.HttpClient,从 Java 11 开始的标准 HTTP 客户端)

从 Java 11 开始,JDK 正式引入了现代化的 HttpClient(java.net.http 包),它取代了老旧的 HttpURLConnection,并成为推荐的内置 HTTP 客户端。

这个客户端支持 HTTP/1.1HTTP/2(甚至未来 JDK 26+ 支持 HTTP/3),同时提供同步和异步两种调用方式,API 设计简洁、现代、功能强大,且零依赖

下面从零基础到生产级用法,一次性讲透。

一、为什么用新的 HttpClient?(对比老方式)

特性HttpURLConnection (老古董)Apache HttpClient / OkHttp新 HttpClient (Java 11+)
引入版本JDK 1.1第三方依赖JDK 11(9/10 孵化)
依赖需要引入 jar无(JDK 自带)
HTTP/2 支持不支持支持(部分版本)原生支持
异步支持几乎无支持(回调/Future)原生 CompletableFuture
API 现代程度非常老旧较好Builder 风格、流式
WebSocket不支持OkHttp 支持支持
性能一般优秀优秀(尤其是 HTTP/2)
推荐场景遗留系统需要极致配置/兼容性新项目首选

结论

  • Java 11+ 新项目 → 优先用 java.net.http.HttpClient
  • 需要极致自定义或 Java 8 → 考虑 OkHttp / Apache HttpClient 5
  • Spring Boot 3+ → 可以用 RestClient(底层基于 HttpClient)

二、快速上手(最常用写法)

1. 同步 GET 请求(最简单)

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.http.HttpResponse.BodyHandlers;

public class SimpleGet {
    public static void main(String[] args) throws Exception {
        HttpClient client = HttpClient.newHttpClient();

        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://api.github.com"))
                .header("Accept", "application/json")
                .GET()
                .build();

        HttpResponse<String> response = client.send(request, BodyHandlers.ofString());

        System.out.println("状态码: " + response.statusCode());
        System.out.println("Body: " + response.body());
    }
}

2. 异步 GET(推荐高并发场景)

HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create("https://api.example.com/data"))
        .build();

client.sendAsync(request, BodyHandlers.ofString())
      .thenApply(HttpResponse::body)
      .thenAccept(System.out::println)
      .join();  // 等待完成(生产中通常不 join)

3. POST JSON(常见场景)

String json = """
    {
        "name": "张三",
        "age": 28
    }
    """;

HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create("https://api.example.com/users"))
        .header("Content-Type", "application/json")
        .POST(HttpRequest.BodyPublishers.ofString(json))
        .build();

4. 表单 POST(x-www-form-urlencoded)

String form = "username=admin&password=123456";

HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create("https://example.com/login"))
        .header("Content-Type", "application/x-www-form-urlencoded")
        .POST(HttpRequest.BodyPublishers.ofString(form))
        .build();

5. 上传文件(Multipart)

HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create("https://example.com/upload"))
        .header("Content-Type", "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW")
        .POST(HttpRequest.BodyPublishers.ofFile(Path.of("photo.jpg")))
        .build();

(复杂 multipart 推荐用第三方库辅助构建 body,或自己拼接)

三、创建 HttpClient 的最佳实践(生产级配置)

HttpClient client = HttpClient.newBuilder()
        .version(HttpClient.Version.HTTP_2)           // 优先 HTTP/2
        //.version(HttpClient.Version.HTTP_1_1)       // 强制 HTTP/1.1
        .followRedirects(HttpClient.Redirect.NORMAL) // 自动重定向(除 https→http)
        .connectTimeout(Duration.ofSeconds(10))
        .sslContext(SSLContext.getDefault())          // 自定义 SSL
        //.executor(Executors.newFixedThreadPool(16)) // 自定义线程池(异步用)
        .build();

推荐不要每次请求都 new HttpClient,而是复用一个实例(内部有连接池,支持 HTTP/2 多路复用)。

四、常见高级用法

  1. 流式响应(处理大文件下载)
HttpResponse<Stream<String>> response = client.send(
    request, 
    HttpResponse.BodyHandlers.ofLines()
);
  1. WebSocket 支持
HttpClient client = HttpClient.newHttpClient();
WebSocket ws = client.newWebSocketBuilder()
        .buildAsync(URI.create("wss://echo.websocket.org"), new WebSocket.Listener() {
            // onOpen, onText, onClose 等回调
        })
        .join();
  1. 认证(Basic / Bearer)
HttpRequest request = HttpRequest.newBuilder()
        .uri(...)
        .header("Authorization", "Bearer " + token)
        .build();

五、常见问题 & 最佳实践(2024-2025)

  • 连接池:HttpClient 内部自动管理,不要频繁创建实例
  • 异常处理:send() 抛出 IOException / InterruptedException,sendAsync 用 exceptionally()
  • 超时:connectTimeout + request timeout(通过 Duration)
  • HTTP/3:JDK 26+ 支持(目前实验阶段)
  • 与 Spring 集成:Spring Boot 3+ 的 RestClient / WebClient 底层可基于 HttpClient
  • 性能:HTTP/2 下复用连接 + 多路复用,性能接近甚至优于很多第三方库

六、总结一句话

Java 11+ 的 HttpClient 是现代 Java 网络编程的首选:零依赖、支持 HTTP/2、同步/异步一体的流式 API、WebSocket 支持、简洁强大。

推荐口诀

  • 小项目 / 快速原型 → 直接 newHttpClient()
  • 中大型项目 → 复用一个配置好的 HttpClient 实例
  • 高并发 → 优先异步 + CompletableFuture 链式调用
  • 需要极致功能(如自动重试、连接池精细控制)→ 再考虑 OkHttp / Apache HttpClient 5

想看具体场景的完整示例吗?(如 OAuth2 认证、文件上传、SSE、结合虚拟线程等)欢迎继续问~

文章已创建 4455

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部