池化HttpClient,拿去就能用

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