Adding header to all request with Retrofit 2

JavaAndroidHeaderHttprequestRetrofit

Java Problem Overview


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?

Java Solutions


Solution 1 - Java

OkHttpClient.Builder httpClient = new OkHttpClient.Builder();

httpClient.addInterceptor(new Interceptor() {
	@Override
	public Response intercept(Chain chain) throws IOException {
		Request request = chain.request().newBuilder().addHeader("parameter", "value").build();
		return chain.proceed(request);
	}
});
Retrofit retrofit = new Retrofit.Builder().addConverterFactory(GsonConverterFactory.create()).baseUrl(url).client(httpClient.build()).build();

Solution 2 - Java

The Latest Retrofit Version HERE -> 2.1.0.

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'

Solution 3 - Java

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

Solution 4 - Java

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

Solution 5 - Java

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

Solution 6 - Java

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.

Solution 7 - Java

In kotlin adding interceptor looks that way:

.addInterceptor{ it.proceed(it.request().newBuilder().addHeader("Cache-Control", "no-store").build())}

Solution 8 - Java

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

Solution 9 - Java

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

Solution 10 - Java

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAshkan SarlakView Question on Stackoverflow
Solution 1 - Javadtx12View Answer on Stackoverflow
Solution 2 - JavaOWADVLView Answer on Stackoverflow
Solution 3 - JavaAvinash VermaView Answer on Stackoverflow
Solution 4 - Javaswetabh sumanView Answer on Stackoverflow
Solution 5 - JavavoghDevView Answer on Stackoverflow
Solution 6 - JavaGallyamovView Answer on Stackoverflow
Solution 7 - JavaDamian JKView Answer on Stackoverflow
Solution 8 - JavaNishant RaiView Answer on Stackoverflow
Solution 9 - JavaMojtaba RazaghiView Answer on Stackoverflow
Solution 10 - JavaAbu YousufView Answer on Stackoverflow