理解
拦路虎,保安,拦截数据,修改数据,返回数据
使用
OkHttpClient client = new OkHttpClient.Builder() .cache(cache) .addInterceptor(interceptor) .addNetworkInterceptor(interceptor) .build();
2类拦截器
AppInterceptor和NetInterceptor
AppInterceptor拦截器
- 不需要担心中间过程的响应,如重定向和重试.
- 总是只调用一次,即使HTTP响应是从缓存中获取.
- 观察应用程序的初衷. 不关心OkHttp注入的头信息如:
If-None-Match
. - 允许短路而不调用
Chain.proceed()
,即中止调用. - 允许重试,使
Chain.proceed()
调用多次. - 我的理解相当于,在连接之前,socket连接服务器之前(没有调用OkHttpCore之前),http也是基于socket通讯,连接之前会走这个连接器
NetInterceptor拦截器
- 能够操作中间过程的响应,如重定向和重试.
- 当网络短路而返回缓存响应时不被调用.
- 只观察在网络上传输的数据.
- 携带请求来访问连接.
- 我的理解就是相当于,连接服务器成功后(调用OkHttpCore之后),执行的拦截
实战
public class RetrofitCreateHelper2 { public static final String BASE_URL = "http://www.baidu.com/"; private Retrofit retrofit; //郁闷还要写单利 dagger2 1个注解就oK private RetrofitCreateHelper2(){ createRetrofit(); } public static RetrofitCreateHelper2 getHelper() { return Holder.holder; } public static class Holder{ public static RetrofitCreateHelper2 holder=new RetrofitCreateHelper2(); } private Interceptor getIntercepter() { return new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); Log.d("wyz", "app拦截请求前,url:" + request.toString()); Response response = chain.proceed(request); Log.d("wyz", "app拦截请求后"); return response; } }; } private Interceptor getNetIntercepter() { return new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); Log.d("wyz", "net拦截请求前,url:"+request.toString()); Response response = chain.proceed(request); Log.d("wyz", "net拦截请求后"); return response; } }; } private Cache getCache(Context context) { File httpCacheFile = context.getExternalCacheDir().getAbsoluteFile(); return new Cache(httpCacheFile, 1024 * 10 * 1024); } public OkHttpClient getHttpClient() { OkHttpClient client = new OkHttpClient.Builder() .cache(getCache(App.getAppContext())) .addInterceptor(getIntercepter())//添加App拦截器 .addNetworkInterceptor(getNetIntercepter())//添加Net拦截器 .build(); return client; } private void createRetrofit(){ retrofit = new Retrofit.Builder() .baseUrl(BASE_URL) .client(getHttpClient()) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create()) .build(); } public <T> T createApi(Class<T> clazz) { return retrofit.create(clazz); } }
先测试访问一个没有重定向到地址,直接访问百度
05-28 15:21:07.005 7060-7083/com.example.mvp D/wyz: app拦截请求前,url:Request{method=GET, url=http://www.baidu.com/, tag=null} 05-28 15:21:07.028 7060-7083/com.example.mvp D/wyz: net拦截请求前,url:Request{method=GET, url=http://www.baidu.com/, tag=Request{method=GET, url=http://www.baidu.com/, tag=null}} 05-28 15:21:07.117 7060-7083/com.example.mvp D/wyz: net拦截请求后 05-28 15:21:07.118 7060-7083/com.example.mvp D/wyz: app拦截请求后可以看到当App调用方法
Response response = chain.proceed(request);
才会走NetInterceptor方法
接下来访问一个重定向的地址
http://www.publicobject.com/helloworld.txt
05-28 15:59:26.825 22805-22863/com.example.mvp D/wyz: app拦截请求前,url:http://www.publicobject.com/helloworld.txt 05-28 15:59:27.075 22805-22863/com.example.mvp D/wyz: net拦截请求前,url:http://www.publicobject.com/helloworld.txt 05-28 15:59:27.287 22805-22863/com.example.mvp D/wyz: net拦截请求后 05-28 15:59:27.749 22805-22863/com.example.mvp D/wyz: net拦截请求前,url:https://publicobject.com/helloworld.txt 05-28 15:59:28.171 22805-22863/com.example.mvp D/wyz: net拦截请求后 05-28 15:59:28.184 22805-22863/com.example.mvp D/wyz: app拦截请求后看到没,重定向都是在net请求中拦截的
ps:如果想禁止重定向
OkHttpClient client = new OkHttpClient.Builder() // .cache(getCache(App.getAppContext())) .addInterceptor(getIntercepter())//添加App拦截器 .addNetworkInterceptor(getNetIntercepter())//添加Net拦截器 .followSslRedirects(false)//禁止重定向 .build();