一、原生Java HTTP组件
1.1 HttpURLConnection(Java核心API)
java
// JDK 1.1+ 内置,无需额外依赖
URL url = new URL("https://api.example.com/data");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// 配置
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
conn.setReadTimeout(5000);
conn.setRequestProperty("Content-Type", "application/json");
// 发送请求
int responseCode = conn.getResponseCode();
String response = new String(conn.getInputStream().readAllBytes());
特性分析:
- ✅ 优点:JDK内置,零依赖
- ✅ 支持HTTP/1.1,基本功能完整
- ❌ 缺点:API古老,不支持HTTP/2
- ❌ 连接管理弱,需手动实现连接池
- ❌ 异步支持差,代码冗长
1.2 HttpClient(Java 11+)
java
// Java 11 引入的标准HTTP客户端
HttpClient client = HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_2) // HTTP/2支持
.connectTimeout(Duration.ofSeconds(10))
.executor(Executors.newVirtualThreadPerTaskExecutor()) // Java 21虚拟线程
.build();
// 同步请求
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.example.com"))
.header("Content-Type", "application/json")
.timeout(Duration.ofSeconds(30))
.POST(HttpRequest.BodyPublishers.ofString(jsonBody))
.build();
HttpResponse<String> response = client.send(request,
HttpResponse.BodyHandlers.ofString());
// 异步请求
CompletableFuture<HttpResponse<String>> future =
client.sendAsync(request, HttpResponse.BodyHandlers.ofString());
future.thenApply(HttpResponse::body)
.thenAccept(System.out::println);
特性分析:
- ✅ 现代API设计,支持HTTP/2和WebSocket
- ✅ 原生异步支持
- ✅ JDK内置,无外部依赖
- ❌ 需Java 11+,Java 8无法使用
- ❌ 功能相对简单,无连接池高级管理
二、Apache HttpClient
2.1 经典版本(4.x)
java
// 添加依赖
// implementation 'org.apache.httpcomponents:httpclient:4.5.14'
// 连接池配置
PoolingHttpClientConnectionManager cm =
new PoolingHttpClientConnectionManager();
cm.setMaxTotal(200); // 最大连接数
cm.setDefaultMaxPerRoute(20); // 每个路由最大连接数
// 连接保活策略
cm.setValidateAfterInactivity(30000); // 30秒后验证连接
// 创建HttpClient
CloseableHttpClient httpClient = HttpClients.custom()
.setConnectionManager(cm)
.setDefaultRequestConfig(RequestConfig.custom()
.setConnectTimeout(5000)
.setSocketTimeout(30000)
.setConnectionRequestTimeout(5000)
.build())
.setRetryHandler(new DefaultHttpRequestRetryHandler(3, true))
.setKeepAliveStrategy((response, context) -> 30000)
.evictIdleConnections(30, TimeUnit.SECONDS) // 定期清除空闲连接
.build();
// 执行请求
HttpGet httpGet = new HttpGet("https://api.example.com");
httpGet.setHeader("Authorization", "Bearer token");
try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
HttpEntity entity = response.getEntity();
String result = EntityUtils.toString(entity);
EntityUtils.consume(entity); // 确保连接释放
}
2.2 HTTP/5版本(新特性)
java
// implementation 'org.apache.httpcomponents.client5:httpclient5:5.2.1'
// HTTP/2支持
H2Config h2Config = H2Config.custom()
.setPushEnabled(false)
.build();
CloseableHttpClient client = HttpClients.custom()
.setVersionPolicy(HttpVersionPolicy.NEGOTIATE)
.setConnectionManager(connectionManager)
.build();
// 异步HTTP/2请求
SimpleHttpRequest request = SimpleHttpRequest.get(uri);
client.execute(request, new FutureCallback<SimpleHttpResponse>() {
@Override
public void completed(SimpleHttpResponse result) {
// 处理成功
}
// ... 其他回调
});
特性分析:
- ✅ 功能最全面,连接管理完善
- ✅ 支持HTTP/2(5.x版本)
- ✅ 完善的Cookie管理、认证、缓存
- ✅ 丰富的拦截器机制
- ❌ 依赖较大,学习成本高
- ❌ API较复杂,代码冗长
三、OkHttp
3.1 基础使用
java
// implementation 'com.squareup.okhttp3:okhttp:4.12.0'
// 全局配置
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.retryOnConnectionFailure(true)
// 连接池配置
.connectionPool(new ConnectionPool(
20, // 最大空闲连接
5, TimeUnit.MINUTES)) // 保活时间
// 拦截器
.addInterceptor(new LoggingInterceptor())
.addNetworkInterceptor(chain -> {
Request request = chain.request().newBuilder()
.addHeader("User-Agent", "MyApp/1.0")
.build();
return chain.proceed(request);
})
// 事件监听
.eventListener(new EventListener() {
@Override
public void callStart(Call call) {
// 记录请求开始
}
})
.build();
// 同步请求
Request request = new Request.Builder()
.url("https://api.example.com")
.header("Authorization", "Bearer token")
.get()
.build();
try (Response response = client.newCall(request).execute()) {
String body = response.body().string();
}
// 异步请求
client.newCall(request).enqueue(new Callback() {
@Override
public void onResponse(Call call, Response response) {
// 主线程外执行
}
@Override
public void onFailure(Call call, IOException e) {
// 错误处理
}
});
3.2 高级特性
java
// 1. 连接复用与线程池
Dispatcher dispatcher = new Dispatcher();
dispatcher.setMaxRequests(64); // 最大并发请求
dispatcher.setMaxRequestsPerHost(5); // 每个主机最大并发
// 2. WebSocket支持
WebSocket ws = client.newWebSocket(request, new WebSocketListener() {
@Override
public void onMessage(WebSocket webSocket, String text) {
System.out.println("收到消息: " + text);
}
});
// 3. 缓存机制
Cache cache = new Cache(new File("./http_cache"), 10 * 1024 * 1024);
OkHttpClient cachedClient = client.newBuilder()
.cache(cache)
.build();
// 4. 自定义DNS
Dns customDns = hostname -> {
// 自定义DNS解析逻辑
return InetAddress.getAllByName(hostname);
};
特性分析:
- ✅ API设计优雅,使用简单
- ✅ 默认开启HTTP/2和连接复用
- ✅ 拦截器链式调用,功能强大
- ✅ 连接池自动管理
- ✅ 轻量级,性能优秀
- ❌ 依赖Kotlin运行时(4.x后)
- ❌ 不支持Transfer-Encoding: chunked请求体
四、Retrofit(HTTP客户端框架)
4.1 声明式HTTP客户端
java
// implementation 'com.squareup.retrofit2:retrofit:2.9.0'
// implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
// 定义接口
public interface ApiService {
@GET("users/{id}")
Call<User> getUser(@Path("id") long userId);
@POST("users")
@Headers("Content-Type: application/json")
Call<User> createUser(@Body User user);
@Multipart
@POST("upload")
Call<ResponseBody> uploadFile(@Part MultipartBody.Part file);
// 协程支持
@GET("users/{id}")
suspend fun getUserSuspend(@Path("id") id: Long): User
}
// 构建Retrofit实例
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.example.com/")
.client(okHttpClient) // 复用OkHttp能力
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava3CallAdapterFactory.create())
.build();
// 使用
ApiService service = retrofit.create(ApiService.class);
Call<User> call = service.getUser(123);
call.enqueue(new Callback<User>() {
@Override
public void onResponse(Call<User> call, Response<User> response) {
User user = response.body();
}
@Override
public void onFailure(Call<User> call, Throwable t) {
// 错误处理
}
});
特性分析:
- ✅ 声明式API,开发效率高
- ✅ 天然支持异步和响应式
- ✅ 自动序列化/反序列化
- ✅ 可扩展的Converter/Adapter
- ❌ 需搭配OkHttp使用
- ❌ 学习曲线(注解体系)
五、Spring生态HTTP组件
5.1 RestTemplate(传统)
java
// Spring自带
@Bean
public RestTemplate restTemplate() {
// 使用HttpComponentsClientHttpRequestFactory
HttpComponentsClientHttpRequestFactory factory =
new HttpComponentsClientHttpRequestFactory();
factory.setConnectTimeout(5000);
factory.setReadTimeout(30000);
RestTemplate restTemplate = new RestTemplate(factory);
// 添加拦截器
restTemplate.setInterceptors(Collections.singletonList(
(request, body, execution) -> {
request.getHeaders().add("Authorization", "Bearer token");
return execution.execute(request, body);
}
));
return restTemplate;
}
// 使用
String result = restTemplate.getForObject(
"https://api.example.com/data", String.class);
ResponseEntity<User> response = restTemplate.postForEntity(
"https://api.example.com/users",
user,
User.class);
5.2 WebClient(响应式)
java
// Spring WebFlux - 现代替代
@Bean
public WebClient webClient() {
// 连接池配置
ConnectionProvider provider = ConnectionProvider.builder("custom")
.maxConnections(500)
.maxIdleTime(Duration.ofSeconds(20))
.maxLifeTime(Duration.ofSeconds(60))
.pendingAcquireTimeout(Duration.ofSeconds(60))
.evictInBackground(Duration.ofSeconds(120))
.build();
HttpClient httpClient = HttpClient.create(provider)
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000)
.responseTimeout(Duration.ofSeconds(30))
.compress(true);
return WebClient.builder()
.clientConnector(new ReactorClientHttpConnector(httpClient))
.baseUrl("https://api.example.com")
.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.filter(ExchangeFilterFunction.ofRequestProcessor(request -> {
// 日志记录
log.info("Request: {} {}", request.method(), request.url());
return Mono.just(request);
}))
.build();
}
// 使用(响应式)
Mono<User> userMono = webClient.get()
.uri("/users/{id}", 123)
.retrieve()
.bodyToMono(User.class);
// 错误处理
userMono
.onErrorResume(WebClientResponseException.class, ex -> {
if (ex.getStatusCode() == HttpStatus.NOT_FOUND) {
return Mono.just(new User()); // 降级
}
return Mono.error(ex);
})
.subscribe(user -> {
// 处理结果
});
5.3 RestClient(Spring 6.1+)
java
// Spring Boot 3.2+ 引入的同步HTTP客户端
@Bean
public RestClient restClient() {
return RestClient.builder()
.baseUrl("https://api.example.com")
.defaultHeader("Authorization", "Bearer token")
.requestFactory(new JdkClientHttpRequestFactory()) // 或HttpComponents
.build();
}
// 使用(同步但语法优雅)
User user = restClient.get()
.uri("/users/{id}", 123)
.accept(MediaType.APPLICATION_JSON)
.retrieve()
.body(User.class);
// 错误处理
User user = restClient.get()
.uri("/users/{id}", 123)
.retrieve()
.onStatus(status -> status.value() == 404,
(request, response) -> {
throw new UserNotFoundException("用户不存在");
})
.body(User.class);
六、完整对比表
| 特性 | HttpURLConnection | HttpClient | Apache HttpClient | OkHttp | Retrofit | RestTemplate | WebClient |
|---|---|---|---|---|---|---|---|
| JDK版本 | 1.1+ | 11+ | - | - | - | Spring | Spring WebFlux |
| HTTP/2 | ❌ | ✅ | ✅(5.x) | ✅ | ✅ | ❌ | ✅ |
| 异步 | ❌ | ✅ | ✅(5.x) | ✅ | ✅ | ❌ | ✅ |
| 连接池 | ❌ | 基础 | ✅强大 | ✅ | ✅ | 依赖实现 | ✅ |
| WebSocket | ❌ | ✅ | ❌ | ✅ | ❌ | ❌ | ✅ |
| 声明式API | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ |
| 响应式 | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ✅ |
| 学习成本 | 低 | 中 | 高 | 中 | 中 | 低 | 中 |
| 依赖大小 | 0 | 0 | ~1MB | ~600KB | +OkHttp | Spring | Spring |
| 社区活跃 | 官方 | 官方 | 高 | 非常高 | 非常高 | 维护模式 | 活跃 |
七、场景选择指南
7.1 选择决策树
是否需要Spring生态?
├── 是 → 是否响应式?
│ ├── 是 → WebClient(响应式全栈)
│ └── 否 → Spring Boot 3.2+ → RestClient
│ └── 更早版本 → RestTemplate(考虑迁移)
│
└── 否 → 是否需要声明式API?
├── 是 → Retrofit + OkHttp
│
└── 否 → 能否使用Java 11+?
├── 是 → JDK HttpClient(简单场景)
│ └── 复杂场景 → OkHttp
└── 否 → API复杂度?
├── 低 → OkHttp(推荐)
└── 高 → Apache HttpClient(功能全面)
7.2 具体场景推荐
java
// 场景1:简单工具类/脚本
// 推荐:JDK HttpClient (Java 11+) 或 OkHttp
HttpClient.newHttpClient().send(
HttpRequest.newBuilder().uri(URI.create("https://api.example.com")).build(),
HttpResponse.BodyHandlers.ofString()
);
// 场景2:Spring Boot REST API客户端
// 推荐:RestClient (3.2+) 或 WebClient(响应式)
@RestController
public class UserController {
@Autowired
private RestClient restClient;
@GetMapping("/proxy/users/{id}")
public User proxyUser(@PathVariable Long id) {
return restClient.get()
.uri("https://api.example.com/users/{id}", id)
.retrieve()
.body(User.class);
}
}
// 场景3:高并发外部调用(非Spring)
// 推荐:OkHttp(连接池+HTTP/2默认支持)
OkHttpClient client = new OkHttpClient.Builder()
.dispatcher(new Dispatcher(new ThreadPoolExecutor(...)))
.protocols(Arrays.asList(Protocol.HTTP_2, Protocol.HTTP_1_1))
.build();
// 场景4:需要Cookie管理/认证/代理的企业应用
// 推荐:Apache HttpClient
CloseableHttpClient client = HttpClients.custom()
.setDefaultCookieStore(cookieStore)
.setDefaultCredentialsProvider(credentialsProvider)
.setProxy(new HttpHost("proxy.company.com", 8080))
.build();
// 场景5:Android应用
// 推荐:Retrofit + OkHttp(Google官方推荐)
// 原因:轻量、高效、Android优化好
// 场景6:微服务间调用
// 推荐:Spring Cloud OpenFeign(声明式)+ HttpComponent连接池
@FeignClient(name = "user-service", configuration = FeignConfig.class)
public interface UserClient {
@GetMapping("/users/{id}")
User getUser(@PathVariable Long id);
}
八、性能对比数据(参考)
java
// 基准测试场景:10并发,1000次请求,localhost延迟1ms
// JMH基准测试结果(相对性能)
// OkHttp: 100% (基准)
// JDK HttpClient: 95%
// Apache Http5: 90%
// Apache Http4: 85%
// RestTemplate: 80%
// WebClient: 95% (吞吐量)
// 内存占用(连接池50连接)
// OkHttp: 100% (基准)
// JDK HttpClient: 90%
// Apache Http5: 130%
// Apache Http4: 140%
九、迁移建议
java
// 1. HttpURLConnection → OkHttp(平滑迁移)
// Before
URL url = new URL("https://api.example.com");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// After
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url(url).build();
Response response = client.newCall(request).execute();
// 2. RestTemplate → RestClient(Spring生态内迁移)
// Before
restTemplate.getForObject("/api/users/{id}", User.class, id);
// After
restClient.get().uri("/api/users/{id}", id).retrieve().body(User.class);
// 3. RestTemplate → WebClient(响应式迁移)
// Before
restTemplate.getForEntity("/api/users", User[].class);
// After
webClient.get().uri("/api/users").retrieve().bodyToFlux(User.class);
总结建议:
- 新项目首选:OkHttp + Retrofit(Android)或 WebClient/RestClient(Spring)
- 简单场景:JDK HttpClient(Java 11+)
- 企业应用:Apache HttpClient 5.x(功能最全面)
- 避免使用:HttpURLConnection(除非维护旧代码)
每个组件的选择都需要根据项目实际需求、技术栈和团队熟悉度来决定。