如何管理安卓中的Cookie


     Cookie管理是大家在做安卓app開發中難以避免的問題。我在此發表一些關於Cookie管理的拙見。

  Cookie是什么

  Cookie最重要的作用是會話識別(SeesionId)和狀態長期保持(在瀏覽器保存需要長期保持的數據)。

  注意,這些工作並不是必須通過Cookie進行,也可以約定提交數據格式和提交數據格式,固定其中附加數據字段來替代Cookie。但是不推薦這么做,因為如果涉及到與WebView交互,就需要把Json中得數據轉化成Cookie,會增加不必要的工作量和犯錯的幾率。而且HttpClient提供了這個工具,很完善,為什么不用呢。

  Cookie在安卓中的使用方式--標示會話,附加信息

    1.通過Session標示一次會話,舉個例子:注冊時,判斷客戶端注冊錯誤次數(注冊次數已經超過限制,顯示驗證碼)

    2.傳遞附加數據,舉個例子:傳遞單點登陸的token。

     Cookie可能存放的位置--CookieStore,CookieManager

    1.Httpclient會存儲當次請求的cookie內容,存儲位置在 httpClient.getCookieStore 但是Apache建議自定義Cookie存儲方式,因為Cookiestore默認把Cookie放在Arraylist里很容易被系統回收,參見[1]。

    2.WebView會存儲Cookie在CookieManager,具體使用方式,后續的文章會講這里不是重點。

  如何保存Cookie--中間變量,SharedPreference

  通常HttpClient中得Cookie不能直接與WebView中得Cookie共享,而且HttpClient中的Cookie需要進一步修改才能給WebView用,所以這里需要一個中間變量(這里叫做CookieMap)來管理Cookie。每次請求的時候都要刷新CookieMap,我推薦的Cookie管理方式是只增加、修改不刪除。每次請求完成都要進行一次Cookie同步,如果app要求保持登陸狀態的需求,也可以把cookie放入Preference。代碼如下:

        List<Cookie> cookieList = httpClient.getCookieStore().getCookies();
        if (context == null || cookieList == null || cookieList.size() == 0) {
            return;
        }

        SharedPreferences preferences = context.getSharedPreferences(Constant.HTTPHEAD, Context.MODE_PRIVATE);
        Editor edit = preferences.edit();

        for (Cookie cookie : cookieList) {
            edit.putString(cookie.getName(), cookie.getValue());
            httpCookiesMap.put(cookie.getName(), cookie);
        }

        edit.commit();

  請求前處理Cookie

  HttpClient

   將Cookie放入CookieStore中

    httpClient.getCookieStore().addCookie(cookie)

  或者在Request的Header中Setcookie   

  注意,如果進行此操作,就不要保留httpclient中的Cookie,否則容易造成給服務器提交的Request的Header中包含兩個Cookie的情況,會造成有的服務器混亂比如我們的Ngix。

        // 由於自行處理cookie所以要清理client管理的cookie否則容易出現兩個cookie頭的情況
        httpClient.getCookieStore().clear();
        String strHeader =getCookiesForHttpHeader(context);
        request.setHeader(Constant.COOKIE, strHeader);
        HttpResponse response = httpClient.execute(request);  

   WebView

  如果Api和Webview所請求的頁面在不同於(正常也不會在同一個域),那么就要求重新設置Cookie的域(Domain)和Path,這里鼓勵把Path范圍設置的大一些否則有些請求比如(Ajax,Jsonp)可能得不到Cookie。

    cookieManager.setCookie(url, key + "=" + cookie.getValue() + ";domain=" + "xxxx.com"+";path=/");

  清理Cookie

  如果使用cookie來判斷是否登錄的話,則只清理本地CookieMap和SharedPreference中的Cookie是不夠的。還需要清理掉WebView中的對應的Cookie和HttpClient中的Cookie。否則下次登陸依然是登陸狀態。

        // 清理內存cookie
        httpCookiesMap.clear();
        // 清理httpclientcookie
        httpClient.getCookieStore().clear();
        // 清理掉WebViewCookie
        CookieManager.getInstance().removeAllCookie();
        CookieSyncManager.getInstance().sync();
        // 清理preferencecookie相關的項目
        SharedPreferences preferences = context.getSharedPreferences(Constant.HTTPHEAD, Context.MODE_PRIVATE);
        Editor editor = preferences.edit();
        editor.remove(Constant.ACCOUNT);
        editor.remove(Constant.NICKNAME);
        editor.remove(Constant.PHPSESSID);
        editor.commit();

  希望這篇文章對大家的工作有所幫助。

 [1].http://hc.apache.org/httpcomponents-client-ga/tutorial/html/statemgmt.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM