-
-
Save nikhiljha/52d45ca69a8415c6990d2a63f61184ff to your computer and use it in GitHub Desktop.
// By Nikhil Jha | |
// License MIT | |
// DON'T ADD THIS FILE TO YOUR OTHER CLASSES | |
// THIS IS AN EXAMPLE TO TEACH YOU HOW TO MAKE REQUESTS WITH THE MAGIC COOKIES | |
OkHttpClient client = new OkHttpClient(); | |
OkHttpClient.Builder builder = new OkHttpClient.Builder(); | |
builder.addInterceptor(new AddCookiesInterceptor(context)); // VERY VERY IMPORTANT | |
builder.addInterceptor(new ReceivedCookiesInterceptor(context)); // VERY VERY IMPORTANT | |
client = builder.build(); | |
Retrofit retrofit = new Retrofit.Builder() | |
.baseUrl("my-base") // REQUIRED | |
.client(client) // VERY VERY IMPORTANT | |
.addConverterFactory(GsonConverterFactory.create()) | |
.build(); // REQUIRED | |
Your.ThingyClass = retrofit.create(Your.ThingyClass.class); | |
Call<...> call = yourclass.somecall(new yourclass(example, example)); |
अच्छे से काम किया कर भाई
Kotlin version, with helper method to create OkHttp client and Retrofit instance. May be useful ;)
CookieStore.kt
import android.content.Context
import android.preference.PreferenceManager
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.Response
import java.io.IOException
private val cookiesKey = "appCookies"
class SendSavedCookiesInterceptor(private val context: Context) : Interceptor {
@Throws(IOException::class)
override fun intercept(chain: Interceptor.Chain): Response {
val builder = chain.request().newBuilder()
val preferences = PreferenceManager
.getDefaultSharedPreferences(context)
.getStringSet(cookiesKey, HashSet()) as HashSet<String>
preferences.forEach {
builder.addHeader("Cookie", it)
}
return chain.proceed(builder.build())
}
}
class SaveReceivedCookiesInterceptor(private val context: Context) : Interceptor {
@JvmField
val setCookieHeader = "Set-Cookie"
@Throws(IOException::class)
override fun intercept(chain: Interceptor.Chain): Response {
val originalResponse = chain.proceed(chain.request())
if (!originalResponse.headers(setCookieHeader).isEmpty()) {
val cookies = PreferenceManager
.getDefaultSharedPreferences(context)
.getStringSet(cookiesKey, HashSet()) as HashSet<String>
originalResponse.headers(setCookieHeader).forEach {
cookies.add(it)
}
PreferenceManager
.getDefaultSharedPreferences(context)
.edit()
.putStringSet(cookiesKey, cookies)
.apply()
}
return originalResponse
}
}
fun OkHttpClient.Builder.setCookieStore(context: Context) : OkHttpClient.Builder {
return this
.addInterceptor(SendSavedCookiesInterceptor(context))
.addInterceptor(SaveReceivedCookiesInterceptor(context))
}
RetrofitHelper.kt
private val httpConnectTimeoutSeconds = 10
private val httpWriteTimeoutSeconds = 10
private val httpReadTimeoutSeconds = 10
val userAgent = "Your User Agent"
fun newHttpClient(context: Context): OkHttpClient {
val loggingInterceptor = HttpLoggingInterceptor { Log.d("OkHttp", it) }
loggingInterceptor.level = if (BuildConfig.DEBUG)
HttpLoggingInterceptor.Level.BODY // debug log level
else
HttpLoggingInterceptor.Level.NONE // release log level
return OkHttpClient.Builder()
.followRedirects(true)
.followSslRedirects(true)
.retryOnConnectionFailure(true)
.setCookieStore(context)
.addInterceptor(loggingInterceptor)
.addNetworkInterceptor { chain ->
val request = chain.request().newBuilder()
.header("User-Agent", userAgent)
.build()
chain.proceed(request)
}
.cache(null)
.connectTimeout(httpConnectTimeoutSeconds.toLong(), TimeUnit.SECONDS)
.writeTimeout(httpWriteTimeoutSeconds.toLong(), TimeUnit.SECONDS)
.readTimeout(httpReadTimeoutSeconds.toLong(), TimeUnit.SECONDS)
.build()
}
fun <T> newRetrofit(context: Context, baseUrl: String, service: Class<T>): T {
val retrofit = Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(newHttpClient(context))
.build()
return retrofit.create(service)
}
Then, for example in your application subclass, you can write:
class App: Application() {
val apiClient by lazy {
newRetrofit(this, "https://www.yourserver.com/api", YourAPI::class.java)
}
override fun onCreate() {
super.onCreate()
Log.i("App start", "App initialization")
// Do some other initializations
}
}
Thanks @gotev. Very useful classes.
Hi, it is kinda old so reply here. But I have one question. Do I have to call AddCookiesInterceptor and ReceiveCookiesInterceptor every time I have a query?
@makiabuan the interceptors needs to be added once in the http client. Make sure that all requests are using the same okhttp client.
You do not need to call anything. The interceptor does the work by itself.
Thank you very much, This work for me.
Lifesaver !! Thank you.
Anyone has problem on Android Pie with these interceptors? It seems that they are not triggered on Android 9, on other versions it works perfectly..
It seems that the problem was in CertificateFactory.getInstance("X.509", "BC"), X.509 is not found for Android 9. CertificateFactory.getInstance("X509") is the fix.
Thanks, Worked for me
Thanks Bro, its working.. :)
Great help. Thanks Bro.
yo bro thanks ,,, its working, you saved my ass :D
Great help. Thanks
I'm using hilt and am struggling to make 'context' available. Any suggestions?
I got it. My problem was trying to use @ApplicationContext as is (@ApplicationContext context: ApplicationContext). It works fine if you leave it as Context (@ApplicationContext context: Context)
I've pulled everything together for a Hilt-based solution at https://stackoverflow.com/questions/67950681/using-cookies-with-retrofit-and-hilt-and-recommended-architecture
Perfect, Thanks a lot