有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何在使用HTTPUrlConnection时持久化cookie?

我已经开始使用推荐的HTTPUrlConnection,并离开了DefaultHTTPClient。其中一件我还不能粘合在一起的事情是使用持久的cookie存储。我只想在我的连接上附加一个自定义cookie处理程序/管理器来存储cookie。Android文档并没有太大的帮助,因为它将关于cookies的主题概括为两行

我之前一直在使用LoopJ的PersistentCookieStore,效果很好

你知道我如何在安卓系统中建立一个持久的cookie存储库,并将其连接到我的HTTPUrlConnection上,自动保存和检索cookie吗

谢谢


共 (4) 个答案

  1. # 1 楼答案

    这花了我几个小时,但我自己设法建立了一个定制的cookie存储

    您必须通过以下方式连接:

    public class application extends Application {
        @Override
        public void onCreate() {
            super.onCreate();
           CookieManager cmrCookieMan = new CookieManager(new MyCookieStore(this.objContext), CookiePolicy.ACCEPT_ALL);
           CookieHandler.setDefault(cmrCookieMan);
           }
        }
    

    以下是实际存储空间:

    /*
     * 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.
     */
    class MyCookieStore implements CookieStore {
    
        /*
         * The memory storage of the cookies
         */
        private Map<URI, List<HttpCookie>> mapCookies = new HashMap<URI, List<HttpCookie>>();
        /*
         * The instance of the shared preferences
         */
        private final SharedPreferences spePreferences;
    
        /*
         * @see java.net.CookieStore#add(java.net.URI, java.net.HttpCookie)
         */
        public void add(URI uri, HttpCookie cookie) {
    
            System.out.println("add");
            System.out.println(cookie.toString());
    
            List<HttpCookie> cookies = mapCookies.get(uri);
            if (cookies == null) {
                cookies = new ArrayList<HttpCookie>();
                mapCookies.put(uri, cookies);
            }
            cookies.add(cookie);
    
            Editor ediWriter = spePreferences.edit();
            HashSet<String> setCookies = new HashSet<String>();
            setCookies.add(cookie.toString());
            ediWriter.putStringSet(uri.toString(), spePreferences.getStringSet(uri.toString(), setCookies));
            ediWriter.commit();
    
        }
    
       /*
        * Constructor
        * 
        * @param  ctxContext the context of the Activity
        */
        @SuppressWarnings("unchecked")
        public MyCookieStore(Context ctxContext) {
    
            spePreferences = ctxContext.getSharedPreferences("CookiePrefsFile", 0);
            Map<String, ?> prefsMap = spePreferences.getAll();
    
            for(Map.Entry<String, ?> entry : prefsMap.entrySet()) {
    
                for (String strCookie : (HashSet<String>) entry.getValue()) {
    
                    if (!mapCookies.containsKey(entry.getKey())) {
    
                        List<HttpCookie> lstCookies = new ArrayList<HttpCookie>();
                        lstCookies.addAll(HttpCookie.parse(strCookie));
    
                        try {
    
                            mapCookies.put(new URI(entry.getKey()), lstCookies);
    
                        } catch (URISyntaxException e) {
    
                            e.printStackTrace();
    
                        }
    
                    } else {
    
                        List<HttpCookie> lstCookies = mapCookies.get(entry.getKey());
                        lstCookies.addAll(HttpCookie.parse(strCookie));
    
                        try {
    
                            mapCookies.put(new URI(entry.getKey()), lstCookies);
    
                        } catch (URISyntaxException e) {
    
                            e.printStackTrace();
    
                        }
    
                    }
    
                    System.out.println(entry.getKey() + ": " + strCookie);
    
                }
    
            }
    
        }
    
        /*
         * @see java.net.CookieStore#get(java.net.URI)
         */
        public List<HttpCookie> get(URI uri) {
    
            List<HttpCookie> lstCookies = mapCookies.get(uri);
    
            if (lstCookies == null)
                mapCookies.put(uri, new ArrayList<HttpCookie>());
    
            return mapCookies.get(uri);
    
        }
    
        /*
         * @see java.net.CookieStore#removeAll()
         */
        public boolean removeAll() {
    
            mapCookies.clear();
            return true;
    
        }        
    
        /*
         * @see java.net.CookieStore#getCookies()
         */
        public List<HttpCookie> getCookies() {
    
            Collection<List<HttpCookie>> values = mapCookies.values();
    
            List<HttpCookie> result = new ArrayList<HttpCookie>();
            for (List<HttpCookie> value : values) {                
                result.addAll(value);                
            }
    
            return result;
    
        }
    
        /*
         * @see java.net.CookieStore#getURIs()
         */
        public List<URI> getURIs() {
    
            Set<URI> keys = mapCookies.keySet();
            return new ArrayList<URI>(keys);
    
        }
    
        /*
         * @see java.net.CookieStore#remove(java.net.URI, java.net.HttpCookie)
         */
        public boolean remove(URI uri, HttpCookie cookie) {
    
            List<HttpCookie> lstCookies = mapCookies.get(uri);
    
            if (lstCookies == null)
                return false;
    
            return lstCookies.remove(cookie);
    
        }
    
    }
    
  2. # 2 楼答案

    在许多自定义CookieStore实现中存在一些基本问题

    第一个问题是将HttpCookie序列化为字符串-因为HttpCookie.toString()方法的结果不适用于HttpCookie.parse(String header)方法,所以HttpCookie.toString()方法对此是不可接受的

    第二个问题:大多数CookieStore实现(例如,here)没有考虑HttpCookie.maxAge字段的格式。这是cookie live的秒数。但如果你只是坚持它的价值,过一段时间再取消它,那就错了。必须将maxAge字段转换为类似"expire_at"的内容,并将其持久化,而不是maxAge

  3. # 3 楼答案

    在下面的链接中签出实现。它通过主机名保存cookie,就像原始java一样。网InMemoryCookieStore的实现确实如此

    此外,它还包含SerializableHttpCookie,以便能够将完整的HashMap序列化到SharedReferences中

    https://gist.github.com/jacobtabak/78e226673d5a6a4c4367

  4. # 4 楼答案

    我使用了上面的答案,但将add方法更改为以下方法,以处理来自同一URI的多个cookie(出于某种原因,这个带有GAE的cookie存储区将会话令牌和记住令牌视为来自同一URI的两个单独cookie):

    public void add(URI uri, HttpCookie cookie) {
    
    
        List<HttpCookie> cookies = mapCookies.get(uri);
        if (cookies == null) {
            cookies = new ArrayList<HttpCookie>();
            mapCookies.put(uri, cookies);
        }
        cookies.add(cookie);
    
        Editor ediWriter = spePreferences.edit();
        HashSet<String> setCookies = new HashSet<String>();
        setCookies.add(cookie.toString());
        HashSet<String> emptyCookieSet = new HashSet<String>();
        if(spePreferences.contains(uri.toString())){
            emptyCookieSet = (HashSet<String>) spePreferences.getStringSet(uri.toString(), emptyCookieSet);
            if(!emptyCookieSet.isEmpty()){
                if(!emptyCookieSet.contains(cookie.toString())){
                emptyCookieSet.add(cookie.toString());
                ediWriter.putStringSet(uri.toString(), emptyCookieSet);
                }
            }
        }
        else{
            ediWriter.putStringSet(uri.toString(), setCookies);
        }
        ediWriter.commit();
    } 
    

    以及访问和创建组合cookie:

    MyCookieStore store = new MyCookieStore(this.context, false);
    String cookie = TextUtils.join(",", store.get(new URI(URLString)));
    

    连接到连接:

    URL urlToRequest = new URL(stringPath);
    HttpURLConnection urlConnection = (HttpURLConnection) urlToRequest.openConnection();
    urlConnection.setRequestProperty("Cookie", cookie);