Автоматическая обработка cookie с помощью OkHttp 3
Я использую охтпп 3.0.1.
Каждый раз, где я получаю пример для обработки файлов cookie, которые с okhttp2
OkHttpClient client = new OkHttpClient();
CookieManager cookieManager = new CookieManager();
cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
client.setCookieHandler(cookieManager);
Может, кто-нибудь подскажет, как использовать в версии 3. Метод setCookieHandler отсутствует в версии 3.
12 ответов
Сейчас я играю с этим. попробуйте PersistentCookieStore, добавьте зависимости gradle для JavaNetCookieJar:
compile "com.squareup.okhttp3:okhttp-urlconnection:3.0.0-RC1"
и инициация
// 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();
`
Если вы хотите использовать новый OkJttp 3 CookieJar и избавиться от okhttp-urlconnection
зависимость вы можете использовать этот PersistentCookieJar.
Вам нужно только создать экземпляр PersistentCookieJar
а затем просто передать его OkHttp
строитель:
CookieJar cookieJar =
new PersistentCookieJar(new SetCookieCache(), new SharedPrefsCookiePersistor(context));
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.cookieJar(cookieJar)
.build();
Здесь у вас есть простой подход к созданию собственного 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();
Добавление 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.
Здесь работает реализация CookieJar для OkHttp3. Если у вас есть несколько экземпляров OkHttp3 (обычно вы должны иметь только один экземпляр и использовать его в качестве одиночного), вы должны установить один и тот же экземпляр cookiejar для всех клиентов http, чтобы они могли делиться файлами cookie!!! В этой реализации не сохраняются файлы cookie (все они будут удалены при перезапуске приложения), но должно быть легко реализовать постоянство SharedPreferences вместо списка файлов cookie в памяти (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();
Я использовал библиотеку https://github.com/franmontiel/PersistentCookieJar для okhttp3 и дооснащения.2. Преимущество такого подхода заключается в следующем: не нужно манипулировать вашим запросом охттп. Просто установите куки или сеанс при создании модернизации
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;
}
Вы можете попробовать это в Котлине:
val cookieJar = JavaNetCookieJar(CookieManager())
val url = "https://www.google.com/"
val requestBuilder = Request
.Builder()
.url(url)
.get()
val request = requestBuilder
.build()
val response = OkHttpClient.Builder()
.cookieJar(cookieJar)
.build()
.newCall(request)
.execute()
Gradle
dependencies {
implementation("com.squareup.okhttp3:okhttp:4.2.2")
implementation("com.squareup.okhttp3:okhttp-urlconnection:4.2.2")
}
Минимальное решение, которое сохраняет 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;
}
}
если вы используете Kotlin с кинжалом или рукоятью и вводите свой Okhttp, вы можете добавить
implementation 'com.squareup.okhttp3:okhttp-urlconnection:4.9.0'
Я считаю, что версия должна быть такой же, как ваша версия okhttpclient.
@Provides
@Singleton
fun providesOkHTTPClient(application: Application): OkHttpClient {
val cookieManager = CookieManager()
cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL)
return OkHttpClient.Builder()
.cookieJar(JavaNetCookieJar(cookieManager))
.addInterceptor(
ChuckInterceptor(application)
.showNotification(true)
.retainDataFor(ChuckInterceptor.Period.ONE_DAY)
).addInterceptor(
HttpLoggingInterceptor().setLevel(
if (BuildConfig.DEBUG) HttpLoggingInterceptor.Level.BODY
else HttpLoggingInterceptor.Level.NONE
)
).build()
}
не забудьте добавить зависимость от того же модуля (данных), где вы предоставляете okhttpClient
Я использовал решение @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 не сохраняются при запуске приложений, но это не является обязательным требованием для моего приложения, поскольку мы используем сеансы на основе токенов, и единственная потребность в файлах cookie - это короткое время между входом в систему и генерацией токена.
Примечание: BasicCookieJar - это та же самая реализация, что и MyCookieJar от gncabrera.
Добавьте реализацию com.squareup.okhttp3:okhttp-urlconnection:3.8.1 в свой build.gradle.
var interceptor = HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)
var cookieHandler: CookieHandler = CookieManager()
private var retrofit: Retrofit? = null
retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.client(client)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build()
private val client : OkHttpClient
private get() {
val builder = OkHttpClient.Builder()
builder.addNetworkInterceptor(interceptor)
builder.cookieJar(JavaNetCookieJar(cookieHandler))
builder.connectTimeout(15, TimeUnit.SECONDS)
builder.readTimeout(20, TimeUnit.SECONDS)
builder.writeTimeout(20, TimeUnit.SECONDS)
builder.retryOnConnectionFailure(true)
return builder.build()
}
Я могу показать вам библиотеку, позволяющую OkHttp3 автоматически обрабатывать файлы 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'
специалист
<dependency>
<groupId>org.riversun</groupId>
<artifactId>okhttp3-cookie-helper</artifactId>
<version>1.0.0</version>
</dependency>