Cookies 使用OkHttp 3自动处理cookie

Cookies 使用OkHttp 3自动处理cookie,cookies,okhttp3,Cookies,Okhttp3,我正在使用OKHTTP3.0.1 我得到的每一个关于cookie处理的例子都是okhttp2 OkHttpClient client = new OkHttpClient(); CookieManager cookieManager = new CookieManager(); cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL); client.setCookieHandler(cookieManager); 可以请一些人指导我如何在版

我正在使用OKHTTP3.0.1

我得到的每一个关于cookie处理的例子都是okhttp2

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

    } 
}

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

编译“com.squareup.okhttp3:okhttpurlconnection:3.0.0-RC1”

和初始化

//初始化cookie管理器
CookieHandler CookieHandler=新建CookieManager(
新的PersistentCookieStore(ctx)、CookiePolicy.ACCEPT_ALL);
//init-okhttp3记录器
HttpLoggingInterceptor logging=新的HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
//init-OkHttpClient
OkHttpClient httpClient=新建OkHttpClient.Builder()
.cookieJar(新JavaNetCookieJar(cookieHandler))
.addInterceptor(日志记录)
.build();

`

如果您想使用新的OkHttp 3 CookieJar并摆脱
OkHttp urlconnection
依赖关系,您可以使用它

您只需创建一个
PersistentCookieJar
实例,然后将其传递给
OkHttp
builder:

CookieJar CookieJar=
新的PersistentCookieJar(新的SetCookieCache(),新的SharedPrefscookePersistor(上下文));
OkHttpClient OkHttpClient=新建OkHttpClient.Builder()
.cookieJar(cookieJar)
.build();

我使用了@gncabrera的解决方案,但也创建了一个helper类来帮助初始化,并使在整个应用程序中共享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();
    }

}
日志侦听器在调试模式下用于打印请求信息,并共享CookieJAR实例。跨调用者,以便如果请求需要使用公共cookie处理程序,它们可以。这些cookie不会在应用程序启动时持续存在,但这不是我的应用程序的要求,因为我们使用基于令牌的会话,cookie的唯一需要是登录和生成令牌之间的短时间

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

这里是OkHttp3的CookieJar实现。如果您有多个OkHttp3实例(通常您应该只有一个实例并将其用作单音),那么您应该为所有http客户端设置相同的cookiejar实例,以便它们可以共享cookies!!!此实现不是持久化cookie(它们在应用程序重新启动时都将被丢弃),但实现SharedReferences持久化应该很容易,而不是内存中的cookie列表(cookieStore)

CookieJar-CookieJar=new-CookieJar(){
private final HashMap cookieStore=新HashMap();
@凌驾
public void saveFromResponse(HttpUrl、列表cookie){
cookieStore.put(url.host(),cookies);
}
@凌驾
公共列表loadForRequest(HttpUrl url){
List cookies=cookieStore.get(url.host());
返回cookies!=null?cookies:new ArrayList();
}
};
OkHttpClient httpClient=新建OkHttpClient.Builder()
.cookieJar(cookieJar)
.build();
我使用库进行okhttp3和改装。这种方法的好处是:不需要操纵您的okhttp请求。创建改装时只需设置cookie或会话

1.首先将其添加到build.gradle(projectname)中
    compile 'com.github.franmontiel:PersistentCookieJar:v1.0.1'
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自动处理cookies。它可以很容易地使用

只要把cookies保存在内存中,如果需要的话,自己做持久化。 在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'
dependencies {
    implementation("com.squareup.okhttp3:okhttp:4.2.2")
    implementation("com.squareup.okhttp3:okhttp-urlconnection:4.2.2")
}
Maven

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

org.riversiun
okhttp3 cookie帮助程序
1.0.0
编译“com.squareup.okhttp3:okhttpurlconnection:3.8.1”
添加到build.gradle中

    compile 'com.github.franmontiel:PersistentCookieJar:v1.0.1'
然后加上

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

}

您可以在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

compile 'org.riversun:okhttp3-cookie-helper:1.0.0'
dependencies {
    implementation("com.squareup.okhttp3:okhttp:4.2.2")
    implementation("com.squareup.okhttp3:okhttp-urlconnection:4.2.2")
}

将实现“com.squareup.okhttp3:okhttpurlconnection:3.8.1”添加到build.gradle中。

    compile 'com.github.franmontiel:PersistentCookieJar:v1.0.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()
            }

非常感谢你的方法。对我来说效果很好。很棒的朋友为此浪费了2天。。。终于用你的方法实现了。对于使用改型2的用户,请使用jar而不是persistancecookie store类。@franmontiel库工作正常,但当我们关闭应用程序并返回应用程序时,它不会持久保存Cookie,因此api在第一次调用web api时就获得了新的Cookie。我有一个ur库实例,并从应用程序类调用。你能告诉我怎么更正吗?@AshuKumar可能是因为你的饼干没有过期日期。这将使它们成为会话cookies,因此它们不应被持久化。感谢您回复我。真的非常感谢@弗兰蒙蒂尔。我的应用程序要求是不要让cookie过期,如果cookie过期,则会话将不相同,因此客户将自动注销。如果你能给我一些解决方案或解决方法,那会更好。仅供参考:在不久的将来,他们计划删除okhttp urlconnection模块。github.com/square/okhttp/blob/master/CHANGELOG.md这实际上非常有效!我的猜测是,抱怨它不起作用的人没有意识到他们需要在整个应用程序中使用相同的mycokiejar实例,以便cookies在其他地方起作用。。此外,他们还需要了解,自t