池化HttpClient,拿去就能用

  1 import lombok.extern.slf4j.Slf4j;
  2 import org.apache.http.HttpEntity;
  3 import org.apache.http.HttpResponse;
  4 import org.apache.http.HttpStatus;
  5 import org.apache.http.NameValuePair;
  6 import org.apache.http.client.HttpRequestRetryHandler;
  7 import org.apache.http.client.config.RequestConfig;
  8 import org.apache.http.client.entity.UrlEncodedFormEntity;
  9 import org.apache.http.client.methods.CloseableHttpResponse;
 10 import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
 11 import org.apache.http.client.methods.HttpPost;
 12 import org.apache.http.client.methods.HttpRequestBase;
 13 import org.apache.http.config.Registry;
 14 import org.apache.http.config.RegistryBuilder;
 15 import org.apache.http.conn.socket.ConnectionSocketFactory;
 16 import org.apache.http.conn.socket.PlainConnectionSocketFactory;
 17 import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
 18 import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
 19 import org.apache.http.entity.StringEntity;
 20 import org.apache.http.impl.client.CloseableHttpClient;
 21 import org.apache.http.impl.client.HttpClients;
 22 import org.apache.http.impl.client.StandardHttpRequestRetryHandler;
 23 import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
 24 import org.apache.http.message.BasicNameValuePair;
 25 import org.apache.http.ssl.SSLContextBuilder;
 26 import org.apache.http.util.EntityUtils;
 27 import org.slf4j.Logger;
 28 import org.slf4j.LoggerFactory;
 29 
 30 import java.io.IOException;
 31 import java.io.UnsupportedEncodingException;
 32 import java.util.ArrayList;
 33 import java.util.List;
 34 import java.util.Map;
 35 import java.util.Set;
 36 import java.util.concurrent.ScheduledExecutorService;
 37 import java.util.concurrent.ScheduledThreadPoolExecutor;
 38 import java.util.concurrent.TimeUnit;
 39 
 40 /**
 41  * 可为每个域名设置单独的连接池数量
 42  * connectionManager.setMaxPerRoute(new HttpRoute(new HttpHost("www.baidu.com")), 1);
 43  * setConnectTimeout表示设置建立连接的超时时间
 44  * setConnectionRequestTimeout表示从连接池中拿连接的等待超时时间
 45  * setSocketTimeout表示发出请求后等待对端应答的超时时间
 46  */
 47 
 48 @Slf4j
 49 public class HttpConnectionPoolUtils {
 50 
 51     private static final Logger LOGGER = LoggerFactory.getLogger(HttpConnectionPoolUtils.class);
 52 
 53     private static final String ENCODING = "UTF-8";
 54 
 55     private static PoolingHttpClientConnectionManager connectionManager = null;
 56 
 57     private static CloseableHttpClient httpClient;
 58 
 59     static {
 60         LOGGER.info("初始化http connection 连接池 ...");
 61         try {
 62             // 配置同时支持 HTTP 和 HTPPS
 63             SSLContextBuilder builder = new SSLContextBuilder();
 64             builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
 65             SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(builder.build());
 66             Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create().register("http", PlainConnectionSocketFactory.getSocketFactory()).register("https", sslConnectionSocketFactory).build();
 67             connectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
 68         }catch (Exception e){
 69             LOGGER.error("初始化http 连接池异常",e);
 70             connectionManager = new PoolingHttpClientConnectionManager();
 71         }
 72         // 总连接池数量
 73         connectionManager.setMaxTotal(20);
 74         connectionManager.setDefaultMaxPerRoute(100);
 75         RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(1000).setConnectionRequestTimeout(2000).setSocketTimeout(3000).build();
 76         HttpRequestRetryHandler retryHandler = new StandardHttpRequestRetryHandler();
 77 
 78         httpClient = HttpClients.custom().setConnectionManager(connectionManager).setDefaultRequestConfig(requestConfig).setRetryHandler(retryHandler).build();
 79 
 80         ScheduledExecutorService scheduledExecutorService = new ScheduledThreadPoolExecutor(1);
 81         scheduledExecutorService.scheduleWithFixedDelay(() -> {
 82             connectionManager.closeExpiredConnections();
 83             connectionManager.closeIdleConnections(20,TimeUnit.SECONDS);
 84             LOGGER.info("回收过期的http连接完成 status:{}",connectionManager.getTotalStats());
 85         },30,120,TimeUnit.SECONDS);
 86 
 87         Runtime.getRuntime().addShutdownHook(new Thread(() -> {
 88             log.info("关闭 httpClient 连接");
 89             try {
 90                 if(httpClient != null){
 91                     httpClient.close();
 92                 }
 93             } catch (IOException e) {
 94                 log.error("关闭 httpClient 异常",e);
 95             }
 96         }));
 97     }
 98 
 99     public static HttpClientResult doPost(String url, Map<String, String> params) throws IOException {
100         return doPost(url, null, params);
101     }
102 
103     public static HttpClientResult doPost(String url, Map<String, String> headers, Map<String, String> params) throws IOException {
104 
105         log.info("http post 请求:url={}", url);
106         log.info("http post 请求:params = {}", params);
107         // 创建httpClient对象
108         HttpPost httpPost = new HttpPost(url);
109         packageHeader(headers, httpPost);
110         // 封装请求参数
111         try {
112             packageParam(params, httpPost);
113         } catch (UnsupportedEncodingException e) {
114             throw e;
115         }
116 
117         // 创建httpResponse对象
118         CloseableHttpResponse httpResponse = null;
119 
120         try {
121             // 执行请求并获得响应结果
122             long startTime = System.currentTimeMillis();
123             HttpClientResult httpClientResult = getHttpClientResult(httpResponse, httpClient, httpPost);
124             long endTime = System.currentTimeMillis();
125             log.info("http post 请求相应时间:{}", (endTime-startTime));
126             log.info("http post 请求返回结果:{}", httpClientResult);
127             return httpClientResult;
128         } catch (Exception e) {
129             throw e;
130         } finally {
131             // 释放资源
132             if (httpResponse != null) {
133                 httpResponse.close();
134             }
135         }
136     }
137 
138     public static void packageHeader(Map<String, String> params, HttpRequestBase httpMethod) {
139         // 封装请求头
140         if (params != null) {
141             Set<Map.Entry<String, String>> entrySet = params.entrySet();
142             for (Map.Entry<String, String> entry : entrySet) {
143                 // 设置到请求头到HttpRequestBase对象中
144                 httpMethod.setHeader(entry.getKey(), entry.getValue());
145             }
146         }
147     }
148 
149     public static void packageParam(Map<String, String> params, HttpEntityEnclosingRequestBase httpMethod)
150             throws UnsupportedEncodingException {
151         // 封装请求参数
152         if (params != null) {
153             List<NameValuePair> nvps = new ArrayList<NameValuePair>();
154             Set<Map.Entry<String, String>> entrySet = params.entrySet();
155             for (Map.Entry<String, String> entry : entrySet) {
156                 nvps.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
157             }
158 
159             // 设置到请求的http对象中
160             httpMethod.setEntity(new UrlEncodedFormEntity(nvps, ENCODING));
161         }
162     }
163 
164     public static HttpClientResult getHttpClientResult(CloseableHttpResponse httpResponse,
165                                                        CloseableHttpClient httpClient, HttpRequestBase httpMethod) throws IOException {
166         // 执行请求
167         httpResponse = httpClient.execute(httpMethod);
168 
169         // 获取返回结果
170         if (httpResponse != null && httpResponse.getStatusLine() != null) {
171             String content = "";
172             if (httpResponse.getEntity() != null) {
173                 content = EntityUtils.toString(httpResponse.getEntity(), ENCODING);
174             }
175             return new HttpClientResult(httpResponse.getStatusLine().getStatusCode(), content);
176         }
177         return new HttpClientResult(HttpStatus.SC_INTERNAL_SERVER_ERROR);
178     }
179 
180     public static String doPost(String url,String postBody) throws IOException {
181         HttpPost httpPost = new HttpPost(url);
182         StringEntity entity = new StringEntity(postBody,"utf-8");
183         entity.setContentEncoding("UTF-8");
184         entity.setContentType("application/json");
185         httpPost.setEntity(entity);
186         HttpResponse resp = httpClient.execute(httpPost);
187 
188         String respContent = "";
189         if(resp.getStatusLine().getStatusCode() == 200) {
190             HttpEntity he = resp.getEntity();
191             respContent = EntityUtils.toString(he,"UTF-8");
192         }
193         return respContent;
194     }
195 }
196 
posted @ 2019-12-18 17:18  苏景辰  阅读(737)  评论(0编辑  收藏  举报