|
HttpClient是基于HttpCore实现的一个HTTP/1.1兼容的HTTP客户端,它提供了一系列可重用的客户端身份验证、HTTP状态保持、HTTP连接管理module。功能丰富的HTTPClient同时兼具出色的可扩展性和健壮性,目前已经成为了最为流行的Java HTTP客户端组件,为开发Web浏览器、Web Service客户端提供了很大的便利。
HttpClient(4.x)是Jakarta Commons HttpClient 3.x的继承,当前最新版本HttpClient 4.0-beta2。Android SDK在M5这个Milestone对HttpClient做了重大更新,开始捆绑HttpClient 4.x(当时还处于Alpha阶段)的包,而之前的M3则是捆绑了Jakarta Commons HttpClient 3.x。这一举动虽然在当时看起来太过激进,但是保证了在Android正式发布以后的API一致性。而嘀咕作为国内为博客的后起之秀,以众多好用的插件赢得了不少用户的青睐,这背后所依靠的则是它开放的API。看起来嘀咕API + HttpClient + Android的组合会非常有意思。
当然,实际上Android中的HttpClient在使用上与PC环境下并没有什么区别,我们只要记得在创建Project后给当前的Application设定Internet访问权限即可。
一般情况下,使用 HttpClient 需要以下5个步骤:
1. 创建 HttpClient 的实例
2. 创建某种连接方法的实例,在这里是最常见的是Get和Post
3. 调用第一步中创建好的HttpClient实例的execute方法,得到执行结果
4. 释放连接
5. 对得到后的内容进行处理
下面就结合代码和注释来说明
Get方法
1、创建HttpClient实例,调用DefaultHttpClient的默认构造函数,这里的DefaultHttpClient取代了HttpClient 3.x中的HttpClient,4.x中的HttpClient是作为一个接口存在。
帮助
1 |
DefaultHttpClient httpclient = new DefaultHttpClient(); | 2、创建HttpGet实例,把请求的URL地址传进去,比如我们想得到嘀咕的Public_Timeline,这个方法不需要身份验证。
帮助
1 |
HttpGet httpget = new HttpGet(“http://api.digu.com/statuses/public_timeline.xml?count=10&page=1”); | 3、调用HttpClient实例的execute方法,对于执行结果为2XX的情况,BasicResponseHandler会自动把response body以String方式返回,对于3xx的response它会在内部自动重定向,而对于没有response body的情况,他会返回null。
帮助
1
2 |
ResponseHandler responseHandler = new BasicResponseHandler();
String response = httpclient.execute(httpget, responseHandler); | 对于execute可能抛出的IOException这个可恢复异常,请参考HttpRequestRetryHandler接口来解决
4、最后,释放httpClient资源
帮助
1 |
httpclient.getConnectionManager().shutdown(); | 需要身份验证的Get方法
在嘀咕API中,绝大多数是需要身份验证的,接下来我们就来看一看如何通过HttpClient调用对需要身份验证的嘀咕API。
我起初参考了HttpClient Example中的Client authentication方法来调用需要身份验证的嘀咕API,比如friends_timeline,但是无法成功,一直是ClientProtocolException和MalformedChallengeException。从Wireshark抓包的情况来分析,似乎是发出的Get请求包头中并没有包含Authentiction信息。由于网上的HOWTO基本也都是以3.x为主,我花了很多时间也没能找到这个Exmaple的问题在哪里。
http://lh6.ggpht.com/_pq5z0vEqyaA/Shf0JKxm_CI/AAAAAAAAB-0/OCZae1KlG7I/s400/get_without_auth.PNG
好在后来看了Preemptive BASIC authentication,至少有了一个功能正常的解决办法。
与Client authentication中的做法最大的不同就在于给HttpClient设置了一个请求拦截器(Request Interceptor),当Http请求即将被执行的时候,如果发现AuthScheme为null就尝试初始化。
帮助
1
2 |
// Add as the first request intercepter
httpclient.addRequestInterceptor(new PreemptiveAuth(), 0); | Post方法
我们以更新一个嘀咕消息为例,Post方法比较特别的地方就在于
1、我们创建的是HttpPost实例,而非HttpGet实例
帮助
1 |
HttpPost httppost = new HttpPost("http://api.digu.com/statuses/public_timeline.xml"); | 2、我们把需要向服务端传递的数据封装在一个ArrayList中,这里比如我们想要发送的嘀咕消息内容对应字段为content。接下来,我们通过setEntity方法把经过URLEncode的字串传给httppost。
帮助
1
2
3
4 |
List nvps = new ArrayList();
nvps.add(new BasicNameValuePair("content", "test digu api, 测试嘀咕API"));
httppost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8)); | 3、后面的execute等方法调用就和Get没有什么区别了,并且因为我们是在向服务端提交内容,所以会比较关心请求是否成功执行,用esponse.getStatusLine()就可以得到请求执行的状态。
结语
在尝试用HttpClient调用嘀咕API的过程中,WireShark帮了我很大的忙。另外大家如果想在编码前就测试一下每个API的调用方法和返回结果,curl是个简便的途径,通过-u username:password的方法,它还能够支持需要身份验证的API调用。
得到了XML数据以后,下一步就是解析数据了,关于这一点,我将在下一篇中介绍。
参考资料
HttpClient Example
HttpClient JavaDoc |
|