Retrofit添加User-Agent信息

最近这两天遇到一个问题,找到了一个公有的开放的API,但是通过Retrofit默认请求得到的结果是code = 400, message = Bad Request。看别人写的用Volley,完全没有问题。

添加Headers

开始我以为是头文件信息不对导致的。在ApiServer里面添加了注释

1
2
3
4
5
6
@Headers({
"Content-Type: application/json; charset=utf-8",
"Accept: application/json"
})
@GET("xxxxx")
Call<ResponseBody> getxxxData();

配置Charles

请求后,通过Charles抓包,得到的结果是个乱码。,。根据Charles的提示,应该是SSL没有配置导致的

  • 手机去下载一个Charles的CA,点击这里
  • 下载完毕后,在Charles中「Proxy -> SSL Proxying -> 勾选Enable SSL Proxying」
  • 将需要访问的Https网址加入到下面的Location里面

配置Charles的SSL成功后,再次请求,发现Header的信息是正常的,但是返回的仍然是400。我猜想应该是UA没有发送导致的。

添加UA

在Android API17之后,可以用下面的方法获取User-Agent

WebSettings.getDefaultUserAgent(getApplicationContext())

接下来就需要将这个UA添加到okHttp的请求当中了。我们自己构造一个OkHttpClient来实现这个。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private OkHttpClient getOkHttpClient() {
OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder();

httpClientBuilder.addInterceptor(new Interceptor() {
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
@Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request request = chain.request()
.newBuilder()
.removeHeader("User-Agent")//移除旧的
.addHeader("User-Agent", WebSettings.getDefaultUserAgent(getApplicationContext()))//添加真正的头部
.build();
return chain.proceed(request);
}
});
return httpClientBuilder.build();
}

再次测试,成功的获取了该API返回的数据。

添加HttpLoggingInterceptor

在日常网络发起请求的时候,添加一个Http的Log信息很有必要,能看到网络交互的时候一些关键信息,所以我们将上面的OkHttpClient改造一下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
private OkHttpClient getOkHttpClient() {
//显示级别
HttpLoggingInterceptor.Level level = HttpLoggingInterceptor.Level.BODY;

//新建拦截器log
HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
@Override
public void log(String message) {
Log.d("OKHTTP====Message", message);
}
});
loggingInterceptor.setLevel(level);

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

httpClientBuilder.addInterceptor(new Interceptor() {
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
@Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request request = chain.request()
.newBuilder()
.removeHeader("User-Agent")//移除旧的
.addHeader("User-Agent", WebSettings.getDefaultUserAgent(getApplicationContext()))//添加真正的头部
.build();
return chain.proceed(request);
}
});

httpClientBuilder.addInterceptor(loggingInterceptor);

return httpClientBuilder.build();
}
-------------The End-------------
请我喝一杯啤酒~