HttpClient使用方法

来源:互联网 发布:阿里云服务器代理 编辑:程序博客网 时间:2024/06/10 23:54

HttpClient使用方法

HttpClient作为访问Http服务的客户端访问程序已经被广泛使用,对于HttpClient的使用方法也有很多blog进行介绍,本文简明扼要的介绍HttpClient的两种使用方式——简单连接管理的HttpClient(BasicClientConnectionManager)和池化的HttpClient(PoolingClientConnectionManager)。
HttpClient从4.2开始抛弃了先前的SingleClientConnManager和ThreadSafeConnManger,取而代之的是BasicClientConnectionManager和PoolingClientConnectionManager。
BasicClientConnectionManager内部只维护一个活动的connection,尽管这个类是线程安全的,但是最好在一个单独的线程中重复使用它。如果在同一个BasicClientConnectionManager对象中,多次执行http请求,后继请求与先前请求是同一个route,那么BasicClientConnectionManager会使用同一个连接完成后续请求,否则,BasicClientConnectionManager会将先前的connection关闭,然后为后续请求创建一个新的连接。换句话说,BasicClientConnectionManager会尽力复用先前的连接(注意:创建连接和销毁连接都是不小的开销),因此,如果对同一个service有多个连续请求,应该尽量使用同一个BasicClientConnectionManager完成。
PoolingClientConnectionManager可以在多线程中使用,连接按照route被缓存(pooled),当后续的请求route已经在pool中存在,就会使用pool中先前使用的connection获取请求结果。PoolingClientConnectionManager对每个router维护的connection数目有上限要求,默认情况下,每个router最多维护两个并发线程的connection连接,整个pool最多容纳20个并发的connections。当然可以通过设置来修改这些限制。
下面给出两个例子:
Demo 1:BasicClientConnectionManager
public static void basicClientTest() throws ClientProtocolException, IOException{
HttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(“http://m.weather.com.cn/data/101010100.html“);
HttpResponse response = httpClient.execute(httpGet);
String result = EntityUtils.toString(response.getEntity(), Charset.forName(“utf-8”));
System.out.println(result);
httpClient.getConnectionManager().shutdown();
}
Demo1中,使用最简单的方式创建的httpclient内部使用的是BasicClientConnectionManager管理连接,并且使用HttpClient提供的EntityUtils将消息体转换成String输出。httpClient对象可以被重复使用,执行多个http请求,当你真正不需要他的时候,记得调用shutdown,关闭并且释放占用的资源。
Demo2:PoolingClientConnectionManager
public static void httpclientPool() throws ClientProtocolException, IOException{
SchemeRegistry registry = new SchemeRegistry();//创建schema

   SSLContext sslContext = null;//https类型的消息访问   try{       sslContext = SSLContext.getInstance("SSL");       sslContext.init(null, null, null);   }   catch (Exception e) {       e.printStackTrace();   }   SSLSocketFactory sslFactory = newSSLSocketFactory(sslContext,SSLSocketFactory.STRICT_HOSTNAME_VERIFIER);   registry.register(new Scheme("http", 80, PlainSocketFactory.getSocketFactory()));//http 80 端口   registry.register(new Scheme("https", 443, sslFactory));//https 443端口   PoolingClientConnectionManager cm = newPoolingClientConnectionManager(registry);//创建connectionManager   cm.setDefaultMaxPerRoute(20);//对每个指定连接的服务器(指定的ip)可以创建并发20 socket进行访问   cm.setMaxTotal(200);//创建socket的上线是200   HttpHost localhost = new HttpHost("locahost", 80);   cm.setMaxPerRoute(new HttpRoute(localhost), 80);//对本机80端口的socket连接上限是80   HttpClient httpClient = new DefaultHttpClient(cm);//使用连接池创建连接   HttpParams params = httpClient.getParams();   HttpConnectionParams.setSoTimeout(params, 60*1000);//设定连接等待时间   HttpConnectionParams.setConnectionTimeout(params, 60*1000);//设定超时时间   try{       HttpGet httpGet = new HttpGet("http://m.weather.com.cn/data/101010100.html");       HttpResponse response = httpClient.execute(httpGet);       String result = EntityUtils.toString(response.getEntity(), Charset.forName("utf-8"));       System.out.println(result);   }finally{       httpClient.getConnectionManager().shutdown();//用完了释放连接   }}

PoolingClientConnectionManager的创建过程要比BasicClientConnectionManager复杂的多,当然,我们为了举例子,将PoolingClientConnectionManager可能涉及到的多个方面属性都列出来,可以根据需要设置或者使用默认的连接属性。首先我们创建了SchemeRegistry,之后注册了两种http访问方式http和https,创建PoolingClientConnectionManager,指定每个router最多保持20个活动的connection,这个pool最多保持200个活动的connection,对本地的访问可以保持80个活动的connection。最后创建httpClient,设置SO_TIMEOUT和CONNECTION_TIMEOUT,执行请求。在httpClient不再使用时,关闭connectionManager。
Demo2 只是个例子,说明应当如何创建一个带有缓冲池的HttpClient,在实际应用中,可以对多个访问共用一个池化的HttpClient,即提高了性能(重用connection,connection和disconnect是非常耗时的,要选路由,三次握手等),也方便了管理,有利于代码的维护。

0 0
原创粉丝点击