• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 众包
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

绝望生鱼片

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

利用Apache HTTPClient 4.x访问嘀咕API

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<String> 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的问题在哪里。
No authentiction scheme
好在后来看了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<NameValuePair> nvps = new ArrayList<NameValuePair>();
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

posted on 2011-09-05 12:56  绝望生鱼片  阅读(1850)  评论(2)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3