第一步:引入HttpClient 的jar包

  1、httpClient 5.0 开始支持异步(Async)请求;

  2、httpclient 版本过低上传文件会出,原因是 org.apache.http.entity.ContentType 没有方法 withParameters(final NameValuePair... params);

<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<!-- httpClient文件上传需要 -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
</dependency>

  

第二步:创建一个httpClient的配置类

 package com.123.lenovo.adapter.se.config;

 import java.security.KeyStore;
import javax.net.ssl.SSLContext; import org.apache.http.HeaderElement;
import org.apache.http.HeaderElementIterator;
import org.apache.http.HttpResponse;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.conn.ConnectionKeepAliveStrategy;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustAllStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicHeaderElementIterator;
import org.apache.http.protocol.HTTP;
import org.apache.http.protocol.HttpContext;
import org.apache.http.ssl.SSLContexts;
import org.elasticsearch.Build;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import com.123.lenovo.adapter.se.common.IdleConnectionEvictor; @Configuration
public class HttpClientConfig { @Value("${http_max_total}")
private int maxTotal = 800; @Value("${http_default_max_perRoute}")
private int defaultMaxPerRoute = 80; @Value("${http_validate_after_inactivity}")
private int validateAfterInactivity = 1000; @Value("${http_connection_request_timeout}")
private int connectionRequestTimeout = 5000; @Value("${http_connection_timeout}")
private int connectTimeout = 10000; @Value("${http_socket_timeout}")
private int socketTimeout = 20000; @Value("${waitTime}")
private int waitTime = 30000; @Value("${idleConTime}")
private int idleConTime = 3; @Value("${retryCount}")
private int retryCount = 3; @Bean
public PoolingHttpClientConnectionManager createPoolingHttpClientConnectionManager() {
PoolingHttpClientConnectionManager poolmanager = new PoolingHttpClientConnectionManager();
poolmanager.setMaxTotal(maxTotal);
poolmanager.setDefaultMaxPerRoute(defaultMaxPerRoute);
poolmanager.setValidateAfterInactivity(validateAfterInactivity);
return poolmanager;
} @Bean
public CloseableHttpClient createHttpClient(PoolingHttpClientConnectionManager poolManager) {
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create().setConnectionManager(poolManager);
httpClientBuilder.setKeepAliveStrategy(new ConnectionKeepAliveStrategy() { @Override
public long getKeepAliveDuration(HttpResponse response, HttpContext context) {
HeaderElementIterator iterator = new BasicHeaderElementIterator(response.headerIterator(HTTP.CONN_KEEP_ALIVE));
while (iterator.hasNext()) {
HeaderElement headerElement = iterator.nextElement();
String param = headerElement.getName();
String value = headerElement.getValue();
if (null != value && param.equalsIgnoreCase("timeout")) {
return Long.parseLong(value) * 1000;
}
}
return 30 * 1000;
}
});
httpClientBuilder.setRetryHandler(new DefaultHttpRequestRetryHandler(retryCount, false));
return httpClientBuilder.build();
}
@Bean
public RequestConfig createRequestConfig() {
return RequestConfig.custom()
.setConnectionRequestTimeout(connectionRequestTimeout) // 从连接池中取连接的超时时间
.setConnectTimeout(connectTimeout) // 连接超时时间
.setSocketTimeout(socketTimeout) // 请求超时时间
.build();
} @Bean
public IdleConnectionEvictor createIdleConnectionEvictor(PoolingHttpClientConnectionManager poolManager) {
IdleConnectionEvictor idleConnectionEvictor = new IdleConnectionEvictor(poolManager, waitTime, idleConTime);
return idleConnectionEvictor;
} }

第三步:创建httpClient的工具类

 @Component
public class HttpClientHelper { private Logger LOGGER = LoggerFactory.getLogger(HttpClientHelper.class); @Autowired
private CloseableHttpClient httpClient; @Autowired
private RequestConfig requestConfig; public String get(String url, HashMap<String, Object> paramMap, HashMap<String, Object> header) {
String result = null;
if ("".equals(url)) {
return result;
}
// 创建一个request对象
HttpGet httpGet = new HttpGet(url);
CloseableHttpResponse response = null;
try {
// 配置连接参数
httpGet.setConfig(requestConfig);
//设置参数
if (paramMap != null && paramMap.size() > 0) {
List<NameValuePair> params = new ArrayList<>();
for (Entry<String, Object> entry : paramMap.entrySet()) {
params.add(new BasicNameValuePair(entry.getKey(), URLEncoder.encode(entry.getValue().toString(), "UTF-8")));
}
String strParams = EntityUtils.toString(new UrlEncodedFormEntity(params));
// 防止多参数时,分隔符","被转义
String realParams = URLDecoder.decode(strParams, "UTF-8");
httpGet.setURI(new URI(httpGet.getURI().toString().indexOf("?") > 0 ? httpGet.getURI().toString() + "&" + realParams : httpGet.getURI().toString() + "?" + realParams));
}
// 设置头
if (header != null && header.size() > 0) {
for (Entry<String, Object> entry : header.entrySet()) {
httpGet.addHeader(entry.getKey(), entry.getValue().toString());
}
}
// 执行request请求
response = httpClient.execute(httpGet);
result = parseResponse(response); } catch (Exception e) {
LOGGER.error("url : "+ url +", msg : " + e.getMessage());
httpGet.abort();
} finally {
try {
if (response != null) {
response.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
} public String post(String url, HashMap<String, Object> paramMap, HashMap<String, Object> header) {
String result = null;
if ("".equals(url)) {
return result;
}
// 创建一个request对象
HttpPost httpPost = new HttpPost(url);
CloseableHttpResponse response = null;
try {
// 配置连接参数
httpPost.setConfig(requestConfig);
// 设置参数
if (paramMap != null && paramMap.size() > 0) {
List<NameValuePair> params = new ArrayList<>();
for (Entry<String, Object> entry : paramMap.entrySet()) {
params.add(new BasicNameValuePair(entry.getKey(), entry.getValue().toString()));
}
HttpEntity entity = new UrlEncodedFormEntity(params);
httpPost.setEntity(entity);
}
// 设置头
if (header != null && header.size() > 0) {
for (Entry<String, Object> entry : header.entrySet()) {
httpPost.addHeader(entry.getKey(), entry.getValue().toString());
}
}
// 执行request请求
response = httpClient.execute(httpPost);
result = reponseHandle(response);
} catch (Exception e) {
LOGGER.error("url : "+ url +", msg : " + e.getMessage());
httpPost.abort();
} finally {
try {
if (response != null) {
response.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
} public String postJSON(String url, String json_str, HashMap<String, Object> header) {
String result = null;
if ("".equals(url)) {
return result;
}
// 创建一个request对象
HttpPost httpPost = new HttpPost(url);
CloseableHttpResponse response = null;
try {
// 配置连接参数
httpPost.setConfig(requestConfig);
// 设置参数
if (json_str != null && !"".equals(json_str)) {
StringEntity entity = new StringEntity(json_str, ContentType.APPLICATION_JSON);
entity.setContentEncoding("UTF-8");
entity.setContentType("application/json");
httpPost.setEntity(entity);
}
// 设置头
if (header != null && header.size() > 0) {
for (Entry<String, Object> entry : header.entrySet()) {
httpPost.addHeader(entry.getKey(), entry.getValue().toString());
}
}
// 执行request请求
response = httpClient.execute(httpPost);
result = reponseHandle(response); } catch (Exception e) {
LOGGER.error("url : "+ url +", msg : " + e.getMessage()+", param : " +json_str);
httpPost.abort();
} finally {
try {
if (response != null) {
response.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
} public String uploadFile(String url, String filePath, String fileParam, Map<String, Object> params) {
File file = new File(filePath);
if (!(file.exists() && file.isFile())) {
throw new RuntimeException("file : file is null");
}
String result = null;
if ("".equals(url)) {
return result;
}
// 创建一个request对象
HttpPost httpPost = new HttpPost(url);
CloseableHttpResponse response = null;
try {
// 配置连接参数
httpPost.setConfig(requestConfig);
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
builder.addBinaryBody(fileParam, file, ContentType.DEFAULT_BINARY, file.getName());
if (params != null && params.size() > 0) {
for (Entry<String, Object> entry : params.entrySet()) {
builder.addTextBody(entry.getKey(), entry.getValue().toString(), ContentType.create("text/plain", Consts.UTF_8));
}
}
HttpEntity requestEntity = builder.build();
httpPost.setEntity(requestEntity);
// 执行request请求
response = httpClient.execute(httpPost);
result = reponseHandle(response); } catch (Exception e) {
httpPost.abort();
} finally {
try {
if (response != null) {
response.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
} /**
* 解析 response数据
* @description
* @param response
* @return
* @author tangjingjing
* @date 2018年10月12日
*/
private String parseResponse(CloseableHttpResponse response) {
String result = "";
// 获取响应体
HttpEntity httpEntity = null;
InputStream inputStream = null;
try {
// 获取响应状态
int statusCode = response.getStatusLine().getStatusCode();
// 没有正常响应
if (statusCode < HttpStatus.SC_OK || statusCode >= HttpStatus.SC_MULTIPLE_CHOICES) {
throw new RuntimeException("statusCode : " + statusCode);
}
// 获取响应体
httpEntity = response.getEntity();
if (httpEntity != null) {
inputStream = httpEntity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream,"UTF-8"));
StringBuffer sb = new StringBuffer();
String line = "";
while((line=reader.readLine())!=null){
sb.append(line);
}
reader.close();
result = sb.toString();
} } catch (Exception e) {
LOGGER.error("HttpClientHelper parseResponse error", e);
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// 如果httpEntity没有被完全消耗,那么连接无法安全重复使用,将被关闭并丢弃
try {
EntityUtils.consume(httpEntity);
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
} private String reponseHandle(CloseableHttpResponse response) {
String result = "";
// 获取响应体
HttpEntity httpEntity = null;
try {
// 获取响应状态
int statusCode = response.getStatusLine().getStatusCode();
// 没有正常响应
if (statusCode < HttpStatus.SC_OK || statusCode >= HttpStatus.SC_MULTIPLE_CHOICES) {
throw new RuntimeException("statusCode : " + statusCode);
}
// 获取响应体
httpEntity = response.getEntity();
if (httpEntity !=null) {
result = EntityUtils.toString(httpEntity);
} } catch (Exception e) {
LOGGER.error("HttpClientHelper reponseHandle error", e);
} finally {
// 如果httpEntity没有被完全消耗,那么连接无法安全重复使用,将被关闭并丢弃
try {
EntityUtils.consume(httpEntity);
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
} }

第四步:创建HttpClient无效连接清除类

 /**
* 定期清理无效的http连接
* @author viruser
*
*/
package com.123.lenovo.adapter.se.common; import java.util.concurrent.TimeUnit; import javax.annotation.PreDestroy; import org.apache.http.conn.HttpClientConnectionManager; /**
* 定期清理无效的http连接
* @author viruser
*
*/
public class IdleConnectionEvictor extends Thread { private final HttpClientConnectionManager manager; private Integer waitTime; private Integer idleConTime; private volatile boolean shutdown = true; public IdleConnectionEvictor(HttpClientConnectionManager manager, Integer waitTime, Integer idleConTime) {
this.manager = manager;
this.waitTime = waitTime;
this.idleConTime = idleConTime;
this.start();
} @Override
public void run() {
try {
if (shutdown) {
synchronized (this) {
wait(waitTime);
manager.closeIdleConnections(idleConTime, TimeUnit.SECONDS);
// 关闭失效的连接
manager.closeExpiredConnections();
}
}
} catch (Exception e) { }
} @PreDestroy
public void shutdown() {
shutdown = false;
synchronized (this) {
notifyAll();
}
} }

spring boot 整合 HttpClient的更多相关文章

  1. Spring Boot 整合 Elasticsearch,实现 function score query 权重分查询

    摘要: 原创出处 www.bysocket.com 「泥瓦匠BYSocket 」欢迎转载,保留摘要,谢谢! 『 预见未来最好的方式就是亲手创造未来 – <史蒂夫·乔布斯传> 』 运行环境: ...

  2. spring boot整合jsp的那些坑(spring boot 学习笔记之三)

    Spring Boot 整合 Jsp 步骤: 1.新建一个spring boot项目 2.修改pom文件 <dependency>            <groupId>or ...

  3. spring boot 系列之四:spring boot 整合JPA

    上一篇我们讲了spring boot 整合JdbcTemplate来进行数据的持久化, 这篇我们来说下怎么通过spring boot 整合JPA来实现数据的持久化. 一.代码实现 修改pom,引入依赖 ...

  4. Spring Kafka和Spring Boot整合实现消息发送与消费简单案例

    本文主要分享下Spring Boot和Spring Kafka如何配置整合,实现发送和接收来自Spring Kafka的消息. 先前我已经分享了Kafka的基本介绍与集群环境搭建方法.关于Kafka的 ...

  5. Spring Boot整合Mybatis并完成CRUD操作

    MyBatis 是一款优秀的持久层框架,被各大互联网公司使用,本文使用Spring Boot整合Mybatis,并完成CRUD操作. 为什么要使用Mybatis?我们需要掌握Mybatis吗? 说的官 ...

  6. spring boot整合Hadoop

    最近需要用spring boot + mybatis整合hadoop,其中也有碰到一些坑,记录下来方便后面的人少走些弯路. 背景呢是因为需要在 web 中上传文件到 hdfs ,所以需要在spring ...

  7. Spring Boot整合Elasticsearch

    Spring Boot整合Elasticsearch   Elasticsearch是一个全文搜索引擎,专门用于处理大型数据集.根据描述,自然而然使用它来存储和搜索应用程序日志.与Logstash和K ...

  8. spring boot 整合 百度ueditor富文本

    百度的富文本没有提供Java版本的,只给提供了jsp版本,但是呢spring boot 如果是使用内置tomcat启动的话整合jsp是非常困难得,今天小编给大家带来spring boot整合百度富文本 ...

  9. spring boot 整合quartz ,job不能注入的问题

    在使用spring boot 整合quartz的时候,新建定时任务类,实现job接口,在使用@AutoWire或者@Resource时,运行时出现nullpointException的问题.显然是相关 ...

随机推荐

  1. Django 组件-cookie 与 session

    会话跟踪技术 1 什么是会话跟踪技术 我们需要先了解一下什么是会话!可以把会话理解为客户端与服务器之间的一次会晤,在一次会晤中可能会包含多次请求和响应.例如你给10086打个电话,你就是客户端,而10 ...

  2. CSS——创建css

    CreateInlineStyle: function () { //创建一个内联样式表 var style = document.createElement('style'); //创建一个styl ...

  3. c++builder 解压缩

    c++builder  解压缩  TZCompressionStream  TZDecompressionStream #include <System.ZLib.hpp> void __ ...

  4. 移动端web页面input限制只能输入数字

    <input type="number" pattern="[0-9]*" /> 如上所示,在安卓端设置input类型为number,可限制键盘只输 ...

  5. Phong Shading

    [Phong Shading] The most serious problem with Gouraud shading occurs when specular highlights are fo ...

  6. Android开发实战之拥有Material Design风格的侧滑布局

    在实现开发要求中,有需要会使用抽屉式布局,类似于QQ5.0的侧滑菜单,实现的方式有很多种,可以自定义控件,也可以使用第三方开源库. 同样的谷歌也推出了自己的侧滑组件——DrawLayout,使用方式也 ...

  7. 13-Oulipo(kmp裸题)

    http://acm.hdu.edu.cn/showproblem.php?pid=1686 Oulipo Time Limit: 3000/1000 MS (Java/Others)    Memo ...

  8. hash+链表

    简单的hash就是用数组加链表的组合来实现,这种hash很简单,但hash的思想在那. #ifndef _HASH_H_ #define _HASH_H_ typedef struct _ListNo ...

  9. Halcon中一些突然想不起来但确实有用的算子

    1.Develop dev_display  在现有图形窗口中显示图像目标. dev_set_color   设置一个或更多输出颜色,通常用于设置region或者xld的颜色. dev_set_dra ...

  10. Mysql蠕虫复制

    将查询出来的数据插入到指定表中,形如: INSERT into user_info(version,create_user_count,create_pc_count) select version, ...