一、简介
HttpClient是Apache开源组织提供的HTTP网络访问接口,它是一个简单的HTTP客户端(并不是浏览器),可以发送HTTP请求,接收HTTP响应,但是不会缓存服务器的响应,不能执行HTTP页面中嵌入的JS代码,自然也不会对页面内容进行任何解析、处理,这些都是需要开发人员来完成的。
现在Android已经成功集成了HttpClient,所以开发人员在Android项目中可以直接使用HttpClient来向Web站点提交请求以及接受响应,如果使用其他的Java项目则需要引入相应的Jar包。HttpClient可以在官网上下载,官网链接:http://hc.apache.org/downloads.cgi
HttpClient其实是一个interface类型,它封装了对象需要执行的HTTP请求、身份验证、连接管理和其它特性。由于HttpClient是一个接口,因此无法创建它的实例,但是HttpClient有三个已知的实现类分别是:AbstractHttpClient、AndroidHttpClient、DefaultHttpClient,会发现有一个专门为Android应用准备的实现类AndroidHttpClient,当然使用常规的DefaultHttpClient也可以实现功能。
从两个类包所在位置就可以看出区别:AndroidHttpClient定义在android.net.http.AndroidHttpClient包下,属于Android原生的HTTP访问;而DefaultHttpClient定义在org.apache.http.impl.client.DefaultHttpClient包下,属于对Apache项目的支持。而AndroidHttpClient没有公开的构造函数,只能通过静态方法newInstance()方法来获得AndroidHttpClient对象。
二、特性
- 基于标准、纯净的
Java语言,实现了Http1.0和Http1.1; - 以可扩展的面向对象结构实现了
HTTP全部的方法(GET、POST、PUT、DELETE、HEAD、OPTIONS、TRACE); - 支持
HTTPS协议; - 通过
HTTP代理建立透明的连接; - 利用
CONNECT方法通过HTTP代理建立隧道的HTTPS连接; Basic、Digest、NTLMv1、NTLMv2、NTLM2 Session、SNPNEGO/Kerberos认证方案;- 插件式的自定义认证方案;
- 便携可靠的套接字工厂使它更容易的使用第三方解决方案;
- 连接管理器支持多线程应用,支持设置最大连接数,同时支持设置每个主机的最大连接数,发现并关闭过期的连接;
- 自动处理
Set-Cookie中的Cookie; - 插件式的自定义
Cookie策略; Request的输出流可以避免流中内容直接缓冲到Socket服务器;Response的输入流可以有效的从Socket服务器直接读取相应内容;- 在
Http1.0和Http1.1中利用KeepAlive保持持久连接; - 直接获取服务器发送的
response code和headers; - 设置连接超时的能力;
- 实验性的支持
http1.1 response caching; - 源代码基于
Apache License可免费获取;
三、集成
在Eclipse或Android Studio开发过程中,设置Android SDK的编译版本为23且使用了HttpClient相关类的方法时会出现有一些类找不到的错误。
原因
Android 6.0(API 23)SDK不再提供org.apache.http.*(只保留几个类)。解决方法
2.1Eclipse:在项目libs中加入:org.apache.http.legacy.jar
上面的jar包在:**\android-sdk-windows\platforms\android-23\optional下(需要下载Android 6.0的SDK)。2.2
Android Studio:在项目相应module的build.gradle中加入:android { useLibrary 'org.apache.http.legacy' }
四、权限
在AndroidManifest.xml文件添加网络权限
<uses-permission android:name="android.permission.INTERNET" />
五、混淆
#不混淆android-async-http(这里混淆由你使用的HttpClient框架决定)
-keep class com.loopj.android.http.**{*;}
#不混淆org.apache.http.legacy.jar
-dontwarn android.net.compatibility.**
-dontwarn android.net.http.**
-dontwarn com.android.internal.http.multipart.**
-dontwarn org.apache.commons.**
-dontwarn org.apache.http.**
-keep class android.net.compatibility.**{*;}
-keep class android.net.http.**{*;}
-keep class com.android.internal.http.multipart.**{*;}
-keep class org.apache.commons.**{*;}
-keep class org.apache.http.**{*;}
六、使用
简单来说,使用HttpClient发送请求、接收响应都很简单,只需要五大步骤即可:
- 创建客户端的
HttpClient对象; - 创建请求的对象。如果需要发送
GET请求,则创建HttpGet对象;如果需要发送POST请求,则创建HttpPost对象。注:对于发送请求的参数而言GET和POST的使用方式略有不同,GET方式可以使用拼接字符串的方式将参数拼接在URL末尾;POST方式则需要使用setEntityHttpEntity entity)方法来设置请求参数; - 调用
HttpClient对象的execute(HttpUriRequest request)发送请求,执行该方法后将获得服务器返回的HttpResponse对象。服务器返回给我们的数据就在这个HttpResponse相应当中,调用HttpResponse的对应方法可以获取服务器的响应头、响应内容等; - 检查响应状态是否正常。服务器返回给客户端的响应有一个响应码:相应码为
200时表示正常返回;相应码为404时表示客户端错误;相应码为505时表示服务器端错误; - 获得响应对象当中的数据。
七、调用
主线程中访问网络时异常:NetworkOnMainThreadException
- 原因
Android在4.0之前的版本支持在主线程中访问网络,但是在4.0以后对这部分程序进行了优化,也就是说访问网络的代码不能写在主线程中了。 - 解决方法
采用多线程、异步加载的方式加载数据。
八、示例
public static final int CONNECTION_TIME_OUT = 1000 * 20;//连接超时
public static final int SO_TIMEOUT = 1000 * 20;//Socket 超时
public static final String ENCODING = "UTF-8";//编码格式
/**
* HttpClient Post 请求
*
* @param apiUrl 接口地址
* @param paramsMap 接口参数
* @return
*/
public static ResultDesc postRequest(String apiUrl, Map<String, String> paramsMap) {
// 创建表单
List<NameValuePair> params = new ArrayList<NameValuePair>();
if (paramsMap != null && paramsMap.size() != 0) {
for (String key : paramsMap.keySet()) {
params.add(new BasicNameValuePair(key, paramsMap.get(key)));
}
}
//创建HttpClient对象
HttpClient httpClient = getHttpClient();
//创建请求对象,参数是访问的服务器地址
HttpPost httpPost = new HttpPost(apiUrl);
HttpResponse httpResponse;
ResultDesc resultDesc = null;
try {
UrlEncodedFormEntity encode = new UrlEncodedFormEntity(params, ENCODING);
httpPost.setEntity(encode);
//执行请求,获取服务器返回的相应对象
httpResponse = httpClient.execute(httpPost);
//检查相应的状态是否正常,状态码返回值为200表示正常
if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
//从相应对象当中取出数据放到entity当中
HttpEntity entity = httpResponse.getEntity();
//将entity当中的数据转换为字符串
String response = EntityUtils.toString(entity, ENCODING);
LogUtil.e(Constant.LOG_TAG, "接口地址:" + apiUrl + "\n请求返回:" + response);
resultDesc = getReturnData(response);
} else {
resultDesc = dataRestructuring(-1, UIUtils.getString(R.string.back_abnormal_results), "");
}
} catch (Exception e) {
resultDesc = dataRestructuring(-1, ExceptionCode(e), "");
}
return resultDesc;
}
/**
* HttpClient Get 请求
*
* @param apiUrl 接口地址
* @param paramsMap 接口参数
* @return
*/
public static ResultDesc getRequest(String apiUrl, Map<String, String> paramsMap) {
//创建表单
List<NameValuePair> params = new ArrayList<NameValuePair>();
if (paramsMap != null && paramsMap.size() != 0) {
for (String key : paramsMap.keySet()) {
params.add(new BasicNameValuePair(key, paramsMap.get(key)));
}
//对参数编码
String param = URLEncodedUtils.format(params, ENCODING);
apiUrl += "?" + param;
}
//创建HttpClient对象
HttpClient httpClient = getHttpClient();
//创建请求对象,参数是访问的服务器地址
HttpGet httpGet = new HttpGet(apiUrl);
HttpResponse httpResponse;
ResultDesc resultDesc = null;
try {
//执行请求,获取服务器返回的相应对象
httpResponse = httpClient.execute(httpGet);
//检查相应的状态是否正常,状态码返回值为200表示正常
if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
//从相应对象当中取出数据放到entity当中
HttpEntity entity = httpResponse.getEntity();
//将entity当中的数据转换为字符串
String response = EntityUtils.toString(entity, ENCODING);
LogUtil.e(Constant.LOG_TAG, "接口地址:" + apiUrl + "\n请求返回:" + response);
resultDesc = getReturnData(response);
} else {
resultDesc = dataRestructuring(-1, UIUtils.getString(R.string.back_abnormal_results), "");
}
} catch (Exception e) {
resultDesc = dataRestructuring(-1, ExceptionCode(e), "");
}
return resultDesc;
}
/**
* HttpClient 配置
*
* @return
*/
public static HttpClient getHttpClient() {
//创建HttpParams以用来设置HTTP参数(这一部分不是必需的)
BasicHttpParams httpParams = new BasicHttpParams();
//设置连接超时
HttpConnectionParams.setConnectionTimeout(httpParams, CONNECTION_TIME_OUT);
//设置Socket超时
HttpConnectionParams.setSoTimeout(httpParams, SO_TIMEOUT);
//设置Socket缓存大小
HttpConnectionParams.setSocketBufferSize(httpParams, 8192);
//设置userAgent
String userAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2) Gecko/20100115 Firefox/3.6";
HttpProtocolParams.setUserAgent(httpParams, userAgent);
//设置重定向,缺省为true
//HttpClientParams.setRedirecting(httpParams, true);
//设置HttpClient支持HTTP和HTTPS两种模式
//SchemeRegistry schReg = new SchemeRegistry();
//schReg.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
//schReg.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));
//使用线程安全的连接管理来创建HttpClient
//ClientConnectionManager conMgr = new ThreadSafeClientConnManager(httpParams, schReg);
//创建HttpClient对象
//HttpClient httpClient = new DefaultHttpClient(conMgr, httpParams);
//创建HttpClient对象
HttpClient httpClient = new DefaultHttpClient(httpParams);
return httpClient;
}
项目地址 ☞ 传送门
本文详细介绍了Apache HttpClient的功能特性,包括其在Android平台上的集成与使用方法。HttpClient是一个强大的HTTP客户端工具,支持多种HTTP方法,并能处理HTTPS协议及认证方案。
217

被折叠的 条评论
为什么被折叠?



