本文转截自:http://www.thinkingquest.net/articles/210.html
3.x版本的httpclient属于apache的commons项目。 从4.x开始,httpclient被转移到了httpcomponent项目下。 api也发生了重大的变化。 http 3.x已经不推荐使用。使用3.x版本的地方,官方建议都升级到4.x版本。
本文的api也都基于4.x版本。下面是一个最simple的案例:
private String upload(String url, HttpEntity entity) {
String result = null;
HttpClient httpClient = new DefaultHttpClient();
try {
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(entity);
HttpResponse response = httpClient.execute(httpPost);
int status = response.getStatusLine().getStatusCode();
if (status == HttpStatus.SC_OK) {
HttpEntity resEntity = response.getEntity();
result = EntityUtils.toString(resEntity, "UTF-8");
} else {
logger.error("upload:" + url + " error code:" + status);
}
} catch (Exception ex) {
logger.error("Error with HttpClient ", ex);
} finally {
try {
httpClient.getConnectionManager().shutdown();
} catch (Exception ignore) {}
}
return result;
}
在这段代码中,每调用一次upload方法,都会new一次 BasicHttpClient对象。由此产生一个疑问,这个对象是否是线程安全的呢?查阅了文档,文档中说它是线程安全的。文档地 址:http://hc.apache.org/httpcomponents-client-ga/tutorial/html /httpagent.html
实测对一个BasicHttpClient对象,多个线程调用,只有一个线程运行正常,其他线程全部抛出异常。究其根源,是其中的ConnectionManager的问题。
在多线程的情况下,如果创建一个BasicHttpClient对象,代码应该如下:
PoolingClientConnectionManager cm = new PoolingClientConnectionManager();
cm.setMaxTotal(200);
cm.setDefaultMaxPerRoute(20);
BasicHttpParams params = new BasicHttpParams();
params.setBooleanParameter(CoreConnectionPNames.TCP_NODELAY, true);
params.setIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, 64 * 1024);
client = new DefaultHttpClient(cm, params);
每次执行client.execute(method)之后,需要调用method的releaseConnection()方法。
PoolingClientConnectionManager是其中的关键,替代了默认采用的BasicClientConnectionManager。这样就可以多线程。
setMaxTotal设置的是最大连接数。如果不设置,默认值为20。defaultMaxPerRoute的默认值是2。文档中说,这两个参数过于保守。对于频繁请求的应用来说,都太小了。
关于其它的参数可以参见文档:
http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html#d5e399
本文转截自:http://www.thinkingquest.net/articles/210.html
----
PS:
可以使用method的abort方法 哎~~