2.2. Apache接口
Apache HttpClient 是一个开源项目,弥补了 java.net.* 灵活性不足的缺点,为客户端的HTTP编程提供高效、最新、功能丰富的工具包支持。该项目最早源于2001年开始的 Commons HttpClient ,是 Apache Jakarta Commons 下的子项目,目前版本为3.x。
HttpComponents 则是从2005年开始的脱胎于 Commons HttpClient ,旨在用来替换后者的一个项目,其中也包括了 HttpClient 组件,且大部分接口与 Commons HttpClient 相同。按照官方网站(http://hc.apache.org/)的说法,在 Apache HttpClient 4 稳定之后HttpComponents 将可以完全替换 Commons HttpClient。
Android 平台引入了 Apache HttpClient 的同时还提供了对它的一些封装和扩展,例如设置缺省的HTTP超时和缓存大小等。早期的 Android 曾同时包括 Commons HttpClient (org.apache.commons.httpclient.*) 和 HttpComponents (org.apache.http.client.* ),不过当前版本 (1.5) 中开发者只能使用后者,也就是说类似以下的一些类:
org.apache.commons.httpclient.methods.PostMethod
需要改成对应的
org.apache.http.client.methods.HttpPost
使用这部分接口的基本操作与 java.net.* 基本类似,主要包括:
- 创建 HttpClient 以及 GetMethod / PostMethod, HttpRequest 等对象
- 设置连接参数
- 执行 HTTP 操作
- 处理服务器返回结果
以下例子以 HttpGet 方式通过代理访问 HTTPS 网站:
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.params.ConnRoutePNames;
import org.apache.http.params. HttpConnectionParams;
import org.apache.http.client.params. HttpClientParams;
try {
// 创建 HttpParams 以用来设置 HTTP 参数(这一部分不是必需的)
HttpParams params = new BasicHttpParams();
// 设置连接超时和 Socket 超时,以及 Socket 缓存大小
HttpConnectionParams.setConnectionTimeout(params, 20 * 1000);
HttpConnectionParams.setSoTimeout(params, 20 * 1000);
HttpConnectionParams.setSocketBufferSize(params, 8192);
// 设置重定向,缺省为 true
HttpClientParams.setRedirecting(params, true);
// 设置 user agent
HttpProtocolParams.setUserAgent(params, userAgent);
// 创建一个 HttpClient 实例
// 注意 HttpClient httpClient = new HttpClient(); 是Commons HttpClient
// 中的用法,在 Android 1.5 中我们需要使用 Apache 的缺省实现 DefaultHttpClient
HttpClient httpClient = new DefaultHttpClient(params);
// 创建 HttpGet 方法,该方法会自动处理 URL 地址的重定向
HttpGet httpGet = new HttpGet ("http://www.test_test.com/");
HttpResponse response = client.execute(httpGet);
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
// 错误处理,例如可以在该请求正常结束前将其中断
httpGet.abort();
}
// 读取更多信息
Header[] headers = response.getHeaders();
HttpEntity entity = response.getEntity();
Header header = response.getFirstHeader("Content-Type");
} catch (Exception ee) {
//
} finally {
// 释放连接
client.getConnectionManager().shutdown();
}
以下例子以 HttpGet 方式通过代理访问 HTTPS 网站:
HttpClient httpClient = new HttpClient();
// 设置认证的数据
httpClient.getCredentialsProvider().setCredentials(
new AuthScope("your_auth_host", 80, "your_realm"),
new UsernamePasswordCredentials("username", "password"));
// 设置服务器地址,端口,访问协议
HttpHost targetHost = new HttpHost("www.test_test.com", 443, "https");
// 设置代理
HttpHost proxy = new HttpHost("192.168.1.1", 80);
httpClient.getParams().setParameter
(ConnRoutePNames.DEFAULT_PROXY, proxy);
// 创建一个 HttpGet 实例
HttpGet httpGet = new HttpGet("/a/b/c");
// 连接服务器并获取应答数据
HttpResponse response = httpClient.execute(targetHost, httpGet);
// 读取应答数据
int statusCode = response.getStatusLine().getStatusCode();
Header[] headers = response.getHeaders();
HttpEntity entity = response.getEntity();
} catch (Exception ee) {
//
}
以上例子中都是通过同步的方式来读写服务器,某些情况下出于效率上的考虑,应用可能需要异步的发送和接收数据。HttpClient 同样也为我们提供了相关的接口来满足这一需求,不过在这种情况下可能需要开发者自己根据具体的需要,编写一些额外的代码来调用这些接口,具体可参考 android.net.http 中的相关实现。
由于 HttpClient 工具包提供了相当丰富的接口和不同层次的封装,开发者可以用于实现 HTTP 实现的方法还有很多,并不一定限于以上介绍的两种方式。关于 HttpClient 的更多信息还可以参考其主页。