1 package com.util; 2 3 import java.io.IOException; 4 import java.io.UnsupportedEncodingException; 5 import java.security.cert.CertificateException; 6 import java.security.cert.X509Certificate; 7 import java.util.ArrayList; 8 import java.util.HashMap; 9 import java.util.List; 10 import java.util.Map; 11 import java.util.Map.Entry; 12 import java.util.Set; 13 14 import javax.net.ssl.SSLContext; 15 import javax.net.ssl.TrustManager; 16 import javax.net.ssl.X509TrustManager; 17 18 import org.apache.commons.collections.MapUtils; 19 import org.apache.http.HttpStatus; 20 import org.apache.http.NameValuePair; 21 import org.apache.http.client.config.RequestConfig; 22 import org.apache.http.client.entity.UrlEncodedFormEntity; 23 import org.apache.http.client.methods.CloseableHttpResponse; 24 import org.apache.http.client.methods.HttpDelete; 25 import org.apache.http.client.methods.HttpEntityEnclosingRequestBase; 26 import org.apache.http.client.methods.HttpGet; 27 import org.apache.http.client.methods.HttpPost; 28 import org.apache.http.client.methods.HttpPut; 29 import org.apache.http.client.methods.HttpRequestBase; 30 import org.apache.http.client.utils.URIBuilder; 31 import org.apache.http.config.Registry; 32 import org.apache.http.config.RegistryBuilder; 33 import org.apache.http.conn.socket.ConnectionSocketFactory; 34 import org.apache.http.conn.socket.PlainConnectionSocketFactory; 35 import org.apache.http.conn.ssl.SSLConnectionSocketFactory; 36 import org.apache.http.entity.StringEntity; 37 import org.apache.http.impl.client.CloseableHttpClient; 38 import org.apache.http.impl.client.HttpClientBuilder; 39 import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; 40 import org.apache.http.message.BasicNameValuePair; 41 import org.apache.http.util.EntityUtils; 42 43 /** 44 * commons-httpclient(停更)与httpclient(继续升级中) 45 * 46 * HTTP连接池请求,支持http和https请求, 47 * <p> 48 * 基于org.apache.httpcomponents.httpcore<version>4.4.10</version> 49 * </p> 50 * <p> 51 * 基于org.apache.httpcomponents.httpclient<version>4.5.6</version> 52 * </p> 53 * 54 * @author Henry(fba02) 55 * @version [版本号, 2019年12月8日] 56 * @see [相关类/方法] 57 * @since [产品/模块版本] 58 */ 59 public class HttpClientPoolUtil { 60 private static final String ENCODING = "UTF-8"; 61 public static final int DEFAULT_CONNECT_TIMEOUT = 6000; 62 public static final int DEFAULT_READ_TIMEOUT = 6000; 63 public static final int DEFAULT_CONNECT_REQUEST_TIMEOUT = 6000; 64 private static final int MAX_TOTAL = 64; 65 private static final int MAX_PER_ROUTE = 32; 66 private static final RequestConfig requestConfig; 67 private static final PoolingHttpClientConnectionManager connectionManager; 68 private static final HttpClientBuilder httpBuilder; 69 private static final CloseableHttpClient httpClient; 70 private static final CloseableHttpClient httpsClient; 71 private static SSLContext sslContext; 72 73 static { 74 try { 75 sslContext = SSLContext.getInstance("TLS"); 76 X509TrustManager tm = new X509TrustManager() { 77 @Override 78 public void checkClientTrusted(X509Certificate[] chain, String authType) 79 throws CertificateException { 80 } 81 @Override 82 public void checkServerTrusted(X509Certificate[] chain, String authType) 83 throws CertificateException { 84 } 85 @Override 86 public X509Certificate[] getAcceptedIssuers() { 87 return null; 88 } 89 }; 90 sslContext.init(null, new TrustManager[] {tm}, null); 91 } catch (Exception e) { 92 e.printStackTrace(); 93 } 94 } 95 96 static { 97 requestConfig = RequestConfig.custom().setSocketTimeout(DEFAULT_READ_TIMEOUT).setConnectTimeout(DEFAULT_CONNECT_TIMEOUT).setConnectionRequestTimeout(DEFAULT_CONNECT_REQUEST_TIMEOUT).build(); 98 @SuppressWarnings("deprecation") 99 Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory> create() 100 .register("http", new PlainConnectionSocketFactory()) 101 .register("https", new SSLConnectionSocketFactory(sslContext, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER)) 102 .build(); 103 connectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry); 104 connectionManager.setMaxTotal(MAX_TOTAL); 105 connectionManager.setDefaultMaxPerRoute(MAX_PER_ROUTE); 106 httpBuilder = HttpClientBuilder.create(); 107 httpBuilder.setDefaultRequestConfig(requestConfig); 108 httpBuilder.setConnectionManager(connectionManager); 109 httpClient = httpBuilder.build(); 110 httpsClient = httpBuilder.build(); 111 } 112 113 /** 114 * GET 115 * 116 * @param url 117 * @return 118 * @throws Exception 119 * @author Henry(fba02) 120 * @version [版本号, 2019年12月8日] 121 * @see [类、类#方法、类#成员] 122 */ 123 public static HttpClientResult doGet(String url) 124 throws Exception { 125 return doGet(url, false); 126 } 127 128 /** 129 * GET 130 * 131 * @param url 132 * @param https 133 * @return 134 * @throws Exception 135 * @author Henry(fba02) 136 * @version [版本号, 2019年12月8日] 137 * @see [类、类#方法、类#成员] 138 */ 139 public static HttpClientResult doGet(String url, boolean https) 140 throws Exception { 141 return doGet(url, null, null, https); 142 } 143 144 /** 145 * GET 146 * 147 * @param url 148 * @param params 149 * @param https 150 * @return 151 * @throws Exception 152 * @author Henry(fba02) 153 * @version [版本号, 2019年12月8日] 154 * @see [类、类#方法、类#成员] 155 */ 156 public static HttpClientResult doGet(String url, Map<String, String> params, boolean https) 157 throws Exception { 158 return doGet(url, null, params, https); 159 } 160 161 /** 162 * GET 163 * 164 * @param url 165 * @param headers 166 * @param params 167 * @param https 168 * @return 169 * @throws Exception 170 * @author Henry(fba02) 171 * @version [版本号, 2019年12月8日] 172 * @see [类、类#方法、类#成员] 173 */ 174 public static HttpClientResult doGet(String url, Map<String, String> headers, Map<String, String> params, boolean https) 175 throws Exception { 176 // 创建访问的地址 177 URIBuilder uriBuilder = new URIBuilder(url); 178 if (params != null) { 179 Set<Entry<String, String>> entrySet = params.entrySet(); 180 for (Entry<String, String> entry : entrySet) { 181 uriBuilder.setParameter(entry.getKey(), entry.getValue()); 182 } 183 } 184 // 创建HTTP对象 185 HttpGet httpGet = new HttpGet(uriBuilder.build()); 186 httpGet.setConfig(requestConfig); 187 // 设置请求头 188 setHeader(headers, httpGet); 189 // 创建httpResponse对象 190 CloseableHttpResponse httpResponse = null; 191 try { 192 if (https) { 193 return getHttpClientResult(httpResponse, httpsClient, httpGet); 194 } else { 195 return getHttpClientResult(httpResponse, httpClient, httpGet); 196 } 197 } finally { 198 httpGet.releaseConnection(); 199 release(httpResponse); 200 } 201 } 202 203 /** 204 * POST不带参数 205 * 206 * @param url 207 * @return 208 * @throws Exception 209 * @author Henry(fba02) 210 * @version [版本号, 2019年12月8日] 211 * @see [类、类#方法、类#成员] 212 */ 213 public static HttpClientResult doPost(String url) 214 throws Exception { 215 return doPost(url, Boolean.FALSE); 216 } 217 218 /** 219 * @param url 220 * @param https 221 * @return 222 * @throws Exception 223 * @author Henry(fba02) 224 * @version [版本号, 2019年12月8日] 225 * @see [类、类#方法、类#成员] 226 */ 227 public static HttpClientResult doPost(String url, boolean https) 228 throws Exception { 229 return doPost(url, null, (Map<String, String>)null, https); 230 } 231 232 /** 233 * 带请求参数 234 * 235 * @param url 236 * @param params 237 * @param https 238 * @return 239 * @throws Exception 240 * @author Henry(fba02) 241 * @version [版本号, 2019年12月8日] 242 * @see [类、类#方法、类#成员] 243 */ 244 public static HttpClientResult doPost(String url, Map<String, String> params, boolean https) 245 throws Exception { 246 return doPost(url, null, params, https); 247 } 248 249 /** 250 * POST 251 * 252 * @param url 253 * @param headers 254 * @param params 255 * @param https 256 * @return 257 * @throws Exception 258 * @author Henry(fba02) 259 * @version [版本号, 2019年12月8日] 260 * @see [类、类#方法、类#成员] 261 */ 262 public static HttpClientResult doPost(String url, Map<String, String> headers, Map<String, String> params, boolean https) 263 throws Exception { 264 // 创建HTTP对象 265 HttpPost httpPost = new HttpPost(url); 266 httpPost.setConfig(requestConfig); 267 // 设置请求头 268 setHeader(headers, httpPost); 269 // 封装请求参数 270 setParam(params, httpPost); 271 // 创建httpResponse对象 272 CloseableHttpResponse httpResponse = null; 273 try { 274 if (https) { 275 return getHttpClientResult(httpResponse, httpsClient, httpPost); 276 } else { 277 return getHttpClientResult(httpResponse, httpClient, httpPost); 278 } 279 } finally { 280 httpPost.releaseConnection(); 281 release(httpResponse); 282 } 283 } 284 285 /** 286 * POST请求JSON 287 * 288 * @param url 289 * @param headers 290 * @param json 291 * @param https 292 * @return 293 * @throws Exception 294 * @author Henry(fba02) 295 * @version [版本号, 2019年12月8日] 296 * @see [类、类#方法、类#成员] 297 */ 298 public static HttpClientResult doPost(String url, Map<String, String> headers, String json, boolean https) 299 throws Exception { 300 // 创建HTTP对象 301 HttpPost httpPost = new HttpPost(url); 302 httpPost.setConfig(requestConfig); 303 // 设置请求头 304 setHeader(headers, httpPost); 305 StringEntity stringEntity = new StringEntity(json, ENCODING); 306 stringEntity.setContentEncoding(ENCODING); 307 httpPost.setEntity(stringEntity); 308 // 创建httpResponse对象 309 CloseableHttpResponse httpResponse = null; 310 try { 311 if (https) { 312 return getHttpClientResult(httpResponse, httpsClient, httpPost); 313 } else { 314 return getHttpClientResult(httpResponse, httpClient, httpPost); 315 } 316 } finally { 317 httpPost.releaseConnection(); 318 release(httpResponse); 319 } 320 } 321 322 323 /** 324 * 发送put请求;不带请求参数 325 * 326 * @param url 请求地址 327 * @param params 参数集合 328 * @return 329 * @throws Exception 330 */ 331 public static HttpClientResult doPut(String url) 332 throws Exception { 333 return doPut(url); 334 } 335 336 /** 337 * 发送put请求;带请求参数 338 * 339 * @param url 请求地址 340 * @param params 参数集合 341 * @return 342 * @throws Exception 343 */ 344 public static HttpClientResult doPut(String url, Map<String, String> params) 345 throws Exception { 346 // CloseableHttpClient httpClient = HttpClients.createDefault(); 347 HttpPut httpPut = new HttpPut(url); 348 // RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(CONNECT_TIMEOUT).setSocketTimeout(SOCKET_TIMEOUT).build(); 349 httpPut.setConfig(requestConfig); 350 setParam(params, httpPut); 351 CloseableHttpResponse httpResponse = null; 352 try { 353 return getHttpClientResult(httpResponse, httpClient, httpPut); 354 } finally { 355 httpPut.releaseConnection(); 356 release(httpResponse); 357 } 358 } 359 360 /** 361 * 不带请求参数 362 * 363 * @param url 364 * @return 365 * @throws Exception 366 * @author Henry(fba02) 367 * @version [版本号, 2019年12月8日] 368 * @see [类、类#方法、类#成员] 369 */ 370 public static HttpClientResult doDelete(String url) 371 throws Exception { 372 // CloseableHttpClient httpClient = HttpClients.createDefault(); 373 HttpDelete httpDelete = new HttpDelete(url); 374 // RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(CONNECT_TIMEOUT).setSocketTimeout(SOCKET_TIMEOUT).build(); 375 httpDelete.setConfig(requestConfig); 376 CloseableHttpResponse httpResponse = null; 377 try { 378 return getHttpClientResult(httpResponse, httpClient, httpDelete); 379 } finally { 380 httpDelete.releaseConnection(); 381 release(httpResponse); 382 } 383 } 384 385 /** 386 * 带请求参数 387 * 388 * @param url 389 * @param params 390 * @param https 391 * @return 392 * @throws Exception 393 * @author Henry(fba02) 394 * @version [版本号, 2019年12月8日] 395 * @see [类、类#方法、类#成员] 396 */ 397 public static HttpClientResult doDelete(String url, Map<String, String> params, boolean https) 398 throws Exception { 399 if (params == null) { 400 params = new HashMap<String, String>(); 401 } 402 params.put("_method", "delete"); 403 return doPost(url, params, https); 404 } 405 406 /** 407 * 设置封装请求头 408 * 409 * @param params 410 * @param httpMethod 411 * @author Henry(fba02) 412 * @version [版本号, 2019年12月8日] 413 * @see [类、类#方法、类#成员] 414 */ 415 public static void setHeader(Map<String, String> params, HttpRequestBase httpMethod) { 416 // 封装请求头 417 if (MapUtils.isNotEmpty(params)) { 418 Set<Entry<String, String>> entrySet = params.entrySet(); 419 for (Entry<String, String> entry : entrySet) { 420 // 设置到请求头到HttpRequestBase对象中 421 httpMethod.setHeader(entry.getKey(), entry.getValue()); 422 } 423 } 424 } 425 426 /** 427 * 封装请求参数 428 * 429 * @param params 430 * @param httpMethod 431 * @throws UnsupportedEncodingException 432 * @author Henry(fba02) 433 * @version [版本号, 2019年12月8日] 434 * @see [类、类#方法、类#成员] 435 */ 436 public static void setParam(Map<String, String> params, HttpEntityEnclosingRequestBase httpMethod) 437 throws UnsupportedEncodingException { 438 // 封装请求参数 439 if (MapUtils.isNotEmpty(params)) { 440 List<NameValuePair> nvps = new ArrayList<NameValuePair>(); 441 Set<Entry<String, String>> entrySet = params.entrySet(); 442 for (Entry<String, String> entry : entrySet) { 443 nvps.add(new BasicNameValuePair(entry.getKey(), entry.getValue())); 444 } 445 // 设置到请求的http对象中 446 httpMethod.setEntity(new UrlEncodedFormEntity(nvps, ENCODING)); 447 } 448 } 449 450 /** 451 * 获得响应结果 452 * 453 * @param httpResponse 454 * @param httpClient 455 * @param httpMethod 456 * @return 457 * @throws Exception 458 * @author Henry(fba02) 459 * @version [版本号, 2019年12月8日] 460 * @see [类、类#方法、类#成员] 461 */ 462 public static HttpClientResult getHttpClientResult(CloseableHttpResponse httpResponse, CloseableHttpClient httpClient, HttpRequestBase httpMethod) 463 throws Exception { 464 // 执行请求 465 httpResponse = httpClient.execute(httpMethod); 466 // 获取返回结果 467 if (httpResponse != null && httpResponse.getStatusLine() != null) { 468 String content = ""; 469 if (httpResponse.getEntity() != null) { 470 content = EntityUtils.toString(httpResponse.getEntity(), ENCODING); 471 } 472 return new HttpClientResult(httpResponse.getStatusLine().getStatusCode(), content); 473 } 474 return new HttpClientResult(HttpStatus.SC_INTERNAL_SERVER_ERROR); 475 } 476 477 /** 478 * 释放资源 479 * 480 * @param httpResponse 481 * @throws IOException 482 * @author Henry(fba02) 483 * @version [版本号, 2019年12月8日] 484 * @see [类、类#方法、类#成员] 485 */ 486 public static void release(CloseableHttpResponse httpResponse) 487 throws IOException { 488 // 释放资源 489 if (httpResponse != null) { 490 httpResponse.close(); 491 } 492 } 493 } 494 495 package com.util; 496 497 import java.io.Serializable; 498 499 @SuppressWarnings("serial") 500 public class HttpClientResult implements Serializable { 501 /** 502 * 响应状态码 503 */ 504 private int code; 505 506 /** 507 * 响应数据 508 */ 509 private String content; 510 511 public int getCode() { 512 return code; 513 } 514 515 public void setCode(int code) { 516 this.code = code; 517 } 518 519 public String getContent() { 520 return content; 521 } 522 523 public void setContent(String content) { 524 this.content = content; 525 } 526 527 public HttpClientResult() { 528 super(); 529 } 530 531 public HttpClientResult(int code) { 532 super(); 533 this.code = code; 534 } 535 536 public HttpClientResult(int code, String content) { 537 super(); 538 this.code = code; 539 this.content = content; 540 } 541 542 @Override 543 public String toString() { 544 return "HttpClientResult [code=" + code + ", content=" + content + "]"; 545 } 546 }