retrofit中Interceptor拦截器的使用

文章目录

        • 一、使用Interceptor拦截器原因
        • 二、Interceptor使用
          • 1、自定义Interceptor实现Interceptor接口
          • 2、查看Chain接口源码
          • 3、查看Request类源码
          • 4、拿到网络请求原先的url
          • 5、切换新的url
          • 6、完整的自定义Interceptor拦截器
          • 7、使用自定义的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类源码

retrofit中Interceptor拦截器的使用_第1张图片
发现在这里就可以拿到网络请求的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 对象就写入了一些必须的公共参数。

你可能感兴趣的:(#,框架库,android,java,android,studio)