当前位置: 首页 > news >正文

SpringBoot19-HttpClient 详解及 SpringBoot 使用指南

一、HttpClient 是什么?

HttpClient 是 Apache 提供的一个 HTTP 协议客户端工具库,用于在 Java 应用中发送 HTTP 请求和接收 HTTP 响应。它比 Java 原生的 HttpURLConnection 更加强大和易用。

主要特性:

  • 支持多种 HTTP 方法:GET、POST、PUT、DELETE 等
  • 连接池管理:复用连接,提高性能
  • 超时控制:连接超时、读取超时
  • 重试机制:自动重试失败的请求
  • Cookie 管理:自动处理 Cookie
  • SSL/TLS 支持:支持 HTTPS
  • 请求/响应拦截器:可以自定义处理逻辑

二、在 SpringBoot 中使用 HttpClient

1. 添加依赖

<dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5.14</version>
</dependency>

【备注】:

若是加了阿里云oss的依赖,可以不加httpclient的依赖,因为阿里云oss的依赖中已经包含了httpclient的依赖。

2、测试使用示例

package com.sky.test;import com.alibaba.fastjson.JSONObject;
import com.google.gson.JsonObject;
import io.swagger.util.Json;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;import java.io.IOException;
import java.io.UnsupportedEncodingException;@SpringBootTest
public class HttpClientTest {@Testpublic void testGet() throws IOException {// 创建httpClient对象CloseableHttpClient httpClient = HttpClients.createDefault();// 创建请求对象HttpGet httpGet = new HttpGet("http://localhost:8080/user/shop/status");// 发送请求,接收响应信息CloseableHttpResponse httpResponse = httpClient.execute(httpGet);// 获取服务端返回的状态码int statusCode = httpResponse.getStatusLine().getStatusCode();System.out.println("服务端返回的状态码为: " + statusCode);HttpEntity httpEntity = httpResponse.getEntity();String body = EntityUtils.toString(httpEntity);System.out.println("服务端返回的数据为:" + body);// 关闭资源httpResponse.close();httpClient.close();}@Testpublic void testPost() throws Exception {// 创建 httpClient 对象CloseableHttpClient httpClient = HttpClients.createDefault();// 创建post请求对象HttpPost httpPost = new HttpPost("http://localhost:8080/admin/employee/login");// 以json的方式提交请求参数JSONObject jsonObject = new JSONObject();jsonObject.put("username", "admin");jsonObject.put("password", "123456");StringEntity stringEntity = new StringEntity(jsonObject.toString());// 指定请求的编码方式stringEntity.setContentEncoding("utf-8");// 指定数据格式stringEntity.setContentType("application/json");httpPost.setEntity(stringEntity);// 发送请求CloseableHttpResponse httpResponse = httpClient.execute(httpPost);// 获得响应码int statusCode = httpResponse.getStatusLine().getStatusCode();System.out.println("服务区返回的响应码:" + statusCode);HttpEntity responseEntity = httpResponse.getEntity();String body = EntityUtils.toString(responseEntity);System.out.println("服务端返回的响应体:{}" + body);// 关闭资源httpResponse.close();httpClient.close();}}

3. 配置 HttpClient(推荐方式)

创建一个配置类,将 HttpClient 注册为 Spring Bean:

@Configuration
public class HttpClientConfig {@Beanpublic HttpClient httpClient() {// 连接池管理PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();connectionManager.setMaxTotal(200); // 最大连接数connectionManager.setDefaultMaxPerRoute(20); // 每个路由最大连接数// 请求配置RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(5000) // 连接超时 5 秒.setSocketTimeout(10000) // 读取超时 10 秒.setConnectionRequestTimeout(3000) // 从连接池获取连接超时 3 秒.build();// 构建 HttpClientreturn HttpClients.custom().setConnectionManager(connectionManager).setDefaultRequestConfig(requestConfig).setRetryHandler(new DefaultHttpRequestRetryHandler(3, true)) // 重试 3 次.build();}@Beanpublic CloseableHttpClient closeableHttpClient() {return HttpClients.createDefault();}
}

为什么?

  • HttpClient 是 Apache 提供的第三方类
  • 它不在 Spring 的扫描路径下
  • 没有 @Component@Service 等注解
  • Spring 容器根本不知道它的存在

所以需要配置类手动注册。

4. 使用示例

GET 请求:

@Service
public class HttpClientService {@Autowiredprivate HttpClient httpClient;public String doGet(String url) throws IOException {HttpGet httpGet = new HttpGet(url);// 设置请求头httpGet.setHeader("User-Agent", "Mozilla/5.0");httpGet.setHeader("Accept", "application/json");HttpResponse response = httpClient.execute(httpGet);// 获取响应状态码int statusCode = response.getStatusLine().getStatusCode();// 获取响应内容HttpEntity entity = response.getEntity();String result = EntityUtils.toString(entity, "UTF-8");// 释放资源EntityUtils.consume(entity);return result;}
}

POST 请求(JSON 数据):

public String doPostJson(String url, String jsonData) throws IOException {HttpPost httpPost = new HttpPost(url);// 设置请求头httpPost.setHeader("Content-Type", "application/json");// 设置请求体StringEntity stringEntity = new StringEntity(jsonData, "UTF-8");httpPost.setEntity(stringEntity);HttpResponse response = httpClient.execute(httpPost);String result = EntityUtils.toString(response.getEntity(), "UTF-8");EntityUtils.consume(response.getEntity());return result;
}

POST 请求(表单数据):

public String doPostForm(String url, Map<String, String> params) throws IOException {HttpPost httpPost = new HttpPost(url);// 构建表单参数List<NameValuePair> formParams = new ArrayList<>();for (Map.Entry<String, String> entry : params.entrySet()) {formParams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));}// 设置表单实体UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formParams, "UTF-8");httpPost.setEntity(entity);HttpResponse response = httpClient.execute(httpPost);String result = EntityUtils.toString(response.getEntity(), "UTF-8");EntityUtils.consume(response.getEntity());return result;
}

文件上传:

public String uploadFile(String url, File file) throws IOException {HttpPost httpPost = new HttpPost(url);// 构建多部分表单MultipartEntityBuilder builder = MultipartEntityBuilder.create();builder.addBinaryBody("file", file, ContentType.APPLICATION_OCTET_STREAM, file.getName());builder.addTextBody("description", "文件描述", ContentType.TEXT_PLAIN);HttpEntity multipart = builder.build();httpPost.setEntity(multipart);HttpResponse response = httpClient.execute(httpPost);String result = EntityUtils.toString(response.getEntity(), "UTF-8");EntityUtils.consume(response.getEntity());return result;
}

5. 使用 CloseableHttpClient(推荐)

public String doGetWithCloseable(String url) {try (CloseableHttpClient httpClient = HttpClients.createDefault();CloseableHttpResponse response = httpClient.execute(new HttpGet(url))) {HttpEntity entity = response.getEntity();String result = EntityUtils.toString(entity, "UTF-8");return result;} catch (IOException e) {e.printStackTrace();return null;}
}

6. 工具类封装示例

@Component
public class HttpClientUtil {@Autowiredprivate HttpClient httpClient;public String get(String url) {return get(url, null);}public String get(String url, Map<String, String> headers) {try {HttpGet httpGet = new HttpGet(url);if (headers != null) {for (Map.Entry<String, String> entry : headers.entrySet()) {httpGet.setHeader(entry.getKey(), entry.getValue());}}HttpResponse response = httpClient.execute(httpGet);return EntityUtils.toString(response.getEntity(), "UTF-8");} catch (IOException e) {throw new RuntimeException("HTTP GET 请求失败", e);}}public String postJson(String url, String jsonData) {try {HttpPost httpPost = new HttpPost(url);httpPost.setHeader("Content-Type", "application/json");StringEntity entity = new StringEntity(jsonData, "UTF-8");httpPost.setEntity(entity);HttpResponse response = httpClient.execute(httpPost);return EntityUtils.toString(response.getEntity(), "UTF-8");} catch (IOException e) {throw new RuntimeException("HTTP POST 请求失败", e);}}
}

三、SpringBoot 中的替代方案

除了直接使用 HttpClient,SpringBoot 还提供了其他 HTTP 客户端工具:

1. RestTemplate(Spring 提供)

@Autowired
private RestTemplate restTemplate;String result = restTemplate.getForObject("http://example.com/api", String.class);

2. WebClient(Spring WebFlux,响应式)

@Autowired
private WebClient webClient;String result = webClient.get().uri("http://example.com/api").retrieve().bodyToMono(String.class).block();

3. OpenFeign(声明式客户端,微服务常用)

@FeignClient(name = "user-service", url = "http://localhost:8080")
public interface UserClient {@GetMapping("/users/{id}")User getUser(@PathVariable Long id);
}

四、最佳实践建议

  1. 使用连接池:避免频繁创建和销毁连接
  2. 设置超时时间:防止请求长时间挂起
  3. 异常处理:妥善处理 IOException 等异常
  4. 资源释放:及时释放 HttpEntity 资源
  5. 使用工具类:封装常用操作,提高代码复用性
  6. 选择合适工具:简单场景用 RestTemplate,微服务用 Feign,响应式用 WebClient

五、目前企业中 HTTP 客户端使用情况

1. RestTemplate - 使用最广泛 ⭐⭐⭐⭐⭐

为什么最多?

  • Spring 生态内置:无需额外依赖,开箱即用
  • 学习成本低:API 简单直观
  • 历史悠久:存在大量遗留系统在使用
  • 适用场景:传统单体应用、简单微服务

现状:

  • 大部分使用 Spring Boot 2.x 的项目都在用
  • 虽然 Spring 5.0 后标记为 "维护模式"(不推荐新项目使用)
  • 但由于存量项目庞大,仍是使用最多的
// 企业中最常见的用法
@Autowired
private RestTemplate restTemplate;String result = restTemplate.getForObject(url, String.class);

2. OpenFeign - 微服务场景第一选择 ⭐⭐⭐⭐⭐

为什么流行?

  • Spring Cloud 标配:微服务架构必备
  • 声明式调用:代码简洁优雅
  • 功能强大:集成负载均衡、熔断降级、服务发现

适用场景:

  • 微服务之间的内部调用
  • 需要服务治理的场景
@FeignClient(name = "user-service")
public interface UserClient {@GetMapping("/users/{id}")User getUser(@PathVariable Long id);
}

3. Apache HttpClient - 底层场景 ⭐⭐⭐

使用场景:

  • 需要精细控制 HTTP 请求(连接池、超时、重试)
  • 第三方 API 对接
  • 复杂的 HTTP 场景(文件上传、自定义协议)

现状:

  • 大型企业的基础组件层仍在使用
  • 通常被封装成工具类供业务使用
  • 新项目直接使用的较少

4. WebClient - 新兴力量 ⭐⭐⭐

特点:

  • Spring WebFlux 提供的响应式客户端
  • 非阻塞、高性能
  • Spring 官方推荐的 RestTemplate 替代品

现状:

  • 使用率逐年上升
  • 响应式编程、高并发场景首选
  • 但由于响应式编程学习曲线陡峭,普及率还不如 RestTemplate

企业实际使用排名(2024-2025)

根据实际情况,我估计的使用率排名:

  1. RestTemplate - 约 40-50%(存量项目多)
  2. OpenFeign - 约 30-35%(微服务场景)
  3. Apache HttpClient - 约 15-20%(基础组件)
  4. WebClient - 约 5-10%(新项目、响应式)

不同场景的选择建议

场景推荐工具理由
传统单体应用RestTemplate简单够用
微服务架构OpenFeign服务治理完善
第三方 API 对接HttpClient 或 RestTemplate灵活可控
高并发响应式WebClient非阻塞高性能
新项目WebClient 或 Feign官方推荐

趋势预测

  • RestTemplate:使用率会逐步下降,但短期内仍是主流(存量项目太多)
  • OpenFeign:在微服务领域地位稳固
  • WebClient:增长最快,未来可能成为主流
  • HttpClient:底层场景依然需要,但直接使用会减少

总结

当前企业用得最多的是 RestTemplate,因为它是 Spring 生态的默认选择,学习成本低,存量项目多。

微服务场景下 OpenFeign 是第一选择,已经成为事实标准。

未来趋势是 WebClient,但普及还需要时间。

建议你根据项目实际情况选择:

  • 维护老项目:继续用 RestTemplate
  • 新建微服务:用 OpenFeign
  • 追求性能和新技术:用 WebClient
  • 需要底层控制:用 HttpClient
http://www.dtcms.com/a/618650.html

相关文章:

  • 17做网店一样的网站网站按域名跳转不同的页面
  • 13.2 国产之光崛起:深度求索与通义千问的技术突破
  • 旅游网站建设的结论阿里云商标注册官网
  • 第五次:郑州银行杯2025郑州马拉松
  • Three.js使用教程
  • Reqable 工具报错 Netbare Code Error Unknown
  • 宝山网页设计制作黄石seo诊断
  • git-Git约定式提交
  • wap建站教程0元玩手游平台
  • nw.js桌面软件开发系列 第.节 HTML和桌面软件开发的碰撞
  • 设计一套网站费用北京网页
  • 7.3、Python-函数的返回值
  • 网站建设咨询话术技巧网站开发程序设计
  • 【Qt】配置安卓开发环境
  • 基于Qt,调用千问7B大模型,实现智能对话
  • Ubuntu 美化
  • 网站互动营销专门app软件开发公司
  • .net开发微信网站流程网站怎么做收费
  • 变分自编码器(VAE)的原理方法(一)
  • OpenCV 张氏标定法(三)
  • 网站做成app网站建设与管理设计
  • 建设礼品网站的策划书如何用阿里云做网站
  • C++:智能指针的使用及其原理
  • 25.Linux逻辑卷管理
  • 苏州旺道seo做网站排名优化的公司
  • 6. Linux 硬盘分区管理
  • 中山微网站建设报价银行网站建设前期合同
  • 25年11月软考架构真题《论秒杀场景及其技术解决方案》考后复盘总结
  • 怎么做公司网站竞价最新国际新闻10条简短
  • jQuery 属性详解