第一步:引入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. idea展现目录清晰方式

  2. [Z]QPS、PV和需要部署机器数量计算公式

    QPS = req/sec = 请求数/秒 [QPS计算PV和机器的方式] QPS统计方式 [一般使用 http_load 进行统计]QPS = 总请求数 / ( 进程总数 *   请求时间 )QPS ...

  3. Netty心跳之IdleStateHandler

    Netty提供了对心跳机制的天然支持,心跳可以检测远程端是否存活,或者活跃 今天我们就一起初识一下Netty4的心跳机制 Netty4.0提供了一个类,名为IdleStateHandler,这个类可以 ...

  4. HTTP之URL

    URI 和 URL 与 URI(统一资源标识符)相比,我们更熟悉 URL(Uniform Resource Locator,统一资源定位符).URL 正是使用 Web 浏览器等访问 Web 页面时需要 ...

  5. objective-C: NSString应该用initWithFormat? 还是 stringWithFormat?

    今天在看书上的一段代码时,发现NSString实例化时,有时用的是initWithFormat方法,有时用的是stringWithFormat,到底应该如何选择呢? 区别: 1.initWithFor ...

  6. Handlebars学习第一天

    1.什么是handlebars???是用来做什么的??? 首先我们要了解几种前端页面展示的几种模式: a.Struct+vo+el表达式的模式 这种模式的特点:代码看起来比较整齐,但代码解析完才发送到 ...

  7. Spark会产生shuffle的算子

    去重 def distinct() def distinct(numPartitions: Int) 聚合 def reduceByKey(func: (V, V) => V, numParti ...

  8. 解剖Nginx·模块开发篇(3)ngx_http_hello_world_module 模块的基本函数实现

    还记得我们定义过一个结构体如下吗? typedef struct { ngx_str_t output_words; } ngx_http_hello_world_loc_conf_t; 它就是 He ...

  9. 本地yum源构建以及Docker离线安装

    Docker离线安装以及本地yum源构建 在docker的使用过程中有时候会遇到一些私有化部署的问题,就是在一些无法上网的机器上面安装使用dokcer,这就引出了docker的离线安装的问题,dock ...

  10. Python binascii

    Python binascii模块 Python binascii模块 用处 包含的函数 相关内置函数 code使用示例 转载请标明出处(http://blog.csdn.net/lis_12/art ...