HttpClientGenerator.java 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. package com.nosum.common.util;
  2. import org.apache.http.HttpException;
  3. import org.apache.http.HttpRequest;
  4. import org.apache.http.HttpRequestInterceptor;
  5. import org.apache.http.client.CookieStore;
  6. import org.apache.http.config.Registry;
  7. import org.apache.http.config.RegistryBuilder;
  8. import org.apache.http.config.SocketConfig;
  9. import org.apache.http.conn.socket.ConnectionSocketFactory;
  10. import org.apache.http.conn.socket.PlainConnectionSocketFactory;
  11. import org.apache.http.conn.ssl.DefaultHostnameVerifier;
  12. import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
  13. import org.apache.http.impl.client.BasicCookieStore;
  14. import org.apache.http.impl.client.CloseableHttpClient;
  15. import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
  16. import org.apache.http.impl.client.HttpClientBuilder;
  17. import org.apache.http.impl.client.HttpClients;
  18. import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
  19. import org.apache.http.impl.cookie.BasicClientCookie;
  20. import org.apache.http.protocol.HttpContext;
  21. import org.slf4j.Logger;
  22. import org.slf4j.LoggerFactory;
  23. import us.codecraft.webmagic.Site;
  24. import us.codecraft.webmagic.downloader.CustomRedirectStrategy;
  25. import javax.net.ssl.SSLContext;
  26. import javax.net.ssl.TrustManager;
  27. import javax.net.ssl.X509TrustManager;
  28. import java.io.IOException;
  29. import java.security.KeyManagementException;
  30. import java.security.NoSuchAlgorithmException;
  31. import java.security.cert.CertificateException;
  32. import java.security.cert.X509Certificate;
  33. import java.util.Map;
  34. /**
  35. * @author: sumbytes
  36. * @date: 2019/8/3 14:57
  37. * @modified:
  38. */
  39. public class HttpClientGenerator {
  40. private transient Logger logger = LoggerFactory.getLogger(getClass());
  41. private PoolingHttpClientConnectionManager connectionManager;
  42. public HttpClientGenerator() {
  43. Registry<ConnectionSocketFactory> reg = RegistryBuilder.<ConnectionSocketFactory>create()
  44. .register("http", PlainConnectionSocketFactory.INSTANCE)
  45. .register("https", buildSSLConnectionSocketFactory())
  46. .build();
  47. connectionManager = new PoolingHttpClientConnectionManager(reg);
  48. connectionManager.setDefaultMaxPerRoute(100);
  49. }
  50. private SSLConnectionSocketFactory buildSSLConnectionSocketFactory() {
  51. try {
  52. return new SSLConnectionSocketFactory(createIgnoreVerifySSL(), new String[]{"SSLv3", "TLSv1", "TLSv1.1", "TLSv1.2"},
  53. null,
  54. new DefaultHostnameVerifier()); // 优先绕过安全证书
  55. } catch (KeyManagementException e) {
  56. logger.error("ssl connection fail", e);
  57. } catch (NoSuchAlgorithmException e) {
  58. logger.error("ssl connection fail", e);
  59. }
  60. return SSLConnectionSocketFactory.getSocketFactory();
  61. }
  62. private SSLContext createIgnoreVerifySSL() throws NoSuchAlgorithmException, KeyManagementException {
  63. // 实现一个X509TrustManager接口,用于绕过验证,不用修改里面的方法
  64. X509TrustManager trustManager = new X509TrustManager() {
  65. @Override
  66. public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
  67. }
  68. @Override
  69. public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
  70. }
  71. @Override
  72. public X509Certificate[] getAcceptedIssuers() {
  73. return null;
  74. }
  75. };
  76. SSLContext sc = SSLContext.getInstance("SSLv3");
  77. sc.init(null, new TrustManager[]{trustManager}, null);
  78. return sc;
  79. }
  80. public HttpClientGenerator setPoolSize(int poolSize) {
  81. connectionManager.setMaxTotal(poolSize);
  82. return this;
  83. }
  84. public CloseableHttpClient getClient(Site site) {
  85. return generateClient(site);
  86. }
  87. private CloseableHttpClient generateClient(Site site) {
  88. HttpClientBuilder httpClientBuilder = HttpClients.custom();
  89. httpClientBuilder.setConnectionManager(connectionManager);
  90. if (site.getUserAgent() != null) {
  91. httpClientBuilder.setUserAgent(site.getUserAgent());
  92. } else {
  93. httpClientBuilder.setUserAgent("");
  94. }
  95. if (site.isUseGzip()) {
  96. httpClientBuilder.addInterceptorFirst(new HttpRequestInterceptor() {
  97. @Override
  98. public void process(
  99. HttpRequest request,
  100. HttpContext context) throws HttpException, IOException {
  101. if (!request.containsHeader("Accept-Encoding")) {
  102. request.addHeader("Accept-Encoding", "gzip");
  103. }
  104. }
  105. });
  106. }
  107. //解决post/redirect/post 302跳转问题
  108. httpClientBuilder.setRedirectStrategy(new CustomRedirectStrategy());
  109. SocketConfig.Builder socketConfigBuilder = SocketConfig.custom();
  110. socketConfigBuilder.setSoKeepAlive(true).setTcpNoDelay(true);
  111. socketConfigBuilder.setSoTimeout(site.getTimeOut());
  112. SocketConfig socketConfig = socketConfigBuilder.build();
  113. httpClientBuilder.setDefaultSocketConfig(socketConfig);
  114. connectionManager.setDefaultSocketConfig(socketConfig);
  115. httpClientBuilder.setRetryHandler(new DefaultHttpRequestRetryHandler(site.getRetryTimes(), true));
  116. generateCookie(httpClientBuilder, site);
  117. return httpClientBuilder.build();
  118. }
  119. private void generateCookie(HttpClientBuilder httpClientBuilder, Site site) {
  120. if (site.isDisableCookieManagement()) {
  121. httpClientBuilder.disableCookieManagement();
  122. return;
  123. }
  124. CookieStore cookieStore = new BasicCookieStore();
  125. for (Map.Entry<String, String> cookieEntry : site.getCookies().entrySet()) {
  126. BasicClientCookie cookie = new BasicClientCookie(cookieEntry.getKey(), cookieEntry.getValue());
  127. cookie.setDomain(site.getDomain());
  128. cookieStore.addCookie(cookie);
  129. }
  130. for (Map.Entry<String, Map<String, String>> domainEntry : site.getAllCookies().entrySet()) {
  131. for (Map.Entry<String, String> cookieEntry : domainEntry.getValue().entrySet()) {
  132. BasicClientCookie cookie = new BasicClientCookie(cookieEntry.getKey(), cookieEntry.getValue());
  133. cookie.setDomain(domainEntry.getKey());
  134. cookieStore.addCookie(cookie);
  135. }
  136. }
  137. httpClientBuilder.setDefaultCookieStore(cookieStore);
  138. }
  139. }