鴻洋大神の穴を踏んで、彼のCookieの支持がもたらしたBUGを最適化して修復します
5486 ワード
前言:現在、APP内のネットワークフレームワークでRetrofitを使用するのは一般的な現象であるはずですが、ビジネスのニーズでログイン状態を維持する必要がある場合や、サービス側がクライアントにデータを書く必要がある場合があり、次のリクエストでこれらのデータをサービス側に書き返します.PC側のブラウザメカニズムを完全にシミュレートしたので、ここでは鴻洋大神のRetrofitのCookieへのサポートを使用しました.
げんしょう
正常に使用して、問題がないことを発見して、JESSIONIDも正常に使用することができて、会話は維持することができます.昨日楽屋は私に言って、彼はクライアントに他のCOOKIEを書いて、どうして安卓端は帰ってこなかったのですか?
チェック
取り戻せない以上,二つのところに疑いがある最初のResponseはローカルに と書いていません.第2のRequestはサーバに を伝えなかった.
見てみましょうCookieJar.JAvaのソース:
ここでは主に2つの方法を見ます. とローカルに書く. を加える.
ローカライズにはPersistentCookieStoreが使用されています.JAvaで実現
ここではまずsaveFromResponse(HttpUrl url,List cookies)の中で、鴻洋大神がこんな一節を書いたのを見てみましょう.
ここでは簡単な判断と、サービス側から返されたクッキーのリストを1つずつローカルに追加し、コード:
PersistentCookieStore.java
ここの論理は、まず彼のtokenを手に入れて、tokenはどのように構成されていますか?ドメイン名@CookieのKey例:127.0.0.1@key1 , 127.0.0.1@key2 , 127.0.0.1@key3
Cookieが期限切れかどうかを判断します.期限が切れたら新しい空のmapを追加します. 期限切れがなければ、Cookieに同じKeyのCookieが存在するか否かを判断し、存在する場合、removeは同じnameの古いcookieデータを消去する.
実はここで問題があります.期限が切れていないときは、古いデータをremoveしてから、新しいデータを追加しなければなりません.はっきり言って、古いデータを上書きして、新しいデータをローカルに永続化しなければなりません.
問題を解決する
OK、問題が見つかりましたので、ここで彼のコードを修正します.
ここでは最適化処理を行い,まずhost対応のcookieMapを取得し,空でなければ直接putを入れる.どうしてそうするの?ここではまずcookiesについて説明します.containsKey(url.host()この行のコードの意味は何ですか??mapにこのkeyが存在するかどうか、keyが存在する場合はtrueを返すという意味です.でもちょうどmapにnullが保存されていたら??mapではkey-valueの形式で、valueはnullに許可されています.
だから私はここでまず対応するvalueを取得して、判断が空ではありませんて、更に対応する処理を行って、論理的に言えば、比較的に安全な1つの方法です.それから直接putに入って、keyと同じなら古いデータを上書きします.クッキーを永続化するローカルでは、これ以上言うことはありません.
の最後の部分
ここに貼って、私が修正したGitHubアドレスとGradle直接使用アドレス:GitHub:https://github.com/xiaolei123/OkHttpHelper Gradle : implementation 'com.xiaolei:OkHttpUtil:1.0.6'使用:
The End
げんしょう
正常に使用して、問題がないことを発見して、JESSIONIDも正常に使用することができて、会話は維持することができます.昨日楽屋は私に言って、彼はクライアントに他のCOOKIEを書いて、どうして安卓端は帰ってこなかったのですか?
チェック
取り戻せない以上,二つのところに疑いがある
見てみましょうCookieJar.JAvaのソース:
public interface CookieJar {
/** A cookie jar that never accepts any cookies. */
CookieJar NO_COOKIES = new CookieJar() {
@Override public void saveFromResponse(HttpUrl url, List cookies) {
}
@Override public List loadForRequest(HttpUrl url) {
return Collections.emptyList();
}
};
/**
* Saves {@code cookies} from an HTTP response to this store according to this jar's policy.
*
* Note that this method may be called a second time for a single HTTP response if the response
* includes a trailer. For this obscure HTTP feature, {@code cookies} contains only the trailer's
* cookies.
*/
void saveFromResponse(HttpUrl url, List cookies);
/**
* Load cookies from the jar for an HTTP request to {@code url}. This method returns a possibly
* empty list of cookies for the network request.
*
*
Simple implementations will return the accepted cookies that have not yet expired and that
* {@linkplain Cookie#matches match} {@code url}.
*/
List loadForRequest(HttpUrl url);
}
ここでは主に2つの方法を見ます.
void saveFromResponse(HttpUrl url, List cookies);
ResponseからList loadForRequest(HttpUrl url);
ローカルからRequestリクエストにローカライズにはPersistentCookieStoreが使用されています.JAvaで実現
ここではまずsaveFromResponse(HttpUrl url,List cookies)の中で、鴻洋大神がこんな一節を書いたのを見てみましょう.
override fun saveFromResponse(httpUrl: HttpUrl, cookies: List?)
{
if ( cookies != null && cookies.isNotEmpty())
{
for (item in cookies)
{
cookieStore.add(httpUrl, item)
}
}
}
ここでは簡単な判断と、サービス側から返されたクッキーのリストを1つずつローカルに追加し、コード:
cookieStore.add(httpUrl, item)
という行のポイントソースポイントを追跡します.PersistentCookieStore.java
public void add(HttpUrl url, Cookie cookie)
{
String name = getCookieToken(cookie);
// cookies cookie
if (!cookie.persistent())
{
if (!cookies.containsKey(url.host()))
{
cookies.put(url.host(), new ConcurrentHashMap());
}
cookies.get(url.host()).put(name, cookie);
} else
{
if (cookies.containsKey(url.host()))
{
cookies.get(url.host()).remove(name);
}
}
// cookies
SharedPreferences.Editor prefsWriter = cookiePrefs.edit();
if (url.host() != null && cookies.get(url.host()) != null)
{
prefsWriter.putString(url.host(), TextUtils.join(",", cookies.get(url.host()).keySet()));
}
prefsWriter.putString(name, encodeCookie(new OkHttpCookies(cookie)));
prefsWriter.apply();
}
ここの論理は、まず彼のtokenを手に入れて、tokenはどのように構成されていますか?ドメイン名@CookieのKey例:127.0.0.1@key1 , 127.0.0.1@key2 , 127.0.0.1@key3
Cookieが期限切れかどうかを判断します.
実はここで問題があります.期限が切れていないときは、古いデータをremoveしてから、新しいデータを追加しなければなりません.はっきり言って、古いデータを上書きして、新しいデータをローカルに永続化しなければなりません.
問題を解決する
OK、問題が見つかりましたので、ここで彼のコードを修正します.
public void add(HttpUrl url, Cookie cookie)
{
String name = getCookieToken(cookie);
// cookies cookie
if (!cookie.persistent())
{
if (!cookies.containsKey(url.host()))
{
cookies.put(url.host(), new ConcurrentHashMap());
}
cookies.get(url.host()).put(name, cookie);
} else
{
//
Map cookieMap = cookies.get(url.host());
if (cookieMap != null)
{
cookieMap.put(name, cookie);
}
}
// cookies
SharedPreferences.Editor prefsWriter = cookiePrefs.edit();
if (url.host() != null && cookies.get(url.host()) != null)
{
prefsWriter.putString(url.host(), TextUtils.join(",", cookies.get(url.host()).keySet()));
}
prefsWriter.putString(name, encodeCookie(new OkHttpCookies(cookie)));
prefsWriter.apply();
}
ここでは最適化処理を行い,まずhost対応のcookieMapを取得し,空でなければ直接putを入れる.どうしてそうするの?ここではまずcookiesについて説明します.containsKey(url.host()この行のコードの意味は何ですか??mapにこのkeyが存在するかどうか、keyが存在する場合はtrueを返すという意味です.でもちょうどmapにnullが保存されていたら??mapではkey-valueの形式で、valueはnullに許可されています.
だから私はここでまず対応するvalueを取得して、判断が空ではありませんて、更に対応する処理を行って、論理的に言えば、比較的に安全な1つの方法です.それから直接putに入って、keyと同じなら古いデータを上書きします.クッキーを永続化するローカルでは、これ以上言うことはありません.
の最後の部分
ここに貼って、私が修正したGitHubアドレスとGradle直接使用アドレス:GitHub:https://github.com/xiaolei123/OkHttpHelper Gradle : implementation 'com.xiaolei:OkHttpUtil:1.0.6'使用:
com.xiaolei.okhttputil.Cookie.CookieJar cookiejar = new CookieJar(context,null);
new OkHttpClient.Builder()
.cookieJar(cookiejar)
.build();
The End