Как да внедрите обработка на бисквитки на Android с помощта на OkHttp?

Използвайки OkHttp от Square https://github.com/square/okhttp, как мога да:

  1. Извличане на бисквитка, върната от сървъра
  2. Съхранявайте бисквитката за предстоящи заявки
  3. Използвайте съхранената бисквитка в следващите заявки
  4. Актуализирайте бисквитката, върната от последващата заявка

В идеалния случай бисквитката ще се съхранява, изпраща повторно и актуализира автоматично при всяка заявка.


person Daniel    schedule 17.06.2014    source източник


Отговори (3)


За OkHttp3 простото приемане на всичко, непостоянно CookieJar изпълнение може да бъде както следва:

OkHttpClient client = new OkHttpClient.Builder()
    .cookieJar(new CookieJar() {
        private final HashMap<HttpUrl, List<Cookie>> cookieStore = new HashMap<>();

        @Override
        public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
            cookieStore.put(url, cookies);
        }

        @Override
        public List<Cookie> loadForRequest(HttpUrl url) {
            List<Cookie> cookies = cookieStore.get(url);
            return cookies != null ? cookies : new ArrayList<Cookie>();
        }
    })
    .build();

Или ако предпочитате да използвате java.net.CookieManager, включете okhttp-urlconnection във вашия проект, който съдържа JavaNetCookieJar, клас обвивка, който делегира на java.net.CookieHandler:

dependencies {
    compile "com.squareup.okhttp3:okhttp:3.0.0"
    compile "com.squareup.okhttp3:okhttp-urlconnection:3.0.0"
}

CookieManager cookieManager = new CookieManager();
cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
OkHttpClient client = new OkHttpClient.Builder()
    .cookieJar(new JavaNetCookieJar(cookieManager))
    .build();
person hidro    schedule 12.01.2016
comment
Значи автоматично се запазва и нищо не трябва да правя? След рестартиране работи? - person Kamil Nękanowicz; 14.01.2016
comment
Не, примерът е за буркан с непостоянни бисквитки. За постоянно решение можете да внедрите свое собствено, напр. stackoverflow.com/a/25462286/836540 и го обвийте с JavaNetCookieJar. - person hidro; 14.01.2016
comment
Между другото, url е „ПЪЛЕН URL“ към сървъра и той ще изпраща бисквитки само когато прави заявка към точно същия URL. Може да искате да замените cookieStore.put(url, cookies); с cookieStore.put(url.host(), cookies); За loadForRequest, coookieStore.get(url.host());. И заменете HashMap<HttpUrl, List<Cookie>> с HashMap<String, ...> - person Eddie; 18.02.2016
comment
@hidro как да създам бисквитки? - person Michael A; 02.03.2016
comment
Използвате Cookie.Builder? https://github.com/square/okhttp/blob/master/okhttp/src/main/java/okhttp3/Cookie.java#L451 - person hidro; 02.03.2016
comment
Добавянето на кодове по-долу ми помогна. Благодаря! CookieManager cookieManager = нов CookieManager(); cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL); OkHttpClient клиент = нов OkHttpClient.Builder() .cookieJar(нов JavaNetCookieJar(cookieManager)) .build(); - person Can Uludağ; 06.04.2016
comment
За информация: В близко бъдеще те планират да премахнат модула okhttp-urlconnection. https://github.com/square/okhttp/blob/master/CHANGELOG.md - person Tobliug; 12.04.2016
comment
Използването само на HttpUrl ограничава бисквитката само до този url - и не е особено полезно. Трябва да бъде само името на домейна като ключ - и тогава работи по предназначение. - person slott; 26.04.2016
comment
Това е грешно. saveFromResponse заменя списъка, вместо да ги обединява. Това означава, че настройката на всяка бисквитка изтрива всички бисквитки, зададени в предишни заявки. - person Agent_L; 30.11.2016
comment
Съгласен съм с @Agent_L. Това замества всички бисквитки всеки път, когато пристигнат нови бисквитки. Това означава, че ако влезете, получите бисквитка за удостоверяване в отговор, след което направите друга заявка, която връща различна бисквитка в отговора, бисквитката за удостоверяване ще бъде презаписана и повече няма да сте влезли. - person Cypress Frankenfeld; 26.06.2017
comment
@Agent_L и как да обединя бисквитките? - person Maxim Toyberman; 04.07.2018
comment
@MaximToyberman Бихте искали нещо, което изглежда така private final HashMap<String, List<Cookie>> cookieStore = new HashMap<>(); @Override public void saveFromResponse(HttpUrl url, List<Cookie> cookies) { if(cookieStore.containsKey(url.host())) { cookieStore.get(url.host()).addAll(cookies); } else { cookieStore.put(url.host(), cookies); } } - person Mikael Mengistu; 27.09.2018
comment
Все още не мога да получа отговор. Има някакъв проблем със сесията, който се показва в сървъра. Но тъй като работи в мрежата и iOS, както и нямам друга опция само да проверя кода си. - person Priyanka Singhal; 15.03.2019
comment
Не мога да разбера защо сесията не работи с CookieJar изпълнение. CookieManager работи като чар. - person Kimi Chiu; 30.06.2020

Преди OkHttp 3 можете да предадете CookieHandler на вашето копие на OkHttpClient. Можете да използвате внедряването на CookieManager от java.net или можете да внедрите свое собствено, ако желаете. Изберете политиката, която работи най-добре за вашите нужди.

OkHttpClient client = new OkHttpClient();
CookieManager cookieManager = new CookieManager();
cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
client.setCookieHandler(cookieManager);

OkHttp ще записва бисквитките, получени от Responses, в CookieHandler и ще ги чете от него при изпращане на заявки. Това ще направи за съответстващи URI адреси на заявка/отговор.

person Miguel    schedule 17.06.2014
comment
Важно е да се отбележи: CookieManager не е постоянен. Следващият път, когато стартирате приложението си, бурканът с бисквитки ще бъде празен. - person Jesse Wilson; 18.06.2014
comment
@JesseWilson, как да го направя постоянен? - person Saeed Neamati; 06.08.2015
comment
Постоянните бисквитки все още не са внедрени. Ако имате нужда от тях, трябва да направите свой собствен CookieStore. - person Jesse Wilson; 07.08.2015
comment
@JesseWilson Прав си. Ето библиотека, която помага за запазването на CoockieJar github.com/franmontiel/PersistentCookieJar - person Manjunath; 09.08.2016
comment
Методът setCookieHandler не е тук okhttp 3.0 - person Asthme; 23.12.2016
comment
Трябва ли да внедрим new CookieJar() във всяка okhttp заявка или можем да го направим веднъж завинаги? - person Miljan Rakita; 11.11.2017

Трябваше да споделя буркана с бисквитки по подразбиране (CookieManager.getInstance()), така че това изглеждаше добре за мен.

return new CookieJar() {

        @Override
        public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
            CookieManager cookieManager = CookieManager.getInstance();

            for (Cookie cookie : cookies) {
                cookieManager.setCookie(url.toString(), cookie.toString());
            }
        }

        @Override
        public List<Cookie> loadForRequest(HttpUrl url) {
            CookieManager cookieManager = CookieManager.getInstance();
            List<Cookie> cookies = new ArrayList<>();
            if (cookieManager.getCookie(url.toString()) != null) {
                String[] splitCookies = cookieManager.getCookie(url.toString()).split("[,;]");
                for (int i=0; i<splitCookies.length; i++) {
                    cookies.add(Cookie.parse(url, splitCookies[i].trim()));
                }
            }
            return cookies;
        }
    };
person hmac    schedule 14.06.2017
comment
Благодаря, работи наистина добре. Добра работа. Просто решение, благодаря!! - person KZoNE; 17.08.2017
comment
здравей, @hmac, този подход работи за мен. Можете ли да ме насочите как да изчистя бисквитката, когато потребител излезе? - person Rozina; 24.05.2018
comment
Реших проблема с чистите бисквитки. Ето връзката, която може да помогне на някой stackoverflow.com/a/50505170/8159810 - person Rozina; 24.05.2018