Httpclient工具类封装

配置连接工厂

package org.common.framework.component.httpclient.config;

import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

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

import org.apache.http.client.config.RequestConfig;
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.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.common.framework.component.httpclient.consts.HttpConstants;

/**
 * httpclient连接工厂
 */
public class HttpClientConnectFactory {
	
	private static PoolingHttpClientConnectionManager cm = null;
	
	/**
	 * 初始化连接池
	 */
	static {
		SSLContext sslcontext;
		try {
			sslcontext = createIgnoreVerifySSL();
			ConnectionSocketFactory plainsf = PlainConnectionSocketFactory.getSocketFactory();
			Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
                    .register(HttpConstants.HTTP_PROTOCOL, plainsf)
                    .register(HttpConstants.HTTPS_PROTOCOL,getSSLConnectionSocketFactory(sslcontext))
                    .build();
			cm = new PoolingHttpClientConnectionManager(registry);
			cm.setMaxTotal(HttpConstants.MAX_TOTAL_POOL);
			cm.setDefaultMaxPerRoute(HttpConstants.MAX_CONPERROUTE);
		} catch (Exception e) {
			e.getStackTrace();
		}
	}
	
	/**
	 * 获取httpclient连接
	 * @return
	 */
	public static CloseableHttpClient getHttpClient() {
		RequestConfig requestConfig = RequestConfig.custom()
                .setConnectionRequestTimeout(HttpConstants.CONNECTION_REQUEST_TIMEOUT)
                .setConnectTimeout(HttpConstants.CONNECT_TIMEOUT)
                .setSocketTimeout(HttpConstants.SOCKET_TIMEOUT)
                .build();
		CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(cm)
                .setDefaultRequestConfig(requestConfig)
                .setRetryHandler(new MyHttpRequestRetryHandler())
                .setConnectionManagerShared(true)
                .build();
		return httpClient;
	}
	
	/**
	 * 创建sslcontext
	 * @return
	 * @throws NoSuchAlgorithmException
	 * @throws KeyManagementException
	 */
	private static SSLContext createIgnoreVerifySSL() throws NoSuchAlgorithmException, KeyManagementException {
		SSLContext sc = SSLContext.getInstance(HttpConstants.SSL_CONTEXT);
		X509TrustManager trustManager = new X509TrustManager(){
			public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
				
			}
			public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
				
			}
			public X509Certificate[] getAcceptedIssuers() {
				return null;
			}
		};
		sc.init(null, new TrustManager[] { trustManager }, null);
		return sc; 
	}
	
	/**
	 * getSSLConnectionSocketFactory
	 * @param sslcontext
	 * @return
	 */
	private static ConnectionSocketFactory getSSLConnectionSocketFactory(SSLContext sslcontext) {
		return new SSLConnectionSocketFactory(sslcontext,NoopHostnameVerifier.INSTANCE);
	}
	

}

配置重试处理

package org.common.framework.component.httpclient.config;

import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.UnknownHostException;

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

import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpRequest;
import org.apache.http.NoHttpResponseException;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.protocol.HttpContext;

/**
 * 定义重试处理机制
 */
public class MyHttpRequestRetryHandler extends DefaultHttpRequestRetryHandler {

	private int retry_times = 3;

	public MyHttpRequestRetryHandler() {
		super();
	}

	/**
	 * 覆盖默认的重试次数及重试标志
	 * @param retry_times
	 * @param retryFlag
	 */
	public MyHttpRequestRetryHandler(int retry_times) {
		super();
		this.retry_times = retry_times;
	}

	/**
	 * 检查重试次数 检查连接异常原因
	 */
	@Override
	public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
		if (executionCount >= retry_times) {// 如果已经重试了3次,就放弃
			return false;
		}
		if (exception instanceof NoHttpResponseException) {// 如果服务器丢掉了连接,那么就重试
			return true;
		}
		if (exception instanceof InterruptedIOException) {// 超时
			return true;
		}
		if (exception instanceof SSLHandshakeException) {// 不要重试SSL握手异常
			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;
	}

}

定义http工具类

依赖-CustomHttpMethod

package org.common.framework.component.httpclient.consts;

/**
 *	 自定义请求类型
 */
public enum CustomHttpMethod {

	GET, POST, DELETE, PUT
	
}

依赖-HttpConstants

package org.common.framework.component.httpclient.consts;

/**
 * http请求常量
 */
public interface HttpConstants {
	
	/**
	 * 连接池最大连接数
	 */
	int MAX_TOTAL_POOL = 256;
	
	/**
	 * 每路连接最多连接数
	 */
	int MAX_CONPERROUTE = 32;
	
	/**
	 * socket超时时间
	 */
	int SOCKET_TIMEOUT = 60 * 1000;

	/**
	 * 连接请求超时时间
	 */
	int CONNECTION_REQUEST_TIMEOUT = 5 * 1000;

	/**
	 * 连接超时时间
	 */
	int CONNECT_TIMEOUT = 5 * 1000;
	
	/**
	 * http协议
	 */
	String HTTP_PROTOCOL = "http";

	/**
	 * https协议
	 */
	String HTTPS_PROTOCOL = "https";
	
	/**
	 * sslv3
	 */
	String SSL_CONTEXT = "SSLv3";

	/**
	 * utf-8编码
	 */
	String CHARSET_UTF_8 = "UTF-8";

	/**
	 * application/json
	 */
	String CONTENT_TYPE_JSON = "application/json";
	
	/**
	 * content-type
	 */
	String CONTENT_TYPE = "Content-Type";
}

请求配置类-HttpRequestConfigUtil

package org.common.framework.component.httpclient.util;

import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.entity.StringEntity;
import org.common.framework.component.httpclient.consts.HttpConstants;

/**
 *	 请求配置的公共
 */
public class HttpRequestConfigUtil {
	
	/**
	 * 返回默认的类容类型【application/json】
	 * 
	 * @return
	 */
	protected static String getDefaultContentType() {
		return HttpConstants.CONTENT_TYPE_JSON;
	}

	/**
	 * 设置默认的content-type: application/json
	 */
	protected static void setContentTypeApplicationJson(HttpRequestBase httpBase) {
		httpBase.setHeader(HttpConstants.CONTENT_TYPE, HttpConstants.CONTENT_TYPE_JSON);
	}

	/**
	 * 设置content-Type
	 */
	protected static void setContentType(HttpRequestBase httpBase, String contentType) {
		httpBase.setHeader(HttpConstants.CONTENT_TYPE, contentType);
	}

	/**
	 * 设置请求体
	 */
	protected static void setHttpBody(HttpEntityEnclosingRequestBase httpRequest, String body) {
		if(StringUtils.isBlank(body)) {
			return;
		}
		StringEntity entity = new StringEntity(body, HttpConstants.CHARSET_UTF_8);
		entity.setContentEncoding(HttpConstants.CHARSET_UTF_8);
		entity.setContentType(HttpConstants.CHARSET_UTF_8);
		httpRequest.setEntity(entity);
	}

	/**
	 * 设置头部参数
	 * 
	 * @param httpBase
	 * @param map
	 */
	protected static void setHeader(HttpRequestBase httpBase, Map<String, String> map) {
		if (map == null || map.size() == 0) {
			return;
		}
		for (String item : map.keySet()) {
			httpBase.setHeader(item, map.get(item));
		}
	}
	
}

请求发送类-BaseHttpUtil

package org.common.framework.component.httpclient.util;

import java.lang.reflect.Type;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.common.framework.component.httpclient.config.HttpClientConnectFactory;
import org.common.framework.component.httpclient.consts.CustomHttpMethod;

import com.alibaba.fastjson.JSON;

/**
 * http抽象类,继承工具类的公共函数
 * @author Administrator
 *
 */
public class BaseHttpUtil extends HttpRequestConfigUtil {

	/**
	 * 创建请求对象 httpRequestBase
	 * 
	 * @param Method
	 * @param url
	 * @return
	 */
	protected static HttpRequestBase createHttpRequestBase(CustomHttpMethod Method, String url) {
		switch (Method) {
		case POST:
			return new HttpPost(url);
		case GET:
			return new HttpGet(url);
		case PUT:
			return new HttpPut(url);
		case DELETE:
			return new HttpDelete(url);
		default:
			return new HttpGet(url);
		}
	}
	
	/**
	 * send请求
	 * @param <T>
	 * @param url
	 * @param header
	 * @param content
	 * @param type
	 * @return
	 */
	protected static String exec( String url, CustomHttpMethod method, Map<String, String> header, String contentType, String body) {
		CloseableHttpClient httpClient = HttpClientConnectFactory.getHttpClient();
		HttpRequestBase httpBase = createHttpRequestBase(method, url);
		setHeader(httpBase, header);
		setContentType(httpBase, contentType);
		if (httpBase instanceof HttpEntityEnclosingRequestBase) {
			setHttpBody((HttpEntityEnclosingRequestBase) httpBase, body);
		}
		CloseableHttpResponse response = null;
		try {
			response = httpClient.execute(httpBase);
			response.getStatusLine().getStatusCode();
			HttpEntity httpEntity = response.getEntity();
			return EntityUtils.toString(httpEntity,"utf-8");
		}catch (Exception e) {
			e.printStackTrace();
			System.err.println("httpGetUtil error : {}" + e.getMessage());
		}
		return JSON.toJSONString(response);
	}
	
	
	/**
	 * 处理响应值
	 * @param <T>
	 * @param <B>
	 * @param apiResult
	 * @param defaultResult
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <T> T handleResponse(String apiResult, T defaultResult, Type type) {
		if(StringUtils.isBlank(apiResult)) {
			return defaultResult;
		}
		try {
			return (T)JSON.parseObject(apiResult, type); 
		} catch (Exception e) {
			return defaultResult;
		}
	}
	
}

多参工具类-MultiHttpUtil

package org.common.framework.component.httpclient.util;

import java.util.Map;

import org.common.framework.component.httpclient.consts.CustomHttpMethod;

/**
 * Http 多种 请求方式定义
 */
public class MultiHttpUtil extends BaseHttpUtil {

	/**
	 * exec请求,通过以下参数获取数据
	 * @param url   请求地址
	 * @return
	 */
	public static String exec(CustomHttpMethod customHttpMethod, String url) {
		return exec(customHttpMethod, url, null, getDefaultContentType(), null);
	}
	
	/**
	 * exec请求,通过以下参数获取数据
	 * @param url   请求地址
	 * @param header  请求头部参数
	 * @return
	 */
	public static String exec(CustomHttpMethod customHttpMethod, String url, Map<String, String> header) {
		return exec(customHttpMethod, url, header, getDefaultContentType(), null);
	}
	
	
	/**
	 * exec请求,通过以下参数获取数据 content-Type 默认 application/json
	 * @param url   请求地址
	 * @param body  请求内容
	 * @return
	 */
	public static String exec(CustomHttpMethod customHttpMethod, String url, String body) {
		return exec(customHttpMethod, url, null, getDefaultContentType(), body);
	}
	
	/**
	 * exec请求,通过以下参数获取数据 
	 * @param url   请求地址
	 * @param contentType  请求内容体类型
	 * @param body  请求内容
	 * @return
	 */
	public static String exec(CustomHttpMethod customHttpMethod, String url, String contentType, String body) {
		return exec(customHttpMethod, url, null, contentType, body);
	}
	
	/**
	 * exec请求,通过以下参数获取数据 content-Type 默认 application/json
	 * @param url   请求地址
	 * @param header  请求头部参数
	 * @param body  请求内容
	 * @return
	 */
	public static String exec(CustomHttpMethod customHttpMethod, String url, Map<String, String> header, String body) {
		return exec(customHttpMethod, url, header, getDefaultContentType(), body);
	}
	
	/**
	 * exec请求,通过以下参数获取数据
	 * @param url   请求地址
	 * @param header  请求头部参数
	 * @param contentType  请求内容体类型
	 * @param body  请求内容
	 * @return
	 */
	public static String exec(CustomHttpMethod customHttpMethod, String url, Map<String, String> header, String contentType, String body) {
		return exec(url, customHttpMethod, header, contentType, body);
	}
	
}

pom

<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.nblh.framework</groupId>
	<artifactId>common-utils</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<dependencies>
		<dependency>
			<groupId>org.apache.httpcomponents</groupId>
			<artifactId>httpclient</artifactId>
			<version>4.5.1</version>
		</dependency>
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-lang3</artifactId>
			<version>3.7</version>
		</dependency>
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>1.2.6</version>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
			<version>1.7.30</version>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-jar-plugin</artifactId>
				<version>2.0</version>
			</plugin>
		</plugins>
	</build>

</project>
posted @ 2020-09-03 17:57  pengsn  阅读(1645)  评论(0编辑  收藏  举报