http与https创建CloseableHttpClient

import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.URL;
import java.net.UnknownHostException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Map;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLHandshakeException;

import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.HttpStatus;
import org.apache.http.NoHttpResponseException;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.routing.HttpRoute;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
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.protocol.HttpContext;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.nucc.NuccConstants;
import com.nucc.base.BankTxnException;

public class HttpClientUtil {

	private static final Logger logger = LoggerFactory.getLogger(HttpClientUtil.class);
	private static CloseableHttpClient poolHttpClient = null;
	private final static Object syncLock = new Object();

	public static final String DEFAULT_SEND_CHARSET = "UTF-8";

	public static final String DEFAULT_RES_CHARSET = "UTF-8";

	private static final RequestConfig config;
	static {
		config = RequestConfig.custom().setConnectTimeout(60000).setSocketTimeout(60000).build();
	}

	/**
	 * 
	 * <p>Title: doPostPooling</p>  
	 * <p>Description: </p>  
	 * @param url
	 * @param headers
	 * @param dataContent
	 * @return
	 * @throws Exception
	 */
	public static String doPostPooling(String url, Map<String, String> headers, String dataContent) throws Exception {
		return doPostPooling(url, headers, dataContent, "application/xml", DEFAULT_SEND_CHARSET, DEFAULT_RES_CHARSET);
	}
	/**
	 * 
	 * <p>Title: doPostPooling</p>  
	 * <p>Description: </p>  
	 * @param url
	 * @param headers
	 * @param dataContent
	 * @param contentType
	 * @param reqCharset
	 * @param resCharset
	 * @return
	 * @throws Exception
	 */
	private static String doPostPooling(String url, Map<String, String> headers, String dataContent, String contentType,
			String reqCharset, String resCharset) throws Exception {
		CloseableHttpResponse response = null;
		if (StringUtils.isBlank(url)) {
			return null;
		}
		CloseableHttpClient httpClient = getPoolingHttpClient(config, url);
		HttpPost httpPost = new HttpPost(url);
		httpPost.addHeader("Content-Type", contentType);

		for (Map.Entry<String, String> entry : headers.entrySet()) {
			httpPost.addHeader(entry.getKey(), entry.getValue());
		}

		HttpEntity reqentity = new StringEntity(dataContent, ContentType.create(contentType, reqCharset));
		httpPost.setEntity(reqentity);

		response = httpClient.execute(httpPost);
		int statusCode = response.getStatusLine().getStatusCode();
		if (statusCode != HttpStatus.SC_OK) {
			logger.error("HttpClientEpcc.doPostPooling :  状态码非200, 为 " + statusCode);
			httpPost.abort();
			throw new BankTxnException(NuccConstants.httpRspError, "状态码非200, 为 :" + statusCode);
		}
		HttpEntity entity = response.getEntity();
		String result = null;
		if (entity != null) {
			result = EntityUtils.toString(entity, resCharset == null ? DEFAULT_RES_CHARSET : resCharset);
		}
		EntityUtils.consume(entity);
		response.close();

		if (response != null)
			response.close();
		return result;
	}
	/**
	 * 
	 * <p>Title: getPoolingHttpClient</p>  
	 * <p>Description: </p>  
	 * @param config
	 * @param url
	 * @return
	 * @throws Exception
	 */
	private static CloseableHttpClient getPoolingHttpClient(RequestConfig config, String url) throws Exception {
		URL u = new URL(url);
		String hostname = u.getHost();
		int port = u.getPort();
		if (port == -1) {
			port = "https".equals(u.getProtocol()) ? 443 : 80;
		}
		if (poolHttpClient == null) {
			synchronized (syncLock) {
				if (poolHttpClient == null) {
					poolHttpClient = createPoolingConnection(config, 400, 40, 100, hostname, port);
				}
			}
		}
		return poolHttpClient;
	}

	/**
	 * 
	 * <p>Title: createPoolingConnection</p>  
	 * <p>Description: </p>  
	 * @param config
	 * @param maxTotal
	 * @param maxPerRoute
	 * @param maxRoute
	 * @param hostname
	 * @param port
	 * @return
	 * @throws Exception
	 */
	private static CloseableHttpClient createPoolingConnection(RequestConfig config, int maxTotal, int maxPerRoute,
			int maxRoute, String hostname, int port) throws Exception {
		
		CloseableHttpClient httpClient = null;
		ConnectionSocketFactory plainsf = PlainConnectionSocketFactory.getSocketFactory();
		SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
			@Override
			public boolean isTrusted(X509Certificate[] paramArrayOfX509Certificate, String paramString)
					throws CertificateException {
				return true;
			}
		}).build();

//		X509TrustManager trustManager = new X509TrustManager() {
//			@Override
//			public X509Certificate[] getAcceptedIssuers() {
//				return null;
//			}
//			@Override
//			public void checkClientTrusted(X509Certificate[] xcs, String str) {}
//			@Override
//			public void checkServerTrusted(X509Certificate[] xcs, String str) {}
//		};
		 SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
//		SSLContext ctx = SSLContext.getInstance(SSLConnectionSocketFactory.TLS);
//        ctx.init(null, new TrustManager[] { trustManager }, null);
//        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(ctx, NoopHostnameVerifier.INSTANCE);
        
		
//		SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, new String[] { "TLSv1.2" },
//				new String[] { "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384", "TLS_RSA_WITH_AES_256_GCM_SHA384" },
//				SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

		Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
				.register("http", plainsf).register("https", sslsf).build();
		PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry);
		// 将最大连接数增加
		cm.setMaxTotal(maxTotal);
		// 将每个路由基础的连接增加
		cm.setDefaultMaxPerRoute(maxPerRoute);
		HttpHost httpHost = new HttpHost(hostname, port);
		// 将目标主机的最大连接数增加
		cm.setMaxPerRoute(new HttpRoute(httpHost), maxRoute);

		// 请求重试处理
		HttpRequestRetryHandler httpRequestRetryHandler = new HttpRequestRetryHandler() {
			@Override
			public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
				if (executionCount >= 5) {// 如果已经重试了5次,就放弃
					return false;
				}
				if (exception instanceof NoHttpResponseException) {// 如果服务器丢掉了连接,那么就重试
					return true;
				}
				if (exception instanceof SSLHandshakeException) {// 不要重试SSL握手异常
					return false;
				}
				if (exception instanceof InterruptedIOException) {// 超时
					return false;
				}
				if (exception instanceof UnknownHostException) {// 目标服务器不可达
					return false;
				}
				if (exception instanceof ConnectTimeoutException) {// 连接被拒绝
					return false;
				}
				if (exception instanceof SSLException) {// SSL握手异常
					return false;
				}

				HttpClientContext clientContext = HttpClientContext.adapt(context);
				HttpRequest request = clientContext.getRequest();
				// 如果请求是幂等的,就再次尝试
				if (!(request instanceof HttpEntityEnclosingRequest)) {
					return true;
				}
				return false;
			}
		};
		httpClient = HttpClients.custom().setConnectionManager(cm).setDefaultRequestConfig(config)
				.setRetryHandler(httpRequestRetryHandler).build();
		return httpClient;
	}

}

猜你喜欢

转载自blog.csdn.net/jellyjiao2008/article/details/84786685