使用 OkHttp 3 自动处理 cookie
Automatic cookie handling with OkHttp 3
我正在使用 okhttp 3.0.1。
我在每个地方都得到了使用 okhttp2 处理 cookie 的示例
OkHttpClient client = new OkHttpClient();
CookieManager cookieManager = new CookieManager();
cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
client.setCookieHandler(cookieManager);
请谁指导我如何在版本 3 中使用。setCookieHandler 方法在版本 3 中不存在。
在这里,您有一个创建自己的 CookieJar 的简单方法。它可以根据需要扩展。我所做的是实现一个 CookieJar 并使用 OkHttpClient.Builder 和这个 CookieJar.
构建 OkHttpClient
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();
现在我正在玩它。
尝试 PersistentCookieStore,为 JavaNetCookieJar 添加 gradle 依赖项:
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();
`
如果您想使用新的 OkHttp 3 CookieJar 并摆脱 okhttp-urlconnection
依赖项,您可以使用此 PersistentCookieJar.
您只需要创建一个 PersistentCookieJar
的实例,然后将其传递给 OkHttp
构建器:
CookieJar cookieJar =
new PersistentCookieJar(new SetCookieCache(), new SharedPrefsCookiePersistor(context));
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.cookieJar(cookieJar)
.build();
我使用了@gncabrera 的解决方案,但也创建了一个帮助程序 class 来帮助初始化并使跨应用程序共享 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 jar实例。跨调用者,以便如果请求需要使用通用的 cookie 处理程序,他们可以。这些 cookie 不会在应用程序启动时持续存在,但这不是我的应用程序的要求,因为我们使用基于令牌的会话,唯一需要 cookie 的是登录和生成令牌之间的短时间。
注意:
BasicCookieJar 与 gncabrera 的 MyCookieJar
实现相同
这里是 OkHttp3 的 CookieJar 实现。如果您有多个 OkHttp3 实例(通常您应该只有一个实例并将其用作单例),您应该为所有 http 客户端设置相同的 cookiejar 实例,以便它们可以共享 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();
我为 okhttp3 和 retrofit.2 使用了 franmontiel PeristentCookieJar 库。这种方法的好处是:不需要操纵您的 okhttp 请求。创建改造时只需设置 cookies 或 session
1. 首先将其添加到您的 build.gradle(projectname)
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;
}
我可以向您展示一个让 OkHttp3 自动处理 cookie 的库。它可以很容易地使用。
只需将 cookie 保留在内存中,以便在需要时自行持久化。
运行 Android 和纯 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>
正在将 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 的那个之外,没有添加任何第三方依赖项就帮助了我。
在第一个 运行
之后保留 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中尝试:
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")
}
将实现 "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()
}
如果您将 Kotlin 与 dagger 或 hilt 一起使用并注入 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 的同一模块(数据)上添加依赖项
我正在使用 okhttp 3.0.1。
我在每个地方都得到了使用 okhttp2 处理 cookie 的示例
OkHttpClient client = new OkHttpClient();
CookieManager cookieManager = new CookieManager();
cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
client.setCookieHandler(cookieManager);
请谁指导我如何在版本 3 中使用。setCookieHandler 方法在版本 3 中不存在。
在这里,您有一个创建自己的 CookieJar 的简单方法。它可以根据需要扩展。我所做的是实现一个 CookieJar 并使用 OkHttpClient.Builder 和这个 CookieJar.
构建 OkHttpClientpublic 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();
现在我正在玩它。 尝试 PersistentCookieStore,为 JavaNetCookieJar 添加 gradle 依赖项:
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();
`
如果您想使用新的 OkHttp 3 CookieJar 并摆脱 okhttp-urlconnection
依赖项,您可以使用此 PersistentCookieJar.
您只需要创建一个 PersistentCookieJar
的实例,然后将其传递给 OkHttp
构建器:
CookieJar cookieJar =
new PersistentCookieJar(new SetCookieCache(), new SharedPrefsCookiePersistor(context));
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.cookieJar(cookieJar)
.build();
我使用了@gncabrera 的解决方案,但也创建了一个帮助程序 class 来帮助初始化并使跨应用程序共享 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 jar实例。跨调用者,以便如果请求需要使用通用的 cookie 处理程序,他们可以。这些 cookie 不会在应用程序启动时持续存在,但这不是我的应用程序的要求,因为我们使用基于令牌的会话,唯一需要 cookie 的是登录和生成令牌之间的短时间。
注意: BasicCookieJar 与 gncabrera 的 MyCookieJar
实现相同这里是 OkHttp3 的 CookieJar 实现。如果您有多个 OkHttp3 实例(通常您应该只有一个实例并将其用作单例),您应该为所有 http 客户端设置相同的 cookiejar 实例,以便它们可以共享 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();
我为 okhttp3 和 retrofit.2 使用了 franmontiel PeristentCookieJar 库。这种方法的好处是:不需要操纵您的 okhttp 请求。创建改造时只需设置 cookies 或 session
1. 首先将其添加到您的 build.gradle(projectname) 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;
}
我可以向您展示一个让 OkHttp3 自动处理 cookie 的库。它可以很容易地使用。
只需将 cookie 保留在内存中,以便在需要时自行持久化。 运行 Android 和纯 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>
正在将 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 的那个之外,没有添加任何第三方依赖项就帮助了我。
在第一个 运行
之后保留 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中尝试:
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")
}
将实现 "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()
}
如果您将 Kotlin 与 dagger 或 hilt 一起使用并注入 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 的同一模块(数据)上添加依赖项