使用HttpClinet保持session一致
来源:互联网 发布:java线程死锁是什么 编辑:程序博客网 时间:2024/06/16 22:54
我们在访问网路时,有时候会用到Android已经封装好的一个类——HttpClient,这个类就相当于一个小型的浏览器,集成了很多允许我们访问网络的方法,在普通的应用程序中,我们只需封装HttpRequest对象并传给HttpClient,使用HttpClient就可以访问网络了。如果请求的端口或者URL没有变化,可以采用单例模式来封装一个HttpClient。
代码片段,双击复制
在需要调用的地方调用上面的方法,获得httpClient实例:
代码片段,双击复制
这样就可以连接网络了。
但有些时候,情况会有些复杂,某些程序需要访问不同的端口,如果用单例模式,就需要手动的清除这个单例,在需要的地方再重新实例化,这样会造成程序上的混乱,而我们不用单例模式的话,每次访问网络是都一个新的httpClient对象,又会造成每次的session值不一致,服务器会认为你的多次请求并非在一次会话中,从而出现问题,打个比方:程序第一次请求服务器是进行登录功能,请求成功,服务器返回给response一个sessionid用作本次会话的标示,然而再下一次访问的时候,因为我们不用单例模式了,httpClient会重新实例化一个对象,这次请求的时候如果在request对象中没有sessionid的设置,那么服务器会认为这次请求和上次的请求不在一个会话中,造成错误。
我木有找到如何有效的在单例模式中关闭httpClient的方法,所以我的解决办法是手动的将每次的request请求保持一致
代码片段,双击复制
之后在调用处:
代码片段,双击复制
OK,这样就解决了在httpClient中保持session一致的问题了。
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
/**
* 获得httpclient实例
* @return
*/
public
static
synchronized
HttpClient getHttpClient() {
if
(httpClient ==
null
) {
HttpParams params =
new
BasicHttpParams();
// 设置一些基本参数
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, encoding);
HttpProtocolParams.setUseExpectContinue(params,
true
);
HttpProtocolParams
.setUserAgent(
params,
"Mozilla/5.0(Linux;U;Android 2.2.1;en-us;Nexus One Build.FRG83) "
+
"AppleWebKit/553.1(KHTML,like Gecko) Version/4.0 Mobile Safari/533.1"
);
// 超时设置
/* 从连接池中取连接的超时时间 */
ConnManagerParams.setTimeout(params, 1000);
/* 连接超时 */
HttpConnectionParams.setConnectionTimeout(params, 2000);
/* 请求超时 */
HttpConnectionParams.setSoTimeout(params,
4000
);
// 设置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 =
new
DefaultHttpClient(conMgr, params);
}
return
httpClient;
}
在需要调用的地方调用上面的方法,获得httpClient实例:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
public
static
byte
[] httpConnect(HttpRequest request)
throws
Exception {
HttpResponse response =
null
;
if
(request
instanceof
HttpGet) {
HttpGet get = (HttpGet) request;
response = getHttpClient().execute(get);
}
else
if
(request
instanceof
HttpPost) {
HttpPost post = (HttpPost) request;
response = getHttpClient().execute(post);
}
if
(response !=
null
&& response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
HttpEntity resEntity = response.getEntity();
return
(resEntity ==
null
) ?
null
: EntityUtils
.toByteArray(resEntity);
}
return
null
;
}
这样就可以连接网络了。
但有些时候,情况会有些复杂,某些程序需要访问不同的端口,如果用单例模式,就需要手动的清除这个单例,在需要的地方再重新实例化,这样会造成程序上的混乱,而我们不用单例模式的话,每次访问网络是都一个新的httpClient对象,又会造成每次的session值不一致,服务器会认为你的多次请求并非在一次会话中,从而出现问题,打个比方:程序第一次请求服务器是进行登录功能,请求成功,服务器返回给response一个sessionid用作本次会话的标示,然而再下一次访问的时候,因为我们不用单例模式了,httpClient会重新实例化一个对象,这次请求的时候如果在request对象中没有sessionid的设置,那么服务器会认为这次请求和上次的请求不在一个会话中,造成错误。
我木有找到如何有效的在单例模式中关闭httpClient的方法,所以我的解决办法是手动的将每次的request请求保持一致
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/**
* 获得httpclient实例
*
* @return
*/
private
static
synchronized
HttpClient getHttpClient(HttpRequest request) {
HttpParams params =
new
BasicHttpParams();
// 设置一些基本参数
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setUseExpectContinue(params,
true
);
HttpProtocolParams
.setUserAgent(
params,
"Mozilla/5.0(Linux;U;Android 2.2.1;en-us;Nexus One Build.FRG83) "
+
"AppleWebKit/553.1(KHTML,like Gecko) Version/4.0 Mobile Safari/533.1"
);
// 超时设置
/* 从连接池中取连接的超时时间 */
ConnManagerParams.setTimeout(params, 1000 * 8);
/* 连接超时 */
HttpConnectionParams.setConnectionTimeout(params, 1000 * 10);
/* 请求超时 */
HttpConnectionParams.setSoTimeout(params,
1000
*
10
);
// 设置HttpClient支持HTTP和HTTPS两种模式
SchemeRegistry schReg =
new
SchemeRegistry();
schReg.register(
new
Scheme(
"http"
, PlainSocketFactory
.getSocketFactory(), getHttpPort(request)));
schReg.register(
new
Scheme(
"https"
,
SSLSocketFactory.getSocketFactory(), getHttpPort(request)));
// 使用线程安全的连接管理来创建HttpClient
ClientConnectionManager conMgr =
new
ThreadSafeClientConnManager(
params, schReg);
return
new
DefaultHttpClient(conMgr, params);
}
之后在调用处:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
/**
* 通过HttpRequest实例连接网络
*
* @param request
* 网络请求,支持get和post<br>
* 若为get方式,需要传入HttpGet实例,若为post方式,传入HttpPost实例
* <a href="\"http://www.eoeandroid.com/home.php?mod=space&uid=7300\"" target="\"_blank\"">@return</a> 服务器的返回内容,这里将响应的内容处理为byte数组
* @throws Exception
*/
private
static
byte
[] httpConnect(HttpRequest request)
throws
Exception {
// Log.e("请求", CommonDefines.SESSIONID);
HttpResponse response =
null
;
if
(CommonDefines.SESSIONID !=
null
||CommonDefines.SESSIONID!=
""
) {
//设置sessionid,把第一次请求的id放在之后要请求的request报文头里
request.setHeader(
"Cookie"
, CommonDefines.SESSIONID);
}
if
(request
instanceof
HttpGet) {
HttpGet get = (HttpGet) request;
response = getHttpClient(request).execute(get);
}
else
if
(request
instanceof
HttpPost) {
HttpPost post = (HttpPost) request;
response = getHttpClient(request).execute(post);
}
if
(response !=
null
&& response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
HttpEntity resEntity = response.getEntity();
Header[] headers = response.getHeaders(
"set-cookie"
);
//保存服务器返回的session
for
(
int
i =
0
; i < headers.length; i++) {
// Log.e("sessionid", headers<i>.getValue());
String value = headers<i>.getValue();
CommonDefines.SESSIONID = value
.substring(
0
, value.indexOf(
";"
));
}
return
(resEntity ==
null
) ?
null
: EntityUtils
.toByteArray(resEntity);
}
return
null
;
}</i></i>
OK,这样就解决了在httpClient中保持session一致的问题了。
- 使用HttpClinet保持session一致
- ajax跨域请求保持session一致
- Httpclinet
- 使用Volley实现session会话保持
- cookie的使用与session的保持
- session保持
- (4.1.28.1)HTTP通信之HttpClinet保持登录状态问题
- 【Android】GridView 保持items图片大小一致
- Redis 如何保持和MySQL数据一致
- 用C#使用HttpWebRequest Post数据时如何保持Session
- 根据用户是否使用来保持Session对象的有效性
- 使用AJAX.NET使Session一直保持有效
- 使用web园 多线程web应用程序的session会话保持
- 使用KSoap2-anroid连接WebService并保持Session
- 保持Session的有效期
- 保持用户状态Session
- HttpWebRequest 保持session
- 状态保持-Session
- oracle rowid存贮类型
- 杭电1003 maxsum--解题报告
- git同步远程分支
- HTTP请求与响应(转载)
- 正则表达式
- 使用HttpClinet保持session一致
- hibernate4.1.7+ehcache2.4.3配置二级缓存
- IOS笔记之 视图圆角
- PLSQL developer 连接不上64位Oracle 的解决方法
- Codeforces Round #185 (Div. 2)--A,B
- 视频流抛错“ text=Error #2095: flash.net.NetStream 无法调用回调 onLastSecond” 遇到过这样的错误: Error #2044: 未处理的 Async
- git 常用命令
- js显示一个始终
- Android 百度地图 (v 2.0)覆盖物图层动画效果的实现