2017-06-19 120 views
3

我正在改造,需要能夠使用多個攔截器。目前我正在使用一個來自動附加一個授權令牌,但我需要能夠不使用授權令牌進行調用。如果我在標題中添加另一個沒有auth標記的攔截器,我該如何使用那個而不是auth令牌攔截器。Retrofit 2.0多個攔截器

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) 
+0

嘿,你最終搞清楚了嗎?我正在尋找完全相同的東西。 – MikeOscarEcho

回答

2

OkHttpClient維護您可以訪問的攔截器列表,但它是一個不可修改的集合。

這給我們留下了三個選項,我相信:

  1. 創建兩個OkHttpClient實例,並扣除2種改造 情況下,一個用於身份認證的請求,以及一個用於 認證請求。

  2. 檢查是否應該使用攔截器,例如,在您的身份驗證攔截器中,您可以首先檢查您的首選項中是否存在用於該令牌的密鑰,如果是,請使用它;如果不是,您只需繼續而不修改任何內容。你也可以爲你的未經認證的攔截器做這個。我認爲這是您的案例最簡單的解決方案。

  3. 創建一個攔截器,它將保留攔截器的可修改列表 ,您可以隨意添加和刪除攔截器。你需要 來保持對這個攔截器的引用,也許把它變成一個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; 
    } 
} 

在這種情況下,你將需要實現自定義接口RequestInterceptorResponseInterceptor

什麼這些接口的實現看起來像一個例子:

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實例。例如,如果您想支持重試請求,則需要額外的工作。