package com.template.utils.http;
import cn.hutool.core.map.MapUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.*;
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.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.ConnectionKeepAliveStrategy;
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.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.BasicHeader;
import org.apache.http.message.BasicHeaderElementIterator;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
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 java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* @author
* @Title: HttpsPoolUtil.java
* @Description: http请求工具类
* @date
*/
public class HttpsPoolUtil {
private static Logger log = LoggerFactory.getLogger(HttpsPoolUtil.class);
private static final String _HTTP = "http";
private static final String _HTTPS = "https";
/**
* 配置连接池获取超时时间
*/
private static final int CONNECTION_REQUEST_TIMEOUT = 1 * 1000;
/**
* 配置客户端连接服务器超时时间
*/
private static final int CONNECT_TIMEOUT = 3 * 1000;
/**
* 配置服务器响应超时时间
*/
private static final int SOCKET_TIMEOUT = 20 * 1000;
/**
* 默认返回null串
*/
private static String EMPTY_STR = "";
private static SSLConnectionSocketFactory sslConnectionSocketFactory = null;
/**
* 连接池管理类
*/
private static PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = null;
/**
* 管理Https连接的上下文类
*/
private static SSLContextBuilder sslContextBuilder = null;
static {
try {
sslContextBuilder = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
@Override
public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
//忽略http校验
return true;
}
});
sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContextBuilder.build(), NoopHostnameVerifier.INSTANCE);
//注册两种请求形式
Registry<ConnectionSocketFactory> registryBuilder = RegistryBuilder.<ConnectionSocketFactory>create()
.register(_HTTP, new PlainConnectionSocketFactory())
.register(_HTTPS, sslConnectionSocketFactory).build();
poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager(registryBuilder);
//最大连接数
poolingHttpClientConnectionManager.setMaxTotal(500);
//最大并发数
poolingHttpClientConnectionManager.setDefaultMaxPerRoute(100);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
}
/**
* @Description: http初始化连接配置
*/
private static RequestConfig getDefaultRequestConfig() {
RequestConfig requestConfig = RequestConfig.custom()
/*
* 从连接池中获取连接的超时时间,假设:连接池中已经使用的连接数等于setMaxTotal,新来的线程在等待1*1000
* 后超时,错误内容:org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool
*/
.setConnectionRequestTimeout(CONNECTION_REQUEST_TIMEOUT)
/*
* 这定义了通过网络与服务器建立连接的超时时间。
* Httpclient包中通过一个异步线程去创建与服务器的socket连接,这就是该socket连接的超时时间,
* 此处设置为2秒。假设:访问一个IP,192.168.10.100,这个IP不存在或者响应太慢,那么将会返回
* java.net.SocketTimeoutException: connect timed out
*/
.setConnectTimeout(CONNECT_TIMEOUT)
/*
* 指的是连接上一个url,获取response的返回等待时间,假设:url程序中存在阻塞、或者response
* 返回的文件内容太大,在指定的时间内没有读完,则出现
* java.net.SocketTimeoutException: Read timed out
*/
.setSocketTimeout(SOCKET_TIMEOUT)
.build();
return requestConfig;
}
/**
* @Description: http初始化keep-Alive配置
*/
public static ConnectionKeepAliveStrategy getKeepAliveStrategy() {
ConnectionKeepAliveStrategy myStrategy = new ConnectionKeepAliveStrategy() {
@Override
public long getKeepAliveDuration(HttpResponse response, HttpContext context) {
HeaderElementIterator it = new BasicHeaderElementIterator
(response.headerIterator(HTTP.CONN_KEEP_ALIVE));
while (it.hasNext()) {
HeaderElement he = it.nextElement();
String param = he.getName();
String value = he.getValue();
if (value != null && param.equalsIgnoreCase
("timeout")) {
return Long.parseLong(value) * 1000;
}
}
//如果没有约定,则默认定义时长为20s
return 20 * 1000;
}
};
return myStrategy;
}
/**
* @return
* @Description: 从池子中获取获取httpclient连接
*/
public static CloseableHttpClient getHttpClinet() {
CloseableHttpClient httpClient = HttpClients.custom()
//设置ssl工厂
.setSSLSocketFactory(sslConnectionSocketFactory)
//设置连接管理方式-连接池
.setConnectionManager(poolingHttpClientConnectionManager)
//设置http请求规则
.setDefaultRequestConfig(getDefaultRequestConfig())
//设置keep-Alive
.setKeepAliveStrategy(getKeepAliveStrategy())
.build();
return httpClient;
}
/**
* @param url
* @param json
* @return
* @Description: post请求——JSON格式
*/
public static String postJson(String url, String json, Map<String, String> headerMap) {
HttpPost httpPost = new HttpPost(url);
if (MapUtil.isNotEmpty(headerMap)) {
for (Map.Entry<String, String> entry : headerMap.entrySet()) {
httpPost.addHeader(new BasicHeader(entry.getKey(), entry.getValue()));
}
}
//解决中文乱码问题
StringEntity entity = new StringEntity(json, Consts.UTF_8);
entity.setContentType("application/json;charset=UTF-8");
httpPost.setEntity(entity);
return getResult(httpPost);
}
/**
* @param url
* @return
* @Description: post请求——form格式
* form 为true时 可以传入StringEntity的参数
*/
public static String postForm(String url, Map<String, String> headerMap, Map<String, String> params) {
HttpPost httpPost = new HttpPost(url);
if (MapUtil.isNotEmpty(headerMap)) {
for (Map.Entry<String, String> entry : headerMap.entrySet()) {
httpPost.addHeader(new BasicHeader(entry.getKey(), entry.getValue()));
}
}
//拼装参数,设置编码格式
if (MapUtil.isNotEmpty(params)) {
List<NameValuePair> paramList = new ArrayList<>();
for (Map.Entry<String, String> stringStringEntry : params.entrySet()) {
paramList.add(new BasicNameValuePair(stringStringEntry.getKey(), stringStringEntry.getValue()));
}
UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(paramList, Consts.UTF_8);
httpPost.setEntity(urlEncodedFormEntity);
}
return getResult(httpPost);
}
/**
* 发送http get请求
*
* @param url 请求的url
* @param headersMap 请求头
* @param params 请求的参数
* @return
*/
public static String getRequest(String url, Map<String, String> headersMap, Map<String, Object> params) {
String apiUrl = url;
if (null != params && params.size() > 0) {
StringBuffer param = new StringBuffer();
int i = 0;
for (String key : params.keySet()) {
if (i == 0) {
param.append("?");
} else {
param.append("&");
}
param.append(key).append("=").append(params.get(key));
i++;
}
apiUrl += param;
}
HttpGet httpGet = new HttpGet(apiUrl);
if (MapUtil.isNotEmpty(headersMap)) {
for (Map.Entry<String, String> entry : headersMap.entrySet()) {
httpGet.addHeader(new BasicHeader(entry.getKey(), entry.getValue()));
}
}
return getResult(httpGet);
}
/**
* @param request
* @return
* @Description: 通用版处理http请求
*/
private static String getResult(HttpRequestBase request) {
/**
* 获取httpClient
*/
CloseableHttpClient httpClient = null;
try {
//获取httpClient
httpClient = getHttpClinet();
} catch (Exception e) {
log.error("【新版http】获取httpClient失败:请求地址:{},异常信息:", request.getURI(), e);
throw new RuntimeException("获取httpClient失败");
}
/**
* 发起http请求,并处理响应结果
*/
String resultStr = null;
CloseableHttpResponse httpResponse = null;
try {
//发起http请求
httpResponse = httpClient.execute(request);
int statusCode = httpResponse.getStatusLine().getStatusCode();
//响应成功
if (statusCode == HttpStatus.SC_OK) {
HttpEntity httpResponseEntity = httpResponse.getEntity();
resultStr = EntityUtils.toString(httpResponseEntity,Consts.UTF_8);
log.info("【新版http】请求正常,请求地址:{},响应结果:{}", request.getURI(), resultStr);
return resultStr;
}
//响应失败,打印http异常信息
StringBuffer stringBuffer = new StringBuffer();
HeaderIterator headerIterator = httpResponse.headerIterator();
while (headerIterator.hasNext()) {
stringBuffer.append("\t" + headerIterator.next());
}
log.info("【新版http】异常信息:请求地址:{},响应状态:{},请求返回结果:{}", request.getURI(), statusCode, stringBuffer);
} catch (Exception e) {
log.error("【新版http】发生异常:请求地址:{},异常信息:", request.getURI(), e);
throw new RuntimeException("http请求失败");
} finally {
//关闭httpResponse
if (httpResponse != null) {
try {
httpResponse.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return EMPTY_STR;
}
public static void main(String[] args) {
String url = "https://www.baidu.com";
String s = postForm(url, null, null);
// String s = HttpUtils.getRequest(url);
System.out.println(s);
}
}
http请求工具类
于 2022-11-03 08:56:25 首次发布