第一步:引入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. JS控制文字只显示两行,超出部分显示省略号

    由于使用css控制文字只显示多行,超出部分显示省略号,存在一定的兼容性问题,所以总结了一下网上一些大咖使用js实现控制行数的解决方案. 第一步:依次引入jquery.js+jquery.ellipsi ...

  2. Balls(poj 3783)

    The classic Two Glass Balls brain-teaser is often posed as: “Given two identical glass spheres, you ...

  3. IDEA debug

    版权声明: 本文转自:https://blog.csdn.net/qq_27093465/article/details/64124330 1,rerun XXX,这个就是直接重新跑某个程序.2,这个 ...

  4. 什么时候必须使用UI相机? 多个相机的作用原理?

    首先,要从主画布说起,maincanvas,这个有什么限制?主画布是一张默认用来绘制UI的地方,这些UI必须是系统提供的UI组件,在画面下挂一个3D物体或非UI的2D物品是不会被绘制到画布上的,但是仍 ...

  5. U3D非常诡异的【结构体引用】现象-个例

    void Awake() { SceneManager.sceneLoaded += SceneManager_sceneLoaded; } Scene xscen; //文档说明:SceneMana ...

  6. IOS学习经验总结

    学习ios有一段时间了,感觉有些盲目.有些迷茫,从网上收集了一些比人的学习经验,来参考. IOS学习经验总结--来自知乎网友 转自知乎:http://www.zhihu.com/question/20 ...

  7. iOS 布局之 Springs and Struts

    “springs and struts” 模式,就是代码中的autosizing masks布局控制. autosizing mask决定了一个view会发生什么当它的superview 改变大小的时 ...

  8. C#中打开设计视图时报"未将对象引用设置到对象的实例"

    通常情况下,若是你将用户控件写好了放入窗体中,若是有不合理的代码,则会弹出错误提示框,不让你放.若是你之前只是随便加了一个用户控件,并且没有什么问题,但后来你又把控件改坏掉了,那么你打开就会报错(在窗 ...

  9. Ubuntu设置开机启动服务

    一.查看当前的运行级别 runlevel 二.加载服务 $ cd /etc/init.d $ sudo update-rc.d test defaults 95 三.增加默认启动脚本 sudo vi ...

  10. 高性能Web服务器Nginx的配置与部署研究(4)Nginx常用命令

    1. 启动 Nginx poechant@ubuntu:sudo ./sbin/nginx 2. 停止 Nginx poechant@ubuntu:sudo ./sbin/nginx -s stop ...