<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.4.4</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.76</version>
</dependency>
package com.coolw.codedemo.http;
/**
* @Description Http 属性请求常量
* @Date 2021/5/11 11:46
* @Author coolw
*/
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";
/**
* TLS
*/
String SSL_CONTEXT = "TLS";
/**
* utf-8编码
*/
String CHARSET_UTF_8 = "UTF-8";
/**
* application/json
*/
String CONTENT_TYPE_JSON = "application/json";
/**
* content-type
*/
String CONTENT_TYPE = "Content-Type";
}
package com.coolw.codedemo.http;
/**
* @Description Http请求类型
* @Date 2021/5/11 12:21
* @Author coolw
*/
public enum HttpMethod {
GET, POST
}
package com.coolw.codedemo.http;
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 java.util.Map;
/**
* @Description Http请求公共配置
* @Date 2021/5/11 11:45
* @Author coolw
*/
public class HttpRequestConfig {
/**
* 返回默认的content-type: application/json
*/
protected static String getDefaultContentType() {
return HttpConstants.CONTENT_TYPE_JSON;
}
/**
* 设置默认的content-Type:application/json
*/
protected static void setContentTypeApplicationJson(HttpRequestBase requestBase) {
requestBase.setHeader(HttpConstants.CONTENT_TYPE, HttpConstants.CONTENT_TYPE_JSON);
}
/**
* 设置content-Type
*/
protected static void setContentType(HttpRequestBase httpBase, String contentType) {
if (StringUtils.isNotBlank(contentType)) {
contentType = getDefaultContentType();
}
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);
}
/**
* 设置头部参数
*/
protected static void setHeader(HttpRequestBase httpBase, Map<String, String> headerMap) {
if (headerMap == null || headerMap.size() == 0) {
return;
}
for (Map.Entry<String, String> entry : headerMap.entrySet()) {
httpBase.addHeader(entry.getKey(), entry.getValue());
}
}
}
package com.coolw.codedemo.http;
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 javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
/**
* @Description HttpClient 连接工厂
* @Date 2021/5/11 12:26
* @Author coolw
*/
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 连接
*/
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 HttpRequestRetryHandler())
.setConnectionManagerShared(true)
.build();
return httpClient;
}
/**
* 创建 SSLContext
*/
private static SSLContext createIgnoreVerifySSL() throws NoSuchAlgorithmException, KeyManagementException {
SSLContext sc = SSLContext.getInstance(HttpConstants.SSL_CONTEXT);
X509TrustManager trustManager = new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
sc.init(null, new TrustManager[]{trustManager}, null);
return sc;
}
/**
* 获取 SSLConnectionSocketFactory
*/
private static ConnectionSocketFactory getSSLConnectionSocketFactory(SSLContext sslcontext) {
return new SSLConnectionSocketFactory(sslcontext, NoopHostnameVerifier.INSTANCE);
}
}
package com.coolw.codedemo.http;
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.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.protocol.HttpContext;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLHandshakeException;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.UnknownHostException;
/**
* @Description Http重试处理机制
* @Date 2021/5/11 10:20
* @Author coolw
*/
public class HttpRequestRetryHandler extends DefaultHttpRequestRetryHandler {
/**
* 重试次数,默认3次
*/
private int retryCount = 3;
public HttpRequestRetryHandler() {
super();
}
public HttpRequestRetryHandler(int retryCount) {
super();
this.retryCount = retryCount;
}
@Override
public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
// 重试次数已上限,不重试
if (executionCount >= retryCount) {
return false;
}
if (exception instanceof SSLHandshakeException) {
return false;
}
if (exception instanceof UnknownHostException) {
return false;
}
if (exception instanceof SSLException) {
return false;
}
// 重试
if (exception instanceof NoHttpResponseException) {
return true;
}
if (exception instanceof InterruptedIOException) {
return true;
}
HttpClientContext clientContext = HttpClientContext.adapt(context);
HttpRequest request = clientContext.getRequest();
// 如果请求是幂等的,重试
if (!(request instanceof HttpEntityEnclosingRequest)) {
return true;
}
return false;
}
}
package com.coolw.codedemo.http;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.*;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.Map;
/**
* @Description Http工具类
* @Date 2021/5/11 12:17
* @Author coolw
*/
@Slf4j
public class BaseHttpUtils extends HttpRequestConfig {
/**
* 创建Http请求对象
*/
protected static HttpRequestBase createHttpRequestBase(HttpMethod method, String url) {
switch (method) {
case GET:
return new HttpGet(url);
case POST:
return new HttpPost(url);
default:
return new HttpGet(url);
}
}
protected static String exec(String url, HttpMethod method, Map<String, String> headerMap, String contentType, String body) {
HttpRequestBase httpRequest = createHttpRequestBase(method, url);
setHeader(httpRequest, headerMap);
setContentType(httpRequest, contentType);
if (httpRequest instanceof HttpEntityEnclosingRequestBase) {
setHttpBody((HttpEntityEnclosingRequestBase) httpRequest, body);
}
CloseableHttpResponse response = null;
try (CloseableHttpClient httpClient = HttpClientConnectFactory.getHttpClient()) {
response = httpClient.execute(httpRequest);
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == HttpStatus.SC_OK) {
return EntityUtils.toString(response.getEntity(), "utf-8");
}
log.warn("http exec status fail. url={},statusCode={}", url, statusCode);
} catch (IOException e) {
log.error("http exec error. url:{},body={}", url, body, e);
}
return JSON.toJSONString(response);
}
@SuppressWarnings("unchecked")
public static <T> T responseHandle(String apiResult, T defaultResult, Type type) {
if (StringUtils.isBlank(apiResult)) {
return defaultResult;
}
try {
return (T) JSON.parseObject(apiResult, type);
} catch (Exception e) {
return defaultResult;
}
}
}
package com.coolw.codedemo.http;
import java.util.Map;
/**
* @Description 多参Http工具类
* @Date 2021/5/11 13:54
* @Author coolw
*/
public class MultiHttpUtils extends BaseHttpUtils {
/**
* exec请求。content-Type 默认 application/json
*
* @param method 请求类型
* @param url 请求地址
* @return String
*/
public static String exec(HttpMethod method, String url) {
return exec(method, url, null, getDefaultContentType(), null);
}
/**
* exec请求,通过以下参数获取数据
*
* @param method 请求类型
* @param url 请求地址
* @param headerMap 请求头部参数
* @return String
*/
public static String exec(HttpMethod method, String url, Map<String, String> headerMap) {
return exec(method, url, headerMap, getDefaultContentType(), null);
}
/**
* exec请求。content-Type 默认 application/json
*
* @param method 请求类型
* @param url 请求地址
* @param body 请求内容
* @return String
*/
public static String exec(HttpMethod method, String url, String body) {
return exec(method, url, null, getDefaultContentType(), body);
}
/**
* exec请求
*
* @param method 请求类型
* @param url 请求地址
* @param contentType 请求内容体类型
* @param body 请求内容
* @return String
*/
public static String exec(HttpMethod method, String url, String contentType, String body) {
return exec(method, url, null, contentType, body);
}
/**
* exec请求。content-Type 默认 application/json
*
* @param method 请求类型
* @param url 请求地址
* @param headerMap 请求头部参数
* @param body 请求内容
* @return String
*/
public static String exec(HttpMethod method, String url, Map<String, String> headerMap, String body) {
return exec(method, url, headerMap, getDefaultContentType(), body);
}
/**
* exec请求
*
* @param method 请求类型
* @param url 请求地址
* @param headerMap 请求头部参数
* @param contentType 请求内容体类型
* @param body 请求内容
* @return String
*/
public static String exec(HttpMethod method, String url, Map<String, String> headerMap, String contentType, String body) {
return exec(url, method, headerMap, contentType, body);
}
}