安卓会话管理

24

是否有适用于Android会话管理的特定库?我需要在普通的Android应用程序中管理我的会话,而不是在WebView中。我可以从我的POST方法设置会话。但是当我发送另一个请求时,该会话就会丢失。有人可以帮我解决这个问题吗?

DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("My url");

HttpResponse response = httpClient.execute(httppost);
List<Cookie> cookies = httpClient.getCookieStore().getCookies();

if (cookies.isEmpty()) {
    System.out.println("None");
} else {
    for (int i = 0; i < cookies.size(); i++) {
        System.out.println("- " + cookies.get(i).toString());
    }
}

当我尝试访问同一主机时会丢失会话:

HttpGet httpGet = new HttpGet("my url 2");
HttpResponse response = httpClient.execute(httpGet);
我获得了登录页面的响应内容。
4个回答

39

这与Android无关,而是与你用于HTTP访问的Apache HttpClient库有关。

会话Cookie存储在你的DefaultHttpClient对象中。不要为每个请求创建新的DefaultHttpClient,而是将其保留并重复使用,这样可以维护你的会话Cookie。

你可以在此处了解Apache HttpClient (点击),并在此处了解HttpClient中的Cookie管理 (点击)


谢谢CommonsWare,它真的解决了我的问题。非常感谢.. :) - Dinesh Sharma
2
这个链接提供了如何在Android中实现HTTP连接重用的想法。http://foo.jasonhudgins.com/2009/08/http-connection-reuse-in-android.html - Sam

4

这是我用于发布文章的方法。我可以使用新的httpClients来实现这个方法,其中phpsessid是从登录脚本中提取的PHP会话ID,使用上面的代码。

ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();

nameValuePairs.add(new BasicNameValuePair("PHPSESSID",phpsessid));

3

一般来说,在Java的HttpURLConnection中,您可以通过以下方式设置/获取cookie(这里是整个连接过程)。下面的代码位于我的ConnectingThread的run()方法中,所有连接活动类都继承自该方法。它们共享一个静态的sCookie字符串,该字符串将与所有请求一起发送。因此,您可以维护一个常见状态,例如已登录/未登录:

        HttpURLConnection conn = (HttpURLConnection) url.openConnection();             

        //set cookie. sCookie is my static cookie string
        if(sCookie!=null && sCookie.length()>0){
            conn.setRequestProperty("Cookie", sCookie);                  
        }

        // Send data
        OutputStream os = conn.getOutputStream(); 
        os.write(mData.getBytes());
        os.flush();
        os.close(); 

        // Get the response!
        int httpResponseCode = conn.getResponseCode();         
        if (httpResponseCode != HttpURLConnection.HTTP_OK){
           throw new Exception("HTTP response code: "+httpResponseCode); 
        }

        // Get the data and pass them to the XML parser
        InputStream inputStream = conn.getInputStream();                
        Xml.parse(inputStream, Xml.Encoding.UTF_8, mSaxHandler);                
        inputStream.close();

        //Get the cookie
        String cookie = conn.getHeaderField("set-cookie");
        if(cookie!=null && cookie.length()>0){
            sCookie = cookie;              
        }

        /*   many cookies handling:                  
        String responseHeaderName = null;
        for (int i=1; (responseHeaderName = conn.getHeaderFieldKey(i))!=null; i++) {
            if (responseHeaderName.equals("Set-Cookie")) {                  
            String cookie = conn.getHeaderField(i);   
            }
        }*/                

        conn.disconnect();                

0
完全透明的方式在Android应用程序中保持会话活动(用户已登录等)。它在单例内使用apache DefaultHttpClient和HttpRequest / Response Interceptors。
SessionKeeper类只是检查其中一个标题是否为Set-Cookie,如果是,则简单地记住它。 SessionAdder仅在请求中添加会话ID(如果不为空)。 这样,整个身份验证过程都是完全透明的。
public class HTTPClients {

    private static DefaultHttpClient _defaultClient;
    private static String session_id;
    private static HTTPClients _me;
    private HTTPClients() {

    }
    public static DefaultHttpClient getDefaultHttpClient(){
        if ( _defaultClient == null ) {
            _defaultClient = new DefaultHttpClient();
            _me = new HTTPClients();
            _defaultClient.addResponseInterceptor(_me.new SessionKeeper());
            _defaultClient.addRequestInterceptor(_me.new SessionAdder());
        }
        return _defaultClient;
    }

    private class SessionAdder implements HttpRequestInterceptor {

        @Override
        public void process(HttpRequest request, HttpContext context)
                throws HttpException, IOException {
            if ( session_id != null ) {
                request.setHeader("Cookie", session_id);
            }
        }

    }

    private class SessionKeeper implements HttpResponseInterceptor {

        @Override
        public void process(HttpResponse response, HttpContext context)
                throws HttpException, IOException {
            Header[] headers = response.getHeaders("Set-Cookie");
            if ( headers != null && headers.length == 1 ){
                session_id = headers[0].getValue();
            }
        }

    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接