0
OkHttp 3 使用 PersistentCookieJar 自动处理 Cookie
配置
在 build.gradle 里面添加
allprojects {
repositories {
...
maven { url "https://jitpack.io" }
}
}
dependencies {
compile 'com.github.franmontiel:PersistentCookieJar:v1.0.1'
}
使用
ClearableCookieJar cookieJar =
new PersistentCookieJar(new SetCookieCache(), new SharedPrefsCookiePersistor(context));
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.cookieJar(cookieJar)
.build();
OkHttp 2
如果是使用OkHttp 2的项目使用下面的代码
/*
* Copyright (c) 2015 Fran Montiel
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
public class PersistentCookieStore implements CookieStore {
private static final String TAG = PersistentCookieStore.class
.getSimpleName();
// Persistence
private static final String SP_COOKIE_STORE = "cookieStore";
private static final String SP_KEY_DELIMITER = "|"; // Unusual char in URL
private static final String SP_KEY_DELIMITER_REGEX = "\\"
+ SP_KEY_DELIMITER;
private SharedPreferences sharedPreferences;
// In memory
private Map<URI, Set<HttpCookie>> allCookies;
public PersistentCookieStore(Context context) {
sharedPreferences = context.getSharedPreferences(SP_COOKIE_STORE,
Context.MODE_PRIVATE);
loadAllFromPersistence();
}
private void loadAllFromPersistence() {
allCookies = new HashMap<URI, Set<HttpCookie>>();
Map<String, ?> allPairs = sharedPreferences.getAll();
for (Entry<String, ?> entry : allPairs.entrySet()) {
String[] uriAndName = entry.getKey().split(SP_KEY_DELIMITER_REGEX,
2);
try {
URI uri = new URI(uriAndName[0]);
String encodedCookie = (String) entry.getValue();
HttpCookie cookie = new SerializableHttpCookie()
.decode(encodedCookie);
Set<HttpCookie> targetCookies = allCookies.get(uri);
if (targetCookies == null) {
targetCookies = new HashSet<HttpCookie>();
allCookies.put(uri, targetCookies);
}
// Repeated cookies cannot exist in persistence
// targetCookies.remove(cookie)
targetCookies.add(cookie);
} catch (URISyntaxException e) {
Log.w(TAG, e);
}
}
}
@Override
public synchronized void add(URI uri, HttpCookie cookie) {
uri = cookieUri(uri, cookie);
Set<HttpCookie> targetCookies = allCookies.get(uri);
if (targetCookies == null) {
targetCookies = new HashSet<HttpCookie>();
allCookies.put(uri, targetCookies);
}
targetCookies.remove(cookie);
targetCookies.add(cookie);
saveToPersistence(uri, cookie);
}
/**
* Get the real URI from the cookie "domain" and "path" attributes, if they
* are not set then uses the URI provided (coming from the response)
*
* @param uri
* @param cookie
* @return
*/
private static URI cookieUri(URI uri, HttpCookie cookie) {
URI cookieUri = uri;
if (cookie.getDomain() != null) {
// Remove the starting dot character of the domain, if exists (e.g: .domain.com -> domain.com)
String domain = cookie.getDomain();
if (domain.charAt(0) == '.') {
domain = domain.substring(1);
}
try {
cookieUri = new URI(uri.getScheme() == null ? "http"
: uri.getScheme(), domain,
cookie.getPath() == null ? "/" : cookie.getPath(), null);
} catch (URISyntaxException e) {
Log.w(TAG, e);
}
}
return cookieUri;
}
private void saveToPersistence(URI uri, HttpCookie cookie) {
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(uri.toString() + SP_KEY_DELIMITER + cookie.getName(),
new SerializableHttpCookie().encode(cookie));
editor.apply();
}
@Override
public synchronized List<HttpCookie> get(URI uri) {
return getValidCookies(uri);
}
@Override
public synchronized List<HttpCookie> getCookies() {
List<HttpCookie> allValidCookies = new ArrayList<HttpCookie>();
for (URI storedUri : allCookies.keySet()) {
allValidCookies.addAll(getValidCookies(storedUri));
}
return allValidCookies;
}
private List<HttpCookie> getValidCookies(URI uri) {
List<HttpCookie> targetCookies = new ArrayList<HttpCookie>();
// If the stored URI does not have a path then it must match any URI in
// the same domain
for (URI storedUri : allCookies.keySet()) {
// Check ith the domains match according to RFC 6265
if (checkDomainsMatch(storedUri.getHost(), uri.getHost())) {
// Check if the paths match according to RFC 6265
if (checkPathsMatch(storedUri.getPath(), uri.getPath())) {
targetCookies.addAll(allCookies.get(storedUri));
}
}
}
// Check it there are expired cookies and remove them
if (!targetCookies.isEmpty()) {
List<HttpCookie> cookiesToRemoveFromPersistence = new ArrayList<HttpCookie>();
for (Iterator<HttpCookie> it = targetCookies.iterator(); it
.hasNext(); ) {
HttpCookie currentCookie = it.next();
if (currentCookie.hasExpired()) {
cookiesToRemoveFromPersistence.add(currentCookie);
it.remove();
}
}
if (!cookiesToRemoveFromPersistence.isEmpty()) {
removeFromPersistence(uri, cookiesToRemoveFromPersistence);
}
}
return targetCookies;
}
/* http://tools.ietf.org/html/rfc6265#section-5.1.3
A string domain-matches a given domain string if at least one of the
following conditions hold:
o The domain string and the string are identical. (Note that both
the domain string and the string will have been canonicalized to
lower case at this point.)
o All of the following conditions hold:
* The domain string is a suffix of the string.
* The last character of the string that is not included in the
domain string is a %x2E (".") character.
* The string is a host name (i.e., not an IP address). */
private boolean checkDomainsMatch(String cookieHost, String requestHost) {
return requestHost.equals(cookieHost) || requestHost.endsWith("." + cookieHost);
}
/* http://tools.ietf.org/html/rfc6265#section-5.1.4
A request-path path-matches a given cookie-path if at least one of
the following conditions holds:
o The cookie-path and the request-path are identical.
o The cookie-path is a prefix of the request-path, and the last
character of the cookie-path is %x2F ("/").
o The cookie-path is a prefix of the request-path, and the first
character of the request-path that is not included in the cookie-
path is a %x2F ("/") character. */
private boolean checkPathsMatch(String cookiePath, String requestPath) {
return requestPath.equals(cookiePath) ||
(requestPath.startsWith(cookiePath) && cookiePath.charAt(cookiePath.length() - 1) == '/') ||
(requestPath.startsWith(cookiePath) && requestPath.substring(cookiePath.length()).charAt(0) == '/');
}
private void removeFromPersistence(URI uri, List<HttpCookie> cookiesToRemove) {
SharedPreferences.Editor editor = sharedPreferences.edit();
for (HttpCookie cookieToRemove : cookiesToRemove) {
editor.remove(uri.toString() + SP_KEY_DELIMITER
+ cookieToRemove.getName());
}
editor.apply();
}
@Override
public synchronized List<URI> getURIs() {
return new ArrayList<URI>(allCookies.keySet());
}
@Override
public synchronized boolean remove(URI uri, HttpCookie cookie) {
Set<HttpCookie> targetCookies = allCookies.get(uri);
boolean cookieRemoved = targetCookies != null && targetCookies
.remove(cookie);
if (cookieRemoved) {
removeFromPersistence(uri, cookie);
}
return cookieRemoved;
}
private void removeFromPersistence(URI uri, HttpCookie cookieToRemove) {
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.remove(uri.toString() + SP_KEY_DELIMITER
+ cookieToRemove.getName());
editor.apply();
}
@Override
public synchronized boolean removeAll() {
allCookies.clear();
removeAllFromPersistence();
return true;
}
private void removeAllFromPersistence() {
sharedPreferences.edit().clear().apply();
}
}
Recommend
相关搜索关键词
Recent search keywords
- -1" or 3+860-860-1=0+0+0+1 --
- answers
- @@l00ww
- iecho.cc
- golbel
- 129084
- cssbuilder
- DOVE加速器
- Graphcore
- n950f
- eb341820cd3a3485461a61b1e97d31b1
- onepiece
- Samsung gaming
- contact
- hindi
- golang9478590
- http\x3A\x2F\x2Fbestbuy.com
- 哥们
- 黑兽
- -4307" or 5781=5781 and "yvut"="yvut
- yiyo
- Inda
- -1" or 2+501-501-1=0+0+0+1 --
- upi
- 印度支付通道
- AC8227L+Android+head+unit+4gb/32gb
- xperia+5+v
- org+chart
- Iptv+2023
- san+francisco+web+development
- 8257+logo
- hacks+in+blooket
- 深入理解+Gem5
- xperia+5+v+kernel
- hacks in blooket
- Iptv 2023
- teligu
- Read.Me
- flip
- wrp android video player pro" and 8553=8553 and "fygz"="fygz
- -1 or 3+520-520-1=0+0+0+1
- abap
- 深入理解 Gem5
- xperia 5 v kernel
- xperia 5 v
- san francisco web development
- flutter内核源码剖析
- zepp
- m31s
- khmer
- iptv+smart+player
- JAC+8229B
- Savings+Account
- 4th+generation
- Personal+Loan+Account
- clash+tun
- Oneplus+8t
- galaxy+s24+ultra
- checking+system+health+gpt
- Indian+Rupee+Ngultrum
- Kuwaiti+Dinar
- PlayWright
- solid+state
- Slim+odan
- radio+setup
- mlc+llm
- junsun+v1+pro+c,+radio+setup
- AGGIORNAMENTO+ROM+AC8227L+-+Android+JCAC10003-OC2
- checking+system+health
- read+only
- Ergonomic+Frozen+Shirt
- unidoc+health
- tab+4
- YT9217b+firmware
- Northern+Mariana+Islands
- utunnel
- read only
- radio
- 著作權
- M3U8
- 鸿蒙
- Japan
- @@neb61
- Laptop Rental - All Major Brand Laptops For Rent in Mumbai
- yt9213aj
- galaxy s24 ultra
- alwinner
- nat geo
- AGGIORNAMENTO ROM AC8227L - Android JCAC10003-OC2
- wulu
- office
- offcie
- gospel americano
- junsun v1 pro c, radio setup
- radio setup
- AC8227L Android head unit 4gb/32gb
- K4811_NWD_S217206
- unidoc health
- 5ber
- YT9217b
Android Studio 找不到com.github.franmontiel:persistentcookiejar
报 failed to resolve: com.github.franmontiel:persistentcookiejar:v1.0.1
看下配置这个添加没有
persistentcookiejar中保存的cookie没有保存本地, APP退出后就消失咯。
消失的这情况是因为服务端设置了cookie过期是时间的。让写API的人改下, 或者抓包看看。
之前一天掉线也是让server端解决的。