- 传统的
HttpURLConnection(Java 标准库) - 功能强大的
Apache HttpClient(第三方库) - 现代化的
java.net.http(Java 11+) (Java 标准库)
下面我将详细介绍这三个包,并提供代码示例。

java.net.HttpURLConnection (Java 标准库)
这是 Java 最早内置的 HTTP 客户端 API,无需引入任何第三方依赖。
特点:
- 优点:
- 无需依赖: 作为 Java 标准库的一部分,开箱即用。
- 简单场景足够: 对于简单的 GET/POST 请求,代码量不算太多。
- 缺点:
- API 过于陈旧: 设计于 Java 1.1,使用起来比较繁琐。
- 功能有限: 对 HTTP/2 支持、连接池、异步请求等高级特性支持不佳或没有。
- 阻塞式: 默认是同步的,实现异步和回调非常复杂。
- 手动管理资源: 需要手动处理
InputStream和OutputStream,容易出错。
基本用法示例 (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.net.http.HttpClient (Java 11+)
这是 Java 11 引入的官方现代化 HTTP 客户端,旨在替代老旧的 HttpURLConnection,并提供与 Apache HttpClient 相媲美的功能。
特点:
- 优点:
- 现代化 API: 设计简洁,采用了 Java 8 的
Stream和CompletableFuture,易于使用。 - 内置支持 HTTP/2 和 WebSocket: 原生支持,无需额外配置。
- 异步支持: 异步 API 非常简洁,基于
CompletableFuture。 - 响应式编程: 可以轻松与 Project Reactor 等响应式框架集成。
- 类型安全: 请求和响应模型更加类型化。
- 标准库: 无需任何外部依赖。
- 现代化 API: 设计简洁,采用了 Java 8 的
- 缺点:
- 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,但请务必谨慎处理资源和异常。
- 只能选择
