I am using okhttp 2.0 in my Android app and didn't find a way to set some common User Agent for all outgoing requests.
I thought I could do something like
OkHttpClient client = new OkHttpClient();
client.setDefaultUserAgent(...)...but there's no such method or similar.
Of course I could provide some extension utility method which would wrap a RequestBuilder to attach .header("UserAgent") and then I would use it for building all my requests, but I thought maybe I missed some existing and simpler way?
7 Answers
You can use an interceptor to add the User-Agent header to all your requests.
For more information about okHttp interceptors see
Example implementation of this interceptor:
/* This interceptor adds a custom User-Agent. */
public class UserAgentInterceptor implements Interceptor { private final String userAgent; public UserAgentInterceptor(String userAgent) { this.userAgent = userAgent; } @Override public Response intercept(Chain chain) throws IOException { Request originalRequest = chain.request(); Request requestWithUserAgent = originalRequest.newBuilder() .header("User-Agent", userAgent) .build(); return chain.proceed(requestWithUserAgent); }
}Test for the UserAgentInterceptor:
public void testUserAgentIsSetInRequestHeader() throws Exception { MockWebServer server = new MockWebServer(); server.enqueue(new MockResponse().setBody("OK")); server.play(); String url = server.getUrl("/").toString(); OkHttpClient client = new OkHttpClient(); client.networkInterceptors().add(new UserAgentInterceptor("foo/bar")); Request testRequest = new Request.Builder().url(url).build() String result = client.newCall(testRequest).execute().body().string(); assertEquals("OK", result); RecordedRequest request = server.takeRequest(); assertEquals("foo/bar", request.getHeader("User-Agent"));
} 2 In case anyone is looking for this working with OkHttp 3 and in Kotlin:
val client = OkHttpClient.Builder() .addNetworkInterceptor { chain -> chain.proceed( chain.request() .newBuilder() .header("User-Agent", "COOL APP 9000") .build() ) } .build() 4 OkHttp v2.1 which is set to be released in the next few weeks will automatically set a User-Agent header if one is not already set.
As of now there isn't a good way to add this header to every request in a centralized way. The only workaround is to include the header manually for every Request that is created.
Based on @josketres answer, here is a similar Interceptor for OkHttp version 3
public class UserAgentInterceptor implements Interceptor { private final String mUserAgent; public UserAgentInterceptor(String userAgent) { mUserAgent = userAgent; } @Override public Response intercept(@NonNull Chain chain) throws IOException { Request request = chain.request() .newBuilder() .header("User-Agent", mUserAgent) .build(); return chain.proceed(request); }
}Plus the updated test:
@Test
public void testUserAgentIsSetInRequestHeader() throws IOException, InterruptedException { final String expectedUserAgent = "foo/bar"; MockWebServer server = new MockWebServer(); server.enqueue(new MockResponse().setBody("OK")); server.start(); OkHttpClient.Builder okHttpBuilder = new OkHttpClient.Builder(); okHttpBuilder.addInterceptor(new UserAgentInterceptor(expectedUserAgent)); Request request = new Request.Builder().url(server.url("/").url()).build(); ResponseBody result = okHttpBuilder.build().newCall(request).execute().body(); assertNotNull(result); assertEquals("OK", result.string()); assertEquals(expectedUserAgent, server.takeRequest().getHeader("User-Agent"));
} Using an intercepter is no longer required in the newer versions of OkHttp. Adding a user agent is as simple as:
Request request = new Request.Builder() .url("") .header("User-Agent", "OkHttp Example") .build();Source: OkHttp wiki.
3You have to use builder in newer versions. (Sep 2021)
client = new OkHttpClient.Builder() .addInterceptor(new Interceptor() { @NotNull @Override public Response intercept(@NotNull Chain chain) throws IOException { Request originalRequest = chain.request(); Request requestWithUserAgent = originalRequest.newBuilder() .header("User-Agent", "My Agent is so cool") .build(); return chain.proceed(requestWithUserAgent); } }) .build(); Adding an interceptor with Kotlin,
private val client = OkHttpClient.Builder() .addInterceptor(object: Interceptor{ override fun intercept(chain: Interceptor.Chain): Response { val request = chain.request() val reqBuilder = request.newBuilder() .header("Accept-Language", Locale.getDefault().language) .header("User-Agent", "New User-Agent String") return chain.proceed(reqBuilder.build()) } }) .build()
private val retrofit: Retrofit = Retrofit.Builder() .baseUrl(Constants.BASE_URL) .client(client) .addConverterFactory(GsonConverterFactory.create()) .build()