在项目期初是用HttpConnection,近期为了用应对大促问题,大家决定将请求外部地图接口改为httpclient连接池。期初是朝着httpclient4.X准备的,结果在开发过程中,发现项目中引入的是httpClient3.2。多方找资料,发现3.X的资料已经相当少,特记录一下。
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
/**
* 单例连接池
*
*/
public class HttpClientPool {
private static final Logger LOGGER = LoggerFactory.getLogger(HttpClientPool.class);
private static volatile HttpClientPool pool;
private MultiThreadedHttpConnectionManager connectionManager;
private HttpClientPool(){
connectionManager = new MultiThreadedHttpConnectionManager();
HttpConnectionManagerParams params = new HttpConnectionManagerParams();//连接池属性实例
params.setDefaultMaxConnectionsPerHost(100);//每个网址最大连接数
params.setMaxTotalConnections(100);//最大连接数
params.setConnectionTimeout(1000);//连接超时时间
params.setSoTimeout(2000);//获取数据超时时间
connectionManager.setParams(params);
}
public static HttpClientPool getInstance(){
if(null == pool){
LOGGER.info("外层判断实例不存在,进行锁定,锁定线程{}",Thread.currentThread().getName());
synchronized (HttpClientPool.class){
if(null == pool){
LOGGER.info("内层判断实例不存在,进行创建线程池,创建线程{}",Thread.currentThread().getName());
pool = new HttpClientPool();
}
}
}
return pool;
}
/**
* 执行get方法,并将返回信息以字符串返回-不允许有留或文件操作
* @param url
* @return
* @throws IOException
*/
public String exeGetMethod(String url) {
LOGGER.info("通过HttpClient请求路径:{}",url);
GetMethod getMethod = null;
try {
HttpClient client = new HttpClient(this.connectionManager);//创建客户端,并交由连接池管理
getMethod = new GetMethod(url);
int statusCode = client.executeMethod(getMethod);
if(200 == statusCode){
return getMethod.getResponseBodyAsString();
}else {
LOGGER.info("获取网络信息失败,url:{},返回码:{}",url,statusCode);
throw new RuntimeException("获取网络信息失败,url:" + url + ",返回码:" + statusCode);
}
} catch (Exception e){
LOGGER.error("调用httpclient异常:",e);
throw new RuntimeException("调用HttpClient异常!");
} finally {
if(null != getMethod){
getMethod.releaseConnection();//释放连接
}
}
}
}
HttpClient 3.X连接池注意事项:
1. 创建MultiThreadedHttpConnectionManager对象
2. client属性设置通过HttpConnectionManagerParams对象,如最大连接数、超时时间等。
3. 创建HttpClient对象需要传入创建MultiThreadedHttpConnectionManager对象,这样创建的client对象是交由连接池管理的
4. 调用结束后,需要将连接释放。getMethod.releaseConnection();