wake-up-neo.net

Automatisches Cookie-Handling mit OkHttp 3

Ich benutze okhttp 3.0.1. 

Ich bekomme überall, wo ich ein Beispiel für das Cookie-Handling bekomme, das mit okhttp2 

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

Kann mir bitte einer helfen, wie man mit Version 3 arbeitet. Die setCookieHandler-Methode ist in Version 3 nicht vorhanden.

27
user2672763

im Moment spiele ich damit. try PersistentCookieStore , füge gradle Abhängigkeiten für JavaNetCookieJar hinzu:

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

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

`

29
1f7

Wenn Sie den neuen OkHttp 3 CookieJar verwenden und die okhttp-urlconnection-Abhängigkeit beseitigen möchten, können Sie diese PersistentCookieJar verwenden.

Sie müssen lediglich eine Instanz von PersistentCookieJar erstellen und diese dann einfach an den Builder OkHttp übergeben:

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

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

Hier haben Sie einen einfachen Ansatz, um Ihr eigenes CookieJar zu erstellen. Sie kann beliebig erweitert werden. Was ich getan habe, ist ein CookieJar zu implementieren und den OkHttpClient mithilfe des OkHttpClient.Builder mit diesem CookieJar zu erstellen.

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

    } 
}

So erstellen Sie den OkHttpClient

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

Hier ist die CookieJar-Implementierung für OkHttp3. Wenn Sie mehrere Instanzen von OkHttp3 haben (normalerweise sollten Sie nur eine Instanz haben und diese als Singletone verwenden), sollten Sie dieselbe Instanz von CookieJar auf alle http-Clients setzen, damit sie Cookies freigeben können. Diese Implementierung enthält keine Cookies (sie werden alle beim Neustart der Anwendung verworfen), es sollte jedoch einfach sein, die SharedPreferences-Persistenz anstelle der Liste der Cookies im Speicher (cookieStore) zu implementieren.

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

Hinzufügen von compile "com.squareup.okhttp3:okhttp-urlconnection:3.8.1" zu Ihrem build.gradle.

Und dann hinzufügen 

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

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

hat mir geholfen, ohne die Abhängigkeit von Drittanbietern außer der von OkHttp hinzuzufügen.

7
Shubham

ich habe franmontiel PeristentCookieJar library für okhttp3 und retrofit.2 verwendet. Der Vorteil dieses Ansatzes ist, dass Sie Ihre okhttp-Anfrage nicht bearbeiten müssen. Setzen Sie beim Erstellen von Retrofit einfach Cookies oder Sitzungen

 allprojects {
     repositories {
         jcenter()
         maven { url "https://jitpack.io" }
     }
 }
    compile 'com.github.franmontiel:PersistentCookieJar:v1.0.1'
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;
        }
4
iman kazemayni

minimale Lösung, die den Cookie nach dem ersten Durchlauf beibehält

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

}

mit Dolch

@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;
    }
}
2
Vihaan Verma

Ich habe die Lösung von @ gncabrera verwendet, aber auch eine Hilfsklasse erstellt, die bei der Initialisierung hilft und auch das Teilen von CookieJar in der gesamten Anwendung erleichtert.

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

}

Der Protokollierungs-Interceptor wird im Debug-Modus verwendet, um Anforderungsinformationen auszudrucken, und die Cookie-Jar-Instanz wird gemeinsam genutzt. Anrufer, so dass bei Anfragen ein gemeinsamer Cookie-Handler verwendet werden kann. Diese Cookies bleiben nicht über App-Starts hinweg bestehen. Dies ist jedoch keine Anforderung für meine Anwendung, da wir tokenbasierte Sitzungen verwenden. Die einzige Notwendigkeit für Cookies besteht in der kurzen Zeit zwischen dem Anmelden und dem Generieren des Tokens.

Hinweis: BasicCookieJar ist genau dieselbe Implementierung wie gncabreras MyCookieJar

0
Matt Wolfe