retrofit中Interceptor拦截器的使用

一、使用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 对象就写入了一些必须的公共参数。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值