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