第13.2.4讲 HTTPClient的高级功能
1 HttpClient构造实现
1.1 背景
通过连个应用场景来说明为什么需要不同的构造以及各自的应用场景; (1.1.1)访问同一个网站下的不同子地址;
(1.1.1.1) 在MainActivity的onCreate中创建HttpClient的构造;
(1.1.1.2) 在MainActivity的button 1中,通过HttpGet的实例访问百度图片服务下的"
http://g.hiphotos.baidu.com/image/pic/item/p01.jpg";
(1.1.1.3) 在MainActivity的button 2中,通过HttpGet的实例访问百度图片服务下的"
http://g.hiphotos.baidu.com/image/pic/item/p02.jpg";
(1.1.1.4) 在MainActivity的button 3中,通过HttpPost的实例访问百度图片服务下的"
http://c.hiphotos.baidu.com/image/pic/item/p03.jpg";
(1.1.1.5) 本例中HttpClient的实例服务维护客户端跟百度图片服务器的Session和身份认证,POST和GET的实例负责具体不同子地址的访问细节;
(1.1.1.6) 本例中只有一个Session,Session的访问、维护、管理相对安全;
(1.1.2)交叉访问不同网站下的不同子地址;
(1.1.2.1) 在MainActivity的onCreate中创建HttpClient的构造;
(1.1.2.2) 在MainActivity的button 1中,通过HttpGet的实例访问百度图片服务下的"
http://g.hiphotos.baidu.com/image/pic/item/p01.jpg";
(1.1.2.3) 在MainActivity的button 2中,通过HttpGet的实例访问360图片服务下的"
http://g.hiphotos.360.com/image/pic/item/p02.jpg";
(1.1.2.4) 在MainActivity的button 3中,通过HttpPost的实例访问淘宝服务下的"
http://c.hiphotos.淘宝.com/image/pic/item/p03.jpg";
(1.1.2.5) 本例中HttpClient的实例服务维护客户端跟百度图片服务器、360图片服务器、淘宝服务器之间的三个不同的Session和身份认证,POST和GET的实例负责具体不同子地址的访问细节;
(1.1.1.6) 本例中同时有三个不同的Session,这样Session的访问、维护、管理就变得很复杂,甚至不安全,只有通过特定的安全处理才能安全使用,所以需要不同的实例构造;
1.2 HttpClient的普通构造
(1.2.1)普通无参数默认设置的应用,例如:
HttpClient mHttpClient = new DefaultHttpClient();
(1.2.2)普通无参数非默认设置的应用,例如:
/***
*此方法用于获取一个HttpClient的实例
*/
private HttpClient getHttpClient(){
//获取一个HttpClient的实例
HttpClient httpClient=new DefaultHttpClient();
//设置基本的通信参数
httpClient.getParams().setParameter(
"http.connection.timeout", Integer.valueOf(10000));
httpClient.getParams().setParameter("http.socket.timeout",
Integer.valueOf(10000));
}
1.3 HttpClient的多线程安全构造步骤
(1.3.1)创建一个基本参数类BasicHttpParams的实例params;
(1.3.2)设置params的参数基本参数;
(1.3.3)创建一个模式注册类SchemeRegistry的实例schReg;
(1.3.4)设置schReg支持HTTP和HTTPS两种模式;
(1.3.5)利用params和schReg创建一个安全线程客户端端连接管理类ThreadSafeClientConnManager(params, schReg)的实例conMgr;
(1.3.6)利用params和conMgr创建一个HttpClient类DefaultHttpClient(conMgr, params)的实例client;
(1.3.7)新创建的实例client就是安全的HttpClient;
/**创建HttpClient实例
* @return HttpClient 实例
*/
private HttpClient createHttpClient(){
HttpParams params = new BasicHttpParams();
//需要设置代理时 如何设置代理主机
//HttpHost proxy = new HttpHost("211.142.236.137", 8080);
//httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
//----------注意使用的是HttpProtocolParams
//设置基本参数 HTTP协议的版本号、字符集、 ttp协议1.1中的header属性
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params,HTTP.UTF_8);
HttpProtocolParams.setUseExpectContinue(params, true);
// 设置 user agent
String userAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2)";
HttpProtocolParams.setUserAgent(params, userAgent);
//----------注意使用的是ConnManagerParams
//设置最大连接数
ConnManagerParams.setMaxTotalConnections(params, 50);
//设置本地代理路由每个路由的最大连接数(GPRS都是通过代理路由)
ConnPerRouteBean localConnPerRouteBean = new ConnPerRouteBean(50);
ConnManagerParams.setMaxConnectionsPerRoute(this.mHttpParams,
localConnPerRouteBean);
//三类超时时间1 从网络连接池中取一个连接的超时时间
ConnManagerParams.setTimeout(params, 1000);
//----------注意使用的是HttpConnectionParams
//设置Socket的缓冲区大小
HttpConnectionParams.setSocketBufferSize(params, 8192);
//三类超时时间2 网络与服务器建立连接的超时时间
HttpConnectionParams.setConnectionTimeout(params, 2000);
//三类超时时间3 请求超时
HttpConnectionParams.setSoTimeout(params, 4000);
//----------注意使用的是HttpClientParams
// 设置重定向,缺省为 true
HttpClientParams.setRedirecting(params, 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(params, schReg);
HttpClient client = new DefaultHttpClient(conMgr, params);
return client;
}
/**关闭实例httpClient
* @return
*/
private void shutdownHttpClient(HttpClient httpClient){
if(httpClient != null && httpClient.getConnectionManager() != null){
mHttpClient.getConnectionManager().shutdown();
}
}
2. URL中的参数和参数格式转换
HTTPClient中经常提到的参数包括两类:一个时URL地址串中的参数和HTTPClient集成包的的参数,一般意义上的参数是指后者。 2.1 HttpPost或HttpGet中URL参数的一般出现形式 ;
(2.1.1)参数类原型 BasicNameValuePair (String key, object value);
(2.1.2)参数通过List构成参数数据集List <BasicNameValuePair>使用;
2.2 参数列表在POST和GET的使用方式;
XXXX 函数 {
...
String urlStr="
http://192.168.1.88:8888/login.jsp";
//重点之1: 由基本参数类BasicNameValuePair的实例构成List参数集
List<BasicNameValuePair> paramList = new ArrayList();
paramList.add(new BasicNameValuePair("userName", “张飞”));
paramList.add(new BasicNameValuePair("userPass", “123321”));
paramList.add(new BasicNameValuePair("loginGroup", “system”));
doHttpClientGet(urlStr,paramList);
...
doHttpClientPost(urlStr,paramList);
...
}
//调用httpClient的DoPost
public boolean httpClientDoPost(String urlStr,List<BasicNameValuePair> parmList){
HttpPost post = new HttpPost(urlStr);
//重点之2:参数集在POST中的使用方式
// 参数强制转码,避免有汉字和特殊字符,然后设置post的Entity中的参数
post.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
...
}
//调用httpClient的DoGet
public boolean httpClientDoGet(String urlStr,List<BasicNameValuePair> parmList){
if(parmList !=null && parmList.size>0){
//重点之3:参数集在GET中的使用方式
String param =URLEncodedUtils.format(params, "UTF-8");
urlStr+="?"+param;
}
HttpPost post = new HttpGost(urlStr);
...
}
3. HttpClient支持包中的参数类和相关关系
3.1 包中的参数种类
HttpClient支持包中的新概念、新名词、新技术点真的叫多,光Parms的类就7个,依次是:HttpParams、DefaultHttpParams、HttpConnectionParams、HostParams、HttpMethodParams、HttpConnectionManagerParams、HttpClientParams; 3.2 各参数类的集成关系
|--L1: HttpParams(根类、Interface类型)
| ↓
|--L2: DefaultHttpParams
| |
| ↓----------------↓-------------------↓
|--L3: HttpConnectionParams HostParams HttpMethodParams
| ↓ ↓
|--L4: HttpConnectionManagerParams HttpClientParams
3.3 各种参数类的使用方式
见构造的代码举例中 3.4 个别参数的使用解释
(3.4.1)
4. Response中的字符流编码解决方案
4.1使用指定的编码格式读流
//使用UTF-8格式读流
BufferedReader br = new BufferedReader(
new InputStreamReader(conn.getInputStream(),HTTP.UTF_8))
String line="";
StringBuilder result=new StringBuilder();
while ((line = br.readLine()) != null){
result.append("\r\n" + line);
}
return result.toString();