文章目录
一、使用Interceptor拦截器原因
- 在实际开发中可能会遇上网络请求同时存在多个baseUrl的情况,或者测试环境和正式环境用的是不同的baseUrl。或者是在多个API接口中存在一些必须的统一参数;在开发过程中调试网络请求等。然后想起retrofit 有一个拦截器的配置。
二、Interceptor使用
1、自定义Interceptor实现Interceptor接口
自定义Interceptor拦截器需要实现Interceptor接口
public class MyBaseUrlInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
return null;
}
}
2、查看Chain接口源码
interface Chain {
Request request();
Response proceed(Request request) throws IOException;
/**
* Returns the connection the request will be executed on. This is only available in the chains
* of network interceptors; for application interceptors this is always null.
*/
@Nullable Connection connection();
Call call();
int connectTimeoutMillis();
Chain withConnectTimeout(int timeout, TimeUnit unit);
int readTimeoutMillis();
Chain withReadTimeout(int timeout, TimeUnit unit);
int writeTimeoutMillis();
Chain withWriteTimeout(int timeout, TimeUnit unit);
}
在这里就发现到这里可以拿到网络请求的Request、Response等对象
3、查看Request类源码
发现在这里就可以拿到网络请求的url和headers、RequestBody这些信息
4、拿到网络请求原先的url
那么在我们的自定义Interceptor中,我们就可以这样拿到网络请求原先的url:
Request request = chain.request();//获取原始的originalRequest
HttpUrl oldUrl = request.url();//获取原先的url
5、切换新的url
拿到原先的url后就可以根据业务需求来切换新的url:
HttpUrl newURL = null;
newURL = HttpUrl.parse(“新的url”);
HttpUrl newHttpUrl = oldUrl.newBuilder()//重建新的HttpUrl,需要重新设置的url部分
.scheme(newURL .scheme())//http协议如:http或者https
.host(newURL .host())//主机地址
.port(newURL .port())//端口
.build();
Request.Builder builder = request.newBuilder();//获取originalRequest的创建者builder
Request newRequest = builder.url(newHttpUrl).build();//获取处理后的新newRequest
return chain.proceed(newRequest);//返回新的Request 对象进行网络请求
这样就完成了一个自定义的Interceptor拦截器
6、完整的自定义Interceptor拦截器
public class BaseUrlInterceptor implements Interceptor {
@Override
public Response intercept(okhttp3.Interceptor.Chain chain) throws IOException {
Request request = chain.request();//获取原始的originalRequest
HttpUrl oldUrl = request.url();//获取老的url
HttpUrl baseURL = HttpUrl.parse("https://api.apiopen.top");
HttpUrl newHttpUrl = oldUrl.newBuilder()//重建新的HttpUrl,需要重新设置的url部分
.scheme(baseURL.scheme())//http协议如:http或者https
.host(baseURL.host())//主机地址
.port(baseURL.port())//端口
.build();
Request.Builder builder = request.newBuilder();//获取originalRequest的创建者builder
Request newRequest = builder.url(newHttpUrl).build();//获取处理后的新newRequest
return chain.proceed(newRequest);
}
}
7、使用自定义的Interceptor
可以在构造OkHttpClient实例时使用自定义的Interceptor:
OkHttpClient.Builder builder = new OkHttpClient.Builder()
.addInterceptor(new MyCacheInterceptor(mContext))
OkHttpClient okHttpClient = builder.build();
三、其他:
因为在看源码的时候发现能拿到Request、Response对象,那么就想到了一些必须的统一参数应该也可以写一个Interceptor进行配置。于是来到HttpUrl类的源码查找,找到了这个addQueryParameter()方法。
那么添加公共参数的Interceptor 就可以这样实现:
Request request = chain.request();
HttpUrl httpUrl = request.url();//获取url
HttpUrl modifiedUrl = request.url().newBuilder()
.addQueryParameter("appid", "010")
.addQueryParameter("appkey", "1000")
.build();
Request newRequest;
newRequest = request.newBuilder().url(modifiedUrl).build();
return chain.proceed(newRequest);
返回新的Request 对象去进行网络请求,这个新的Request 对象就写入了一些必须的公共参数。