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