安卓:使用cookie时发出HTTP调用坚持服务器会话 [英] Android: Persisting Server Session using cookie When Making HTTP calls

查看:126
本文介绍了安卓:使用cookie时发出HTTP调用坚持服务器会话的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

服务器侧会话存储在数据库和使用cookie保持。因此,每个客户端必须配备有效的cookie数据库匹配的会话。

Server side sessions are stored in database and maintained using cookies. So, every client must come with a valid cookie matching a session in the database.

和Android上侧:

and on Android side:

DefaultHttpClient client = new DefaultHttpClient();
HttpPost httppost = new HttpPost(url);
HttpResponse response = client.execute(httppost);

如果我使用的是同一个客户端的所有服务器调用,客户端需要这些cookie的照顾。

If I am using the same client for all the server calls, the client takes care of these cookies.

但问题是,因为所需的设备内存,当客户端被破坏,cookie丢失和任何后续的服务器调用是行不通的。

But the problem is, when the client is destroyed, because of memory needed by the device, the cookies are lost and any subsequent server calls doesn't work.

有没有办法让的HttpClient 执着?或者有什么是平常的方法来保持在Android端Cookie。

Is there a way to make the HttpClient persistent? Or what is the usual way to maintain cookies on android side.

推荐答案

这样做的正确的方法是实现的CookieHandler:的 http://developer.android.com/reference/java/net/CookieHandler.html

The "correct" way of doing this is to implement a CookieHandler: http://developer.android.com/reference/java/net/CookieHandler.html

这样做的最基本的方法是扩大应用,并把这个应用程序的onCreate():

The most basic way of doing this is to extend Application and put this in your applications onCreate():

CookieHandler.setDefault(new CookieManager());

请注意:这将只实现一个默认的CookieManger。默认CookieManger将您的应用程序的特定会话过程中管理Cookie的所有HTTP请求。然而,它不具有持续饼干在应用程序的后续使用的任何手段。

PLEASE NOTE: This will only implement a DEFAULT CookieManger. The default CookieManger will manage cookies for all of your HTTP requests during a specific session of your application. However, it does not have any means of persisting cookies over subsequent uses of the application.

为了做到这一点,你需要通过实施CookieStore的编写自己的cookie管理器: http://developer.android.com/reference/java/net/CookieStore.html

In order to do that, you'll need to write your own cookie manager by implementing CookieStore: http://developer.android.com/reference/java/net/CookieStore.html

下面是一个的CookieStore实现我用在一个应用程序,目前在谷歌Play商店的例子:

Here's an example of a CookieStore implementation i used in an app that is currently in the Google Play store:

package com.touchvision.util;

import java.net.CookieStore;
import java.net.HttpCookie;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.util.Log;

import com.touchvision.Config;

/*
 * This is a custom cookie storage for the application. This
 * will store all the cookies to the shared preferences so that it persists
 * across application restarts.
 */
public class TvCookieStore implements CookieStore {

    private static final String LOGTAG = "TV-TvCookieStore";

    /*
     * The memory storage of the cookies
     */
    private Map<String, Map<String,String>> mapCookies = new HashMap<String, Map<String,String>>();
    /*
     * The instance of the shared preferences
     */
    private final SharedPreferences sharedPrefs;

    /*
     * @see java.net.CookieStore#add(java.net.URI, java.net.HttpCookie)
     */
    public void add(URI uri, HttpCookie cookie) {

        String domain = cookie.getDomain();     

        // Log.i(LOGTAG, "adding ( " + domain +", " + cookie.toString() );

        Map<String,String> cookies = mapCookies.get(domain);
        if (cookies == null) {
            cookies = new HashMap<String, String>(); 
            mapCookies.put(domain, cookies);
        }
        cookies.put(cookie.getName(), cookie.getValue());

        if (cookie.getName().startsWith("SPRING_SECURITY") && !cookie.getValue().equals("")){
           //  Log.i(LOGTAG, "Saving rememberMeCookie = " + cookie.getValue() );            
            // Update in Shared Preferences
            Editor e = sharedPrefs.edit();       
            e.putString(Config.PREF_SPRING_SECURITY_COOKIE, cookie.toString());       
            e.commit(); // save changes 
        }

    }

   /*
    * Constructor
    * 
    * @param  ctxContext the context of the Activity
    */
    public TvCookieStore(Context ctxContext) {

        // Log.i(LOGTAG, "constructor()");

        sharedPrefs = ctxContext.getSharedPreferences(Config.SHARED_PREF_NAME, Context.MODE_PRIVATE);
    }

    /*
     * @see java.net.CookieStore#get(java.net.URI)
     */
    public List<HttpCookie> get(URI uri) {

        List<HttpCookie> cookieList = new ArrayList<HttpCookie>();

        String domain = uri.getHost(); 

        // Log.i(LOGTAG, "getting ( " + domain +" )" );

        Map<String,String> cookies = mapCookies.get(domain);
        if (cookies == null) {
               cookies = new HashMap<String, String>(); 
               mapCookies.put(domain, cookies);
        }  

        for (Map.Entry<String, String> entry : cookies.entrySet()) {
            cookieList.add(new HttpCookie(entry.getKey(), entry.getValue()));
            // Log.i(LOGTAG, "returning cookie: " + entry.getKey() + "="+ entry.getValue());
        }
        return cookieList; 

    }

    /*
     * @see java.net.CookieStore#removeAll()
     */
    public boolean removeAll() {

        // Log.i(LOGTAG, "removeAll()" );

        mapCookies.clear();
        return true;

    }        

    /*
     * @see java.net.CookieStore#getCookies()
     */
    public List<HttpCookie> getCookies() {

        Log.i(LOGTAG, "getCookies()" );

        Set<String> mapKeys = mapCookies.keySet();

        List<HttpCookie> result = new ArrayList<HttpCookie>();
        for (String key : mapKeys) {
            Map<String,String> cookies =    mapCookies.get(key);
            for (Map.Entry<String, String> entry : cookies.entrySet()) {
                result.add(new HttpCookie(entry.getKey(), entry.getValue()));
                Log.i(LOGTAG, "returning cookie: " + entry.getKey() + "="+ entry.getValue());
            }             
        }

        return result;

    }

    /*
     * @see java.net.CookieStore#getURIs()
     */
    public List<URI> getURIs() {

        Log.i(LOGTAG, "getURIs()" );

        Set<String> keys = mapCookies.keySet();
        List<URI> uris = new ArrayList<URI>(keys.size());
        for (String key : keys){
            URI uri = null;
            try {
                uri = new URI(key);
            } catch (URISyntaxException e) {
                e.printStackTrace();
            }
            uris.add(uri);
        }
        return uris;

    }

    /*
     * @see java.net.CookieStore#remove(java.net.URI, java.net.HttpCookie)
     */
    public boolean remove(URI uri, HttpCookie cookie) {

        String domain = cookie.getDomain();     

        Log.i(LOGTAG, "remove( " + domain +", " + cookie.toString() );

        Map<String,String> lstCookies = mapCookies.get(domain);

        if (lstCookies == null)
            return false;

        return lstCookies.remove(cookie.getName()) != null;

    }

}

以上的自定义的CookieStore使用共享preferences坚持饼干。您可以实现上面的类的相似,你将如何实现你的应用程序类的默认CookieManager,但该行是这样的:

The above custom CookieStore uses SharedPreferences to persist cookies. You implement the above class the similar to how you would implement the default CookieManager in your application class, but the line would look like this:

CookieHandler.setDefault( new CookieManager( new TvCookieStore(this), CookiePolicy.ACCEPT_ALL));

正如你所看到的,唯一的Cookie我真正关心的持续存在是春季安全Cookie(我们正在使用Spring框架在服务器端)。您的code显然是不同的考虑您的特定需求。

As you can see, the only Cookie i really cared about persisting was the Spring Security Cookie (we were using Spring Framework on the server side). Your code will obviously be different to account for your specific needs.

另一个要点:我试过无数次这样做,你在做什么和处理cookie的持久性在我的HTTP客户端类。这无非是头痛。给这个战略的一个镜头。

Another quick note: I tried countless times to do what you're doing and handle the persistence of cookies within my http client class. It was nothing but headaches. Give this strategy a shot.

这篇关于安卓:使用cookie时发出HTTP调用坚持服务器会话的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆