package utils.http;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.*;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpResponseException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ConnectionPoolTimeoutException;
import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.SocketTimeoutException;
import java.nio.charset.Charset;
import java.util.Map;
/**
* HttpClientå®ä½ç±»
* è¿ä¸ªç±»æ¯å¯¹Apacheçorg.apache.http.client.HttpClientçä¸å±å°è£
*
* Created by littlelory on 02/11/2017.
*/
public class HttpClient {
private Log log = LogFactory.getLog(HttpClient.class);
//Apache httpclientå®ä¾
private org.apache.http.client.HttpClient httpClient;
//clientæ è¯
private String key;
private HttpClient(org.apache.http.client.HttpClient httpClient, String key) {
this.httpClient = httpClient;
this.key = key;
}
/**
* post请æ±
* åurlåæ°ä¼ å
¥çè¿æ¥åé请æ±ï¼è¯·æ±çBodyå
容ç±bodyåæ°å³å®
*
* @param url 请æ±url
* @param headerMap http headeræ°æ®ï¼key为headeråï¼value为headerå¼
* @param body 请æ±çBodyå
容
* @return ååºæ°æ®
* @throws IOException 请æ±è¿ç¨ä¸åçå¼å¸¸
*/
public String doPost(String url, Map headerMap, String body) throws IOException {
log.info("[httpclient]["+key+"] to post, url = [" + url + "], headerMap = [" + headerMap + "], body = [" + body + "].");
//å建请æ±å®ä¾
HttpPost request = new HttpPost(url);
//设置Headers
if (headerMap != null && headerMap.size() > 0) {
int headerSize = headerMap.size();
Header[] headers = new Header[headerSize];
int index = 0;
for (Map.Entry entry : headerMap.entrySet()) {
headers[index] = new BasicHeader(entry.getKey(), entry.getValue());
index++;
}
request.setHeaders(headers);
}
//设置request body
StringEntity entity = new StringEntity(body);
request.setEntity(entity);
//å起请æ±
try {
long start = System.currentTimeMillis();
String response = httpClient.execute(request, responseHandler);
long cost = System.currentTimeMillis() - start;
log.info(String.format("[httpclient]["+key+"][cost] url[%s], postMethod cost time:%dms", url, cost));
return response;
} catch (ConnectionPoolTimeoutException e) {
log.warn("[httpcient]["+key+"][timeout] connection pool timeout, url[" + url + "], msg[" + e.getMessage() + "].");
throw e;
} catch (SocketTimeoutException e) {
log.warn("[httpcient]["+key+"][timeout] socket timeout, url[" + url + "], msg[" + e.getMessage() + "].");
throw e;
} catch (IOException e) {
log.error(String.format("[httpclient]["+key+"][error] url[%s], msg = [%s].", url, e.getMessage()), e);
throw e;
}
}
/**
* get请æ±
* åéget请æ±ï¼è¯·æ±çurl伿 ¹æ®urlåæ°åparamsåæ°å
±åå³å®
* ä¾å¦urlåæ°="www.xxx.com",paramsåæ°="uid=1×tamp=1510557964"ï¼
* åæç»ç请æ±url="www.xxx.com?uid=1×tamp=1510557964"
*
* @param url 请æ±url
* @param headerMap http headeræ°æ®ï¼key为headeråï¼value为headerå¼
* @param params 请æ±åæ°
* @return ååºæ°æ®
* @throws IOException 请æ±è¿ç¨ä¸åçå¼å¸¸
*/
public String doGet(String url, Map headerMap, String params) throws IOException {
log.info("[httpclient]["+key+"] to get, url = [" + url + "], headerMap = [" + headerMap + "], params = [" + params + "].");
//å建请æ±å®ä¾
HttpGet request = new HttpGet(url + (params != null && params.length() > 0 ? "?" + params : ""));
if (headerMap != null && headerMap.size() > 0) {
//设置Headers
int headerSize = headerMap.size();
Header[] headers = new Header[headerSize];
int index = 0;
for (Map.Entry entry : headerMap.entrySet()) {
headers[index] = new BasicHeader(entry.getKey(), entry.getValue());
index++;
}
request.setHeaders(headers);
}
//å起请æ±
try {
long start = System.currentTimeMillis();
String response = httpClient.execute(request, responseHandler);
long cost = System.currentTimeMillis() - start;
log.info(String.format("[httpclient]["+key+"][cost] url[%s], postMethod cost time:%dms", url, cost));
return response;
} catch (ConnectionPoolTimeoutException e) {
log.warn("[httpcient]["+key+"][timeout] connection pool timeout, url[" + url + "], msg[" + e.getMessage() + "].");
throw e;
} catch (SocketTimeoutException e) {
log.warn("[httpcient]["+key+"][timeout] socket timeout, url[" + url + "], msg[" + e.getMessage() + "].");
throw e;
} catch (IOException e) {
log.error(String.format("[httpclient]["+key+"][error] url[%s], msg = [%s].", url, e.getMessage()), e);
throw e;
}
}
//请æ±ååºHandler
private ResponseHandler responseHandler = new ResponseHandler() {
@Override
public String handleResponse(
final HttpResponse response) throws IOException {
StatusLine statusLine = response.getStatusLine();
HttpEntity entity = response.getEntity();
log.info("[httpclient]["+key+"] response: statusLine[" + statusLine + "].");
if (statusLine.getStatusCode() != HttpStatus.SC_OK) {
throw new HttpResponseException(
statusLine.getStatusCode(),
statusLine.getReasonPhrase());
}
if (entity == null) {
throw new ClientProtocolException("Response contains no content.");
}
ContentType contentType = ContentType.getOrDefault(entity);
Charset charset = contentType.getCharset();
BufferedReader reader = new BufferedReader(charset == null ? new InputStreamReader(entity.getContent()) : new InputStreamReader(entity.getContent(), charset));
StringBuilder sb = new StringBuilder();
String line;
while ((line = reader.readLine()) != null)
sb.append(line).append("\n");
return sb.length() > 0 ? sb.substring(0, sb.length() - 1) : null;
}
};
/**
* å建HttpClientçBuilderå®ä¾
*
* @param connectionManager ç®¡çæ¤clientçHttpClientManager
* @param key æ¤clientçæ è¯
* @return Builderå®ä¾
*/
public static Builder instance(HttpClientManager connectionManager, String key) {
return new Builder(connectionManager, key);
}
//HttpClientçæé å¨
public static class Builder {
//建ç«è¿æ¥ è¶
æ¶æ¶é´
private int connectTimeout = 150;
//çå¾
ååº è¶
æ¶æ¶é´
private int socketTimeout = 150;
//ä»connectManagerè·åè¿æ¥ è¶
æ¶æ¶é´
private int connectRequestTimeout = 150;
//éè¯æ¬¡æ°
private int retryCount = 0;
//éè¯å¼å
³
private boolean retryEnable = false;
private final HttpClientManager connectionManager;
private final String key;
public Builder(HttpClientManager connectionManager, String key) {
this.connectionManager = connectionManager;
this.key = key;
}
public Builder connectTimeout(int timeout) {
this.connectTimeout = timeout;
return this;
}
public Builder socketTimeout(int socketTimeout) {
this.socketTimeout = socketTimeout;
return this;
}
public Builder connectRequestTimeout(int connectRequestTimeout) {
this.connectRequestTimeout = connectRequestTimeout;
return this;
}
public Builder retryCount(int retryCount) {
if (retryCount > 0) {
this.retryEnable = true;
this.retryCount = retryCount;
}
return this;
}
public HttpClient build() {
org.apache.http.client.HttpClient client = HttpClients
.custom()
.setConnectionManager(connectionManager.getConnectionManager())
.setDefaultRequestConfig(
RequestConfig
.custom()
.setConnectTimeout(this.connectTimeout)
.setSocketTimeout(this.socketTimeout)
.setConnectionRequestTimeout(this.connectRequestTimeout)
.build()
)
.setRetryHandler(new DefaultHttpRequestRetryHandler(this.retryCount, this.retryEnable))
.build();
return new HttpClient(client, key);
}
}
}