杰瑞科技汇

Java HttpClient包如何高效使用?

  1. 传统的 HttpURLConnection (Java 标准库)
  2. 功能强大的 Apache HttpClient (第三方库)
  3. 现代化的 java.net.http (Java 11+) (Java 标准库)

下面我将详细介绍这三个包,并提供代码示例。

Java HttpClient包如何高效使用?-图1
(图片来源网络,侵删)

java.net.HttpURLConnection (Java 标准库)

这是 Java 最早内置的 HTTP 客户端 API,无需引入任何第三方依赖。

特点:

  • 优点:
    • 无需依赖: 作为 Java 标准库的一部分,开箱即用。
    • 简单场景足够: 对于简单的 GET/POST 请求,代码量不算太多。
  • 缺点:
    • API 过于陈旧: 设计于 Java 1.1,使用起来比较繁琐。
    • 功能有限: 对 HTTP/2 支持、连接池、异步请求等高级特性支持不佳或没有。
    • 阻塞式: 默认是同步的,实现异步和回调非常复杂。
    • 手动管理资源: 需要手动处理 InputStreamOutputStream,容易出错。

基本用法示例 (GET 请求):

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class HttpURLConnectionExample {
    public static void main(String[] args) throws Exception {
        String urlString = "https://jsonplaceholder.typicode.com/posts/1";
        URL url = new URL(urlString);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        // 设置请求方法
        connection.setRequestMethod("GET");
        // 设置请求头
        connection.setRequestProperty("User-Agent", "My-App/1.0");
        // 获取响应码
        int responseCode = connection.getResponseCode();
        System.out.println("Response Code: " + responseCode);
        if (responseCode == HttpURLConnection.HTTP_OK) { // 200
            // 读取响应内容
            try (BufferedReader in = new BufferedReader(
                    new InputStreamReader(connection.getInputStream()))) {
                String inputLine;
                StringBuilder response = new StringBuilder();
                while ((inputLine = in.readLine()) != null) {
                    response.append(inputLine);
                }
                System.out.println("Response Body: " + response.toString());
            }
        } else {
            System.out.println("GET request failed");
        }
        // 关闭连接
        connection.disconnect();
    }
}

只在极简单的工具或无法引入外部依赖的旧项目中使用。新项目不推荐


Apache HttpClient (第三方库)

这是多年来 Java 生态中最流行、功能最强大的 HTTP 客户端库,它提供了丰富、灵活且高度可定制的 API。

特点:

  • 优点:
    • 功能全面: 支持最新的 HTTP/1.1 和 HTTP/2 协议。
    • 强大的连接池: 内置高效的连接池管理,能显著提升性能。
    • 灵活的 API: 提供了构建器模式(RequestBuilder)、自定义拦截器、响应处理器等,非常灵活。
    • 丰富的功能: 支持异步请求、重试机制、Cookie 管理、代理等。
    • 稳定可靠: 经过大量项目验证,非常稳定。
  • 缺点:
    • 需要引入依赖: 需要在项目中添加 Maven 或 Gradle 依赖。
    • API 相对复杂: 相比于 Java 11 的 HttpClient,API 学习曲线稍陡峭。

Maven 依赖:

<dependency>
    <groupId>org.apache.httpcomponents.client5</groupId>
    <artifactId>httpclient5</artifactId>
    <version>5.3.1</version> <!-- 请使用最新版本 -->
</dependency>
<!-- 通常还需要 httpcore5 -->
<dependency>
    <groupId>org.apache.httpcomponents.core5</groupId>
    <artifactId>httpcore5</artifactId>
    <version>5.2.4</version> <!-- 请使用最新版本 -->
</dependency>

基本用法示例 (GET 请求):

import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.net.URIBuilder;
import java.net.URI;
import java.net.URISyntaxException;
public class ApacheHttpClientExample {
    public static void main(String[] args) throws Exception {
        // 1. 创建 HttpClient 实例
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            // 2. 创建 HttpGet 请求
            // 可以方便地构建带参数的 URL
            URI uri = new URIBuilder("https://jsonplaceholder.typicode.com/posts")
                    .addParameter("userId", "1")
                    .build();
            HttpGet request = new HttpGet(uri);
            // 3. 设置请求头
            request.setHeader("Accept", "application/json");
            request.setHeader("User-Agent", "My-App/1.0");
            System.out.println("Executing request: " + request.getMethod() + " " + request.getUri());
            // 4. 执行请求并获取响应
            try (CloseableHttpResponse response = httpClient.execute(request)) {
                System.out.println("Response status: " + response.getCode());
                // 5. 获取响应实体
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    // 将响应实体内容转换为字符串
                    String result = EntityUtils.toString(entity);
                    System.out.println("Response Body: " + result);
                    // 确保实体内容被完全消费,以便连接可以被重用
                    EntityUtils.consume(entity);
                }
            }
        }
    }
}

目前仍然是许多企业级项目的首选,因为它功能强大、稳定且社区支持好,如果你需要高级特性和对旧版本 Java 的兼容性,它是最佳选择。

Java HttpClient包如何高效使用?-图2
(图片来源网络,侵删)

java.net.http.HttpClient (Java 11+)

这是 Java 11 引入的官方现代化 HTTP 客户端,旨在替代老旧的 HttpURLConnection,并提供与 Apache HttpClient 相媲美的功能。

特点:

  • 优点:
    • 现代化 API: 设计简洁,采用了 Java 8 的 StreamCompletableFuture,易于使用。
    • 内置支持 HTTP/2 和 WebSocket: 原生支持,无需额外配置。
    • 异步支持: 异步 API 非常简洁,基于 CompletableFuture
    • 响应式编程: 可以轻松与 Project Reactor 等响应式框架集成。
    • 类型安全: 请求和响应模型更加类型化。
    • 标准库: 无需任何外部依赖。
  • 缺点:
    • Java 11+: 需要 Java 11 或更高版本。
    • 生态相对年轻: 虽然功能强大,但相比 Apache HttpClient,社区和生态还稍显年轻,第三方集成可能不如前者丰富。

基本用法示例 (同步 GET 请求):

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
public class Java11HttpClientExample {
    public static void main(String[] args) throws Exception {
        // 1. 创建 HttpClient 实例
        // 可以配置超时、代理、SSL 等
        HttpClient client = HttpClient.newBuilder()
                .version(HttpClient.Version.HTTP_2) // 强制使用 HTTP/2
                .connectTimeout(Duration.ofSeconds(10))
                .build();
        // 2. 创建 HttpRequest 请求
        HttpRequest request = HttpRequest.newBuilder()
                .GET()
                .uri(URI.create("https://jsonplaceholder.typicode.com/posts/1"))
                .header("Accept", "application/json")
                .header("User-Agent", "My-App/1.0")
                .timeout(Duration.ofSeconds(5)) // 单个请求的超时
                .build();
        // 3. 发送请求并获取响应 (同步)
        // HttpResponse.BodyHandlers 是一个工厂类,用于指定如何处理响应体
        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
        // 4. 处理响应
        System.out.println("Response status code: " + response.statusCode());
        System.out.println("Response headers: " + response.headers());
        System.out.println("Response Body: " + response.body());
    }
}

基本用法示例 (异步 GET 请求):

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.concurrent.CompletableFuture;
public class Java11HttpClientAsyncExample {
    public static void main(String[] args) {
        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://jsonplaceholder.typicode.com/posts/1"))
                .build();
        // 异步发送请求,返回一个 CompletableFuture
        CompletableFuture<HttpResponse<String>> futureResponse =
                client.sendAsync(request, HttpResponse.BodyHandlers.ofString());
        // 使用 thenAccept 来处理异步结果
        futureResponse.thenAccept(response -> {
            System.out.println("Async Response status code: " + response.statusCode());
            System.out.println("Async Response Body: " + response.body());
        });
        // 主线程需要等待,否则程序会立即退出
        // 在实际应用中,通常是一个持续运行的服务器或事件循环
        System.out.println("Request sent asynchronously. Waiting for response...");
        futureResponse.join(); // 阻塞等待异步操作完成
    }
}

对于新项目,如果使用 Java 11+,这是首选,它是 Java 未来的方向,API 现代且易用,性能优秀。


总结与对比

特性 HttpURLConnection Apache HttpClient java.net.http.HttpClient
来源 Java 标准库 第三方 (Apache) Java 标准库 (Java 11+)
依赖 无需 需要 Maven/Gradle 依赖 无需
易用性 中等
功能 基础 非常强大 强大
HTTP/2 不支持 支持 原生支持
异步支持 复杂 支持 (基于 Future) 优秀 (基于 CompletableFuture)
连接池 有,且强大 有,但配置不如 Apache 灵活
稳定性 一般 非常高 高 (Java 11+)
推荐场景 旧项目、极简单工具 企业级应用、复杂需求、兼容旧 Java 新项目、Java 11+ 环境、追求现代化 API

如何选择?

  • 新项目,使用 Java 11 或更高版本:

    • 首选 java.net.http.HttpClient,它是未来的方向,API 更现代化,无需管理依赖,性能和功能都足够强大。
  • 新项目,但必须使用 Java 8 或更早版本:

    • 选择 Apache HttpClient,它是该时代事实上的标准,功能强大且稳定。
  • 维护一个旧项目:

    • 如果项目已经在用 HttpURLConnection 且改动不大,可以维持现状。
    • 如果需要增加新功能或重构,强烈建议升级到 Apache HttpClient,以获得更好的性能和可维护性。
  • 无法引入任何外部依赖的特殊环境:

    • 只能选择 HttpURLConnection,但请务必谨慎处理资源和异常。
分享:
扫描分享到社交APP
上一篇
下一篇