从零开始 Spring Boot 15:Http Client
在开发Web应用的时候,有时候会涉及到服务器之间的通信,这通常是以借口调用和返回的方式来实现的。
在之前的PHP开发中,我常用的是curl来实现服务器之间的接口调用,在Spring Boot开发中,更常见的是使用Http Client。
Http Client是一个功能强大的Java实现的Http客户端组件,可以用它来实现Http相关调用,它具有以下优点:
- 可自动管理Cookie
- 输出完整的调用和请求信息到日志
更多的Http Client介绍见Apache HttpClient - 简书 (jianshu.com)。
下面实际演示如何在项目中整合和使用Http Client。
这里的示例代码将基于从零开始 Spring Boot 14:文件上传 - 魔芋红茶’s blog (icexmoon.cn)最终代码进行修改,对应的代码仓库是learn_spring_boot/ch14。
依赖
先添加所需依赖:
<!-- http客户端 -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
配置
为Http Client添加相关配置:
#http客户端设置
httpclient.maxTotal=1
httpclient.defaultMaxPerRoute=1
httpclient.connectTimeout=2000
httpclient.connectionRequestTimeout=2000
httpclient.socketTimeout=2000
使用配置类加载这些配置:
@Configuration
@ConfigurationProperties(prefix = "httpclient")
@Data
public class HttpClientConfig {
private Integer maxTotal;
private Integer defaultMaxPerRoute;
private Integer connectTimeout;
private Integer connectionRequestTimeout;
private Integer socketTimeout;
/**
* HttpClient连接池
* @return
*/
@Bean
public HttpClientConnectionManager httpClientConnectionManager() {
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
connectionManager.setMaxTotal(maxTotal);
connectionManager.setDefaultMaxPerRoute(defaultMaxPerRoute);
return connectionManager;
}
/**
* 创建RequestConfig
* @return
*/
@Bean
public RequestConfig requestConfig() {
return RequestConfig.custom().setConnectTimeout(connectTimeout)
.setConnectionRequestTimeout(connectionRequestTimeout).setSocketTimeout(socketTimeout)
.build();
}
/**
* 创建HttpClient
* @param manager
* @param config
* @return
*/
@Bean
public CloseableHttpClient httpClient(HttpClientConnectionManager manager, RequestConfig config) {
return HttpClientBuilder.create().setConnectionManager(manager).setDefaultRequestConfig(config)
.build();
}
}
工具类
为了使用起来更方便,添加一个工具类:
@Component
@Slf4j
public class HttpClientUtil {
/**
* Util工具类封装的返回值,除了原始的HttpResponse对象,还包含一个body作为响应报文体,
* 因为返回的HttpResponse对象已经关闭,无法通过getEntity获取响应报文体
*/
@Getter
@AllArgsConstructor
public static class Response {
@ApiModelProperty("原始的apache HttpResponse对象")
private HttpResponse httpResponse;
@ApiModelProperty("响应报文内容")
private String body;
private long contentLength;
}
@Autowired
private CloseableHttpClient httpClient;
public Response doGet(String url, Map<String, String> param, Map<String, String> headers) {
CloseableHttpResponse response = null;
try {
// 创建uri
URIBuilder builder = new URIBuilder(url);
if (param != null) {
for (String key : param.keySet()) {
builder.addParameter(key