使用OkHttp网络框架在进行网络请求时会发现,传到后台的请求头中会比我们自己添加的参数多出几个额外参数。查看源码会发现
private Response getResponseWithInterceptorChain() throws IOException {
// Build a full stack of interceptors.
List<Interceptor> interceptors = new ArrayList<>();
interceptors.addAll(client.interceptors());
interceptors.add(retryAndFollowUpInterceptor);
interceptors.add(new BridgeInterceptor(client.cookieJar()));
interceptors.add(new CacheInterceptor(client.internalCache()));
interceptors.add(new ConnectInterceptor(client));
if (!retryAndFollowUpInterceptor.isForWebSocket()) {
interceptors.addAll(client.networkInterceptors());
}
interceptors.add(new CallServerInterceptor(
retryAndFollowUpInterceptor.isForWebSocket()));
Interceptor.Chain chain = new RealInterceptorChain(
interceptors, null, null, null, 0, originalRequest);
return chain.proceed(originalRequest);
}
OkHttp会默认添加一个桥接拦截器BridgeInterceptor,查看BridgeInterceptor的源码
MediaType contentType = body.contentType();
if (contentType != null) {
requestBuilder.header("Content-Type", contentType.toString());
}
long contentLength = body.contentLength();
if (contentLength != -1) {
requestBuilder.header("Content-Length", Long.toString(contentLength));
requestBuilder.removeHeader("Transfer-Encoding");
} else {
requestBuilder.header("Transfer-Encoding", "chunked");
requestBuilder.removeHeader("Content-Length");
}
}
if (userRequest.header("Host") == null) {
requestBuilder.header("Host", hostHeader(userRequest.url(), false));
}
if (userRequest.header("Connection") == null) {
requestBuilder.header("Connection", "Keep-Alive");
}
// If we add an "Accept-Encoding: gzip" header field we're responsible for also decompressing
// the transfer stream.
boolean transparentGzip = false;
if (userRequest.header("Accept-Encoding") == null) {
transparentGzip = true;
requestBuilder.header("Accept-Encoding", "gzip");
}
List<Cookie> cookies = cookieJar.loadForRequest(userRequest.url());
if (!cookies.isEmpty()) {
requestBuilder.header("Cookie", cookieHeader(cookies));
}
if (userRequest.header("User-Agent") == null) {
requestBuilder.header("User-Agent", Version.userAgent());
}
在BridgeInterceptor中会默认添加User-Agent,Accept-Encoding等请求头参数。有时候我们并不需要这些默认添加的参数,那么我们如何才能做到移除它们呢?
通过上面第一段的部分源码
interceptors.add(retryAndFollowUpInterceptor);
interceptors.add(new BridgeInterceptor(client.cookieJar()));
interceptors.add(new CacheInterceptor(client.internalCache()));
interceptors.add(new ConnectInterceptor(client));
if (!retryAndFollowUpInterceptor.isForWebSocket()) {
interceptors.addAll(client.networkInterceptors());
}
可以看到OkHttp内部在添加完BridgeInterceptor后,才开始添加networkInterceptors,所以我们需要借助网络拦截器来重新拦截请求头,并操作头部参数。
首先我们要自定义一个拦截器,在拦截器中移除我们不需要的参数。
public class NetInterceptorimplements Interceptor {
private HttpClient builder;
public NetInterceptor() {
super();
}
public NetInterceptor(HttpClient builder) {
this.builder = builder;
}
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
//移除头部参数
request = request.newBuilder()
.removeHeader("User-Agent")
.removeHeader("Accept-Encoding")
.build();
Response response = chain.proceed(request);
if (response.body() != null && response.body().contentType() != null) {
MediaType mediaType = response.body().contentType();
String content = response.body().string();
ResponseBody responseBody = ResponseBody.create(mediaType, content);
return response.newBuilder().body(responseBody).build();
} else {
return response;
}
}
}
然后再将自定义的拦截器设置为网络拦截器
mOkBuilder = new Builder()
.connectTimeout(mbuilder.getConnectTimeout(), TimeUnit.SECONDS)
.readTimeout(mbuilder.getReadTimeout(), TimeUnit.SECONDS)
.writeTimeout(mbuilder.getWriteTimeout(), TimeUnit.SECONDS)
.sslSocketFactory(createSSLSocketFactory(), new TrustAllCerts())// 信任所有证书
.hostnameVerifier(new TrustAllHostnameVerifier())
.cookieJar(new CookieJar() {
private final HashMap<String, List<Cookie>> cookieStore = new HashMap<>();
@Override
public void saveFromResponse(HttpUrl httpUrl, List<Cookie> list) {
cookieStore.put(httpUrl.host(), list);
}
@Override
public List<Cookie> loadForRequest(HttpUrl httpUrl) {
List<Cookie> cookies = cookieStore.get(httpUrl.host());
return cookies != null ? cookies : new ArrayList<Cookie>();
}
});
NetInterceptor netInterceptor = new NetInterceptor(mbuilder);
//mOkBuilder.addNetworkInterceptor(netInterceptor);//设置应用拦截器无效,因为BridgeInterceptor是在应用拦截器之后添加的
mOkBuilder.addNetworkInterceptor(netInterceptor);
这样就能达到移除BridgeInterceptor自动添加的请求头参数的目的了。