HttpClient实例_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > HttpClient实例

HttpClient实例

 2018/3/16 9:47:17  笨小孩在早起  程序员俱乐部  我要评论(0)
  • 摘要:importjava.io.IOException;importjava.io.InterruptedIOException;importjava.net.UnknownHostException;importjava.security.KeyManagementException;importjava.security.NoSuchAlgorithmException;importjava.security.cert.CertificateException;importjava
  • 标签:client 实例 HTTP
class="java">
import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

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

import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.apache.http.Consts;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpRequest;
import org.apache.http.NameValuePair;
import org.apache.http.NoHttpResponseException;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.config.AuthSchemes;
import org.apache.http.client.config.CookieSpecs;
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.HttpRequestBase;
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.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.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;

public class HttpClient {

	private static final Logger logger = LoggerFactory.getLogger(HttpClient.class);

	public static String utf8 = "utf-8";
	
	private static String userAgentName = "User-Agent";
	private static String userAgentValue = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:45.0) "
			+ "Gecko/20100101 Firefox/45.0";

	private String userAgent = null;
	
	public void setUserAgent(String userAgent) {
		this.userAgent = userAgent;
	}

	private static TrustManager manager = new X509TrustManager() {

		@Override
		public X509Certificate[] getAcceptedIssuers() {
			// TODO Auto-generated method stub
			return null;
		}

		@Override
		public void checkServerTrusted(X509Certificate[] chain, String authType)
				throws CertificateException {
			// TODO Auto-generated method stub

		}

		@Override
		public void checkClientTrusted(X509Certificate[] chain, String authType)
				throws CertificateException {
			// TODO Auto-generated method stub

		}
	};

	private static PoolingHttpClientConnectionManager connectionManager = null;

	// 路由(MAX_PER_ROUTE)是对最大连接数(MAX_TOTAL)的细分,整个连接池限制数量实际使用DefaultMaxPerRoute并非MaxTotal。
	// 设置过小无法支持大并发(ConnectionPoolTimeoutException: Timeout waiting for
	// connection from pool)
	static {

		try {
			SSLContext context = SSLContext.getInstance("TLS");
			context.init(null, new TrustManager[] { manager }, null);
			SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(context,
					NoopHostnameVerifier.INSTANCE);
			Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder
					.<ConnectionSocketFactory>create()
					.register("http", PlainConnectionSocketFactory.INSTANCE)
					.register("https", socketFactory)
					.build();
			connectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
			connectionManager.setMaxTotal(50);// 将最大连接数增加到50
			connectionManager.setDefaultMaxPerRoute(5);// 设置路由最大连接数
		} catch (NoSuchAlgorithmException e) {
			logger.error(e.getMessage());
		} catch (KeyManagementException e) {
			logger.error(e.getMessage());
		}

	}
	CloseableHttpClient httpsClient = null;

	private void create() {
		RequestConfig defaultRequestConfig = RequestConfig.custom()
				.setCookieSpec(CookieSpecs.STANDARD_STRICT)
				.setExpectContinueEnabled(true)
				.setConnectionRequestTimeout(5000)
				.setConnectTimeout(10000)
				.setSocketTimeout(10000)
				.setTargetPreferredAuthSchemes(Arrays.asList(AuthSchemes.NTLM, AuthSchemes.DIGEST))
				.setProxyPreferredAuthSchemes(Arrays.asList(AuthSchemes.BASIC)).build();
		HttpRequestRetryHandler httpRequestRetryHandler = (exception, executionCount, context) -> {
			if (executionCount >= 3) {// 如果已经重试了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;
		};
		httpsClient = HttpClients.custom()
				.setConnectionManager(connectionManager)
				.setDefaultRequestConfig(defaultRequestConfig)
				.setRetryHandler(httpRequestRetryHandler)
				.build();

	}
	
	public void close() {
		try {
			if(httpsClient != null) {
				httpsClient.close();
			}
		} catch (IOException e) {
			logger.error(e.getMessage());
		}
	}

	private HttpClient() {
		create();
	}

	public static HttpClient createHttpsClient() {
		return new HttpClient();
	}

	private Result toResult(CloseableHttpResponse response) throws IOException {
		Result result = null;
		try {
			String body = EntityUtils.toString(response.getEntity(), HttpClient.utf8);
			result = new Result();
			result.setBody(body);
			result.setStatus(response.getStatusLine().getStatusCode());
			if (logger.isDebugEnabled()) {
				logger.debug("https result: {}", result);
			}
		} finally {
			if (response != null) {
				response.close();
			}
		}
		return result;
	}

	/**
	 * post 不带参数请求, CloseableHttpResponse 需要调用方关闭
	 * 
	 * @param url
	 * @return
	 * @throws IOException
	 */
	public CloseableHttpResponse doHttpsPost(String url) throws IOException {
		return doHttpsPost(url, (List<NameValuePair>) null);
	}

	/**
	 * post 不带参数请求
	 * 
	 * @param url
	 * @return Result 返回带字符串响应结果和响应状态的对象
	 * @throws IOException
	 */
	public Result doHttpsPostReturnResult(String url) throws IOException {
		return toResult(doHttpsPost(url));
	}

	/**
	 * post 不带参数,返回对象,响应结果必须是json 对象
	 * 
	 * @param url
	 * @param c
	 * @return
	 * @throws IOException
	 */
	public <T> T doHttpsPostReturnObject(String url, Class<T> c) throws IOException {
		T result = null;
		Result response = doHttpsPostReturnResult(url);
		result = JSON.parseObject(response.getBody(), c);
		return result;
	}

	/**
	 * 不带参数,返回集合,响应结果必须是json 数组
	 * 
	 * @param url
	 * @param c
	 * @return
	 * @throws IOException
	 */
	public <T> List<T> doHttpsPostReturnArray(String url, Class<T> c) throws IOException {
		List<T> result = null;
		Result response = doHttpsPostReturnResult(url);
		result = JSON.parseArray(response.getBody(), c);
		return result;
	}

	public CloseableHttpResponse doHttpsPost(String url, Map<String, Object> params) 
			throws IOException {
		List<NameValuePair> values = new ArrayList<>();
		if (params != null) {
			for (Map.Entry<String, Object> entry : params.entrySet()) {
				NameValuePair p = new BasicNameValuePair(entry.getKey(), entry.getValue().toString());
				values.add(p);
			}
		}
		return doHttpsPost(url, values);
	}

	/**
	 * post 任意键值对数据
	 * 
	 * @param url
	 * @return Result 返回带字符串响应结果和响应状态的对象
	 * @throws IOException
	 */
	public Result doHttpsPostReturnResult(String url, Map<String, Object> params) throws IOException {
		return toResult(doHttpsPost(url, params));
	}

	/**
	 * post 任意键值对数据,返回对象,响应结果必须是json 对象
	 * 
	 * @param url
	 * @param c
	 * @return
	 * @throws IOException
	 */
	public <T> T doHttpsPostReturnObject(String url, Map<String, Object> params, Class<T> c) 
			throws IOException {
		T result = null;
		Result response = doHttpsPostReturnResult(url, params);
		result = JSON.parseObject(response.getBody(), c);
		return result;
	}

	/**
	 * post 键值对数据,返回集合,响应结果必须是json 数组
	 * 
	 * @param url
	 * @param c
	 * @return
	 * @throws IOException
	 */
	public <T> List<T> doHttpsPostReturnArray(String url, Map<String, Object> params, Class<T> c) 
			throws IOException {
		List<T> result = null;
		Result response = doHttpsPostReturnResult(url, params);
		result = JSON.parseArray(response.getBody(), c);
		return result;
	}

	public CloseableHttpResponse doHttpsPost(String url, List<NameValuePair> values) throws IOException {
		HttpPost post = new HttpPost(url);
		if (values != null) {
			UrlEncodedFormEntity entity = new UrlEncodedFormEntity(values, Consts.UTF_8);
			post.setEntity(entity);
		}
		RequestConfig requestConf = RequestConfig.custom()
				.setSocketTimeout(10000)
				.setConnectTimeout(10000)
				.build();
		post.setConfig(requestConf);
		setCommonHeader(post);
		CloseableHttpResponse response = httpsClient.execute(post);
		return response;
	}

	/**
	 * post NameValuePair键值对参数
	 * 
	 * @param url
	 * @return Result 返回带字符串响应结果和响应状态的对象
	 * @throws IOException
	 */
	public Result doHttpsPostReturnResult(String url, List<NameValuePair> values) throws IOException {
		return toResult(doHttpsPost(url, values));
	}

	/**
	 * post NameValuePair键值对参数
	 * 
	 * @param url
	 * @param c
	 * @return
	 * @throws IOException
	 */
	public <T> T doHttpsPostReturnObject(String url, List<NameValuePair> values, Class<T> c) 
			throws IOException {
		T result = null;
		Result response = doHttpsPostReturnResult(url, values);
		result = JSON.parseObject(response.getBody(), c);
		return result;
	}

	/**
	 * post NameValuePair键值对参数
	 * 
	 * @param url
	 * @param c
	 * @return
	 * @throws IOException
	 */
	public <T> List<T> doHttpsPostReturnArray(String url, List<NameValuePair> values, Class<T> c) 
			throws IOException {
		List<T> result = null;
		Result response = doHttpsPostReturnResult(url, values);
		result = JSON.parseArray(response.getBody(), c);
		return result;
	}

	public CloseableHttpResponse doHttpsPost(String url, String values) throws IOException {
		HttpPost post = new HttpPost(url);
		if (values != null) {
			StringEntity entity = new StringEntity(values, Consts.UTF_8);
			post.setEntity(entity);
		}
		setCommonHeader(post);
		CloseableHttpResponse response = httpsClient.execute(post);
		return response;
	}

	/**
	 * post 任何字符串数据,包括json等
	 * 
	 * @param url
	 * @return Result 返回带字符串响应结果和响应状态的对象
	 * @throws IOException
	 */
	public Result doHttpsPostReturnResult(String url, String values) throws IOException {
		return toResult(doHttpsPost(url, values));
	}

	/**
	 * post 任何字符串数据,包括json等,返回对象,响应结果必须是json 对象
	 * 
	 * @param url
	 * @param c
	 * @return
	 * @throws IOException
	 */
	public <T> T doHttpsPostReturnObject(String url, String values, Class<T> c) throws IOException {
		T result = null;
		Result response = doHttpsPostReturnResult(url, values);
		result = JSON.parseObject(response.getBody(), c);
		return result;
	}

	/**
	 * post 任何字符串数据,包括json等,响应结果必须是json 数组
	 * 
	 * @param url
	 * @param c
	 * @return
	 * @throws IOException
	 */
	public <T> List<T> doHttpsPostReturnArray(String url, String values, Class<T> c) throws IOException {
		List<T> result = null;
		Result response = doHttpsPostReturnResult(url, values);
		result = JSON.parseArray(response.getBody(), c);
		return result;
	}

	public CloseableHttpResponse doHttpsGet(String url) throws IOException {
		HttpGet get = new HttpGet(url);
		RequestConfig requestConf = RequestConfig.custom()
				.setSocketTimeout(10000)
				.setConnectTimeout(10000)
				.build();
		get.setConfig(requestConf);
		setCommonHeader(get);
		CloseableHttpResponse response = httpsClient.execute(get);
		return response;
	}

	/**
	 * post 不带参数请求
	 * 
	 * @param url
	 * @return Result 返回带字符串响应结果和响应状态的对象
	 * @throws IOException
	 */
	public Result doHttpsGetReturnResult(String url) throws IOException{
		return toResult(doHttpsGet(url));
	}

	/**
	 * post 不带参数,返回对象,响应结果必须是json 对象
	 * 
	 * @param url
	 * @param c
	 * @return
	 * @throws IOException
	 */
	public <T> T doHttpsGetReturnObject(String url, Class<T> c) throws IOException {
		T result = null;
		Result response = doHttpsGetReturnResult(url);
		result = JSON.parseObject(response.getBody(), c);
		return result;
	}

	/**
	 * 不带参数,返回集合,响应结果必须是json 数组
	 * 
	 * @param url
	 * @param c
	 * @return
	 * @throws IOException
	 */
	public <T> List<T> doHttpsGetReturnArray(String url, Class<T> c) throws IOException {
		List<T> result = null;
		Result response = doHttpsGetReturnResult(url);
		result = JSON.parseArray(response.getBody(), c);
		return result;
	}

	private void setCommonHeader(HttpRequestBase request) {
		if(userAgent == null) {
			request.setHeader(userAgentName, userAgentValue);
		} else {
			request.setHeader(userAgentName, userAgent);
		}
		
	}
	
	public static class Result {
		private String body;
		private Integer status;

		public String getBody() {
			return body;
		}

		public void setBody(String body) {
			this.body = body;
		}

		public Integer getStatus() {
			return status;
		}

		public void setStatus(Integer status) {
			this.status = status;
		}

		@Override
		public String toString() {
			return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
		}

	}
	
}
上一篇: spring的基于java的项目配置示例1 下一篇: 没有下一篇了!
发表评论
用户名: 匿名