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);

}

}

相关文章
相关标签/搜索