用途
可以拦截request和reponse,对其监视、重写和重试调用,比如请求前对request修改或增加header,响应后对reponse修改或过滤。
用法
步骤1:实现 Interceptor 接口,并重写 intercept 方法;
步骤2:在intercept方法中,通过chain参数可以获取到request和reponse。
步骤3:添加到OKHttpClient中。
实际使用
实现 Interceptor 类,并重写 intercept 方法,请求头增加token和时间戳
public class SelfLoginInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
String token = TokenManager.INSTANCE.getIhuToken();
Request originalRequest = chain.request();
if (token == null) {
return chain.proceed(originalRequest);
}
Request authorised = originalRequest.newBuilder()
.addHeader("Authorization", "Bearer " + token)
.addHeader("timestamp", System.currentTimeMillis() + "")
.build();
return chain.proceed(authorised);
}
public static SelfLoginInterceptor create() {
return new SelfLoginInterceptor();
}
}
添加到OKHttpClient中
retrofit = retrofitBuilder(BASE_URL,
httpClientBuilder(SelfLoginInterceptor.create())
.build())
.build();
private OkHttpClient.Builder httpClientBuilder(Interceptor custom) {
//HttpLoggingInterceptor,okhttp3自带的拦截器,用于输出log,比如请求流和响应流
HttpLoggingInterceptor logging = new HttpLoggingInterceptor(message -> Log.i(TAG, message));
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.addInterceptor(custom)
.addInterceptor(logging);
return builder;
};
private Retrofit.Builder retrofitBuilder(String url, OkHttpClient client) {
return new Retrofit.Builder()
.baseUrl(url)
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create());
}
分类
ApplicationInterceptor(应用拦截器)
- 不需要担心中间过程的响应,如重定向和重试.
- 总是只调用一次,即使HTTP响应是从缓存中获取.
- 观察应用程序的初衷. 不关心OkHttp注入的头信息如: If-None-Match.
- 允许短路而不调用 Chain.proceed(),即中止调用.
- 允许重试,使 Chain.proceed()调用多次.
NetworkInterceptor(网络拦截器)
- 能够操作中间过程的响应,如重定向和重试.
- 当网络短路而返回缓存响应时不被调用.
- 只观察在网络上传输的数据.
- 携带请求来访问连接.
异同
相同点:
1)都能对server返回的response进行拦截
2)这两种拦截器本质上都是基于Interceptor接口,由开发者实现这个接口,然后将自定义的Interceptor类的对象设置到okhttpClient对象中。所以,他们的对象,本质上没什么不同,都是Interceptor的实现类的对象。
3)两者都会被add到OkHttpClient内的一个ArrayList中。当请求执行的时候,多个拦截器会依次执行(list本身就是有序的)。
不同点:
1)okhttpClient添加两种拦截器的api不同。添加应用拦截器的接口是addInterceptor(),而添加网络拦截器的接口是addNetworkInterceptor().
2)两者负责的区域不同,应用拦截器作用于okhttpCore到Application之间,网络拦截器作用于 network和okhttpCore之间
3)当访问的url发生重定向时,网络拦截器有可能被执行多次,但是不论任何情况,application只会被执行一次。