maven依赖
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
package com.demo.utils;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
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.client.utils.URIBuilder;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
* Description: httpclient工具类
*/
@Slf4j
public class HttpClientUtils {
private static final int MAX_TOTAL = 400;
private static final int MAX_PER_ROUTE = 100;
private static final int SOCKET_TIMEOUT = 30000;
private static final int CONNECT_TIMEOUT = 10000;
private static final int CONNECTION_REQUEST_TIMEOUT = 1000;
private static final int CLOSE_IDLE_CONNECTIONS = 5;
private static final int SCHEDULE_FIXED_RATE = 1;
private static final int TIME_TO_LIVE = 60;
private static final PoolingHttpClientConnectionManager CONNECTION_MANAGER;
private static final RequestConfig REQUEST_CONFIG;
private static final CloseableHttpClient HTTP_CLIENT;
private static final ScheduledExecutorService EXECUTOR_SERVICE = Executors.newSingleThreadScheduledExecutor();
static {
// 每个版本不一样,请根据具体版本进行设置
// 忽略https证书
Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.getSocketFactory())
.register("https", SSLConnectionSocketFactory.getSocketFactory())
.build();
// 设置连接的生存时间为TIME_TO_LIVE秒
CONNECTION_MANAGER = new PoolingHttpClientConnectionManager(registry,
null, null, null, TIME_TO_LIVE, TimeUnit.SECONDS);
// 设置整个连接池最大连接数
CONNECTION_MANAGER.setMaxTotal(MAX_TOTAL);
// 路由是对maxTotal的细分
CONNECTION_MANAGER.setDefaultMaxPerRoute(MAX_PER_ROUTE);
REQUEST_CONFIG = RequestConfig.custom()
// 返回数据的超时时间,单位:毫秒
.setSocketTimeout(SOCKET_TIMEOUT)
// 连接上服务器的超时时间,单位:毫秒
.setConnectTimeout(CONNECT_TIMEOUT)
// 从连接池中获取连接的超时时间,单位:毫秒
.setConnectionRequestTimeout(CONNECTION_REQUEST_TIMEOUT)
.build();
HTTP_CLIENT = HttpClients.custom()
.setConnectionManager(CONNECTION_MANAGER)
.setDefaultRequestConfig(REQUEST_CONFIG)
// 配置连接池管理器定期清理过期和空闲连接 与 EXECUTOR_SERVICE二选一
// 以下配置在高版本才有,低版本无此方法;高版本使用此配置,低版本使用EXECUTOR_SERVICE
// .evictExpiredConnections()
// .evictIdleConnections(CLOSE_IDLE_CONNECTIONS, TimeUnit.SECONDS)
.build();
// 每分钟执行1次,定时清理无效链接
EXECUTOR_SERVICE.scheduleAtFixedRate(() -> {
try {
// 关闭异常连接
CONNECTION_MANAGER.closeExpiredConnections();
} catch (Exception e) {
log.error("==>HttpPool关闭异常连接失败", e);
}
try {
// 关闭5s空闲的连接
CONNECTION_MANAGER.closeIdleConnections(CLOSE_IDLE_CONNECTIONS, TimeUnit.SECONDS);
} catch (Exception e) {
log.error("==>HttpPool关闭5s空闲的连接失败", e);
}
log.info("==>HttpPool清理无效链接成功");
}, SCHEDULE_FIXED_RATE, SCHEDULE_FIXED_RATE, TimeUnit.MINUTES);
// 注册关闭钩子,程序结束时释放资源
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
log.info("==>Application is shutting down, free up resources...");
log.info("==>closing scheduled executor service...");
try {
// 关闭线程池,不再接收新任务
EXECUTOR_SERVICE.shutdown();
// 等待已经提交的任务完成
if (!EXECUTOR_SERVICE.awaitTermination(SCHEDULE_FIXED_RATE, TimeUnit.MINUTES)) {
// 取消当前未完成的任务
EXECUTOR_SERVICE.shutdownNow();
log.warn("==>Pool did not terminate after {} minutes", SCHEDULE_FIXED_RATE);
}
} catch (InterruptedException ie) {
// (Re-)Cancel if current thread also interrupted
EXECUTOR_SERVICE.shutdownNow();
// Preserve interrupt status
Thread.currentThread().interrupt();
log.warn("==>Interrupted while waiting for pool to terminate", ie);
}
log.info("==>closing http client...");
try {
if (HTTP_CLIENT != null) {
HTTP_CLIENT.close();
}
} catch (IOException e) {
log.warn("==>closing http client error", e);
}
log.info("==>free up resources end。");
}));
}
public static String doGet(String url, Map<String, String> params, Map<String, String> headers) {
try {
URIBuilder builder = new URIBuilder(url);
if (MapUtils.isNotEmpty(params)) {
for (Map.Entry<String, String> entry : params.entrySet()) {
builder.addParameter(entry.getKey(), entry.getValue());
}
}
HttpGet httpGet = new HttpGet(builder.build());
if (MapUtils.isNotEmpty(headers)) {
for (Map.Entry<String, String> entry : headers.entrySet()) {
httpGet.setHeader(entry.getKey(), entry.getValue());
}
}
httpGet.setHeader("Content-Type", ContentType.APPLICATION_JSON.toString());
try (CloseableHttpResponse response = HTTP_CLIENT.execute(httpGet)) {
String responseContent = StringUtils.EMPTY;
if (response.getEntity() != null) {
responseContent = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
}
log.info("==>HttpPool doGet请求成功,url:{},response:{}", url, responseContent);
return responseContent;
}
} catch (Exception e) {
log.error("==>HttpPool doGet请求失败,url:{}", url, e);
return null;
}
}
public static String doPostForm(String url, Map<String, String> params, Map<String, String> headers) {
try {
HttpPost httpPost = new HttpPost(url);
httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
if (MapUtils.isNotEmpty(params)) {
List<NameValuePair> paramList = Lists.newArrayList();
for (Map.Entry<String, String> entry : params.entrySet()) {
paramList.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
}
httpPost.setEntity(new UrlEncodedFormEntity(paramList, StandardCharsets.UTF_8));
}
if (MapUtils.isNotEmpty(headers)) {
for (Map.Entry<String, String> entry : headers.entrySet()) {
httpPost.setHeader(entry.getKey(), entry.getValue());
}
}
try (CloseableHttpResponse response = HTTP_CLIENT.execute(httpPost)) {
String responseContent = StringUtils.EMPTY;
if (response.getEntity() != null) {
responseContent = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
}
log.info("==>HttpPool doPostForm请求成功,url:{},response:{}", url, responseContent);
return responseContent;
}
} catch (Exception e) {
log.error("==>HttpPool doPostForm请求失败,url:{}", url, e);
return null;
}
}
public static String doPostJson(String url, String paramJson, Map<String, String> headers) {
try {
HttpPost httpPost = new HttpPost(url);
httpPost.setHeader("Content-Type", ContentType.APPLICATION_JSON.toString());
if (MapUtils.isNotEmpty(headers)) {
for (Map.Entry<String, String> entry : headers.entrySet()) {
httpPost.setHeader(entry.getKey(), entry.getValue());
}
}
if (StringUtils.isNotBlank(paramJson)) {
httpPost.setEntity(new StringEntity(paramJson, ContentType.APPLICATION_JSON));
}
try (CloseableHttpResponse response = HTTP_CLIENT.execute(httpPost)) {
String responseContent = StringUtils.EMPTY;
if (response.getEntity() != null) {
responseContent = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
}
log.info("==>HttpPool doPostJson请求成功,url:{},response:{}", url, responseContent);
return responseContent;
}
} catch (Exception e) {
log.error("==>HttpPool doPostJson请求失败,url:{}", url, e);
return null;
}
}
}