Retrofit 2's documentation says:
Headers that need to be added to every request can be specified using an OkHttp interceptor.
It can be done easily using the previous version, here's the related QA.
But using retrofit 2, I couldn't find something like setRequestInterceptor
or setInterceptor
method that can be applied to Retrofit.Builder
object.
Also it seems that there's no RequestInterceptor
in OkHttp anymore. Retrofit's doc refers us to Interceptor that I didn't quite understand how to use it for this purpose.
How can I do this?
This question is related to
java
android
header
httprequest
retrofit
In kotlin adding interceptor looks that way:
.addInterceptor{ it.proceed(it.request().newBuilder().addHeader("Cache-Control", "no-store").build())}
For Logging your request and response you need an interceptor and also for setting the header you need an interceptor, Here's the solution for adding both the interceptor at once using retrofit 2.1
public OkHttpClient getHeader(final String authorizationValue ) {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient okClient = new OkHttpClient.Builder()
.addInterceptor(interceptor)
.addNetworkInterceptor(
new Interceptor() {
@Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request request = null;
if (authorizationValue != null) {
Log.d("--Authorization-- ", authorizationValue);
Request original = chain.request();
// Request customization: add request headers
Request.Builder requestBuilder = original.newBuilder()
.addHeader("Authorization", authorizationValue);
request = requestBuilder.build();
}
return chain.proceed(request);
}
})
.build();
return okClient;
}
Now in your retrofit object add this header in the client
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(url)
.client(getHeader(authorizationValue))
.addConverterFactory(GsonConverterFactory.create())
.build();
Try this type header for Retrofit 1.9 and 2.0. For Json Content Type.
@Headers({"Accept: application/json"})
@POST("user/classes")
Call<playlist> addToPlaylist(@Body PlaylistParm parm);
You can add many more headers i.e
@Headers({
"Accept: application/json",
"User-Agent: Your-App-Name",
"Cache-Control: max-age=640000"
})
Dynamically Add to headers:
@POST("user/classes")
Call<ResponseModel> addToPlaylist(@Header("Content-Type") String content_type, @Body RequestModel req);
Call you method i.e
mAPI.addToPlayList("application/json", playListParam);
Or
Want to pass everytime then Create HttpClient object with http Interceptor:
OkHttpClient httpClient = new OkHttpClient();
httpClient.networkInterceptors().add(new Interceptor() {
@Override
public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
Request.Builder requestBuilder = chain.request().newBuilder();
requestBuilder.header("Content-Type", "application/json");
return chain.proceed(requestBuilder.build());
}
});
Then add to retrofit object
Retrofit retrofit = new Retrofit.Builder().baseUrl(BASE_URL).client(httpClient).build();
UPDATE if you are using Kotlin remove the { }
else it will not work
If you use addInterceptor method for add HttpLoggingInterceptor, it won't be logging the things that added by other interceptors applied later than HttpLoggingInterceptor.
For example: If you have two interceptors "HttpLoggingInterceptor" and "AuthInterceptor", and HttpLoggingInterceptor applied first, then you can't view the http-params or headers which set by AuthInterceptor.
OkHttpClient.Builder builder = new OkHttpClient.Builder()
.addNetworkInterceptor(logging)
.addInterceptor(new AuthInterceptor());
I solved it, via using addNetworkInterceptor method.
lambda version:
builder.addInterceptor(chain -> {
Request request = chain.request().newBuilder().addHeader("key", "value").build();
return chain.proceed(request);
});
ugly long version:
builder.addInterceptor(new Interceptor() {
@Override public Response intercept(Chain chain) throws IOException {
Request request = chain.request().newBuilder().addHeader("key", "value").build();
return chain.proceed(request);
}
});
full version:
class Factory {
public static APIService create(Context context) {
OkHttpClient.Builder builder = new OkHttpClient().newBuilder();
builder.readTimeout(10, TimeUnit.SECONDS);
builder.connectTimeout(5, TimeUnit.SECONDS);
if (BuildConfig.DEBUG) {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BASIC);
builder.addInterceptor(interceptor);
}
builder.addInterceptor(chain -> {
Request request = chain.request().newBuilder().addHeader("key", "value").build();
return chain.proceed(request);
});
builder.addInterceptor(new UnauthorisedInterceptor(context));
OkHttpClient client = builder.build();
Retrofit retrofit =
new Retrofit.Builder().baseUrl(APIService.ENDPOINT).client(client).addConverterFactory(GsonConverterFactory.create()).addCallAdapterFactory(RxJavaCallAdapterFactory.create()).build();
return retrofit.create(APIService.class);
}
}
gradle file (you need to add the logging interceptor if you plan to use it):
//----- Retrofit
compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile "com.squareup.retrofit2:converter-gson:2.1.0"
compile "com.squareup.retrofit2:adapter-rxjava:2.1.0"
compile 'com.squareup.okhttp3:logging-interceptor:3.4.0'
RetrofitHelper library written in kotlin, will let you make API calls, using a few lines of code.
Add headers in your application class like this :
class Application : Application() {
override fun onCreate() {
super.onCreate()
retrofitClient = RetrofitClient.instance
//api url
.setBaseUrl("https://reqres.in/")
//you can set multiple urls
// .setUrl("example","http://ngrok.io/api/")
//set timeouts
.setConnectionTimeout(4)
.setReadingTimeout(15)
//enable cache
.enableCaching(this)
//add Headers
.addHeader("Content-Type", "application/json")
.addHeader("client", "android")
.addHeader("language", Locale.getDefault().language)
.addHeader("os", android.os.Build.VERSION.RELEASE)
}
companion object {
lateinit var retrofitClient: RetrofitClient
}
}
And then make your call:
retrofitClient.Get<GetResponseModel>()
//set path
.setPath("api/users/2")
//set url params Key-Value or HashMap
.setUrlParams("KEY","Value")
// you can add header here
.addHeaders("key","value")
.setResponseHandler(GetResponseModel::class.java,
object : ResponseHandler<GetResponseModel>() {
override fun onSuccess(response: Response<GetResponseModel>) {
super.onSuccess(response)
//handle response
}
}).run(this)
For more information see the documentation
In my case addInterceptor()
didn't work to add HTTP headers to my request, I had to use addNetworkInterceptor()
. Code is as follows:
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.addNetworkInterceptor(new AddHeaderInterceptor());
And the interceptor code:
public class AddHeaderInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request.Builder builder = chain.request().newBuilder();
builder.addHeader("Authorization", "MyauthHeaderContent");
return chain.proceed(builder.build());
}
}
This and more examples on this gist
Use this Retrofit Client
class RetrofitClient2(context: Context) : OkHttpClient() {
private var mContext:Context = context
private var retrofit: Retrofit? = null
val client: Retrofit?
get() {
val logging = HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)
val client = OkHttpClient.Builder()
.connectTimeout(Constants.TIME_OUT, TimeUnit.SECONDS)
.readTimeout(Constants.TIME_OUT, TimeUnit.SECONDS)
.writeTimeout(Constants.TIME_OUT, TimeUnit.SECONDS)
client.addInterceptor(logging)
client.interceptors().add(AddCookiesInterceptor(mContext))
val gson = GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").create()
if (retrofit == null) {
retrofit = Retrofit.Builder()
.baseUrl(Constants.URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.client(client.build())
.build()
}
return retrofit
}
}
I'm passing the JWT along with every request. Please don't mind the variable names, it's a bit confusing.
class AddCookiesInterceptor(context: Context) : Interceptor {
val mContext: Context = context
@Throws(IOException::class)
override fun intercept(chain: Interceptor.Chain): Response {
val builder = chain.request().newBuilder()
val preferences = CookieStore().getCookies(mContext)
if (preferences != null) {
for (cookie in preferences!!) {
builder.addHeader("Authorization", cookie)
}
}
return chain.proceed(builder.build())
}
}
Kotlin version would be
fun getHeaderInterceptor():Interceptor{
return object : Interceptor {
@Throws(IOException::class)
override fun intercept(chain: Interceptor.Chain): Response {
val request =
chain.request().newBuilder()
.header(Headers.KEY_AUTHORIZATION, "Bearer.....")
.build()
return chain.proceed(request)
}
}
}
private fun createOkHttpClient(): OkHttpClient {
return OkHttpClient.Builder()
.apply {
if(BuildConfig.DEBUG){
this.addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BASIC))
}
}
.addInterceptor(getHeaderInterceptor())
.build()
}
Source: Stackoverflow.com