17031四、工具:apache httpClient多線程併發狀況下安全實用及工具類分享

簡單用法介紹:介紹來源網絡java

創建鏈接:在HttpClient中使用多線程的一個主要緣由是能夠一次執行多個方法。在執行期間,每個方法都使用一個HttpConnection實例。因爲在同一時間多個鏈接只能安全地用於單一線程和方法和有限的資源,咱們就必須確保鏈接分配給正確的方法。而MultiThreadedHttpConnectionManager徹底能夠代替咱們完成這一項工做,這樣咱們就沒必要去考慮多線程帶來安全的問題。apache

MultiThreadedHttpConnectionManager connectionManager =new MultiThreadedHttpConnectionManager();json

HttpClient client = new HttpClient(connectionManager);緩存

以上代碼中的HttpClient就在多線程中執行多個方法了。當咱們再次調用httpClient.executeMethod()方法時,就會去Connection Manager中去請求HttpConneciton的實例,這樣就避免了線程安全問題,由於HttpClient已經幫咱們作了。安全

釋放鏈接:Connection Management比較重要的是當鏈接再也不使用時,必定要手動釋放。這樣作的緣由是HttpClient不可以肯定哪一個方法不被使用,哪一個方法還在使用。這是由於Response body不是由HttpClient來自動讀取其數據的,而是由使用HttpClient的應用程序來完成的。當讀取Response的數據是時,必須使用此方法的鏈接。這樣,在Response的數據在讀取前,HttpClient是沒有釋放鏈接的。全部這就要求在讀取完Response的數據後,應用程序及時的使用releaseConnection()方法來釋放鏈接。特別注意,不管執行的方法或是否也不例外被拋出。對於每個HttpClient.executeMethod方法必須有一個method.releaseConnection ( )來釋放鏈接。服務器

重用HttpClient實例:通常說來,建議一個通信組件,甚至說一個應用軟件就始終維持一個HttpClient對象實例存在。可是若是你的應用很稀罕纔用到它,並且還不容許這麼一個實例一直存在,那麼,這裏強烈建議,必定要顯式地shut down 它的MultiThreadedHttpConnectionManager 。這樣作是確保鏈接池裏的Connection獲得釋放。 網絡

HttpMethod併發執行:若是應用程序邏輯容許併發執行多個HTTP請求,(例如對多個服務器的多個併發請求,或對同一個服務器表明不一樣用戶身份的多個請求) ,應用程序能夠爲每個HTTP session開啓一個專門的線程,這樣的設計天然將帶來顯著的性能提高。 而當使用一個線程安全的鏈接管理器MultiThreadedHttpConnectionManager 時,HttpClient能保證線程安全。這樣,多個線程能夠共享這麼一個線程安全的HttpClient實例。請注意,應用程序的每一個各自執行的線程必須使用各自的HttpMethod實例;而且可配置各自的HttpState實例和/或HostConfiguration實例(表明一個特定的會話狀態和主機配置)。這個共享的HttpClient和其標配的MultiThreadedHttpConnectionManager將爲各線程帶來最高的性能。session

使用流來發送和接收數據:HttpClient同時支持Stream和String/byte[]兩種方式來發送和接受數據,可是因爲String/byte[]的方式會形成內存中有一份數據的拷貝或緩存,那麼當請求或應答報文比較大,或者在高併發的應用中,使用String/byte[]就會形成額外的內存開銷,因此使用流的方式來傳輸數據是更好的選擇。多線程

HttpClient的三種超時說明併發

/* 從鏈接池中取鏈接的超時時間 */

ConnManagerParams.setTimeout(params, 1000);

/* 鏈接超時 */

HttpConnectionParams.setConnectionTimeout(params, 2000);

/* 請求超時 */

HttpConnectionParams.setSoTimeout(params, 4000);

第一行設置ConnectionPoolTimeout:這定義了從ConnectionManager管理的鏈接池中取出鏈接的超時時間,此處設置爲1秒。

第二行設置ConnectionTimeout:  這定義了經過網絡與服務器創建鏈接的超時時間。Httpclient包中經過一個異步線程去建立與服務器的socket鏈接,這就是該socket鏈接的超時時間,此處設置爲2秒。

第三行設置SocketTimeout:    這定義了Socket讀數據的超時時間,即從服務器獲取響應數據須要等待的時間,此處設置爲4秒。

以上3種超時分別會拋出ConnectionPoolTimeoutException,ConnectionTimeoutException與SocketTimeoutException。

工具類:jar包commons-httpclient-3.1.jar

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.util.Map;

import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;

import org.apache.commons.httpclient.HostConfiguration;

import org.apache.commons.httpclient.HttpClient;

import org.apache.commons.httpclient.HttpException;

import org.apache.commons.httpclient.HttpMethod;

import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;

import org.apache.commons.httpclient.NameValuePair;

import org.apache.commons.httpclient.methods.GetMethod;

import org.apache.commons.httpclient.methods.PostMethod;

import org.apache.commons.httpclient.methods.RequestEntity;

import org.apache.commons.httpclient.methods.StringRequestEntity;

import org.apache.commons.httpclient.params.HttpClientParams;

import org.apache.commons.httpclient.params.HttpConnectionManagerParams;

import org.apache.commons.httpclient.params.HttpMethodParams;

import org.apache.commons.httpclient.protocol.Protocol;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;

import com.alibaba.fastjson.JSONObject;

public class HttpClientTemplate {

private static Logger logger = LoggerFactory.getLogger(HttpClientTemplate.class);

    private MultiThreadedHttpConnectionManager multiThreadConnManager;

    private HttpClient client;

    public HttpClientTemplate() {

        HttpConnectionManagerParams params = new HttpConnectionManagerParams();

        params.setParameter(HttpMethodParams.RETRY_HANDLER,

            new DefaultHttpMethodRetryHandler());

        params.setMaxTotalConnections(10);

        params.setDefaultMaxConnectionsPerHost(5);

        params.setSoTimeout(10 * 1000);

        params.setConnectionTimeout(10 * 1000);

        multiThreadConnManager = new MultiThreadedHttpConnectionManager();

        multiThreadConnManager.setParams(params);

    }

    private HttpClient getHttpClient() {

        if (client == null)

            synchronized (this) {

                client = new HttpClient(multiThreadConnManager);

                HttpClientParams params = new HttpClientParams();

                params.setContentCharset("UTF-8");

                client.setParams(params);

            }

        return client;

    }

//生成get方法

    private GetMethod genMethod(String baseUrl, String queryString) {

        GetMethod get = new GetMethod(baseUrl);

        get.setQueryString(queryString);

        return get;

    }

//生成get方法

    private GetMethod genMethod(String baseUrl, Map<String, Object> paramMap) {

        GetMethod get = new GetMethod(baseUrl);

        HttpMethodParams params = new HttpMethodParams();

        params.setContentCharset("UTF-8");

        get.setParams(params);

        if (paramMap != null) {

            NameValuePair[] nvp = new NameValuePair[paramMap.values().size()];

            int i = 0;

            for (Map.Entry<String, Object> entry: paramMap.entrySet()) {

                nvp[i++] = new NameValuePair(entry.getKey(), entry.getValue()

                    .toString());

            }

            get.setQueryString(nvp);

        }

        return get;

    }

    public String execute(String baseUrl, Map<String, Object> paramMap) {

     if(logger.isDebugEnabled()) {

     logger.debug("[sending] url={}, param={}", baseUrl, JSON.toJSONString(paramMap));

     }

     try {

        GetMethod method = genMethod(baseUrl, paramMap);

        String result = execute(method);

        if(logger.isDebugEnabled()) {

     logger.debug("[receiving] result ={}, url={}, param={}",result, baseUrl, JSON.toJSONString(paramMap));

     }

        return result;

     }

     catch(Exception e) {

     logger.error("[http exception] url={}, param={}", baseUrl, JSON.toJSONString(paramMap), e);

     return null;

     }   

    }

    //json格式請求

    public String excuteJson(String baseUrl, Map<String, Object> paramMap)

     throws HttpException, IOException

    {

     if(logger.isDebugEnabled()) {

     logger.debug("[sending json] url={}, param={}", baseUrl, JSON.toJSONString(paramMap));

     }

      JSONObject json = new JSONObject();

      json.putAll(paramMap);

      PostMethod method = new PostMethod(baseUrl);

      RequestEntity requestEntity = new StringRequestEntity(json.toString(), "application/json", "UTF-8");

      method.setRequestEntity(requestEntity);

      String result = execute(method);

      if(logger.isDebugEnabled()) {

      logger.debug("[receiving json] result ={}, url={}, param={}",result, baseUrl, JSON.toJSONString(paramMap));

      }

      return result;

    }

//post請求

    public String executePost(String baseUrl, Map<String, Object> paramMap){

     try {

     if(logger.isDebugEnabled()) {

     logger.debug("[sending post] url={}, param={}", baseUrl, JSON.toJSONString(paramMap));

     }

        PostMethod method = new PostMethod(baseUrl);

        HttpMethodParams params = new HttpMethodParams();

        params.setContentCharset("UTF-8");

        method.setParams(params);

        if (paramMap != null) {

            NameValuePair[] nvp = new NameValuePair[paramMap.values().size()];

            int i = 0;

            for (Map.Entry<String, Object> entry: paramMap.entrySet()) {

                nvp[i++] = new NameValuePair(entry.getKey(), entry.getValue()

                    .toString());

            }

            method.addParameters(nvp);

        }

        String result = execute(method);

        if(logger.isDebugEnabled()) {

      logger.debug("[receiving post] result ={}, url={}, param={}",result, baseUrl, JSON.toJSONString(paramMap));

      }

      return result;

     }

     catch(Exception e) {

     logger.error("[http post exception] url={}, param={}", baseUrl, JSON.toJSONString(paramMap), e);

     return null;

     }

    }

 

    public String executePost(String baseUrl, Map<String, Object> paramMap,

        Map<String, Object> headerParams) throws HttpException, IOException {

     if(logger.isDebugEnabled()) {

     logger.debug("[sending head] url={}, param={}, head={}", baseUrl, 

     JSON.toJSONString(paramMap), JSON.toJSONString(headerParams));

     }

        PostMethod method = new PostMethod(baseUrl);

        HttpMethodParams params = new HttpMethodParams();

        params.setContentCharset("UTF-8");

        method.setParams(params);

        if (paramMap != null) {

            NameValuePair[] nvp = new NameValuePair[paramMap.values().size()];

            int i = 0;

            for (Map.Entry<String, Object> entry: paramMap.entrySet()) {

                nvp[i++] = new NameValuePair(entry.getKey(), entry.getValue()

                    .toString());

            }

            method.addParameters(nvp);

        }

 

        if (headerParams != null) {

            // HttpMethodParams mparams = new HttpMethodParams();

            // mparams.setContentCharset("UTF-8");

            // mparams.setVirtualHost(headerParams.get("hostUrl").toString());

            // method.setParams(mparams);

            method.getParams().setVirtualHost(

                headerParams.get("hostUrl").toString());

        }

        String result = execute(method, headerParams);

        if(logger.isDebugEnabled()) {

      logger.debug("[receiving head] result ={}, url={}, param={}, head={}",result, baseUrl, 

      JSON.toJSONString(paramMap), JSON.toJSONString(headerParams));

      }

      return result;

    }

 

    public String execute(String url) throws HttpException, IOException {

        GetMethod method = new GetMethod(url);

        return execute(method);

    }

 

    public String execute(String baseUrl, String queryString)

        throws HttpException, IOException {

        GetMethod method = genMethod(baseUrl, queryString);

        return execute(method);

    }

 

    private String execute(HttpMethod method) throws HttpException, IOException {

        try {

            int statusCode = getHttpClient().executeMethod(method);

            if (200 != statusCode) {

                throw new HttpException("status code: " + statusCode);

            } else {

               // return method.getResponseBodyAsString();

             InputStream resStream = method.getResponseBodyAsStream();

                BufferedReader br = new BufferedReader(new InputStreamReader(

                    resStream, "UTF-8"));

                StringBuffer resBuffer = new StringBuffer();

                String resTemp = "";

                while ((resTemp = br.readLine()) != null) {

                    resBuffer.append(resTemp);

                }

                return resBuffer.toString();

            }

        } finally {

            if (null != method)

                method.releaseConnection();

        }

    }

 

    private String execute(HttpMethod method, Map<String, Object> headerParams)

        throws HttpException, IOException {

        try {

            HttpClient httpClient = getHttpClient();

            if (headerParams != null) {

                HostConfiguration hf = new HostConfiguration();

                if (headerParams.get("hostUrl") != null) {

                    hf.setHost(headerParams.get("hostUrl").toString(), 80,

                        Protocol.getProtocol("http"));

                }

                httpClient.setHostConfiguration(hf);

            }

            int statusCode = httpClient.executeMethod(method);

            if (200 != statusCode) {

                throw new HttpException("status code: " + statusCode);

            } else {

                // return method.getResponseBodyAsString();

                InputStream resStream = method.getResponseBodyAsStream();

                BufferedReader br = new BufferedReader(new InputStreamReader(

                    resStream, "UTF-8"));

                StringBuffer resBuffer = new StringBuffer();

                String resTemp = "";

                while ((resTemp = br.readLine()) != null) {

                    resBuffer.append(resTemp);

                }

                return resBuffer.toString();

            }

        } finally {

            if (null != method)

                method.releaseConnection();

        }

    }

    public static class Factory {

        private static HttpClientTemplate instance = new HttpClientTemplate();

 

        public static HttpClientTemplate getClient() {

            return Factory.instance;

        }

    }

public static void main(String[] args) {

     HttpClientTemplate clientTemplate = HttpClientTemplate.Factory.instance;

     Map<String, Object> paramMap = new LinkedHashMap<>();

     String result = clientTemplate.executePost("", paramMap);

}

}

相關文章
相關標籤/搜索