改装2.0多个拦截器 [英] Retrofit 2.0 multiple interceptors

查看:84
本文介绍了改装2.0多个拦截器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在进行改造,需要能够使用多个拦截器.目前,我正在使用一种自动附加身份验证令牌的方法,但我需要能够在没有身份验证令牌的情况下进行呼叫.如果我在标头中添加了另一个没有身份验证令牌的拦截器,该如何使用它而不是身份验证令牌拦截器.

I am working with retrofit and need to be able to use multiple interceptors. Currently I am using one to automatically append an auth token but i need to be able to make calls with no auth token. If i add another interceptor with no auth token in the header how do I use that one instead of the auth token interceptor.

    val interceptor: Interceptor = Interceptor { chain ->
    val newRequest = chain.request().newBuilder().
            addHeader("Auth_Token", pref.getString(PSPreferences.prefAuthKey, "")).
            cacheControl(CacheControl.FORCE_NETWORK).
            build()
    chain.proceed(newRequest)
}

okHttpClient = OkHttpClient.Builder().
        readTimeout(1, TimeUnit.MINUTES).
        connectTimeout(1, TimeUnit.MINUTES).
        addInterceptor(interceptor).build()

val retrofitInstance = Retrofit.Builder()
        .baseUrl(APIEndpointInterface.BASE_URL)
        .client(okHttpClient)
        .addConverterFactory(GsonConverterFactory.create())
        .build()
apiInterface = retrofitInstance.create<APIEndpointInterface>(APIEndpointInterface::class.java)

推荐答案

OkHttpClient维护您可以访问的拦截器列表,但这是不可修改的集合.

OkHttpClient maintains a list of the interceptors which you can access, however it is an unmodifiable collection.

这给我们留下了三个我相信的选择:

This leaves us with three options I believe:

  1. 创建两个OkHttpClient实例,并通过推导两个Retrofit 实例,一个用于未经身份验证的请求,另一个用于 经过身份验证的请求.

  1. Create two OkHttpClient instances, and by deduction two Retrofit instances, one for the unauthenticated requests, and one for the authenticated requests.

检查是否应使用拦截器,例如在身份验证拦截器中,您可以首先检查您的令牌首选项中是否存在密钥,如果存在,请使用它;如果没有,您只需进行任何修改即可.您也可以对未经身份验证的拦截器执行此操作.我认为这是针对您情况的最简单解决方案.

Check if you should use the interceptor, e.g. in your authentication interceptor, you can first check if there exists a key in your preferences for the token, and if so use it; if not, you simply proceed without modifying anything. You do this for your unauthenticated interceptor too. I think this is the easiest solution for your case.

创建一个拦截器,该拦截器将维护可修改的列表 您可以随意添加和删除的拦截器.你需要 保留对该拦截器的引用,也许将其设为Singleton.

Create a single interceptor, which will maintain a modifiable list of interceptors which you can add and remove at will. You would need to keep a reference to this interceptor, maybe make it a Singleton.

对于第三个选项,我提供了一个非常简单的示例:

For the third option, I have provided a very simple example:

public class HttpRequestResponseInterceptor implements Interceptor {

    public final List<RequestInterceptor> requestInterceptors = new ArrayList<>();
    public final List<ResponseInterceptor> responseInterceptors = new ArrayList<>();

    @Override
    public Response intercept(Chain chain) throws IOException {

        Request request = chain.request();

        for (RequestInterceptor interceptor : requestInterceptors) {
            request = interceptor.intercept(request);
        }

        Response response = chain.proceed(request);

        for (ResponseInterceptor interceptor : responseInterceptors) {
            response = interceptor.intercept(response);
        }

        return response;
    }

    public interface RequestInterceptor {
        Request intercept(Request request) throws IOException;
    }

    public interface ResponseInterceptor {
        Response intercept(Response response) throws IOException;
    }
}

在这种情况下,您将需要实现自定义接口RequestInterceptorResponseInterceptor.

In this case you would need to implement the custom interfaces RequestInterceptor and ResponseInterceptor.

这些接口的实现示例如下:

An example of what an implementation of these interfaces would look like:

public class ExampleInterceptor implements HttpRequestResponseInterceptor.RequestInterceptor,
 HttpRequestResponseInterceptor.ResponseInterceptor {

    @Override
    public Request intercept(Request request) throws IOException {
        return request.newBuilder().addHeader("REQUEST_HEADER", "EXAMPLE").build();
    }

    @Override
    public Response intercept(Response response) throws IOException {
        return response.newBuilder().addHeader("RESPONSE_HEADER", "EXAMPLE").build();
    }
}

然后,您需要将此拦截器添加到我们的主拦截器两次,一次添加到requestInterceptors,一次添加到responseInterceptors(如果仅拦截请求或仅响应,则只添加到其中之一).

You would then need to add this interceptor to our main interceptor twice, once to requestInterceptors and once to responseInterceptors (or only to one of these if it intercepts only requests or only responses).

这个例子远未完成.该解决方案的好处在于,它无需重新创建OkHttpClient实例即可添加添加和删除拦截器的功能.例如,如果您想支持重试请求,则需要额外的工作.

This example is far from complete. The benefit of this solution is that it adds the ability to add and remove interceptors without having to recreate the OkHttpClient instance. It requires extra work if you want to support retrying requests, for example.

这篇关于改装2.0多个拦截器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆