Автоматическая обработка файлов cookie с помощью OkHttp 3

Я использую okhttp 3.0.1.

Каждый, где я получаю пример обработки файлов cookie с okhttp2

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

Может понравиться какой-нибудь один, посоветуйте мне, как использовать в версии 3. Метод setCookieHandler отсутствует в версии 3.

Ответ 1

прямо сейчас я играю с этим. попробуйте PersistentCookieStore, добавьте зависимости gradle для JavaNetCookieJar:

compile "com.squareup.okhttp3:okhttp-urlconnection:3.0.0-RC1"

и init

    // init cookie manager
    CookieHandler cookieHandler = new CookieManager(
            new PersistentCookieStore(ctx), CookiePolicy.ACCEPT_ALL);
    // init okhttp 3 logger
    HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
    logging.setLevel(HttpLoggingInterceptor.Level.BODY);
    // init OkHttpClient
    OkHttpClient httpClient = new OkHttpClient.Builder()
            .cookieJar(new JavaNetCookieJar(cookieHandler))
            .addInterceptor(logging)
            .build();

`

Ответ 2

Если вы хотите использовать новый CookieJar OkHttp 3 и избавиться от зависимостей okhttp-urlconnection, вы можете использовать этот PersistentCookieJar.

Вам нужно создать экземпляр PersistentCookieJar, а затем просто передать его в конструктор OkHttp:

CookieJar cookieJar =
                    new PersistentCookieJar(new SetCookieCache(), new SharedPrefsCookiePersistor(context));

OkHttpClient okHttpClient = new OkHttpClient.Builder()
                    .cookieJar(cookieJar)
                    .build();

Ответ 3

Здесь у вас есть простой подход для создания собственного CookieJar. Он может быть расширен по вашему желанию. Я сделал, чтобы реализовать CookieJar и построить OkHttpClient с помощью OkHttpClient.Builder с этим CookieJar.

public class MyCookieJar implements CookieJar {

    private List<Cookie> cookies;

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

    @Override
    public List<Cookie> loadForRequest(HttpUrl url) {
        if (cookies != null)
            return cookies;
        return new ArrayList<Cookie>();

    } 
}

Вот как вы можете создать OkHttpClient

OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.cookieJar(new MyCookieJar());
OkHttpClient client = builder.build();

Ответ 4

Здесь работает реализация CookieJar для OkHttp3. Если у вас есть несколько экземпляров OkHttp3 (обычно у вас должен быть только один экземпляр и использовать его как одиночный), вы должны установить тот же экземпляр cookiejar для всех http-клиентов, чтобы они могли делиться куками!!! В этой реализации не сохраняются файлы cookie (все они будут удалены при перезагрузке приложения), но должно быть легко реализовать сохранение SharedPreferences вместо списка куки файлов (cookieStore) в памяти.

    CookieJar cookieJar = new CookieJar() {
        private final HashMap<String, List<Cookie>> cookieStore = new HashMap<>();

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

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

Ответ 5

Я использовал библиотека fransmontiel PeristentCookieJar для okhttp3 и retrofit.2. преимущество такого подхода: не нужно манипулировать вашим запросом okhttp. Просто установите cookie или сеанс при создании модификации

1. сначала добавьте это в свой build.gradle(имя проекта)
 allprojects {
     repositories {
         jcenter()
         maven { url "https://jitpack.io" }
     }
 }
2. добавьте это в свой build.gradle
    compile 'com.github.franmontiel:PersistentCookieJar:v1.0.1'
3.стройте такую ​​модернизацию
public static Retrofit getClient(Context context) {

            ClearableCookieJar cookieJar = new PersistentCookieJar(new SetCookieCache(), new SharedPrefsCookiePersistor(context));
            OkHttpClient okHttpClient = new OkHttpClient.Builder()
                    .cookieJar(cookieJar)
                    .build();
            if (retrofit==null) {
                retrofit = new Retrofit.Builder()
                        .baseUrl(BASE_URL)
                        .addConverterFactory(GsonConverterFactory.create())
                        .client(okHttpClient)
                        .build();
            }
            return retrofit;
        }

Ответ 6

Добавление compile "com.squareup.okhttp3:okhttp-urlconnection:3.8.1" в ваш build.gradle.

И затем добавив

 CookieManager cookieManager = new CookieManager();
 cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);

 OkHttpClient defaultHttpClient = new OkHttpClient.Builder()
                                 .cookieJar(new JavaNetCookieJar(cookieManager))
                                 .build()

помог мне, не добавляя зависимостей сторонних разработчиков, кроме одного из OkHttp.

Ответ 7

минимальное решение, сохраняющее cookie после первого запуска

public class SharedPrefCookieJar implements CookieJar {

    Map<String, Cookie> cookieMap = new HashMap();
    private Context mContext;
    private SharedPrefsManager mSharedPrefsManager;

    @Inject
    public SharedPrefCookieJar(Context context, SharedPrefsManager sharedPrefsManager) {
        mContext = context;
        mSharedPrefsManager = sharedPrefsManager;
        cookieMap = sharedPrefsManager.getCookieMap(context);
        if (cookieMap == null) {
            cookieMap = new HashMap<>();
        }
    }

    @Override
    public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {

        for (Cookie cookie : cookies) {
            cookieMap.put(cookie.name(), cookie);
        }
        mSharedPrefsManager.setCookieMap(mContext, cookieMap);
    }

    @Override
    public List<Cookie> loadForRequest(HttpUrl url) {
        List<Cookie> validCookies = new ArrayList<>();
        for (Map.Entry<String, Cookie> entry : cookieMap.entrySet()) {
            Cookie cookie = entry.getValue();
            if (cookie.expiresAt() < System.currentTimeMillis()) {

            } else {
                validCookies.add(cookie);
            }
        }
        return validCookies;
    }

}

с кинжалом

@Module
public class ApiModule {


    @Provides
    @Singleton
    InstagramService provideInstagramService(OkHttpClient client)
    {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(InstagramService.BASE_URL)
                .client(client)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build();
        InstagramService instagramService = retrofit.create(InstagramService.class);
        return instagramService;
    }


    @Provides
    @Singleton
    OkHttpClient provideOkHttpClient(SharedPrefCookieJar sharedPrefCookieJar){
        OkHttpClient client;
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        if(BuildConfig.DEBUG)
        {
            HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
            httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
            builder
                .addInterceptor(httpLoggingInterceptor)
                .addInterceptor(new InstagramHeaderInterceptor())
                .addNetworkInterceptor(new LoggingInterceptor());

        }
        client = builder.cookieJar(sharedPrefCookieJar).build();
        return client;
    }
}

Ответ 8

Я использовал решение @gncabrera, но также создал вспомогательный класс для инициализации, а также упростил совместное использование CookieJar в приложении.

public class OkHttpClientCreator {

    private static CookieJar mCookieJar;

    public static OkHttpClient.Builder getNewHttpClientBuilder(boolean isDebug, boolean useCookies) {
        if (mCookieJar == null && useCookies) {
            mCookieJar = new BasicCookieJar();
        }
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        if (useCookies) {
            builder.cookieJar(mCookieJar);
        }
        if (isDebug) {
            builder.addInterceptor(new LoggingInterceptor());
        }
        return builder;
    }

    public static OkHttpClient getNewHttpClient(boolean isDebug, boolean useCookies) {
       return getNewHttpClientBuilder(isDebug, useCookies).build();
    }

}

Перехватчик протоколирования используется в режиме отладки, чтобы распечатать информацию о запросе, а экземпляр банка cookie является общим. так что если запросы должны использовать общий обработчик файлов cookie, они могут. Эти файлы cookie не будут сохраняться при запуске приложений, но это не является обязательным требованием для моего приложения, поскольку мы используем сеансы на основе токенов, и единственная потребность в куках - это короткое время между входом в систему и созданием токена.

Примечание: BasicCookieJar - это то же самое, что и gncabrera MyCookieJar

Ответ 9

Я могу показать вам библиотеку, позволяющую OkHttp3 автоматически обрабатывать файлы cookie. Его можно легко использовать.

Просто храните файлы cookie в памяти, чтобы сделать упорство, если вам нужно. Запуск в среде Android и Pure Java.

    String url = "https://example.com/webapi";

    OkHttp3CookieHelper cookieHelper = new OkHttp3CookieHelper();

    OkHttpClient client = new OkHttpClient.Builder()
            .cookieJar(cookieHelper.cookieJar())
            .build();

    Request request = new Request.Builder()
            .url(url)
            .build();

Gradle

compile 'org.riversun:okhttp3-cookie-helper:1.0.0'

Maven

<dependency>
<groupId>org.riversun</groupId>
<artifactId>okhttp3-cookie-helper</artifactId>
<version>1.0.0</version>
</dependency>