服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Android - Android持久化保存cookie的方法

Android持久化保存cookie的方法

2022-02-23 14:54袭烽 Android

这篇文章主要介绍了Android持久化保存cookie的方法,在解析网页信息的时候,需要登录后才能访问,所以使用httpclient模拟登录,然后把cookie保存下来,以供下一次访问使用,感兴趣的小伙伴们可以参考一下

在解析网页信息的时候,需要登录后才能访问,所以使用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发送往客户端。

Android持久化保存cookie的方法

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

Android持久化保存cookie的方法

浏览器和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

先看一下下面的代码:

?
1
2
3
4
5
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模拟登录

?
1
2
3
4
5
6
7
8
9
10
11
12
13
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://www.zzvips.com/article/140423.htm是使用数据库来保存的,这里我是使用SharedPreferences保存。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
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是在登录成功后,从下面代码获取保存。

?
1
2
3
4
5
PersistentCookieStore myCookieStore = App.getInstance().getPersistentCookieStore();
List<Cookie> cookies = httpClient.getCookieStore().getCookies();
for (Cookie cookie:cookies){
 myCookieStore.addCookie(cookie);
}

三、cookie的使用

?
1
2
3
PersistentCookieStore cookieStore = new PersistentCookieStore(SmthBestApp.getInstance().getApplicationContext());
httpClient.setCookieStore(cookieStore);
HttpResponse response = httpClient.execute(httpget);

这样就可以免再次登录了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/shimiso/article/details/39033353

延伸 · 阅读

精彩推荐