package com.malk.chuizi.utils; import com.alibaba.fastjson.JSON; import lombok.extern.slf4j.Slf4j; import org.apache.http.HttpEntity; import org.apache.http.client.config.RequestConfig; 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.config.Registry; import org.apache.http.config.RegistryBuilder; import org.apache.http.config.SocketConfig; import org.apache.http.conn.DnsResolver; import org.apache.http.conn.HttpConnectionFactory; import org.apache.http.conn.ManagedHttpClientConnection; import org.apache.http.conn.routing.HttpRoute; 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.DefaultConnectionReuseStrategy; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy; import org.apache.http.impl.client.DefaultHttpRequestRetryHandler; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.conn.ManagedHttpClientConnectionFactory; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.apache.http.impl.conn.SystemDefaultDnsResolver; import org.apache.http.impl.io.DefaultHttpRequestWriterFactory; import org.apache.http.impl.io.DefaultHttpResponseParserFactory; import org.apache.http.util.EntityUtils; import java.nio.charset.Charset; import java.util.Map; import java.util.concurrent.TimeUnit; /** * http请求封装 * * @author lh * @date 2022-09-23 */ @Slf4j public class HttpUtils { /** * 默认请求类型 */ private static final String DEFAULT_CONTENT_TYPE = "application/json"; /** * 默认编码 */ private static final String DEFAULT_ENCODING = "utf-8"; /** * GBK编码 */ private static final String GBK_ENCODING = "GBK"; /** * 默认超时时间 */ private static final int DEFAULT_TIME_OUT = 60; private static PoolingHttpClientConnectionManager manager = null; private static CloseableHttpClient httpClient = null; /** * 获取httpclient对象 * * @return */ public static synchronized CloseableHttpClient getHttpClient(int timeOut) { if (null == httpClient) { log.info("============================================创建"); // 注册访问协议相关的socket工厂 Registry socketFactoryRegistry = RegistryBuilder.create() .register("http", PlainConnectionSocketFactory.INSTANCE) .register("https", SSLConnectionSocketFactory.getSystemSocketFactory()) .build(); // httpConnection工厂 HttpConnectionFactory connectionFactory = new ManagedHttpClientConnectionFactory(DefaultHttpRequestWriterFactory.INSTANCE , DefaultHttpResponseParserFactory.INSTANCE); // DNS解析器 DnsResolver dnsResolver = SystemDefaultDnsResolver.INSTANCE; // 创建池化连接管理器 manager = new PoolingHttpClientConnectionManager(socketFactoryRegistry, connectionFactory, dnsResolver); // socket配置 SocketConfig socketConfig = SocketConfig.custom().setTcpNoDelay(true).build(); manager.setDefaultSocketConfig(socketConfig); // 连接池最大连接数 manager.setMaxTotal(300); manager.setDefaultMaxPerRoute(200); // 5s检测一次连接池连接 manager.setValidateAfterInactivity(5 * 1000); // 默认请求配置 RequestConfig requestConfig = RequestConfig.custom() // 连接超时时间 .setConnectTimeout(timeOut * 1000) // 等待数据超时时间 .setSocketTimeout(timeOut * 1000) // 从连接池获取连接超时时间 .setConnectionRequestTimeout(timeOut * 1000) .build(); // 创建httpclient httpClient = HttpClients.custom() .setConnectionManager(manager) // 连接池不共享 .setConnectionManagerShared(false) // 定期回收空闲连接 .evictIdleConnections(timeOut, TimeUnit.SECONDS) // 定期回收过期连接 .evictExpiredConnections() .setConnectionTimeToLive(timeOut, TimeUnit.SECONDS) // 设置默认请求 .setDefaultRequestConfig(requestConfig) // 连接重用策略 .setConnectionReuseStrategy(DefaultConnectionReuseStrategy.INSTANCE) // 长连接配置 .setKeepAliveStrategy(DefaultConnectionKeepAliveStrategy.INSTANCE) // 设置重试次数 .setRetryHandler(new DefaultHttpRequestRetryHandler(0, false)) .build(); // jvm停止或重启时,关闭连接池释放连接 Runtime.getRuntime().addShutdownHook(new Thread() { @Override public void run() { try { if (null != httpClient) { httpClient.close(); } } catch (Exception e) { log.error("httpclient关闭异常:{}", e); } } }); } return httpClient; } /** * http请求 * * @param url * @param params * @return */ public static String httpPost(String url, Map params,Map headers) { log.info("POST请求url:{}", url); log.info("POST请求参数:{}",JSON.toJSONString(params)); CloseableHttpClient httpClient = getHttpClient(DEFAULT_TIME_OUT); HttpPost httpPost = new HttpPost(url); if (null != headers){ for (String key:headers.keySet()){ httpPost.setHeader(key,headers.get(key).toString()); } } String json = JSON.toJSONString(params); StringEntity stringEntity = new StringEntity(json, DEFAULT_ENCODING); stringEntity.setContentEncoding(DEFAULT_ENCODING); httpPost.setEntity(stringEntity); String result = null; try (CloseableHttpResponse response = httpClient.execute(httpPost);) { HttpEntity entity = response.getEntity(); if (null != entity) { result = EntityUtils.toString(entity, ContentType.getOrDefault(entity).getCharset()); EntityUtils.consume(entity); } } catch (Exception e) { log.error("接口请求异常:{}", e); } return result; } /** * http请求(POST请求,GBK编码) * * @param url * @param params * @return */ public static String httpPostGBK(String url, Map params,Map headers) { log.info("POST请求url:{}", url); log.info("POST请求参数:{}",JSON.toJSONString(params)); CloseableHttpClient httpClient = getHttpClient(DEFAULT_TIME_OUT); HttpPost httpPost = new HttpPost(url); if (null != headers){ for (String key:headers.keySet()){ httpPost.setHeader(key,headers.get(key).toString()); } } String json = JSON.toJSONString(params); StringEntity stringEntity = new StringEntity(json, DEFAULT_ENCODING); stringEntity.setContentEncoding(DEFAULT_ENCODING); httpPost.setEntity(stringEntity); String result = null; try (CloseableHttpResponse response = httpClient.execute(httpPost);) { HttpEntity entity = response.getEntity(); if (null != entity) { // result = EntityUtils.toString(entity, ContentType.getOrDefault(entity).getCharset()); result = EntityUtils.toString(entity, Charset.defaultCharset()); EntityUtils.consume(entity); } } catch (Exception e) { log.error("接口请求异常:{}", e); } return result; } /** * http请求(POST请求,GBK编码) * * @param url * @param params * @param headers * @param timeOut 超时时间 * @return */ public static String httpPostGBK(String url, Map params, Map headers, int timeOut) { log.info("POST请求url:{}", url); log.info("POST请求参数:{}", JSON.toJSONString(params)); CloseableHttpClient httpClient = getHttpClient(timeOut); HttpPost httpPost = new HttpPost(url); if (null != headers) { for (String key : headers.keySet()) { httpPost.setHeader(key, headers.get(key).toString()); } } String json = JSON.toJSONString(params); StringEntity stringEntity = new StringEntity(json, DEFAULT_ENCODING); stringEntity.setContentEncoding(DEFAULT_ENCODING); httpPost.setEntity(stringEntity); String result = null; try (CloseableHttpResponse response = httpClient.execute(httpPost);) { HttpEntity entity = response.getEntity(); if (null != entity) { // result = EntityUtils.toString(entity, ContentType.getOrDefault(entity).getCharset()); result = EntityUtils.toString(entity, Charset.defaultCharset()); EntityUtils.consume(entity); } } catch (Exception e) { log.error("接口请求异常:{}", e); } return result; } /** * http请求 * * @param url * @return */ public static String httpGet(String url) { log.info("请求url:{}", url); CloseableHttpClient httpClient = getHttpClient(DEFAULT_TIME_OUT); HttpGet httpGet = new HttpGet(url); String result = null; try (CloseableHttpResponse response = httpClient.execute(httpGet);) { HttpEntity entity = response.getEntity(); if (null != entity) { result = EntityUtils.toString(entity, ContentType.getOrDefault(entity).getCharset()); EntityUtils.consume(entity); } } catch (Exception e) { log.error("接口请求异常:{}", e); } return result; } }