使用HttpClinet保持session一致

我们在访问网路时,有时候会用到Android已经封装好的一个类——HttpClient,这个类就相当于一个小型的浏览器,集成了很多允许我们访问网络的方法,在普通的应用程序中,我们只需封装HttpRequest对象并传给HttpClient,使用HttpClient就可以访问网络了。如果请求的端口或者URL没有变化,可以采用单例模式来封装一个HttpClient。
?
代码片段,双击复制
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
        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
        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
        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.getValue());
                                String value = headers.getValue();
                                CommonDefines.SESSIONID = value
                                                .substring( 0 , value.indexOf( ";" ));
                        }
  
                        return (resEntity == null ) ? null : EntityUtils
                                        .toByteArray(resEntity);
                }
                return null ;
        }

OK,这样就解决了在httpClient中保持session一致的问题了。
本人才疏学浅,如果有大神发现这个代码有问题,欢迎回帖,如果有有效的清除httpClient对象的方法,希望大神们也回复下哦
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值