1. 程式人生 > >基於HttpClient4.5.2實現的HttpClient工具類

基於HttpClient4.5.2實現的HttpClient工具類

1.maven依賴:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.6</version>
</dependency>
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId
>
<version>4.5.2</version> </dependency>

2.HttpClientUtil工具類

import java.io.IOException;
import java.io.InterruptedIOException;
import java.io.UnsupportedEncodingException;
import java.net.SocketTimeoutException;
import java.net.URLEncoder;
import java.net.UnknownHostException;
import java.nio.charset.Charset; import java.security.NoSuchAlgorithmException; import java.util.Map; import java.util.Map.Entry; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLException; import javax.net.ssl.SSLHandshakeException; import org.apache.commons.lang3.StringUtils; import org.apache.http.Header;
import org.apache.http.HttpEntity; import org.apache.http.HttpEntityEnclosingRequest; import org.apache.http.HttpRequest; import org.apache.http.NoHttpResponseException; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.config.RequestConfig; 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.client.protocol.HttpClientContext; import org.apache.http.config.Registry; import org.apache.http.config.RegistryBuilder; import org.apache.http.config.SocketConfig; 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.NoopHostnameVerifier; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.entity.ContentType; 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.util.EntityUtils; import org.apache.log4j.LogManager; import org.apache.log4j.Logger; /** * * @author Qian Wenjin * */ public class HttpClientUtil { private static final Logger LOG = LogManager.getLogger(HttpClientUtil.class); private static final int CONNECT_TIMEOUT = 5000;//設定超時毫秒數 private static final int SOCKET_TIMEOUT = 10000;//設定傳輸毫秒數 private static final int REQUESTCONNECT_TIMEOUT = 3000;//獲取請求超時毫秒數 private static final int CONNECT_TOTAL = 200;//最大連線數 private static final int CONNECT_ROUTE = 20;//設定每個路由的基礎連線數 private static final int VALIDATE_TIME = 30000;//設定重用連線時間 private static final String RESPONSE_CONTENT = "通訊失敗"; private static PoolingHttpClientConnectionManager manager = null; private static CloseableHttpClient client = null; static { ConnectionSocketFactory csf = PlainConnectionSocketFactory.getSocketFactory(); LayeredConnectionSocketFactory lsf = createSSLConnSocketFactory(); Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create() .register("http", csf).register("https", lsf).build(); manager = new PoolingHttpClientConnectionManager(registry); manager.setMaxTotal(CONNECT_TOTAL); manager.setDefaultMaxPerRoute(CONNECT_ROUTE); manager.setValidateAfterInactivity(VALIDATE_TIME); SocketConfig config = SocketConfig.custom().setSoTimeout(SOCKET_TIMEOUT).build(); manager.setDefaultSocketConfig(config); RequestConfig requestConf = RequestConfig.custom().setConnectTimeout(CONNECT_TIMEOUT) .setConnectionRequestTimeout(REQUESTCONNECT_TIMEOUT).setSocketTimeout(SOCKET_TIMEOUT).build(); client = HttpClients.custom().setConnectionManager(manager).setDefaultRequestConfig(requestConf).setRetryHandler( //實現了HttpRequestRetryHandler介面的 //public boolean retryRequest(IOException exception, int executionCount, HttpContext context)方法 (exception, executionCount, context) -> { if(executionCount >= 3) return false; if(exception instanceof NoHttpResponseException)//如果伺服器斷掉了連線那麼重試 return true; if(exception instanceof SSLHandshakeException)//不重試握手異常 return false; if(exception instanceof InterruptedIOException)//IO傳輸中斷重試 return true; if(exception instanceof UnknownHostException)//未知伺服器 return false; if(exception instanceof ConnectTimeoutException)//超時就重試 return true; if(exception instanceof SSLException) return false; HttpClientContext cliContext = HttpClientContext.adapt(context); HttpRequest request = cliContext.getRequest(); if(!(request instanceof HttpEntityEnclosingRequest)) return true; return false; }).build(); if(manager!=null && manager.getTotalStats()!=null) LOG.info("客戶池狀態:"+manager.getTotalStats().toString()); } private static SSLConnectionSocketFactory createSSLConnSocketFactory() { SSLConnectionSocketFactory sslsf = null; SSLContext context; try { context = SSLContext.getInstance(SSLConnectionSocketFactory.TLS); sslsf = new SSLConnectionSocketFactory(context, NoopHostnameVerifier.INSTANCE); } catch (NoSuchAlgorithmException e) { LOG.error("SSL上下文建立失敗,由於" + e.getLocalizedMessage()); e.printStackTrace(); } return sslsf; } private String res(HttpRequestBase method) { HttpClientContext context = HttpClientContext.create(); CloseableHttpResponse response = null; String content = RESPONSE_CONTENT; try { response = client.execute(method, context);//執行GET/POST請求 HttpEntity entity = response.getEntity();//獲取響應實體 if(entity!=null) { Charset charset = ContentType.getOrDefault(entity).getCharset(); content = EntityUtils.toString(entity, charset); EntityUtils.consume(entity); } } catch(ConnectTimeoutException cte) { LOG.error("請求連線超時,由於 " + cte.getLocalizedMessage()); cte.printStackTrace(); } catch(SocketTimeoutException ste) { LOG.error("請求通訊超時,由於 " + ste.getLocalizedMessage()); ste.printStackTrace(); } catch(ClientProtocolException cpe) { LOG.error("協議錯誤(比如構造HttpGet物件時傳入協議不對(將'http'寫成'htp')or響應內容不符合),由於 " + cpe.getLocalizedMessage()); cpe.printStackTrace(); } catch(IOException ie) { LOG.error("實體轉換異常或者網路異常, 由於 " + ie.getLocalizedMessage()); ie.printStackTrace(); } finally { try { if(response!=null) { response.close(); } } catch(IOException e) { LOG.error("響應關閉異常, 由於 " + e.getLocalizedMessage()); } if(method!=null) { method.releaseConnection(); } } return content; } public String get(String url) { HttpGet get = new HttpGet(url); return res(get); } public String get(String url, String cookie) { HttpGet get = new HttpGet(url); if(StringUtils.isNotBlank(cookie)) get.addHeader("cookie", cookie); return res(get); } public byte[] getAsByte(String url) { return get(url).getBytes(); } public String getHeaders(String url, String cookie, String headerName) { HttpGet get = new HttpGet(url); if(StringUtils.isNotBlank(cookie)) get.addHeader("cookie", cookie); res(get); Header[] headers = get.getHeaders(headerName); return headers == null ? null : headers.toString(); } public String getWithRealHeader(String url) { HttpGet get = new HttpGet(url); get.addHeader("Accept", "text/html,application/xhtml+xml,application/xml;"); get.addHeader("Accept-Language", "zh-cn"); get.addHeader("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3"); get.addHeader("Keep-Alive", "300"); get.addHeader("Connection", "Keep-Alive"); get.addHeader("Cache-Control", "no-cache"); return res(get); } public String post(String url, Map<String, String> param, String cookie) { HttpPost post = new HttpPost(url); param.keySet().stream().forEach(key -> { String value = param.get(key); if(value!=null) post.addHeader(key, value); }); if(StringUtils.isNotBlank(cookie)) post.addHeader("cookie", cookie); return res(post); } public String post(String url, String data) { HttpPost post = new HttpPost(url); if(StringUtils.isNotBlank(data)) post.addHeader("Content-Type", "application/json"); post.setEntity(new StringEntity(data,ContentType.APPLICATION_JSON)); return res(post); } public String post(String url, Map<String, String> param, String cookie, Map<String, String> headers) { HttpPost post = new HttpPost(url); String reqEntity = ""; for(Entry<String, String> entry:param.entrySet()) { post.addHeader(entry.getKey(), entry.getValue()); try { reqEntity += entry.getKey() + "=" + URLEncoder.encode(entry.getValue(), "utf-8") + "&"; } catch (UnsupportedEncodingException e) { LOG.error("請求實體轉換異常,不支援的字符集,由於 " + e.getLocalizedMessage()); e.printStackTrace(); } } try { post.setEntity(new StringEntity(reqEntity)); } catch (UnsupportedEncodingException e) { LOG.error("請求設定實體異常,不支援的字符集, 由於 " + e.getLocalizedMessage()); e.printStackTrace(); } if(StringUtils.isNotEmpty(cookie)) post.addHeader("cookie", cookie); return res(post); } }

4.注意,jdk版本要求1.8以上

ok~