You’ve already learned how to add custom request header using Retrofit. This post specifically touches the details on adding request headers using Retrofit 2 and the OkHttp interceptor. Interceptors are a good way to statically change requests executed with the specific service client which has the interceptor assigned.
Retrofit Series Overview
- Getting Started and Creating an Android Client
- Basics of API Description
- Creating a Sustainable Android Client
- URL Handling, Resolution and Parsing
- How to Change API Base Url at Runtime
- Multiple Server Environments (Develop, Staging, Production)
- Share OkHttp Client and Converters between Retrofit Instances
- Upgrade Guide from 1.9
- Beyond Android: Retrofit for Java Projects
- How to use OkHttp 3 with Retrofit 1
- Synchronous and Asynchronous Requests
- Send Objects in Request Body
- Add Custom Request Header
- Manage Request Headers in OkHttp Interceptor
- Dynamic Request Headers with @HeaderMap
- Multiple Query Parameters of Same Name
- Optional Query Parameters
- Send Data Form-Urlencoded
- Send Data Form-Urlencoded Using FieldMap
- How to Add Query Parameters to Every Request
- Add Multiple Query Parameter With QueryMap
- How to Use Dynamic Urls for Requests
- Constant, Default and Logic Values for POST and PUT Requests
- Cancel Requests
- Reuse and Analyze Requests
- Optional Path Parameters
- How to Send Plain Text Request Body
- Customize Network Timeouts
- How to Trust Unsafe SSL certificates (Self-signed, Expired)
- Dynamic Endpoint-Dependent Interceptor Actions
- How to Update Objects on the Server (PUT vs. PATCH)
- How to Delete Objects on the Server
- Introduction to (Multiple) Converters
- Adding & Customizing the Gson Converter
- Implementing Custom Converters
- How to Integrate XML Converter
- Access Mapped Objects and Raw Response Payload
- Supporting JSON and XML Responses Concurrently
- Handling of Empty Server Responses with Custom Converter
- Send JSON Requests and Receive XML Responses (or vice versa)
- Unwrapping Envelope Responses with Custom Converter
- Wrapping Requests in Envelope with Custom Converter
- Define a Custom Response Converter
Add Request Headers
Adding HTTP request headers is a good practice to add information for API requests. A common example is authorization using the Authorization
header field. If you need the header field including its value on almost every request, you can use an interceptor to add this piece of information. This way, you don’t need to add the @Header
annotation to every endpoint declaration.
OkHttp interceptors offer two ways to add header fields and values. You can either override existing headers with the same key or just add them without checking if there is another header key-value-pair already existing. We’ll walk you through both of them in the following paragraphs.
How to Override Headers
Intercepting HTTP requests with the help of OkHttp interceptors allows you to manipulate the actual request and apply your customization. The request builder has a .header(key, val)
method which will add your defined header to the request. If there is already an existing header with the same key
identifier, this method will override the previously defined value.
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.addInterceptor(new Interceptor() {
@Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request original = chain.request();
// Request customization: add request headers
Request.Builder requestBuilder = original.newBuilder()
.header("Authorization", "auth-value"); // <-- this is the important line
Request request = requestBuilder.build();
return chain.proceed(request);
}
});
OkHttpClient client = httpClient.build();
Retrofit, and especially OkHttp, allow you to add multiple headers with the same key. The .header
method will replace all existing headers with the defined key identifier. Within the code snippet above, every Authorization
header (if multiple have been defined already) will be updated and their previous value will be replaced with auth-value
.
How to Not Override Headers
There are situations where multiple headers with the same name are used. Actually, we’re only aware of one specific example from practise: the Cache-Control
header. The HTTP RFC2616 specifies that multiple header values with the same name are allowed if they can be stated as a comma-separated list.
That means,
Cache-Control: no-cache
Cache-Control: no-store
is the same as
Cache-Control: no-cache, no-store
Using Retrofit 2 and an OkHttp interceptor, you can add multiple request headers with the same key. The method you need to use is .addHeader
.
The following example will add the Cache-Control
headers from the example above:
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.addInterceptor(new Interceptor() {
@Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request original = chain.request();
// Request customization: add request headers
Request.Builder requestBuilder = original.newBuilder()
.addHeader("Cache-Control", "no-cache")
.addHeader("Cache-Control", "no-store");
Request request = requestBuilder.build();
return chain.proceed(request);
}
});
OkHttpClient client = httpClient.build();
Take Away
Notice the small but mighty difference:
.header(key, val)
: will override preexisting headers identified bykey
.addHeader(key, val)
: will add the header and don’t override preexisting ones
Make sure you’re using the appropriate method to achieve your desired request results.
Outlook
This post walked you through the different methods on how to add request headers using OkHttp’s request interceptors. Customizing the request and adding request header enable a simple and effective way to pass data with every request. This method will result in much cleaner code than adding header fields with the @Header
annotation for every request.