android cookie持久化

    xiaoxiao2026-03-15  4

    原博客地址:http://blog.csdn.net/shimiso/article/details/39033353

    在解析网页信息的时候,需要登录后才能访问,所以使用httpclient模拟登录,然后把cookie保存下来,以供下一次访问使用,这时就需要持久化cookie中的内容。

    在之前先科普一下基础知识:

    什么是Cookies?

    Cookies是一些小文件,它们被创建在客户端的系统里,或者被创建在客户端浏览器的内存中(如果是临时性的话)。用它可以实现状态管理的功能。我们可以存储一些少量信息到可以短的系统上,以便在需要的时候使用。最有趣的事情是,它是对用户透明的。在你的web应用程序中,你可以到处使用它,它极其得简单。Cookies是以文本形式存储的。如果一个web应用程序使用cookies,那么服务器负责发送cookies,客户端浏览器将存储它。浏览器在下次请求页面的时候,会返回cookies给服务器。最常用的例子是,使用一个cookie来存储用户信息,用户的喜好,“记住密码”操作等。Cookies有许多优点,当然也有许多缺点。我将在接下来讲述。

    Cookies是如何创建的?

    当一个客户端向服务器发出请求,服务器发送cookies给客户端。而相同的cookies可以被后续的请求使用。例如,如果codeproject.com将Session ID作为cookies存储。当一个客户端首次向web服务器请求页面,服务器生成Session ID,并将其作为cookies发送往客户端。

    现在,所有来自相同客户端的后续请求,它将使用来自cookies的Session ID,就像下面这幅图片展示的那样。

    浏览器和web服务器以交换cookies信息来作为响应。对不同的站点,浏览器会维护不同的cookies。如果一个页面需要cookies中的信息,当某个URL被“点击”,首先浏览器将搜索本地系统的cookies的信息,然后才转向服务器来获得信息。

    Cookies的优势

    下面是使用cookies的主要优势:

    (1)    实现和使用都是非常简单的

    (2)    由浏览器来负责维护发送过来的数据(cookies内容)

    (3)    对来自多个站点的cookies来讲,浏览器自动管理它们

    Cookies的劣势

    下面是cookies的主要劣势:

    (1)    它以简单的文本格式来存储数据,所以它一点也不安全

    (2)    对于cookies数据,有大小限制(4kB)

    (3)    Cookies最大数目也有限制。主流浏览器提供将cookies的个数限制在20条。如果新cookies到来,那么老的将被删除。有些浏览器能支持到300条的cookies数。

    (4)    我们需要配置浏览器,cookies将不能工作在浏览器配置的高安全级别环境下。

    什么是持久化的和非持久化的Cookies

    我们可以将cookies分成两类:

    (1)    持久化的cookies

    (2)    非持久化的cookies

    持久化的cookies:这可以被称为永久性的cookies,它被存储在客户端的硬盘内,直到它们失效。持久化的cookies应该被设置一个失效时间。有时,它们会一直存在直到用户删除它们。持久化的cookies通常被用来为某个系统收集一个用户的标识信息。

    非持久化cookies:也可以被称之为临时性的cookies。如果没有定义失效时间,那么cookie将会被存储在浏览器的内存中。我上面展示的例子就是一个非持久的cookies。

    修改一个持久化的cookies与一个非持久化的cookies并没有什么不同。它们唯一的区别是——持久化的cookies有一个失效时间的设置。

    Cookie持久化

    HttpClient可以和任意物理表示的实现了CookieStore接口的持久化cookie存储一起使用。默认的CookieStore实现称为BasicClientCookie,这是凭借java.util.ArrayList的一个简单实现。在BasicClientCookie对象中存储的cookie当容器对象被垃圾回收机制回收时会丢失。如果需要,用户可以提供更复杂的实现。

    下载着重介绍在安卓中如何利用httpclient来实现对cookie的持久化操作:

    一、请求网络获取cookie

    先看一下下面的代码:

    [java]  view plain copy DefaultHttpClient httpclient = new DefaultHttpClient();   HttpGet httpget = new HttpGet("http://www.hlovey.com");   HttpResponse response = httpclient.execute(httpget);   HttpEntity entity = response.getEntity();   List<Cookie> cookies = httpclient.getCookieStore().getCookies();   Post模拟登录

    [java]  view plain copy HttpPost httpPost = new HttpPost(url);   List<NameValuePair> formparams = new ArrayList<NameValuePair>();   formparams.add(new BasicNameValuePair("id", userid));   formparams.add(new BasicNameValuePair("passwd", passwd));   UrlEncodedFormEntity entity;   try {       entity = new UrlEncodedFormEntity(formparams, mobileSMTHEncoding);   catch (UnsupportedEncodingException e1) {       return 3;   }   httpPost.setEntity(entity);   httpPost.setHeader("User-Agent", userAgent);   HttpResponse response = httpClient.execute(httpPost);   二、保存cookie

    保存cookie有两种方式一种是数据库,另一种是SharedPreferences,其中http://blog.csdn.net/junjieking/article/details/7658551是使用数据库来保存的,这里我是使用SharedPreferences保存。

    [java]  view plain copy     package com.smthbest.smth.util;          import java.util.Locale;       import android.content.Context;       import android.content.SharedPreferences;       import android.text.TextUtils;       import android.util.Log;          import org.apache.http.client.CookieStore;       import org.apache.http.cookie.Cookie;          import java.io.ByteArrayInputStream;       import java.io.ByteArrayOutputStream;       import java.io.ObjectInputStream;       import java.io.ObjectOutputStream;       import java.util.ArrayList;       import java.util.Date;       import java.util.List;       import java.util.Locale;       import java.util.concurrent.ConcurrentHashMap;      ic class PersistentCookieStore implements CookieStore {   private static final String LOG_TAG = "PersistentCookieStore";   private static final String COOKIE_PREFS = "CookiePrefsFile";   private static final String COOKIE_NAME_STORE = "names";   private static final String COOKIE_NAME_PREFIX = "cookie_";   private boolean omitNonPersistentCookies = false;      private final ConcurrentHashMap<String, Cookie> cookies;   private final SharedPreferences cookiePrefs;      /**   * Construct a persistent cookie store.   *   * @param context Context to attach cookie store to   */   public PersistentCookieStore(Context context) {       cookiePrefs = context.getSharedPreferences(COOKIE_PREFS, 0);       cookies = new ConcurrentHashMap<String, Cookie>();          // Load any previously stored cookies into the store       String storedCookieNames = cookiePrefs.getString(COOKIE_NAME_STORE, null);       if (storedCookieNames != null) {           String[] cookieNames = TextUtils.split(storedCookieNames, ",");           for (String name : cookieNames) {               String encodedCookie = cookiePrefs.getString(COOKIE_NAME_PREFIX + name, null);               if (encodedCookie != null) {                   Cookie decodedCookie = decodeCookie(encodedCookie);                   if (decodedCookie != null) {                       cookies.put(name, decodedCookie);                   }               }           }              // Clear out expired cookies           clearExpired(new Date());       }   }      @Override   public void addCookie(Cookie cookie) {       if (omitNonPersistentCookies && !cookie.isPersistent())           return;       String name = cookie.getName() + cookie.getDomain();          // Save cookie into local store, or remove if expired       if (!cookie.isExpired(new Date())) {           cookies.put(name, cookie);       } else {           cookies.remove(name);       }          // Save cookie into persistent store       SharedPreferences.Editor prefsWriter = cookiePrefs.edit();       prefsWriter.putString(COOKIE_NAME_STORE, TextUtils.join(",", cookies.keySet()));       prefsWriter.putString(COOKIE_NAME_PREFIX + name, encodeCookie(new SerializableCookie(cookie)));       prefsWriter.commit();   }      @Override   public void clear() {       // Clear cookies from persistent store       SharedPreferences.Editor prefsWriter = cookiePrefs.edit();       for (String name : cookies.keySet()) {           prefsWriter.remove(COOKIE_NAME_PREFIX + name);       }       prefsWriter.remove(COOKIE_NAME_STORE);       prefsWriter.commit();          // Clear cookies from local store       cookies.clear();   }      @Override   public boolean clearExpired(Date date) {       boolean clearedAny = false;       SharedPreferences.Editor prefsWriter = cookiePrefs.edit();          for (ConcurrentHashMap.Entry<String, Cookie> entry : cookies.entrySet()) {           String name = entry.getKey();           Cookie cookie = entry.getValue();           if (cookie.isExpired(date)) {               // Clear cookies from local store               cookies.remove(name);                  // Clear cookies from persistent store               prefsWriter.remove(COOKIE_NAME_PREFIX + name);                  // We've cleared at least one               clearedAny = true;           }       }          // Update names in persistent store       if (clearedAny) {           prefsWriter.putString(COOKIE_NAME_STORE, TextUtils.join(",", cookies.keySet()));       }       prefsWriter.commit();          return clearedAny;   }      @Override   public List<Cookie> getCookies() {       return new ArrayList<Cookie>(cookies.values());   }      /**   * Will make PersistentCookieStore instance ignore Cookies, which are non-persistent by   * signature (`Cookie.isPersistent`)   *   * @param omitNonPersistentCookies true if non-persistent cookies should be omited   */   public void setOmitNonPersistentCookies(boolean omitNonPersistentCookies) {       this.omitNonPersistentCookies = omitNonPersistentCookies;   }      /**   * Non-standard helper method, to delete cookie   *   * @param cookie cookie to be removed   */   public void deleteCookie(Cookie cookie) {       String name = cookie.getName();       cookies.remove(name);       SharedPreferences.Editor prefsWriter = cookiePrefs.edit();       prefsWriter.remove(COOKIE_NAME_PREFIX + name);       prefsWriter.commit();   }      /**   * Serializes Cookie object into String   *   * @param cookie cookie to be encoded, can be null   * @return cookie encoded as String   */   protected String encodeCookie(SerializableCookie cookie) {       if (cookie == null)           return null;       ByteArrayOutputStream os = new ByteArrayOutputStream();       try {           ObjectOutputStream outputStream = new ObjectOutputStream(os);           outputStream.writeObject(cookie);       } catch (Exception e) {           return null;       }          return byteArrayToHexString(os.toByteArray());   }      /**   * Returns cookie decoded from cookie string   *   * @param cookieString string of cookie as returned from http request   * @return decoded cookie or null if exception occured   */   protected Cookie decodeCookie(String cookieString) {       byte[] bytes = hexStringToByteArray(cookieString);       ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);       Cookie cookie = null;       try {           ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);           cookie = ((SerializableCookie) objectInputStream.readObject()).getCookie();       } catch (Exception exception) {           Log.d(LOG_TAG, "decodeCookie failed", exception);       }          return cookie;   }      /**   * Using some super basic byte array <-> hex conversions so we don't have to rely on any   * large Base64 libraries. Can be overridden if you like!   *   * @param bytes byte array to be converted   * @return string containing hex values   */   protected String byteArrayToHexString(byte[] bytes) {       StringBuilder sb = new StringBuilder(bytes.length * 2);       for (byte element : bytes) {           int v = element & 0xff;           if (v < 16) {               sb.append('0');           }           sb.append(Integer.toHexString(v));       }       return sb.toString().toUpperCase(Locale.US);   }      /**   * Converts hex values from strings to byte arra   *   * @param hexString string of hex-encoded values   * @return decoded byte array   */   protected byte[] hexStringToByteArray(String hexString) {       int len = hexString.length();       byte[] data = new byte[len / 2];       for (int i = 0; i < len; i += 2) {           data[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4) + Character.digit(hexString.charAt(i + 1), 16));       }       return data;   }   使用PersistentCookieStore来存储cookie,首先最好把 PersistentCookieStore放在Application获取其他的地方,取得唯一实例,保存cookie是在登录成功后,从下面代码获取保存。 [java]  view plain copy PersistentCookieStore myCookieStore = App.getInstance().getPersistentCookieStore();   List<Cookie> cookies = httpClient.getCookieStore().getCookies();   for (Cookie cookie:cookies){       myCookieStore.addCookie(cookie);   }   三、cookie的使用 [java]  view plain copy PersistentCookieStore cookieStore = new PersistentCookieStore(SmthBestApp.getInstance().getApplicationContext());   httpClient.setCookieStore(cookieStore);   HttpResponse response = httpClient.execute(httpget);   这样就可以免再次登录了。 相关资源:Android持久化保存cookie的方法
    最新回复(0)