<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.5.2</version>
</dependency>
package com.iscas.datasong.lib.util;
import com.iscas.datasong.lib.common.DataSongException;
import com.iscas.datasong.lib.common.Status;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpRequest;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.*;
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.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.LayeredConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
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.protocol.HttpContext;
import org.apache.http.util.EntityUtils;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.UnknownHostException;
import java.nio.charset.Charset;
import java.security.NoSuchAlgorithmException;
public class BaseHttpClientPoolUtil {
/*最大連接配接數,應該放在配置檔案内*/
private int maxTotal = 800;
/*每個路由的最大連接配接數*/
private int maxPerRoute = 200;
/**
* 向服務端請求逾時時間設定(機關:毫秒)
*/
private static int SERVER_REQUEST_TIME_OUT = 2000;
/**
* 服務端響應逾時時間設定(機關:毫秒)
*/
private static int SERVER_RESPONSE_TIME_OUT = 2000;
/*從連接配接池擷取連接配接的逾時時間*/
private static int CONNECTION_REQUEST_TIME_OUT = 2000;
/*重試次數*/
private static int retry = 3;
// /*是否關閉socket緩沖*/
// private boolean tcpNoDelay = false;
// /*關閉socket後,是否可立即重用端口*/
// private boolean soReuseAddress = true;
// /*接收資料等待逾時時間毫秒*/
// private int soTimeout = 500;
// /*socket最大等待關閉連接配接時間秒*/
// private int soLinger = 60;
private static volatile PoolingHttpClientConnectionManager pollManager = null;
public BaseHttpClientPoolUtil() throws NoSuchAlgorithmException {
init();
}
private void init() throws NoSuchAlgorithmException {
if (pollManager == null) {
synchronized (BaseHttpClientPoolUtil.class){
if(pollManager == null){
LayeredConnectionSocketFactory sslsf = null;
sslsf = new SSLConnectionSocketFactory(SSLContext.getDefault());
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("https", sslsf)
.register("http", new PlainConnectionSocketFactory())
.build();
pollManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
pollManager.setMaxTotal(maxTotal);
pollManager.setDefaultMaxPerRoute(maxPerRoute);
//某個host的路由數配置,覆寫default,暫時不配置
//pollManager.setMaxPerRoute(new HttpRoute(new HttpHost("some host", 80)), 150);
// //socket配置
// SocketConfig socketConfig = SocketConfig.custom()
// .setTcpNoDelay(tcpNoDelay) //是否立即發送資料,設定為true會關閉Socket緩沖,預設為false
// .setSoReuseAddress(soReuseAddress) //是否可以在一個程序關閉Socket後,即使它還沒有釋放端口,其它程序還可以立即重用端口
// .setSoTimeout(soTimeout) //接收資料的等待逾時時間,機關ms
// .setSoLinger(soLinger) //關閉Socket時,要麼發送完所有資料,要麼等待60s後,就關閉連接配接,此時socket.close()是阻塞的
// .setSoKeepAlive(true) //開啟監視TCP連接配接是否有效
// .build();
// pollManager.setDefaultSocketConfig(socketConfig);
}
}
}
}
public CloseableHttpClient getHttpClient(int SERVER_REQUEST_TIME_OUT, int SERVER_RESPONSE_TIME_OUT, int CONNECTION_REQUEST_TIME_OUT) {
RequestConfig requestConfig = RequestConfig.custom()
.setSocketTimeout(SERVER_REQUEST_TIME_OUT).setConnectTimeout(SERVER_RESPONSE_TIME_OUT).build();
CloseableHttpClient httpClient = HttpClients.custom()
.setDefaultRequestConfig(requestConfig)
.setConnectionManager(pollManager)
.setRetryHandler(getHttpRequestRetryHandler())
.build();
return httpClient;
}
public RequestConfig getDefaultRequestConfig() {
RequestConfig requestConfig = RequestConfig.custom()
.setSocketTimeout(SERVER_REQUEST_TIME_OUT)
.setConnectTimeout(SERVER_RESPONSE_TIME_OUT)
.setConnectionRequestTimeout(CONNECTION_REQUEST_TIME_OUT)
.build();
return requestConfig;
}
public HttpRequestRetryHandler getHttpRequestRetryHandler(){
HttpRequestRetryHandler myRetryHandler = new HttpRequestRetryHandler() {
public boolean retryRequest(
IOException exception,
int executionCount,
HttpContext context) {
if (executionCount >= retry) {
// 如果已經重試了5次,就放棄
return false;
}
if (exception instanceof InterruptedIOException) {
// 逾時
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();
boolean idempotent = !(request instanceof HttpEntityEnclosingRequest);
if (idempotent) {
// 如果請求是幂等的,就再次嘗試
return true;
}
return false;
}
};
return myRetryHandler;
}
public CloseableHttpClient getHttpClient() {
RequestConfig requestConfig = getDefaultRequestConfig();
CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(requestConfig)
.setConnectionManager(pollManager)
.setRetryHandler(getHttpRequestRetryHandler())
.build();
return httpClient;
}
public String doGet(String url) throws DataSongException {
if (DataSongStringUtils.isEmpty(url)) {
throw new DataSongException(Status.PARAM_ERROR, "param can not be null");
}
// url = validateUrl(url);
CloseableHttpResponse response = null;
String body = null;
try {
HttpGet get = new HttpGet(url);
get.addHeader("Content-type", "application/json; charset=utf-8");
get.setHeader("Accept", "application/json");
response = getHttpClient().execute(get);
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == HttpStatus.SC_OK) {
body = EntityUtils.toString(response.getEntity());
} else {
throw new DataSongException(Status.SERVER_ERROR, String.format("error code [%s]", statusCode));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (null != response) {
response.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return body;
}
/**
* 執行post方法
* @param url
* @param parameter
* @return
*/
public String doPost(String url, String parameter) throws DataSongException {
if(DataSongStringUtils.isEmpty(url)){
throw new DataSongException(Status.PARAM_ERROR, "url can not be null");
}
// url = validateUrl(url);
String body = null;
CloseableHttpResponse response = null;
try {
HttpPost httpPost = new HttpPost(url);
httpPost.addHeader("Content-type", "application/json; charset=utf-8");
httpPost.setHeader("Accept", "application/json");
if(!DataSongStringUtils.isEmpty(parameter)) {
httpPost.setEntity(new StringEntity(parameter, Charset.forName("UTF-8")));
}
response = getHttpClient().execute(httpPost);
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == HttpStatus.SC_OK) {
body = EntityUtils.toString(response.getEntity());
} else {
throw new DataSongException(Status.SERVER_ERROR, String.format("error code []",statusCode));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(null!=response){
response.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return body;
}
public String doPut(String url, String parameter) throws DataSongException {
// if(DataSongStringUtils.isEmpty(parameter) || DataSongStringUtils.isEmpty(url)){
// throw new DataSongException(Status.PARAM_ERROR, "param can not be null");
// }
// url = validateUrl(url);
String body = null;
CloseableHttpResponse response = null;
try {
HttpPut httpPost = new HttpPut(url);
httpPost.addHeader("Content-type", "application/json; charset=utf-8");
httpPost.setHeader("Accept", "application/json");
if(null!=parameter){
httpPost.setEntity(new StringEntity(parameter, Charset.forName("UTF-8")));
}
response = getHttpClient().execute(httpPost);
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == HttpStatus.SC_OK) {
body = EntityUtils.toString(response.getEntity());
} else {
throw new DataSongException(Status.SERVER_ERROR, String.format("%s ,error code [%s]",response.getStatusLine().getReasonPhrase(),statusCode));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(null!=response){
response.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return body;
}
public String doDelete(String url) throws DataSongException {
if(DataSongStringUtils.isEmpty(url)){
throw new DataSongException(Status.PARAM_ERROR, "param can not be null");
}
// url = validateUrl(url);
String body = null;
CloseableHttpResponse response = null;
try {
HttpDelete delete = new HttpDelete(url);
delete.addHeader("Content-type", "application/json; charset=utf-8");
delete.setHeader("Accept", "application/json");
response = getHttpClient().execute(delete);
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == HttpStatus.SC_OK) {
// Read the response body
body = EntityUtils.toString(response.getEntity());
} else {
throw new DataSongException(Status.SERVER_ERROR, String.format("error code []",statusCode));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(null!=response){
response.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return body;
}
protected String validateUrl(String url){
if(url.contains("?")){
url = url.replace("?","%26");
}
if(url.contains("&")){
url = url.replace("&","%3F");
}
if(url.contains("|")){
url = url.replace("|","%124");
}
if(url.contains("=")){
url = url.replace("=","%3D");
}
if(url.contains("#")){
url = url.replace("#","%23");
}
if(url.contains("/")){
url = url.replace("/","%2F");
}
if(url.contains("+")){
url = url.replace("+","%2B");
}
if(url.contains("%")){
url = url.replace("%","%25");
}
if(url.contains(" ")){
url = url.replace(" ","%20");
}
return url;
}
}