Retrofit 2.0 多重拦截器
Retrofit 2.0 multiple interceptors
我正在进行改造,需要能够使用多个拦截器。目前我正在使用一个自动附加授权令牌,但我需要能够在没有授权令牌的情况下进行调用。如果我在 header 中添加另一个没有身份验证令牌的拦截器,我该如何使用该拦截器而不是身份验证令牌拦截器。
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实例,并推导出两个Retrofit
实例,一个用于未经身份验证的请求,一个用于
经过身份验证的请求。
检查是否应该使用拦截器,例如在您的身份验证拦截器中,您可以首先检查您的令牌首选项中是否存在密钥,如果存在则使用它;如果没有,您只需继续而不修改任何内容。您也可以为未经身份验证的拦截器执行此操作。我认为这是最简单的解决方案。
创建一个单独的拦截器,它将维护一个可修改的列表
您可以随意添加和删除的拦截器。你需要
保留对此拦截器的引用,也许将其设为 Singleton。
对于第三个选项,我提供了一个非常简单的例子:
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;
}
}
在这种情况下,您需要实现自定义接口 RequestInterceptor
和 ResponseInterceptor
。
这些接口的实现示例:
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
(如果它只拦截请求或响应,则只添加其中一个) .
这个例子远未完成。这个解决方案的好处是它增加了添加和删除拦截器的能力,而无需重新创建 OkHttpClient
实例。例如,如果您想支持重试请求,则需要额外的工作。
我正在进行改造,需要能够使用多个拦截器。目前我正在使用一个自动附加授权令牌,但我需要能够在没有授权令牌的情况下进行调用。如果我在 header 中添加另一个没有身份验证令牌的拦截器,我该如何使用该拦截器而不是身份验证令牌拦截器。
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实例,并推导出两个Retrofit 实例,一个用于未经身份验证的请求,一个用于 经过身份验证的请求。
检查是否应该使用拦截器,例如在您的身份验证拦截器中,您可以首先检查您的令牌首选项中是否存在密钥,如果存在则使用它;如果没有,您只需继续而不修改任何内容。您也可以为未经身份验证的拦截器执行此操作。我认为这是最简单的解决方案。
创建一个单独的拦截器,它将维护一个可修改的列表 您可以随意添加和删除的拦截器。你需要 保留对此拦截器的引用,也许将其设为 Singleton。
对于第三个选项,我提供了一个非常简单的例子:
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;
}
}
在这种情况下,您需要实现自定义接口 RequestInterceptor
和 ResponseInterceptor
。
这些接口的实现示例:
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
(如果它只拦截请求或响应,则只添加其中一个) .
这个例子远未完成。这个解决方案的好处是它增加了添加和删除拦截器的能力,而无需重新创建 OkHttpClient
实例。例如,如果您想支持重试请求,则需要额外的工作。