MultiThreadedHttpConnectionManager
HttpClient中使用多线程的一个主要原因是可以一次执行多个方法。在执行期间,每一个方法都使用一个HttpConnection实例。由于在同一时间多个连接只能安全地用於单一线程和方法和有限的资源,我们就必须确保连接分配给正确的方法。而MultiThreadedHttpConnectionManager完全可以代替我们完成这一项工作,这样我们就不必去考虑多线程带来安全的问题。
MultiThreadedHttpConnectionManager connectionManager =
new MultiThreadedHttpConnectionManager();
HttpClient client = new HttpClient(connectionManager);
以上代码中的HttpClient就在多线程中执行多个方法了。当我们再次调用httpClient.executeMethod()方法时,就会去Connection Manager中去请求HttpConneciton的实例,这样就避免了线程安全问题,因为HttpClient已经帮我们做了。
Options
MultThreadedHttpConnectionManager参数配置:
connectionStaleCheckingEnabled:这个标志对所有已经创建的connections都适用。除特殊情况外,此值应该设置成true。
maxConnectionsPerHost:最大连接数,默认是2。
maxTotalConnections:最大活动连接数,默认是20。
释放连接
connection management比较重要的是当连接不再使用时,一定要手动释放。这样做的原因是HttpClient不能够确定哪个方法不被使用,哪个方法还在使用。这是因为Response body不是由HttpClient来自动读取其数据的,而是由使用HttpClient的应用程序来完成的。当读取Response的数据是时,必须使用此方法的连接。这样,在Response的数据在读取前,HttpClient是没有释放连接的。所有这就要求在读取完Response的数据后,应用程序及时的使用releaseConnection()方法来释放连接。
package com.partner.supper;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
import com.alibaba.fastjson.JSON;
public class HttpClientUtil {
private static MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
private static final int TIMEOUT = 5 * 1000;
private static final int MAX_HTTP_CONNECTION = 50;
private static final int MAX_CONNECTION_PER_HOST = 10;
private static HttpClientUtil instance = null;
static{
//HttpClient 连接池属性设置,HOST并发数默认为50, 客户端总并发数为200, TimeOut时间为5s.
HttpConnectionManagerParams httpConnectionManagerParams = new HttpConnectionManagerParams();
httpConnectionManagerParams.setMaxTotalConnections(MAX_HTTP_CONNECTION);
httpConnectionManagerParams.setDefaultMaxConnectionsPerHost(MAX_CONNECTION_PER_HOST);
httpConnectionManagerParams.setSoTimeout(TIMEOUT);
httpConnectionManagerParams.setConnectionTimeout(TIMEOUT);
connectionManager.setParams(httpConnectionManagerParams);
}
public HttpClientUtil(){
}
public static HttpClientUtil getInstance(){
if(null == instance){
synchronized(HttpClientUtil.class){
if(instance == null){
instance = new HttpClientUtil();
}
}
}
return instance;
}
public HttpClient createHttpClient(){
HttpClient httpClient = new HttpClient(connectionManager);
return httpClient;
}
/**
* 进行 http请求返回resultVO结果对象
*
* @param url
* @return
*/
public ResultVO getHttpClientJson(String url){
HttpClient httpClient = createHttpClient();
GetMethod getMethod = new GetMethod(url);
try {
httpClient.executeMethod(getMethod);
String jsonString = getMethod.getResponseBodyAsString();
return JSON.parseObject(jsonString, ResultVO.class);
} catch (Exception e) {
e.printStackTrace();
ResultVO resultVO = new ResultVO();
resultVO.setRet(1);
resultVO.setMsg("调用失败");
return resultVO;
}finally{
getMethod.releaseConnection();
}
}
/**
* 进行 http post请求返回resultVO结果对象
*
* @param url
* @return
*/
public ResultVO postHttpClientJson(String url){
HttpClient httpClient = createHttpClient();
PostMethod postMethod = new PostMethod(url);
try {
httpClient.executeMethod(postMethod);
String jsonString = postMethod.getResponseBodyAsString();
return JSON.parseObject(jsonString, ResultVO.class);
} catch (Exception e) {
e.printStackTrace();
ResultVO resultVO = new ResultVO();
resultVO.setRet(1);
resultVO.setMsg("调用失败");
return resultVO;
}finally{
postMethod.releaseConnection();
}
}
}