HttpClient.java 6.05 KB
package com.yoho.pay;

import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
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.config.Registry;
import org.apache.http.config.RegistryBuilder;
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.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.TrustStrategy;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class HttpClient {
	private Logger logger = LoggerFactory.getLogger(getClass());
	
	protected static final int connectionRequestTimeout = 6000;
	protected static final int connectionTimeout = 3000;
	protected static final int socketTimeout = 2000;
	
	//最大总数
	private final int maxTotal = 30;
	
	//默认并发数
	private final int defaultMaxPerRoute = 10;
	
	protected CloseableHttpClient httpClient;
	
	public void init() throws Exception{
		HttpClientBuilder b = HttpClientBuilder.create();

		// setup a Trust Strategy that allows all certificates.
		//
		SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null,
				new TrustStrategy() {
					@Override
					public boolean isTrusted(X509Certificate[] arg0, String arg1)
							throws CertificateException {
						return true;
					}
				}).build();
		b.setSSLContext(sslContext);

		// don't check Hostnames, either.
		// -- use SSLConnectionSocketFactory.getDefaultHostnameVerifier(), if
		// you don't want to weaken
		HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE;

		// here's the special part:
		// -- need to create an SSL Socket Factory, to use our weakened
		// "trust strategy";
		// -- and create a Registry, to register it.
		//
		SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(
				sslContext, hostnameVerifier);
		Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder
				.<ConnectionSocketFactory> create()
				.register("http",
						PlainConnectionSocketFactory.getSocketFactory())
				.register("https", sslSocketFactory).build();

		// now, we create connection-manager using our Registry.
		// -- allows multi-threaded use
		PoolingHttpClientConnectionManager connMgr = new PoolingHttpClientConnectionManager(
				socketFactoryRegistry);
		connMgr.setMaxTotal(maxTotal);
		connMgr.setDefaultMaxPerRoute(defaultMaxPerRoute);
		b.setConnectionManager(connMgr);

		//request config
		RequestConfig requestConfig = RequestConfig.custom()
				.setConnectionRequestTimeout(connectionRequestTimeout)
				.setConnectTimeout(connectionTimeout)
				.setSocketTimeout(socketTimeout)
				.build();
		b.setDefaultRequestConfig(requestConfig);

		// finally, build the HttpClient;
		// -- done!
		httpClient = b.build();
	}
	
	public void destroy() {
		if(httpClient != null)
			httpClient.getConnectionManager().shutdown();
	}
	
	/**
	 * Get请求
	 * @param url
	 * @return
	 * @throws Exception
	 */
	public String get(String url) throws Exception {
		HttpGet httpget = new HttpGet(url);
        return sendHttpRequest(httpget);
	}
	
	/**
	 * Post请求
	 * @param url
	 * @param body
	 * @return
	 * @throws Exception
	 */
	public String post(String url, String body) throws Exception {
		HttpPost httpPost = new HttpPost(url);
		httpPost.addHeader("Content-Type", "application/json;charset=UTF-8");
		httpPost.setEntity(new StringEntity(body, "UTF-8"));
		return sendHttpRequest(httpPost);
	}
	
	/**
	 * 提交form-data
	 * @param url
	 * @param formDataMap
	 * @return
	 * @throws Exception
	 */
	public String postFormData(String url, Map<String, String> formDataMap) throws Exception {
		HttpPost httpPost = new HttpPost(url);
		//httpPost.addHeader("Content-Type", "multipart/form-data;charset=UTF-8");
		List <NameValuePair> nvps = new ArrayList <NameValuePair>();
		if(formDataMap != null) {
			for(Map.Entry<String, String> data : formDataMap.entrySet()) {
				nvps.add(new BasicNameValuePair(data.getKey(), data.getValue()));
			}
		}
		httpPost.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8"));
		return sendHttpRequest(httpPost);
	}
	
	/**
	 * http发送请求
	 * @param httpRequest
	 * @return
	 * @throws Exception
	 */
	private String sendHttpRequest(HttpUriRequest httpRequest) throws Exception {
		CloseableHttpResponse response =  null;
		try {
			response = httpClient.execute(httpRequest);
	        int statusCode = response.getStatusLine().getStatusCode();
	        if (statusCode != HttpStatus.SC_OK) {
	        	logger.error("http response code: {}, request: {}", statusCode, httpRequest.getURI());
	        	throw new RuntimeException("http response status: " + statusCode);
	        }
	        
	        return EntityUtils.toString(response.getEntity(), "UTF-8");
		}
		finally {
	        if (response != null) {
	            try {
	            	response.close();
	            } catch (Exception e) {
	            	logger.error("pay httpclient resp close failed: {}", e.getMessage());
	            }
	        }
	        if(httpRequest != null) {
	            try {
	            	httpRequest.abort();
	            } catch (Exception e) {
	            	logger.error("pay httpclient req abort failed: {}", e.getMessage());
	            }      	
	        }
		}
	}

}