0
点赞
收藏
分享

微信扫一扫

使用HttpClinet保持session一致


我们在访问网路时,有时候会用到Android已经封装好的一个类——HttpClient,这个类就相当于一个小型的浏览器,集成了很多允许我们访问网络的方法,在普通的应用程序中,我们只需封装HttpRequest对象并传给HttpClient,使用HttpClient就可以访问网络了。如果请求的端口或者URL没有变化,可以采用单例模式来封装一个HttpClient。



代码片段,双击复制

   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实例:



代码片段,双击复制

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 ;
       }



这样就可以连接网络了。


使用HttpClinet保持session一致_服务器



但有些时候,情况会有些复杂,某些程序需要访问不同的端口,如果用单例模式,就需要手动的清除这个单例,在需要的地方再重新实例化,这样会造成程序上的混乱,而我们不用单例模式的话,每次访问网络是都一个新的httpClient对象,又会造成每次的session值不一致,服务器会认为你的多次请求并非在一次会话中,从而出现问题,打个比方:程序第一次请求服务器是进行登录功能,请求成功,服务器返回给response一个sessionid用作本次会话的标示,然而再下一次访问的时候,因为我们不用单例模式了,httpClient会重新实例化一个对象,这次请求的时候如果在request对象中没有sessionid的设置,那么服务器会认为这次请求和上次的请求不在一个会话中,造成错误。


我木有找到如何有效的在单例模式中关闭httpClient的方法,所以我的解决办法是手动的将每次的request请求保持一致



代码片段,双击复制

 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);
  
       }



之后在调用处:



代码片段,双击复制

  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 条评论