我在我的 Android 应用程序中使用 okhttp 2.0,但没有找到为所有传出请求设置一些通用用户代理的方法。
我以为我可以做类似的事情
OkHttpClient client = new OkHttpClient();
client.setDefaultUserAgent(...)
...但是没有这样的方法或类似的方法。 当然,我可以提供一些扩展实用方法来包装一个 RequestBuilder 以附加
.header("UserAgent")
然后我会用它来构建我的所有请求,但我想也许我错过了一些现有的和更简单的方法?
您可以使用拦截器将 User-Agent 标头添加到您的所有请求中。
有关okHttp拦截器的更多信息,请参阅http://square.github.io/okhttp/interceptors/
此拦截器的示例实现:
/* 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);
}
}
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"));
}
如果有人正在寻找使用 OkHttp 3 和 Kotlin 的方法:
val client = OkHttpClient.Builder()
.addNetworkInterceptor { chain ->
chain.proceed(
chain.request()
.newBuilder()
.header("User-Agent", "COOL APP 9000")
.build()
)
}
.build()
OkHttp v2.1 将在接下来的几周内发布 如果尚未设置,将自动设置
User-Agent
标头。
到目前为止,还没有一个很好的方法以集中的方式将此标头添加到每个请求。唯一的解决方法是为创建的每个
Request
手动包含标题。
基于@josketres 的回答,这里有一个类似的 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);
}
}
加上更新的测试:
@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"));
}
您必须在较新的版本中使用
builder
。 (2021 年 9 月)
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();
OkHttp 的新版本不再需要使用拦截器。添加用户代理非常简单:
Request request = new Request.Builder()
.url("http://www.publicobject.com/helloworld.txt")
.header("User-Agent", "OkHttp Example")
.build();
来源:OkHttp wiki.
用 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()