使用OkHttp 3进行自动cookie处理

时间:2016-01-19 16:19:45

标签: cookies okhttp3

我正在使用okhttp 3.0.1。

我正在获取与okhttp2

一起进行cookie处理的示例
OkHttpClient client = new OkHttpClient();
CookieManager cookieManager = new CookieManager();
cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
client.setCookieHandler(cookieManager);

可以请一些人指导我如何在版本3中使用。在版本3中不存在setCookieHandler方法。

11 个答案:

答案 0 :(得分:50)

如果您想使用新的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();

答案 1 :(得分:31)

现在我正在玩它。 尝试PersistentCookieStore,为 JavaNetCookieJar 添加gradle依赖项:

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 :(得分:16)

这里有一个简单的方法来创建自己的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();

答案 3 :(得分:11)

这是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();

答案 4 :(得分:9)

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的那个。

答案 5 :(得分:4)

我将franmontiel PeristentCookieJar库用于okhttp3和retrofit.2。这种方法的好处是:不需要操纵你的okhttp请求。只需在创建改造时设置cookie或会话

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;
        }

答案 6 :(得分: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;
    }
}

答案 7 :(得分:1)

您可以在科特林中尝试:

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()

成绩

dependencies {
    implementation("com.squareup.okhttp3:okhttp:4.2.2")
    implementation("com.squareup.okhttp3:okhttp-urlconnection:4.2.2")
}

答案 8 :(得分:0)

我使用了@ 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 jar实例。跨越调用者,以便如果请求需要使用常见的cookie处理程序,他们可以。这些cookie不会在应用程序启动时持续存在,但这不是我的应用程序的要求,因为我们使用基于令牌的会话,而且只需要cookie就是登录和生成令牌之间的短暂时间。

注意: BasicCookieJar与gncabrera的MyCookieJar实现相同

答案 9 :(得分:0)

在您的build.gradle中添加实现“ com.squareup.okhttp3:okhttp-urlconnection:3.8.1”。

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()
            }

答案 10 :(得分:-1)

我可以向您展示一个库,让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();

<强>摇篮

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>