You’ve already learned how to integrate authentication with Retrofit, how to pass multiple query parameter values for the same identifier. Additionally, if you read the previously published articles within this series, you know how to create your own custom response converter and register it into the Retrofit instance.
This tutorial shows you how to add custom headers to your requests by using the @Header
annotation within your interface definition or by intercepting the request and add defined header fields with their values.
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
Define Custom Request Headers
Retrofit provides two options to define HTTP request header fields: static and dynamic. Static headers can’t be changed for different requests. The header’s key and value are fixed and initiated with the app startup.
In contrast, dynamic headers must be set for each request.
Static Request Header
The first option to add a static header is to define the header and respective value for your API method as an annotation. The header gets automatically added by Retrofit for every request using this method. The annotation can be either key-value-pair as one string or as a list of strings. Let's face two specific examples which illustrate the definition options:
Retrofit 2
public interface UserService {
@Headers("Cache-Control: max-age=640000")
@GET("/tasks")
Call<List<Task>> getTasks();
}
Retrofit 1.9
public interface UserService {
@Headers("Cache-Control: max-age=640000")
@GET("/tasks")
List<Task> getTasks();
}
The example above shows the key-value-definition for the static header. Further, you can pass multiple key-value-strings as a list encapsulated in curly brackets {}
to the @Headers
annotation.
Retrofit 2
public interface UserService {
@Headers({
"Accept: application/vnd.yourapi.v1.full+json",
"User-Agent: Your-App-Name"
})
@GET("/tasks/{task_id}")
Call<Task> getTask(@Path("task_id") long taskId);
}
Retrofit 1.9
public interface UserService {
@Headers({
"Accept: application/vnd.yourapi.v1.full+json",
"User-Agent: Your-App-Name"
})
@GET("/tasks/{task_id}")
Task getTask(@Path("task_id") long taskId);
}
Additionally, you can define static headers via the intercept
method of Retrofits RequestInterceptor
(customized implementation of the Interceptor
interface in Retrofit 2). We already used the RequestInterceptor
within the previous tutorials (Basic and Token Auth, OAuth) and of course you can enhance it by setting header fields.
Retrofit 2
In Retrofit 2, you need to intercept the request on the network layer provided by OkHttp.
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.addInterceptor(new Interceptor() {
@Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request original = chain.request();
Request request = original.newBuilder()
.header("User-Agent", "Your-App-Name")
.header("Accept", "application/vnd.yourapi.v1.full+json")
.method(original.method(), original.body())
.build();
return chain.proceed(request);
}
}
OkHttpClient client = httpClient.build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(API_BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build();
Retrofit 1.9
RequestInterceptor requestInterceptor = new RequestInterceptor() {
@Override
public void intercept(RequestFacade request) {
request.addHeader("User-Agent", "Your-App-Name");
request.addHeader("Accept", "application/vnd.yourapi.v1.full+json");
}
};
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint("https://api.github.com")
.setRequestInterceptor(requestInterceptor)
.build();
As you can see, the examples above set the User-Agent
and Accept
header fields with respective values. These values are passed with every request which is executed using the RestAdapter
(Retrofit
in Retrofit 2) and the integrated RequestInterceptor
(Interceptor
in Retrofit 2).
Dynamic Header
A more customizable approach are dynamic headers. A dynamic header is passed like a parameter to the method. The provided parameter value gets mapped by Retrofit before executing the request. Let's look at the code example:
Retrofit 2
public interface UserService {
@GET("/tasks")
Call<List<Task>> getTasks(@Header("Content-Range") String contentRange);
}
Retrofit 1.9
public interface UserService {
@GET("/tasks")
List<Task> getTasks(@Header("Content-Range") String contentRange);
}
Define dynamic headers where you might pass different values for each request. The example illustrates the dynamic header with Content-Range
definition.
No Header Override in Retrofit 1
Remember: Retrofit doesn't override header definitions with the same name. Every defined header is added to the request.
That's it. Retrofit simplifies header manipulation and allows to simply change them for separated requests when necessary.
In case things went south, give us a shot on twitter @futurestud_io.
Override Existing Headers in Retrofit 2
As opposed to Retrofit v1, you can override the values of existing header fields. You can override the values within the Interceptor
implementation passed to the used OkHttp client. The Request.Builder
offers two methods to add headers:
.header(key, value)
: overrides the respective header key with value if there is already an existing header identified by key.addHeader(key, value)
: adds the respective header key and value even if there is an existing header field with the same key
Summary
In this tutorial you've learned how you can add custom request header to your Retrofit requests. You can add headers dynamically or in a static way.
If you've any questions, let us know on Twitter @futurestud_io or in the comment section below.
Enjoy coding & make it rock!
Additional Resources
- Retrofit API declaration: section Header Manipulation
- Heroku API Content-Range definition