有時候在每一處調用外部代碼寫一次httpclient的調用或者httpurlconnection代碼很冗餘html
爲了方便調用且對各類異常狀況歸類統計java
本身目前在用的HttpUtil的代碼,對於HttpClient和HttpUrlConnection的代碼,包含失敗率的統計,知足常規需求apache
若是不須要統計的,能夠刪除相關代碼json
HttpUtil代碼緩存
package com.shield.util; import java.io.IOException; import java.io.InputStream; import java.io.InterruptedIOException; import java.io.OutputStreamWriter; import java.net.HttpURLConnection; import java.net.URL; import java.net.UnknownHostException; import java.util.HashMap; import java.util.Map; import javax.net.ssl.SSLException; import javax.net.ssl.SSLHandshakeException; import org.apache.commons.httpclient.ConnectTimeoutException; import org.apache.commons.httpclient.NoHttpResponseException; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.HttpEntityEnclosingRequest; import org.apache.http.HttpRequest; import org.apache.http.client.HttpRequestRetryHandler; 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.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 org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.aliyun.oss.common.utils.IOUtils; import com.shield.exception.CallInterfaceException; import com.shield.model.Count; /*** * 全部調用http的服務都必須使用該類 該類實現調用http服務而且統計的功能 * 統計的描述 統計字段 caller 總次數 成功次數 超時次數 * * @author slin * 2015年10月7日 */ public class HttpUtil { private final static Logger LOG = LoggerFactory.getLogger(HttpUtil.class); public final static int DEFAULT_READ_TIMEOUT = 5000 ; public final static int DEFAULT_CONNECT_TIMEOUT = 2000 ; public final static PoolingHttpClientConnectionManager HTTP_CLIENT_CONNECTION_MANAGER; public static CloseableHttpClient httpClient; static{ HTTP_CLIENT_CONNECTION_MANAGER = new PoolingHttpClientConnectionManager(); HTTP_CLIENT_CONNECTION_MANAGER.setMaxTotal(30); HTTP_CLIENT_CONNECTION_MANAGER.setDefaultMaxPerRoute(HTTP_CLIENT_CONNECTION_MANAGER.getMaxTotal()); RequestConfig requestConfig = RequestConfig.custom() .setSocketTimeout(DEFAULT_READ_TIMEOUT+DEFAULT_CONNECT_TIMEOUT) .setConnectTimeout(DEFAULT_CONNECT_TIMEOUT) .build(); //請求重試處理 HttpRequestRetryHandler httpRequestRetryHandler = new HttpRequestRetryHandler() { public boolean retryRequest(IOException exception,int executionCount, HttpContext context) { if (executionCount >= 5) {// 若是已經重試了5次,就放棄 return false; } if (exception instanceof NoHttpResponseException) {// 若是服務器丟掉了鏈接,那麼就重試 return true; } if (exception instanceof SSLHandshakeException) {// 不要重試SSL握手異常 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(); // 若是請求是冪等的,就再次嘗試 if (!(request instanceof HttpEntityEnclosingRequest)) { return true; } return false; } }; httpClient = HttpClients.custom().setConnectionManager(HTTP_CLIENT_CONNECTION_MANAGER).setRetryHandler(httpRequestRetryHandler).setDefaultRequestConfig(requestConfig).build(); } public final static Map<String,Count> counter = new HashMap<String, Count>(); public static String get(String caller,String fullurl) throws CallInterfaceException{ byte [] response = getBytesHttpClientImpl(caller, fullurl,DEFAULT_READ_TIMEOUT,DEFAULT_CONNECT_TIMEOUT); LOG.debug("GET caller ="+caller+",request :"+fullurl); String responseText = null ; if(response != null && response.length > 0){ responseText = new String(response); } LOG.debug("GET caller ="+caller+",response :"+responseText); return responseText; } @Deprecated public static String getStringByHttpUrlConnectImpl(String caller,String fullurl) throws CallInterfaceException{ byte [] response = getBytesHttpUrlConnectionImpl(caller, fullurl,DEFAULT_READ_TIMEOUT,DEFAULT_CONNECT_TIMEOUT); LOG.debug("GET caller ="+caller+",request :"+fullurl); String responseText = null ; if(response != null && response.length > 0){ responseText = new String(response); } LOG.debug("GET caller ="+caller+",response :"+responseText); return responseText; } public static String getStringByHttpClientImpl(String caller,String fullurl,int readTimeout,int connectTimeout,int tryAgainSize) throws CallInterfaceException{ byte [] response = getBytesHttpClientImpl(caller, fullurl,readTimeout,connectTimeout); LOG.debug("GET caller ="+caller+",request :"+fullurl); String responseText = null ; if(response != null && response.length > 0){ responseText = new String(response); } LOG.debug("GET caller ="+caller+",response :"+responseText); return responseText; } public static String getStringByHttpClientImpl(String caller,String fullurl) throws CallInterfaceException{ byte [] response = getBytesHttpClientImpl(caller, fullurl,DEFAULT_READ_TIMEOUT,DEFAULT_CONNECT_TIMEOUT); LOG.debug("GET caller ="+caller+",request :"+fullurl); String responseText = null ; if(response != null && response.length > 0){ responseText = new String(response); } LOG.debug("GET caller ="+caller+",response :"+responseText); return responseText; } public static String getStringByHttpUrlConnectImpl(String caller,String fullurl,int readTimeout,int connectTimeout,int tryAgainSize) throws CallInterfaceException{ byte [] response = getBytesHttpUrlConnectionImpl(caller, fullurl,readTimeout,connectTimeout); LOG.debug("GET caller ="+caller+",request :"+fullurl); String responseText = null ; if(response != null && response.length > 0){ responseText = new String(response); } LOG.debug("GET caller ="+caller+",response :"+responseText); return responseText; } public static String postStringByHttpClientImpl(String caller,String url,String body,Header... headers) throws CallInterfaceException{ byte [] response = postBytesHttpClientImpl(caller, url,body,DEFAULT_READ_TIMEOUT,DEFAULT_CONNECT_TIMEOUT,headers); LOG.debug("POST caller ="+caller+",request :"+url + "?"+body); String responseText = null ; if(response != null && response.length > 0){ responseText = new String(response); } LOG.debug("POST caller ="+caller+",response :"+responseText); return responseText; } @Deprecated public static String postStringByHttpUrlConnectImpl(String caller,String url,String body,Header... headers) throws CallInterfaceException{ byte [] response = postBytesHttpUrlConnectionImpl(caller, url,body,DEFAULT_READ_TIMEOUT,DEFAULT_CONNECT_TIMEOUT,headers); LOG.debug("POST caller ="+caller+",request :"+url+"?"+body); String responseText = null ; if(response != null && response.length > 0){ responseText = new String(response); } LOG.debug("POST caller ="+caller+",response :"+responseText); return responseText; } @Deprecated public static String postStringByHttpUrlConnectImpl(String caller,String url,String body,int readTimeout,int connectTimeout, int trySize) throws CallInterfaceException{ byte [] response = postBytesHttpUrlConnectionImpl(caller, url,body,readTimeout,connectTimeout); LOG.debug("POST caller ="+caller+",request :"+url+"?"+body); String responseText = null ; if(response != null && response.length > 0){ responseText = new String(response); } LOG.debug("POST caller ="+caller+",response :"+responseText); return responseText; } @Deprecated public static byte [] postBytesHttpUrlConnectionImpl(String caller,String url,String postData,int readTimeout,int connectTimeout, Header... headers) throws CallInterfaceException{ Count count = counter.get(caller); if(count == null){ count = new Count(); counter.put(caller, count); } byte [] response = null ; HttpURLConnection httpConn = null ; InputStream inputStream = null; try { URL tirc = new URL(url); httpConn = (HttpURLConnection) tirc.openConnection(); httpConn.setDoOutput(true);// 使用 URL 鏈接進行輸出 httpConn.setDoInput(true);// 使用 URL 鏈接進行輸入 httpConn.setUseCaches(false);// 忽略緩存 httpConn.setRequestMethod("POST");// 設置URL請求方法 httpConn.setConnectTimeout(connectTimeout); httpConn.setReadTimeout(readTimeout); httpConn.setRequestProperty("Content-Length", "" + postData.length()); httpConn.setRequestProperty("Content-Type", "application/json"); httpConn.setRequestProperty("Charset", "UTF-8"); OutputStreamWriter out = new OutputStreamWriter(httpConn.getOutputStream(), "UTF-8"); out.write(postData); out.flush(); out.close(); int responseCode = httpConn.getResponseCode(); if (HttpURLConnection.HTTP_OK == responseCode) {// 鏈接成功 inputStream = httpConn.getInputStream(); response = IOUtils.readStreamAsByteArray(inputStream); } } catch (Exception e) { LOG.warn(e.getMessage() +",url="+url,e); count.timeout ++ ; throw new CallInterfaceException(e,url +"?"+ postData); }finally{ try { if(inputStream!=null) inputStream.close(); if(httpConn!=null) httpConn = null ; } catch (IOException e) { LOG.error(e.getMessage(),e); } } count.success ++ ; return response ; } public static byte [] getBytes(String caller,String fullurl) throws CallInterfaceException{ return getBytesHttpClientImpl(caller, fullurl,DEFAULT_READ_TIMEOUT,DEFAULT_CONNECT_TIMEOUT); } @Deprecated public static byte [] getBytesHttpUrlConnectionImpl(String caller,String fullurl,int readTimeout,int connectTimeout) throws CallInterfaceException{ Count count = counter.get(caller); if(count == null){ count = new Count(); counter.put(caller, count); } byte [] response = null ; String url = null ; HttpURLConnection httpConn = null ; InputStream inputStream = null; try { url = fullurl; URL tirc = new URL(url); httpConn = (HttpURLConnection) tirc.openConnection(); httpConn.setDoOutput(false);// 使用 URL 鏈接進行輸出 httpConn.setDoInput(true);// 使用 URL 鏈接進行輸入 httpConn.setUseCaches(false);// 忽略緩存 httpConn.setRequestMethod("GET");// 設置URL請求方法 httpConn.setConnectTimeout(connectTimeout); httpConn.setReadTimeout(readTimeout); httpConn.setRequestProperty("Content-Type", "application/json"); httpConn.setRequestProperty("Charset", "UTF-8"); int responseCode = httpConn.getResponseCode(); if (HttpURLConnection.HTTP_OK == responseCode) {// 鏈接成功 inputStream = httpConn.getInputStream(); response = IOUtils.readStreamAsByteArray(inputStream); } } catch (Exception e) { LOG.warn(e.getMessage() +",url="+url,e); count.timeout ++ ; throw new CallInterfaceException(e,fullurl); }finally{ try { if(inputStream!=null) inputStream.close(); if(httpConn!=null) httpConn.disconnect(); httpConn = null ; } catch (IOException e) { LOG.error(e.getMessage(),e); } } count.success ++ ; return response ; } public static byte [] getBytesHttpClientImpl(String caller,String fullurl,int readTimeout,int connectTimeout) throws CallInterfaceException{ Count count = counter.get(caller); if(count == null){ count = new Count(); counter.put(caller, count); } byte [] response = null ; CloseableHttpResponse httpResponse = null ; try{ HttpGet httpGet = new HttpGet(fullurl); config(httpGet,readTimeout,connectTimeout); httpResponse = httpClient.execute(httpGet); if (HttpURLConnection.HTTP_OK == httpResponse.getStatusLine().getStatusCode()){ HttpEntity entity = httpResponse.getEntity(); response = EntityUtils.toByteArray(entity); } }catch(Exception e){ LOG.warn(e.getMessage() +",url="+fullurl,e); count.timeout ++ ; throw new CallInterfaceException(e,fullurl); }finally{ try { if(httpResponse!=null) httpResponse.close(); } catch (IOException e) { LOG.error(e.getMessage(),e); } } count.success ++ ; return response ; } public static byte [] postBytesHttpClientImpl(String caller,String fullurl,String body,int readTimeout,int connectTimeout,Header ...headers) throws CallInterfaceException{ Count count = counter.get(caller); if(count == null){ count = new Count(); counter.put(caller, count); } byte [] response = null ; CloseableHttpResponse httpResponse = null ; try{ HttpPost httpPost = new HttpPost(fullurl); config(httpPost,readTimeout,connectTimeout); httpPost.setEntity(new StringEntity(body, "utf-8")); if(headers!=null&&headers.length>0){ httpPost.setHeaders(headers); } httpResponse = httpClient.execute(httpPost); if (HttpURLConnection.HTTP_OK == httpResponse.getStatusLine().getStatusCode()){ HttpEntity entity = httpResponse.getEntity(); response = EntityUtils.toByteArray(entity); } }catch(Exception e){ LOG.warn(e.getMessage() +",url="+fullurl,e); count.timeout ++ ; throw new CallInterfaceException(e,fullurl); }finally{ try { if(httpResponse!=null) httpResponse.close(); } catch (IOException e) { LOG.error(e.getMessage(),e); } } count.success ++ ; return response ; } private static void config(HttpRequestBase httpRequestBase, int readTimeout, int connectTimeout) { httpRequestBase.setHeader("User-Agent", "Devond HttpUtil"); httpRequestBase.setHeader("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"); httpRequestBase.setHeader("Accept-Language", "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3");//"en-US,en;q=0.5"); httpRequestBase.setHeader("Accept-Charset", "ISO-8859-1,utf-8,gbk,gb2312;q=0.7,*;q=0.7"); // 配置請求的超時設置 RequestConfig requestConfig = RequestConfig.custom() .setConnectionRequestTimeout(readTimeout + connectTimeout) .setConnectTimeout(connectTimeout) .setSocketTimeout(readTimeout) .build(); httpRequestBase.setConfig(requestConfig); } }
其餘相關代碼服務器
package com.shield.exception; import java.net.SocketTimeoutException; public class CallInterfaceException extends Exception{ /** * */ private static final long serialVersionUID = 4983997949599323781L; public CallInterfaceException(Throwable throwable, String url) { super(throwable); this.url = url ; this.message = throwable.getMessage() ; if(throwable instanceof SocketTimeoutException){ if(throwable.getMessage().contains("connect")){ this.type = CONNECT_TIMEOUT ; }else{ this.type = READ_TIMEOUT ; } }else{ this.type = EXCEPTION ; } } public CallInterfaceException(Throwable throwable,String url,int type) { super(throwable); this.url = url ; this.message = throwable.getMessage() ; this.type = type ; } private int type ; //失敗類型 private String url ; private String message ; public String getMessage() { return "type="+type+",message="+message+",url="+url; } public int getType() { return type; } public String getUrl() { return url; } public final static int CONNECT_TIMEOUT = 0; public final static int READ_TIMEOUT = 1 ; public final static int NOT_ASSOCIATED = 2 ; public final static int EXCEPTION = -1 ; }
package com.shield.model; import com.shield.util.DateUtil; public class Count { public int error ; public int timeout ; public int success ; public int nodata ; public int unknown ; public long initTime = DateUtil.currentTimeSeconds(); public void clear(){ error = 0 ; timeout = 0; success = 0 ; nodata = 0 ; unknown = 0 ; initTime = DateUtil.currentTimeSeconds(); } }