| 
					
				 | 
			
			
				@ -0,0 +1,407 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				package com.yihu.jw.utils.sfutils; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				import com.google.common.collect.Lists; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				import lombok.extern.slf4j.Slf4j; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				import org.apache.commons.lang3.StringUtils; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				import org.apache.http.*; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				import org.apache.http.client.ClientProtocolException; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				import org.apache.http.client.HttpRequestRetryHandler; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				import org.apache.http.client.ResponseHandler; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				import org.apache.http.client.config.RequestConfig; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				import org.apache.http.client.entity.UrlEncodedFormEntity; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				import org.apache.http.client.methods.HttpGet; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				import org.apache.http.client.methods.HttpPost; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				import org.apache.http.client.methods.HttpUriRequest; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				import org.apache.http.client.protocol.HttpClientContext; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				import org.apache.http.client.utils.URLEncodedUtils; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				import org.apache.http.config.ConnectionConfig; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				import org.apache.http.config.Registry; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				import org.apache.http.config.RegistryBuilder; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				import org.apache.http.config.SocketConfig; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				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.client.CloseableHttpClient; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				import org.apache.http.impl.client.HttpClients; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				import org.apache.http.message.BasicNameValuePair; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				import org.apache.http.ssl.SSLContexts; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				import org.apache.http.util.EntityUtils; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				import org.slf4j.Logger; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				import org.slf4j.LoggerFactory; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				import javax.net.ssl.SSLException; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				import javax.net.ssl.SSLHandshakeException; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				import java.io.IOException; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				import java.io.InterruptedIOException; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				import java.net.UnknownHostException; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				import java.nio.charset.CodingErrorAction; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				import java.util.List; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				import java.util.Map; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				import java.util.stream.Collectors; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				@Slf4j 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				public class HttpClientUtils { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    private static Logger logger = LoggerFactory.getLogger(HttpClientUtils.class); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    HttpClientUtils() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * 连接池最大连接数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    private static final int MAX_TOTAL_CONNECTIONS = 4000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * 设置每个路由上的默认连接个数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    private static final int DEFAULT_MAX_PER_ROUTE = 200; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * 请求的请求超时时间 单位:毫秒 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    private static final int REQUEST_CONNECTION_TIMEOUT = 8 * 1000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * 请求的等待数据超时时间 单位:毫秒 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    private static final int REQUEST_SOCKET_TIMEOUT = 8 * 1000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * 请求的连接超时时间 单位:毫秒 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    private static final int REQUEST_CONNECTION_REQUEST_TIMEOUT = 5 * 1000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * 连接闲置多久后需要重新检测 单位:毫秒 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    private static final int VALIDATE_AFTER_IN_ACTIVITY = 2 * 1000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * 接收数据的等待超时时间,即读超时时间,单位ms 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    private static final int SOCKET_CONFIG_SO_TIMEOUT = 5 * 1000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * 重试次数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    private static final int RETRY_COUNT = 5; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * 声明为 static volatile,会迫使线程每次读取时作为一个全局变量读取 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    private static volatile CloseableHttpClient httpClient = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @param uri 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @return String 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @description get请求方式 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @author: long.he01 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    public static String doGet(String uri) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        String responseBody; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        HttpGet httpGet = new HttpGet(uri); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            httpGet.setConfig(getRequestConfig()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            responseBody = executeRequest(httpGet); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        } catch (IOException e) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				//            logger.eerror("httpclient doGet方法异常{}", e); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            return null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        } finally { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            httpGet.releaseConnection(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        return responseBody; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @param uri 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @param params 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @return string 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @description 带map参数get请求, 此方法会将map参数拼接到连接地址上。 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    public static String doGet(String uri, Map<String, String> params) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        return doGet(getGetUrlFromParams(uri, params)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @param uri 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @param params 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @return String 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @description 根据map参数拼接完整的url地址 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    private static String getGetUrlFromParams(String uri, Map<String, String> params) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        List<BasicNameValuePair> resultList = params.entrySet().stream().map(innerEntry -> new BasicNameValuePair(innerEntry.getKey(), innerEntry.getValue())).collect(Collectors.toList()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        String paramSectionOfUrl = URLEncodedUtils.format(resultList, Consts.UTF_8); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        StringBuilder resultUrl = new StringBuilder(uri); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        if (StringUtils.isEmpty(uri)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            return uri; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            if (!StringUtils.isEmpty(paramSectionOfUrl)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                if (uri.endsWith("?")) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                    resultUrl.append(paramSectionOfUrl); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                    resultUrl.append("?").append(paramSectionOfUrl); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            return resultUrl.toString(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @param uri 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @param params 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @return String 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @description 带map参数的post请求方法 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    public static String doPost(String uri, Map<String, String> params) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        String responseBody; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        HttpPost httpPost = new HttpPost(uri); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            List<NameValuePair> nvps = Lists.newArrayList(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            for (Map.Entry<String, String> entry : params.entrySet()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                String key = entry.getKey(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                String value = entry.getValue(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                nvps.add(new BasicNameValuePair(key, value)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            httpPost.setEntity(new UrlEncodedFormEntity(nvps, Consts.UTF_8)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            httpPost.setConfig(getRequestConfig()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            responseBody = executeRequest(httpPost); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        } catch (Exception e) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            logger.error("httpPosttpclient doPost方法异常{}", e); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            return null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        } finally { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            httpPost.releaseConnection(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        return responseBody; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @param uri 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @param param 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @param contentType 根据具体请求情况指定,比如json可以是 ContentType.APPLICATION_JSON 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @return String 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @description 带单string参数执行post方法 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @param uri 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @param param 请求参数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @param headerParams header参数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @param contentType 根据具体请求情况指定,比如json可以是 ContentType.APPLICATION_JSON 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @description 带单string参数执行post方法 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    /*public static String doPostWithHeader(String uri, String param, Map<String, Object> headerParams, ContentType contentType) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        String responseBody; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        HttpPost httpPost = new HttpPost(uri); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            if (!CollectionUtils.isEmpty(headerParams)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                for (Map.Entry<String, Object> entry : headerParams.entrySet()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                    httpPost.setHeader(entry.getKey(), entry.getValue().toString()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            StringEntity reqEntity = new StringEntity(param, contentType); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            httpPost.setEntity(reqEntity); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            httpPost.setConfig(getRequestConfig()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            responseBody = executeRequest(httpPost); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        } catch (IOException e) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            log.error("httpclient doPost方法异常{}", e); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            return null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        } finally { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            httpPost.releaseConnection(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        return responseBody; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    }*/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @param uri 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @param param 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @param contentType 根据具体请求情况指定,比如json可以是 ContentType.APPLICATION_JSON 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @return String 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @description 带单string参数执行post方法 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    public static String doPost(String uri, String param, ContentType contentType) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        String responseBody; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        HttpPost httpPost = new HttpPost(uri); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            StringEntity reqEntity = new StringEntity(param, contentType); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            httpPost.setEntity(reqEntity); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            httpPost.setConfig(getRequestConfig()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            responseBody = executeRequest(httpPost); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        } catch (IOException e) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            logger.error("errorhttpclient doPost方法异常{}", e); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            return null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        } finally { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            httpPost.releaseConnection(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        return responseBody; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @return RequestConfig 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @description: 获得请求配置信息 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    private static RequestConfig getRequestConfig() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        RequestConfig defaultRequestConfig = RequestConfig.custom() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                //.setCookieSpec(CookieSpecs.DEFAULT) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                .setExpectContinueEnabled(true) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                //.setTargetPreferredAuthSchemes(Arrays.asList(AuthSchemes.NTLM, AuthSchemes.DIGEST)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                //.setProxyPreferredAuthSchemes(Arrays.asList(AuthSchemes.BASIC)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                .build(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        return RequestConfig.copy(defaultRequestConfig) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                .setSocketTimeout(REQUEST_CONNECTION_TIMEOUT) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                .setConnectTimeout(REQUEST_SOCKET_TIMEOUT) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                .setConnectionRequestTimeout(REQUEST_CONNECTION_REQUEST_TIMEOUT) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                .build(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @param method 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @return String 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @throws IOException 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @description 通用执行请求方法 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    private static String executeRequest(HttpUriRequest method) throws IOException { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        ResponseHandler<String> responseHandler = new ResponseHandler<String>() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            @Override 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            public String handleResponse(final HttpResponse response) throws IOException { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                int status = response.getStatusLine().getStatusCode(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                String result; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                if (status >= HttpStatus.SC_OK && status < HttpStatus.SC_MULTIPLE_CHOICES) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                    HttpEntity entity = response.getEntity(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                    result = entity != null ? EntityUtils.toString(entity) : null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                    EntityUtils.consume(entity); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                    return result; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                    throw new ClientProtocolException("Unexpected response status: " + status); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        return getHttpClientInstance().execute(method, responseHandler); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @return CloseableHttpClient 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @description 单例获取httpclient实例 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    private static CloseableHttpClient getHttpClientInstance() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        if (httpClient == null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            synchronized (CloseableHttpClient.class) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                if (httpClient == null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                    httpClient = HttpClients.custom().setConnectionManager(initConfig()).setRetryHandler(getRetryHandler()).build(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        return httpClient; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @return HttpRequestRetryHandler 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @description :获取重试handler 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    private static HttpRequestRetryHandler getRetryHandler() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        // 请求重试处理 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        return (exception, executionCount, context) -> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            if (executionCount >= RETRY_COUNT) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                // 假设已经重试了5次,就放弃 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            if (exception instanceof NoHttpResponseException) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                // 假设server丢掉了连接。那么就重试 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            if (exception instanceof SSLHandshakeException) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                // 不要重试SSL握手异常 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            if (exception instanceof InterruptedIOException) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                // 超时 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            if (exception instanceof UnknownHostException) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                // 目标server不可达 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            if (exception instanceof SSLException) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                // SSL握手异常 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            HttpRequest request = HttpClientContext.adapt(context).getRequest(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            // 假设请求是幂等的,就再次尝试 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            return !(request instanceof HttpEntityEnclosingRequest); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @return PoolingHttpClientConnectionManager 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @description 初始化连接池等配置信息 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    private static PoolingHttpClientConnectionManager initConfig() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                .register("http", PlainConnectionSocketFactory.INSTANCE) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                .register("https", new SSLConnectionSocketFactory(SSLContexts.createSystemDefault())) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                .build(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         * 以下参数设置含义分别为: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         * 1 是否立即发送数据,设置为true会关闭Socket缓冲,默认为false 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         * 2 是否可以在一个进程关闭Socket后,即使它还没有释放端口,其它进程还可以立即重用端口 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         * 3 接收数据的等待超时时间,单位ms 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         * 4 关闭Socket时,要么发送完所有数据,要么等待多少秒后,就关闭连接,此时socket.close()是阻塞的 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         * 5 开启监视TCP连接是否有效 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         * 其中setTcpNoDelay(true)设置是否启用Nagle算法,设置true后禁用Nagle算法,默认为false(即默认启用Nagle算法)。 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         * Nagle算法试图通过减少分片的数量来节省带宽。当应用程序希望降低网络延迟并提高性能时, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         * 它们可以关闭Nagle算法,这样数据将会更早地发 送,但是增加了网络消耗。 单位为:毫秒 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        SocketConfig socketConfig = SocketConfig.custom() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                .setTcpNoDelay(true) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                .setSoReuseAddress(true) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                .setSoTimeout(SOCKET_CONFIG_SO_TIMEOUT) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                //.setSoLinger(SOCKET_CONFIG_SO_LINGER) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                //.setSoKeepAlive(true) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                .build(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        connManager.setDefaultSocketConfig(socketConfig); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        connManager.setValidateAfterInactivity(VALIDATE_AFTER_IN_ACTIVITY); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        ConnectionConfig connectionConfig = ConnectionConfig.custom() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                .setMalformedInputAction(CodingErrorAction.IGNORE) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                .setUnmappableInputAction(CodingErrorAction.IGNORE) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                .setCharset(Consts.UTF_8) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                .build(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        connManager.setDefaultConnectionConfig(connectionConfig); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        connManager.setDefaultMaxPerRoute(DEFAULT_MAX_PER_ROUTE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        connManager.setMaxTotal(MAX_TOTAL_CONNECTIONS); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        return connManager; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				} 
			 |