Reputation: 811
I am using okhttp 3.0.1.
Every where I am getting example for cookie handling that is with okhttp2
OkHttpClient client = new OkHttpClient();
CookieManager cookieManager = new CookieManager();
cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
client.setCookieHandler(cookieManager);
Can please some one guide me how to use in version 3. setCookieHandler method is not present in the version 3.
Upvotes: 58
Views: 87759
Reputation: 729
if you use Kotlin with dagger or hilt and you inject your Okhttp, you can add
implementation 'com.squareup.okhttp3:okhttp-urlconnection:4.9.0'
I feel the version should be the same as your okhttpclient version.
@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()
}
remember to add the dependency on the same module (data) where you are providing okhttpClient
Upvotes: 0
Reputation: 679
Add implementation "com.squareup.okhttp3:okhttp-urlconnection:3.8.1" into your 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()
}
Upvotes: 0
Reputation: 51
You can try it in 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")
}
Upvotes: 4
Reputation: 13143
minimal solution that persists cookie after first run
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;
}
}
with dagger
@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;
}
}
Upvotes: 2
Reputation: 2757
Adding compile "com.squareup.okhttp3:okhttp-urlconnection:3.8.1"
to your build.gradle.
And then adding
CookieManager cookieManager = new CookieManager();
cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
OkHttpClient defaultHttpClient = new OkHttpClient.Builder()
.cookieJar(new JavaNetCookieJar(cookieManager))
.build()
helped me without adding any third-party dependency except the one from OkHttp.
Upvotes: 19
Reputation: 1343
i used franmontiel PeristentCookieJar library for okhttp3 and retrofit.2. the benefit of this approach is : not need manipulate your okhttp request. Just set cookies or session when creating retrofit
1. first add this to your build.gradle(projectname) allprojects {
repositories {
jcenter()
maven { url "https://jitpack.io" }
}
}
2. add this to your build.gradle
compile 'com.github.franmontiel:PersistentCookieJar:v1.0.1'
3. build retrofit like this
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;
}
Upvotes: 5
Reputation: 449
Here is working CookieJar implementation for OkHttp3. If you have multiple instances of OkHttp3 (usually you should have only one instance and use it as singletone) you should set the same instance of cookiejar to all of the http clients so they can share cookies !!! This implementation is not persisting cookies(they will all be discard on application restart) but it should be easy to implement SharedPreferences persistence instead of in-memory list of cookies(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();
Upvotes: 17
Reputation: 838
I can show you a library for letting OkHttp3 handle cookies automatically. It can be used easily.
Just Keep cookies on memory, to do persistence yourself if you need. Run on Android and Pure Java environment.
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>
Upvotes: -1
Reputation: 9284
I used @gncabrera's solution but also created a helper class to help with initialization and also to make it easy to share a CookieJar across the application.
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();
}
}
The logging interceptor is used in debug mode to print out request information and the cookie jar instance is shared. across callers so that if requests need to use a common cookie handler they can. These cookies won't persist across app launches but that's not a requirement for my application since we use token based sessions and the only need for cookies is the short time between logging in and generating the token.
Note: BasicCookieJar is just the same implementation as gncabrera's MyCookieJar
Upvotes: 0
Reputation: 1910
If you want to use the new OkHttp 3 CookieJar and get rid of the okhttp-urlconnection
dependency you can use this PersistentCookieJar.
You only need to create an instance of PersistentCookieJar
and then just pass it to the OkHttp
builder:
CookieJar cookieJar =
new PersistentCookieJar(new SetCookieCache(), new SharedPrefsCookiePersistor(context));
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.cookieJar(cookieJar)
.build();
Upvotes: 70
Reputation: 575
right now I'm playing with it. try PersistentCookieStore, add gradle dependencies for JavaNetCookieJar:
compile "com.squareup.okhttp3:okhttp-urlconnection:3.0.0-RC1"
and 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();
`
Upvotes: 36
Reputation: 645
Here you have a simple approach to create your own CookieJar. It can be extended as you wish. What I did is to implement a CookieJar and build the OkHttpClient using the OkHttpClient.Builder with this this CookieJar.
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>();
}
}
Here is how you can create the OkHttpClient
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.cookieJar(new MyCookieJar());
OkHttpClient client = builder.build();
Upvotes: 33