如何管理安卓中的Cookie

Android开发中怎样使用cookieManager来管理cookie - 博客频道 - CSDN.NET
七号公园的博客
每天进步一点
分类:android开发数据库SQLiteandroid的Http通讯html
在项目开发中遇到一个问题,就是在登录界面向服务器发送登录请求后,然后就跳到一个与用户订阅有关的界面,然后,我想服务器发送的是正确的Url,用Log打印出返回结果,但是只有一个html的元素信息。通过对这个html的元素信息发的分析,与后台同事分析发现,我的url没有cookie 信息。在登录界面向服务器发送的登录验证信息,但是服务器没有存储相应的用户信息,就导致我登录进去后向服务器索要用户相关信息时,服务器判断是一个新用户,就返回了一个登录界面hxml给我。所以就出现了开头那个问题,那么怎样才能解决这个问题呢,在网上查了很多资料,本人发现了一个简单易用的方法,那就是用cookieManager来管理cookie。下面就是使用步骤;
1、首先& 在android应用程序开始的activity中的oncreaty()方法中注册cookiemanager。如下:
//设置网络请求cookie
CookieSyncManager.createInstance(this);
2、然后在到网络请求的那个类中设置如下& 设置和获取cookie的方法
protected String getCookie() {
CookieManager cookieManager = CookieManager.getInstance();
String cookie = cookieManager.getCookie(&cookie&);
if (cookie != null) {
return &&;
protected void setCookie(String cookie) {
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.setCookie(&cookie&, cookie);
& 3、最后一步就在urlConnection.openConnectin()的后面设置如下方法:
uc = (HttpURLConnection) new URL(url + &?& + paramsStr.toString()).openConnection();
uc.setRequestProperty(&Cookie&, getCookie());setCookies(uc.getHeaderFields())
好了到这里就完成了cookie的设置
3. 过期按需处理一下
附1:cookie的获取
response.headerFields = conn.getHeaderFields();
setCookies(response.headerFields);
* 存储cookie
* @param headerFields
protected void setCookies(Map&String, List&String&& headerFields) {
if (null == headerFields) {
List&String& cookies = headerFields.get(COOKIES_KEY);
if (null == cookies) {
for (String cookie : cookies) {
setCookie(cookie);
oQiHaoGongYuan
排名:第12955名
(3)(2)(2)(1)(42)(4)(1)(14)(2)(14)(1)(1)(1)(2)(1)我在使用OkHttp访问某网站爬取公开数据时,因为要保持登录的状态才可以读取或提交数据(例如,登录后才可以使用POST方法提交某文章评论),所以查了很多关于持久化Cookie的资料,现在将经过验证的方法分享给大家。
持久化Cookie实际上是客户端访问某网站时,CookieManager将Cookie的各个信息通过SharedPreference方法写到本地,当下次访问网站时CookieManager会先去查找本地存储的Cookie,如果已经保存,那么读取这个Cookie信息,在访问该网站时提交。如果没有保存那么在第一次访问时就保存下来了。
这里主要用到 PersistenCookieStore.java 和 SerializableHttpCookie.java
两个文件。
其中PersistenCookieStore是用来持久化Cookie的主要类,这个类中保存了很多对Cookie持久化的操作。在参考关于持久化Cookie的文章时遇到了下面的一个问题,访问 后保存的是的cookie,当访问时,并不会将当做已访问过的网站,而是写一个新的cookie。也就是在PersistenCookieStore.java中,SharedPreference将url当做key,而不是将域名当做key,所以我做了一点改进,增加了getUrlDomain的方法,将域名作为key值保存。
PersistenCookieStore.java的代码如下:import android.annotation.TargetA
import android.content.C
import android.content.SharedP
import android.os.B
import android.text.TextU
import android.util.L
import java.io.ByteArrayInputS
import java.io.ByteArrayOutputS
import java.io.IOE
import java.io.ObjectInputS
import java.io.ObjectOutputS
import java.net.CookieS
import java.net.HttpC
import java.net.URI;
import java.net.URISyntaxE
import java.util.ArrayL
import java.util.HashM
import java.util.L
import java.util.L
import java.util.M
import java.util.concurrent.ConcurrentHashM
* Created by fengbo on .
@TargetApi(Build.VERSION_CODES.GINGERBREAD)
public class PersistentCookieStore implements CookieStore {
private static final String LOG_TAG = "PersistentCookieStore";
private static final String COOKIE_PREFS = "CookiePrefsFile";
private static final String COOKIE_NAME_PREFIX = "cookie_";
private final HashMap&String, ConcurrentHashMap&String, HttpCookie&&
private final SharedPreferences cookieP
* 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 HashMap&String, ConcurrentHashMap&String, HttpCookie&&();
// Load any previously stored cookies into the store
Map&String, ?& prefsMap = cookiePrefs.getAll();
for(Map.Entry&String, ?& entry : prefsMap.entrySet()) {
if (((String)entry.getValue()) != null && !((String)entry.getValue()).startsWith(COOKIE_NAME_PREFIX)) {
String[] cookieNames = TextUtils.split((String)entry.getValue(), ",");
for (String name : cookieNames) {
String encodedCookie = cookiePrefs.getString(COOKIE_NAME_PREFIX + name, null);
if (encodedCookie != null) {
HttpCookie decodedCookie = decodeCookie(encodedCookie);
if (decodedCookie != null) {
if(!cookies.containsKey(entry.getKey())) {
cookies.put(entry.getKey(), new ConcurrentHashMap&String, HttpCookie&());
cookies.get(entry.getKey()).put(name, decodedCookie);
public void add(URI uri, HttpCookie cookie) {
String name = getCookieToken(uri, cookie);
// Save cookie into local store, or remove if expired
if (!cookie.hasExpired()) {
if(!cookies.containsKey(getUrlDomain(uri)))
cookies.put(getUrlDomain(uri), new ConcurrentHashMap&String, HttpCookie&());
cookies.get(getUrlDomain(uri)).put(name, cookie);
if(cookies.containsKey(uri.toString()))
cookies.get(getUrlDomain(uri)).remove(name);
// Save cookie into persistent store
SharedPreferences.Editor prefsWriter = cookiePrefs.edit();
prefsWriter.putString(getUrlDomain(uri), TextUtils.join(",", cookies.get(getUrlDomain(uri)).keySet()));
prefsWriter.putString(COOKIE_NAME_PREFIX + name, encodeCookie(new SerializableHttpCookie(cookie)));
protected String getCookieToken(URI uri, HttpCookie cookie) {
return cookie.getName() + cookie.getDomain();
protected String getUrlDomain(URI uri){
String host = uri.getHost();
String domain = host.substring(host.indexOf("."));
public List&HttpCookie& get(URI uri) {
ArrayList&HttpCookie& ret = new ArrayList&&();
if(cookies.containsKey(getUrlDomain(uri))) {
ret.addAll(cookies.get(getUrlDomain(uri)).values());
public boolean removeAll() {
SharedPreferences.Editor prefsWriter = cookiePrefs.edit();
prefsWriter.clear();
cookies.clear();
public boolean remove(URI uri, HttpCookie cookie) {
String name = getCookieToken(uri, cookie);
Log.e("bole", "persistent cookie store remove somecookie");
if(cookies.containsKey(getUrlDomain(uri)) && cookies.get(getUrlDomain(uri)).containsKey(name)) {
cookies.get(getUrlDomain(uri)).remove(name);
SharedPreferences.Editor prefsWriter = cookiePrefs.edit();
if(cookiePrefs.contains(COOKIE_NAME_PREFIX + name)) {
prefsWriter.remove(COOKIE_NAME_PREFIX + name);
prefsWriter.putString(getUrlDomain(uri), TextUtils.join(",", cookies.get(getUrlDomain(uri)).keySet()));
public List&HttpCookie& getCookies() {
ArrayList&HttpCookie& ret = new ArrayList&HttpCookie&();
for (String key : cookies.keySet()) {
ret.addAll(cookies.get(key).values());
public List&URI& getURIs() {
ArrayList&URI& ret = new ArrayList&URI&();
for (String key : cookies.keySet())
ret.add(new URI(key));
} catch (URISyntaxException e) {
e.printStackTrace();
* Serializes Cookie object into String
* @param cookie cookie to be encoded, can be null
* @return cookie encoded as String
protected String encodeCookie(SerializableHttpCookie cookie) {
if (cookie == null)
ByteArrayOutputStream os = new ByteArrayOutputStream();
ObjectOutputStream outputStream = new ObjectOutputStream(os);
outputStream.writeObject(cookie);
} catch (IOException e) {
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 HttpCookie decodeCookie(String cookieString) {
byte[] bytes = hexStringToByteArray(cookieString);
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
HttpCookie cookie =
ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
cookie = ((SerializableHttpCookie) objectInputStream.readObject()).getCookie();
} catch (IOException e) {
Log.d(LOG_TAG, "IOException in decodeCookie", e);
} catch (ClassNotFoundException e) {
Log.d(LOG_TAG, "ClassNotFoundException in decodeCookie", e);
* 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 & 0
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 & i += 2) {
data[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) && 4) + Character.digit(hexString.charAt(i + 1), 16));
SerializableHttpCookie.java主要用来序列化HttpCookie,使其能够持久化。
SerializableHttpCookie.java代码如下:import android.annotation.SuppressL
import android.util.L
import java.io.IOE
import java.io.ObjectInputS
import java.io.ObjectOutputS
import java.io.S
import java.net.HttpC
* Created by fengbo on .
public class SerializableHttpCookie implements Serializable {
private static final long serialVersionUID = 1L;
private transient final HttpC
private transient HttpCookie clientC
public SerializableHttpCookie(HttpCookie cookie) {
this.cookie =
@SuppressLint("NewApi")
public HttpCookie getCookie() {
HttpCookie bestCookie =
if (clientCookie != null) {
bestCookie = clientC
return bestC
@SuppressLint("NewApi")
private void writeObject(ObjectOutputStream out) throws IOException {
out.writeObject(cookie.getName());
out.writeObject(cookie.getValue());
out.writeObject(cookie.getComment());
out.writeObject(cookie.getCommentURL());
out.writeObject(cookie.getDomain());
out.writeLong(cookie.getMaxAge());
out.writeObject(cookie.getPath());
out.writeObject(cookie.getPortlist());
out.writeInt(cookie.getVersion());
out.writeBoolean(cookie.getSecure());
out.writeBoolean(cookie.getDiscard());
@SuppressLint("NewApi")
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
String name = (String) in.readObject();
String value = (String) in.readObject();
clientCookie = new HttpCookie(name, value);
clientCookie.setComment((String) in.readObject());
clientCookie.setCommentURL((String) in.readObject());
clientCookie.setDomain((String) in.readObject());
clientCookie.setMaxAge(in.readLong());
clientCookie.setPath((String) in.readObject());
clientCookie.setPortlist((String) in.readObject());
clientCookie.setVersion(in.readInt());
clientCookie.setSecure(in.readBoolean());
clientCookie.setDiscard(in.readBoolean());
}通过OkHttp使用时可以通过如下方法:OkHttpClient client = new OkHttpClient();
client.setCookieHandler(new CookieManager(new PersistentCookieStore(getApplicationContext()), CookiePolicy.ACCEPT_ALL));
Request request = new Request.Builder().url("Your Url").build();
Response response = client.newCall(request).execute();
if(response.isSuccessful()){
return Jsoup.parse(response.body().string());
} catch (IOException e) {
e.printStackTrace();
}这样,下次再通过OkHttp访问URL就会保持登录状态。参考:
如果您想留下此文,您可以将其发送至您的邮箱(将同时以邮件内容&PDF形式发送)
相关文章推荐
(Ctrl+Enter提交) &&
已有0人在此发表见解
&在& 17:11收藏到了
&&在信息爆炸的时代,您的知识需要整理,沉淀,积累!Lai18为您提供一个简单实用的文章整理收藏工具,在这里您可以收藏对您有用的技术文章,自由分门别类,在整理的过程中,用心梳理自己的知识!相信,用不了多久,您收藏整理的文章将是您一生的知识宝库!
· 蜀ICP备号-1Android OkHttp的Cookie自动化管理
中在使用OkHttp这个库的时候,有时候需要持久化Cookie,那么怎么实现呢。OkHttp的内部过于复杂,不进行深究,这里只看其中的HttpEngineer里面的部分源码,在发起请求以及请求结束都会调用这个类的几个方法。我们先看networkRequest方法,在里面通过client.getCookieHandler()函数获得了CookieHandler对象,通过该对象拿到cookie并设置到请求头里,请求结束后取得响应后通过networkResponse.headers()函数将请求头获得传入receiveHeaders函数,并将取得的cookie存入getCookieHandler得到的一个CookieHandler对象中去
This client doesn't specify a default {@code Accept} header because it
* doesn't know what content types the application is interested in.
private Request networkRequest(Request request) throws IOException {
Request.Builder result = request.newBuilder();
//此处省略n行代码......
CookieHandler cookieHandler = client.getCookieHandler();
if (cookieHandler != null) {
// Capture the request headers added so far so that they can be offered to the CookieHandler.
// This is mostly to stay close to the RI; it is unlikely any of the headers above would
// affect cookie choice besides Host.
Map& headers = OkHeaders.toMultimap(result.build().headers(), null);
Map& cookies = cookieHandler.get(request.uri(), headers);
// Add any new cookies to the request.
OkHeaders.addCookies(result, cookies);
//此处省略n行代码......
return result.build();
} data-snippet-id=ext.4df17b7859 data-snippet-saved=false data-csrftoken=bFkHGE1O-cy7WY9D6w70F6qK9YUKZHLynI5g data-codota-status=done&/**
* Populates request with defaults and cookies.
* This client doesn't specify a default {@code Accept} header because it
* doesn't know what content types the application is interested in.
private Request networkRequest(Request request) throws IOException {
Request.Builder result = request.newBuilder();
//此处省略n行代码......
CookieHandler cookieHandler = client.getCookieHandler();
if (cookieHandler != null) {
// Capture the request headers added so far so that they can be offered to the CookieHandler.
// This is mostly to stay close to the RI; it is unlikely any of the headers above would
// affect cookie choice besides Host.
Map& headers = OkHeaders.toMultimap(result.build().headers(), null);
Map& cookies = cookieHandler.get(request.uri(), headers);
// Add any new cookies to the request.
OkHeaders.addCookies(result, cookies);
//此处省略n行代码......
return result.build();
public void readResponse() throws IOException {
//此处省略n行代码......
receiveHeaders(networkResponse.headers());
//此处省略n行代码......
public void receiveHeaders(Headers headers) throws IOException {
CookieHandler cookieHandler = client.getCookieHandler();
if (cookieHandler != null) {
cookieHandler.put(userRequest.uri(), OkHeaders.toMultimap(headers, null));
而这个CookieHandler对象是OkHttpClient类中的一个属性,提供了getter和setter方法,默认的构造函数OkHttpClient client = new OkHttpClient();不会创建这个CookieHandler对象。假设我们传入了这个对象,那么OkHttp自然会进行cookie的自动管理了。
private CookieHandler cookieH
public OkHttpClient setCookieHandler(CookieHandler cookieHandler) {
this.cookieHandler = cookieH
public CookieHandler getCookieHandler() {
return cookieH
那么假设我们将CookieHandler对象传入
OkHttpClient client = new OkHttpClient();
client.setCookieHandler(CookieHandler cookieHanlder);
那么,现在关键是如何去实现这个CookieHandler 对象。CookieManager是CookieHandler 的一个子类,其构造函数 public CookieManager(CookieStore store, CookiePolicy cookiePolicy)需要传入两个参数,CookieStore 是一个接口,因此我们实现CookieStore接口中的抽象方法,即可实现这个CookieHandler 对象。参考android-async-http这个库,它具有cookie的自动管理功能,主要我们参考其中的两个类
PersistentCookieStore SerializableCookie
参考以上两个类并做适当修改,得到了如下两个类,他们的功能就是将cookie保持在SharedPreferences中。
package com.kltz88.okhttp.
* User:lizhangqu()
* Time: 17:31
import java.io.IOE
import java.io.ObjectInputS
import java.io.ObjectOutputS
import java.io.S
import java.net.HttpC
public class SerializableHttpCookie implements Serializable {
private static final long serialVersionUID = 2046732L;
private transient final HttpC
private transient HttpCookie clientC
public SerializableHttpCookie(HttpCookie cookie) {
this.cookie =
public HttpCookie getCookie() {
HttpCookie bestCookie =
if (clientCookie != null) {
bestCookie = clientC
return bestC
private void writeObject(ObjectOutputStream out) throws IOException {
out.writeObject(cookie.getName());
out.writeObject(cookie.getValue());
out.writeObject(cookie.getComment());
out.writeObject(cookie.getCommentURL());
out.writeObject(cookie.getDomain());
out.writeLong(cookie.getMaxAge());
out.writeObject(cookie.getPath());
out.writeObject(cookie.getPortlist());
out.writeInt(cookie.getVersion());
out.writeBoolean(cookie.getSecure());
out.writeBoolean(cookie.getDiscard());
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
String name = (String) in.readObject();
String value = (String) in.readObject();
clientCookie = new HttpCookie(name, value);
clientCookie.setComment((String) in.readObject());
clientCookie.setCommentURL((String) in.readObject());
clientCookie.setDomain((String) in.readObject());
clientCookie.setMaxAge(in.readLong());
clientCookie.setPath((String) in.readObject());
clientCookie.setPortlist((String) in.readObject());
clientCookie.setVersion(in.readInt());
clientCookie.setSecure(in.readBoolean());
clientCookie.setDiscard(in.readBoolean());
private final SharedPreferences cookieP
* 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 HashMap&();
// Load any previously stored cookies into the store
Map prefsMap = cookiePrefs.getAll();
for(Map.Entry entry : prefsMap.entrySet()) {
if (((String)entry.getValue()) != null && !((String)entry.getValue()).startsWith(COOKIE_NAME_PREFIX)) {
String[] cookieNames = TextUtils.split((String)entry.getValue(), ,);
for (String name : cookieNames) {
String encodedCookie = cookiePrefs.getString(COOKIE_NAME_PREFIX + name, null);
if (encodedCookie != null) {
HttpCookie decodedCookie = decodeCookie(encodedCookie);
if (decodedCookie != null) {
if(!cookies.containsKey(entry.getKey()))
cookies.put(entry.getKey(), new ConcurrentHashMap());
cookies.get(entry.getKey()).put(name, decodedCookie);
public void add(URI uri, HttpCookie cookie) {
String name = getCookieToken(uri, cookie);
// Save cookie into local store, or remove if expired
if (!cookie.hasExpired()) {
if(!cookies.containsKey(uri.getHost()))
cookies.put(uri.getHost(), new ConcurrentHashMap());
cookies.get(uri.getHost()).put(name, cookie);
if(cookies.containsKey(uri.toString()))
cookies.get(uri.getHost()).remove(name);
// Save cookie into persistent store
SharedPreferences.Editor prefsWriter = cookiePrefs.edit();
prefsWriter.putString(uri.getHost(), TextUtils.join(,, cookies.get(uri.getHost()).keySet()));
prefsWriter.putString(COOKIE_NAME_PREFIX + name, encodeCookie(new SerializableHttpCookie(cookie)));
protected String getCookieToken(URI uri, HttpCookie cookie) {
return cookie.getName() + cookie.getDomain();
public List get(URI uri) {
ArrayList ret = new ArrayList();
if(cookies.containsKey(uri.getHost()))
ret.addAll(cookies.get(uri.getHost()).values());
public boolean removeAll() {
SharedPreferences.Editor prefsWriter = cookiePrefs.edit();
prefsWriter.clear();
cookies.clear();
public boolean remove(URI uri, HttpCookie cookie) {
String name = getCookieToken(uri, cookie);
if(cookies.containsKey(uri.getHost()) && cookies.get(uri.getHost()).containsKey(name)) {
cookies.get(uri.getHost()).remove(name);
SharedPreferences.Editor prefsWriter = cookiePrefs.edit();
if(cookiePrefs.contains(COOKIE_NAME_PREFIX + name)) {
prefsWriter.remove(COOKIE_NAME_PREFIX + name);
prefsWriter.putString(uri.getHost(), TextUtils.join(,, cookies.get(uri.getHost()).keySet()));
public List getCookies() {
ArrayList ret = new ArrayList();
for (String key : cookies.keySet())
ret.addAll(cookies.get(key).values());
public List getURIs() {
ArrayList ret = new ArrayList();
for (String key : cookies.keySet())
ret.add(new URI(key));
} catch (URISyntaxException e) {
e.printStackTrace();
* Serializes Cookie object into String
* @param cookie cookie to be encoded, can be null
* @return cookie encoded as String
protected String encodeCookie(SerializableHttpCookie cookie) {
if (cookie == null)
ByteArrayOutputStream os = new ByteArrayOutputStream();
ObjectOutputStream outputStream = new ObjectOutputStream(os);
outputStream.writeObject(cookie);
} catch (IOException e) {
Log.d(LOG_TAG, IOException in encodeCookie, e);
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 HttpCookie decodeCookie(String cookieString) {
byte[] bytes = hexStringToByteArray(cookieString);
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
HttpCookie cookie =
ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
cookie = ((SerializableHttpCookie) objectInputStream.readObject()).getCookie();
} catch (IOException e) {
Log.d(LOG_TAG, IOException in decodeCookie, e);
} catch (ClassNotFoundException e) {
Log.d(LOG_TAG, ClassNotFoundException in decodeCookie, e);
* 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 & 0
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 & i += 2) {
data[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) && 4) + Character.digit(hexString.charAt(i + 1), 16));
} data-snippet-id=ext.8d16b4a8fcca2def684a77bb76fa9bc7 data-snippet-saved=false data-csrftoken=JJvR2MgM-MBb6XEHHuKsz9WziKXBKYfoLLYQ data-codota-status=done&package com.kltz88.okhttp.
* User:lizhangqu()
* Time: 17:31
import android.content.C
import android.content.SharedP
import android.text.TextU
import android.util.L
import java.io.*;
import java.net.CookieS
import java.net.HttpC
import java.net.URI;
import java.net.URISyntaxE
import java.util.*;
import java.util.concurrent.ConcurrentHashM
* A persistent cookie store which implements the Apache HttpClient CookieStore interface.
* Cookies are stored and will persist on the user's device between application sessions since they
* are serialized and stored in SharedPreferences. Instances of this class are
* designed to be used with AsyncHttpClient#setCookieStore, but can also be used with a
* regular old apache HttpClient/HttpContext if you prefer.
public class PersistentCookieStore implements CookieStore {
private static final String LOG_TAG = PersistentCookieS
private static final String COOKIE_PREFS = CookiePrefsF
private static final String COOKIE_NAME_PREFIX = cookie_;
private final HashMap&
private final SharedPreferences cookieP
* 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 HashMap&();
// Load any previously stored cookies into the store
Map prefsMap = cookiePrefs.getAll();
for(Map.Entry entry : prefsMap.entrySet()) {
if (((String)entry.getValue()) != null && !((String)entry.getValue()).startsWith(COOKIE_NAME_PREFIX)) {
String[] cookieNames = TextUtils.split((String)entry.getValue(), ,);
for (String name : cookieNames) {
String encodedCookie = cookiePrefs.getString(COOKIE_NAME_PREFIX + name, null);
if (encodedCookie != null) {
HttpCookie decodedCookie = decodeCookie(encodedCookie);
if (decodedCookie != null) {
if(!cookies.containsKey(entry.getKey()))
cookies.put(entry.getKey(), new ConcurrentHashMap());
cookies.get(entry.getKey()).put(name, decodedCookie);
public void add(URI uri, HttpCookie cookie) {
String name = getCookieToken(uri, cookie);
// Save cookie into local store, or remove if expired
if (!cookie.hasExpired()) {
if(!cookies.containsKey(uri.getHost()))
cookies.put(uri.getHost(), new ConcurrentHashMap());
cookies.get(uri.getHost()).put(name, cookie);
if(cookies.containsKey(uri.toString()))
cookies.get(uri.getHost()).remove(name);
// Save cookie into persistent store
SharedPreferences.Editor prefsWriter = cookiePrefs.edit();
prefsWriter.putString(uri.getHost(), TextUtils.join(,, cookies.get(uri.getHost()).keySet()));
prefsWriter.putString(COOKIE_NAME_PREFIX + name, encodeCookie(new SerializableHttpCookie(cookie)));
protected String getCookieToken(URI uri, HttpCookie cookie) {
return cookie.getName() + cookie.getDomain();
public List get(URI uri) {
ArrayList ret = new ArrayList();
if(cookies.containsKey(uri.getHost()))
ret.addAll(cookies.get(uri.getHost()).values());
public boolean removeAll() {
SharedPreferences.Editor prefsWriter = cookiePrefs.edit();
prefsWriter.clear();
cookies.clear();
public boolean remove(URI uri, HttpCookie cookie) {
String name = getCookieToken(uri, cookie);
if(cookies.containsKey(uri.getHost()) && cookies.get(uri.getHost()).containsKey(name)) {
cookies.get(uri.getHost()).remove(name);
SharedPreferences.Editor prefsWriter = cookiePrefs.edit();
if(cookiePrefs.contains(COOKIE_NAME_PREFIX + name)) {
prefsWriter.remove(COOKIE_NAME_PREFIX + name);
prefsWriter.putString(uri.getHost(), TextUtils.join(,, cookies.get(uri.getHost()).keySet()));
public List getCookies() {
ArrayList ret = new ArrayList();
for (String key : cookies.keySet())
ret.addAll(cookies.get(key).values());
public List getURIs() {
ArrayList ret = new ArrayList();
for (String key : cookies.keySet())
ret.add(new URI(key));
} catch (URISyntaxException e) {
e.printStackTrace();
* Serializes Cookie object into String
* @param cookie cookie to be encoded, can be null
* @return cookie encoded as String
protected String encodeCookie(SerializableHttpCookie cookie) {
if (cookie == null)
ByteArrayOutputStream os = new ByteArrayOutputStream();
ObjectOutputStream outputStream = new ObjectOutputStream(os);
outputStream.writeObject(cookie);
} catch (IOException e) {
Log.d(LOG_TAG, IOException in encodeCookie, e);
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 HttpCookie decodeCookie(String cookieString) {
byte[] bytes = hexStringToByteArray(cookieString);
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
HttpCookie cookie =
ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
cookie = ((SerializableHttpCookie) objectInputStream.readObject()).getCookie();
} catch (IOException e) {
Log.d(LOG_TAG, IOException in decodeCookie, e);
} catch (ClassNotFoundException e) {
Log.d(LOG_TAG, ClassNotFoundException in decodeCookie, e);
* 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 & 0
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 & i += 2) {
data[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) && 4) + Character.digit(hexString.charAt(i + 1), 16));
使用的时候,在发起请求前对CookieHandler进行设置,后续的cookie全都是自动管理,无需你关心cookie的保存于读取
OkHttpClient client = new OkHttpClient();
client.setCookieHandler(new CookieManager(
new PersistentCookieStore(getApplicationContext()),
CookiePolicy.ACCEPT_ALL));
这样,实现模拟登录,抓取一些数据就方便很多了,再也不用手动处理cookie了。}

我要回帖

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信