HttpClientUtil
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.NoHttpResponseException;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.config.RequestConfig;
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.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.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 javax.net.ssl.*;
import java.io.IOException;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.HashSet;
import java.util.Set;
public class HttpClientUtil {
/**
* 超时时间
*/
private static final int timeOut = 30 * 1000;
/**
* 最大连接数
*/
private static final int maxTotal = 200;
/**
* 每个路由基础连接数
*/
private static final int maxPerRoute = 40;
/**
* 目标主机的最大连接数
*/
private static final int maxRoute = 100;
private static CloseableHttpClient httpClient = null;
private static final Object syncLock = new Object();
/**
* 请求超时设置
*/
public static void config(HttpRequestBase httpRequestBase){
RequestConfig requestConfig = RequestConfig.custom()
.setConnectionRequestTimeout(timeOut)
.setConnectTimeout(timeOut)
.setSocketTimeout(timeOut)
.build();
httpRequestBase.setConfig(requestConfig);
}
/**
* 获取httpClient对象
* @param url
*/
public static CloseableHttpClient getHttpClient(String url){
String hostName = url.split("/")[2];
int port = 80;
if(hostName.contains(":")){
String[] arr = hostName.split(":");
hostName = arr[0];
port = Integer.parseInt(arr[1]);
}
if(httpClient == null){
synchronized (syncLock){
if(httpClient == null){
httpClient = createHttpClient(hostName, port);
}
}
}
return httpClient;
}
public static CloseableHttpClient createHttpClient(String hostName, int port) {
try{
ConnectionSocketFactory plainsf = PlainConnectionSocketFactory.getSocketFactory();
SSLConnectionSocketFactory socketFactory = buildSSLConnectSocketFactory();
Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", plainsf).register("https", socketFactory).build();
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry);
// 设置最大连接数
cm.setMaxTotal(maxTotal);
// 设置每个路由基础连接数
cm.setDefaultMaxPerRoute(maxRoute);
HttpHost httpHost = new HttpHost(hostName, port);
// 设置目标主机的最大连接数
cm.setMaxPerRoute(new HttpRoute(httpHost), maxRoute);
// 请求重试处理
HttpRequestRetryHandler httpRequestRetryHandler = new HttpRequestRetryHandler(){
@Override
public boolean retryRequest(IOException e, int i, HttpContext httpContext) {
if(i >= 3){
// 如果已经重试了3次就放弃
return false;
}
if(e instanceof NoHttpResponseException){
// 服务器丢掉了连接,重试
return true;
}
if(e instanceof SSLHandshakeException || e instanceof SSLException){
// SSL握手异常,放弃重试
return false;
}
if(e instanceof UnknownHostException){
// 目标服务器不可达,放弃重试
return false;
}
if(e instanceof ConnectTimeoutException){
// 连接被拒绝,放弃重试
return false;
}
HttpClientContext clientContext = HttpClientContext.adapt(httpContext);
HttpRequest request = clientContext.getRequest();
// 如果请求是幂等的,就再次尝试
if(!(request instanceof HttpEntityEnclosingRequest)){
return true;
}
return false;
}
};
CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(cm).setRetryHandler(httpRequestRetryHandler).build();
return httpClient;
} catch (Exception e){
throw new RuntimeException(e);
}
}
static SSLConnectionSocketFactory buildSSLConnectSocketFactory() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
SSLContext sslContext = new MySSLContextBuilder().loadTrustMaterial(null, (X509Certificate, s) -> true).build();
return new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
}
/**
* 把keyManagers和trustManagers置空,不验证证书
*/
static class MySSLContextBuilder extends SSLContextBuilder{
static final String TLS = "TLS";
static final String SSL = "SSL";
private String protocol;
private Set<KeyManager> keyManagers;
private Set<TrustManager> trustManagers;
private SecureRandom secureRandom;
public MySSLContextBuilder(){
super();
this.keyManagers = new HashSet<KeyManager>();
this.trustManagers = new HashSet<TrustManager>();
}
}
}
RequestUtil
public class RequestUtil {
/**
* 判断是否是base64位字符串的正则表达式
*/
private static final String base64Pattern = "^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$";
/**
* 发送get请求
*/
public static String sendGet(HttpServletRequest request, String url, Map<String, String> headerMap){
CloseableHttpResponse response = null;
try{
// url参数拼装
Map<String, String[]> queryMap = request.getParameterMap();
Iterator<String> it = queryMap.keySet().iterator();
while(it.hasNext()){
String key = it.next();
String[] values = queryMap.get("key");
for(int i = 0; i < values.length; i++){
url = url.replace("{" + key + "}", values[i]);
}
}
HttpGet httpGet = new HttpGet(url);
// 请求头拼装
for(Map.Entry<String, String> entry : headerMap.entrySet()){
httpGet.setHeader(entry.getKey(), entry.getValue());
}
response = HttpClientUtil.getHttpClient(url).execute(httpGet, HttpClientContext.create());
HttpEntity entity = response.getEntity();
String result = EntityUtils.toString(entity);
EntityUtils.consume(entity);
return result;
} catch (Exception e){
throw new RuntimeException(e);
}
finally {
try{
if(response != null){
response.close();
}
} catch (Exception e){
throw new RuntimeException(e);
}
}
}
public static String sendPost(HttpServletRequest request, String url, Map<String, String> headerMap, String jsonBody){
CloseableHttpResponse response = null;
try{
// url参数拼装
Map<String, String[]> queryMap = request.getParameterMap();
Iterator<String> it = queryMap.keySet().iterator();
while(it.hasNext()){
String key = it.next();
String[] values = queryMap.get("key");
for(int i = 0; i < values.length; i++){
url = url.replace("{" + key + "}", values[i]);
}
}
Map<String, String> dataMap = JSON.parseObject(jsonBody, Map.class);
HttpPost httpPost = new HttpPost(url);
// 请求头拼装
for(Map.Entry<String, String> entry : headerMap.entrySet()){
httpPost.setHeader(entry.getKey(), entry.getValue());
}
// 请求体拼装
MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create();
for(Map.Entry<String, String> entry : dataMap.entrySet()){
if(Pattern.matches(base64Pattern, entry.getValue())){
entityBuilder.addBinaryBody(entry.getKey(), Base64.decode(entry.getValue()), ContentType.DEFAULT_BINARY, "");
} else {
entityBuilder.addTextBody(entry.getKey(), entry.getValue());
}
}
httpPost.setEntity(entityBuilder.build());
HttpClientUtil.config(httpPost);
response = HttpClientUtil.getHttpClient(url).execute(httpPost, HttpClientContext.create());
HttpEntity entity = response.getEntity();
String result = EntityUtils.toString(entity);
EntityUtils.consume(entity);
return result;
} catch (Exception e){
throw new RuntimeException(e);
}
finally {
try{
if(response != null){
response.close();
}
} catch (Exception e){
throw new RuntimeException(e);
}
}
}
}