Httpclient工具類封裝
阿新 • • 發佈:2020-09-03
配置連線工廠
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>