44

次のように、複数の Cookie を返すサーバー リクエストがあります。

ここに画像の説明を入力

これは、これらの Cookie を cookieManager に保存する方法です。

HttpURLConnection connection = ... ;
static java.net.CookieManager msCookieManager = new java.net.CookieManager();
msCookieManager.put(COOKIES_URI, connection.getHeaderFields());

これは、次の接続にこれらの Cookie を追加する方法です。

connection.setRequestProperty("Cookie", 
  msCookieManager.getCookieStore().get(COOKIES_URI).toString());

cookieManager から Cookie を取得するのは正しい方法ですか?, もっと良い方法があると確信しています...

4

5 に答える 5

108

わかりました、正しい方法は次のとおりです。

応答ヘッダーから Cookie を取得し、cookieManager にロードします。

static final String COOKIES_HEADER = "Set-Cookie";
HttpURLConnection connection = ... ;
static java.net.CookieManager msCookieManager = new java.net.CookieManager();

Map<String, List<String>> headerFields = connection.getHeaderFields();
List<String> cookiesHeader = headerFields.get(COOKIES_HEADER);

if (cookiesHeader != null) {
    for (String cookie : cookiesHeader) {
        msCookieManager.getCookieStore().add(null,HttpCookie.parse(cookie).get(0));
    }               
}

cookieManager から Cookie を取得し、それらを接続にロードします。

if (msCookieManager.getCookieStore().getCookies().size() > 0) {
    // While joining the Cookies, use ',' or ';' as needed. Most of the servers are using ';'
    connection.setRequestProperty("Cookie",
    TextUtils.join(";",  msCookieManager.getCookieStore().getCookies()));    
}
于 2013-04-23T14:16:28.160 に答える
52

問題を解決するために何日も検索/試行してきました: 正常にログインした後でも、保護された Web リソースにアクセスできません

iOS で同じアプリを作成しましたが、NSUrlConnection がバックグラウンドで Cookie のメンテナンスを行っていたため、同じ問題は発生しませんでした。Androidで、Cookieを手動で追加してみました

connection.setRequestProperty("Cookie", "PHPSESSID=str_from_server")

運がなければ。

最後にこれを読みました

そして、私のアプリの最初のどこかに次の2行を追加しました:

CookieManager cookieManager = new CookieManager();
CookieHandler.setDefault(cookieManager);

そして、すべてが正常に動作するようになりました。

于 2014-02-11T16:33:05.787 に答える
3

@Davidの答えは最高です。ローカルの CookieManager を維持し、この Cookie マネージャーに関連付けられた Cookie ストアに手動で書き込みおよび読み取りを行うのが最も簡単です。

このコードは、応答から Cookie マネージャーに Cookie をロードします。

/**
 * Gets Cookies from the response header and loads them into cookie manager
 *
 * @param conn          instance of {@link HttpURLConnection} object
 * @param cookieManager the cookie manager({@link CookieManager} instance) in which the cookies are to be loaded<p>In case a null object is passed, the function will not perform any action and return back to the caller. </p>
 */
public static void loadResponseCookies(@Nullable HttpURLConnection conn,@Nullable CookieManager cookieManager) {

    //do nothing in case a null cokkie manager object is passed
    if (cookieManager == null || conn == null){
        return;
    }

    List<String> cookiesHeader = conn.getHeaderFields().get(COOKIES_HEADER);
    if (cookiesHeader != null) {
        for (String cookieHeader : cookiesHeader) {
            List<HttpCookie> cookies;
            try {
                cookies = HttpCookie.parse(cookieHeader);
            } catch (NullPointerException e) {
                log.warn(MessageFormat.format("{0} -- Null header for the cookie : {1}",conn.getURL().toString(), cookieHeader.toString()));
                //ignore the Null cookie header and proceed to the next cookie header
                continue;
            }

            if (cookies != null) {
                Debug("{0} -- Reading Cookies from the response :", conn.getURL().toString());
                for (HttpCookie cookie : cookies) {
                    Debug(cookie.toString());
                }
                if (cookies.size() > 0) {
                    cookieManager.getCookieStore().add(null, HttpCookie.parse(cookieHeader).get(0));
                }
            }
        }
    }
}

このコードは、Cookie manager に関連付けられた Cookie を HttpUrlConnection オブジェクトに取り込みます。

public void populateCookieHeaders(HttpURLConnection conn) {

    if (this.cookieManager != null) {
        //getting cookies(if any) and manually adding them to the request header
        List<HttpCookie> cookies = this.cookieManager.getCookieStore().getCookies();

        if (cookies != null) {
            if (cookies.size() > 0) {
                Debug("{0} -- Adding Cookie Headers : ", url.toString());
                for (HttpCookie cookie : cookies) {
                    Debug(cookie.toString(), null);
                }

                //adding the cookie header
                conn.setRequestProperty(COOKIE_REQUEST_HEADER, StringUtils.join(cookies, ";"));
            }
        }
    }
}

これは、Cookie を処理する最もスレッド セーフな方法です。

スレッドローカル Cookiestore と CookieManager の拡張機能を使用してみました。私の場合、これらのアプローチはどちらも機能しませんでした。

于 2016-05-30T11:53:09.880 に答える
1

他の回答はそれぞれのコンテキストに適していますが、誰も明白なことを言っていません: CookieHandler はほとんどの場合、Cookie を自動的に処理します。たとえば、サーバー セッションを維持するために、あるリクエストから次のリクエストまで Cookie を維持するには、次のコード行で十分です。

CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));

UrlConnection を使用した最初のリクエストの前に、必ず 1 回実行してください。

現在、私は自分で Cookie の管理を一切行っておらず、すべてのサーバー セッション データは、要求から要求まで完璧に維持されています。

私はクレイジーですか?なぜこれについてインターネットは沈黙しているのですか?ドキュメントでも見つかりません。

于 2020-09-23T19:39:21.903 に答える