2015-02-16 24 views
22

Ho bisogno di riprovare la richiesta all'interno di OkHttp Interceptor. Ad esempio, c'è una richiesta in entrata che necessita del token Authorization. Se il token Authorization è scaduto, il server restituisce la risposta con il codice 403. In questo caso sto recuperando un nuovo token e sto tentando di effettuare nuovamente la chiamata utilizzando lo stesso oggetto chain.Intercettazione e riprovare la chiamata tramite OkHttp Interceptors

Ma OkHttp genera un'eccezione, in cui si afferma che non è possibile effettuare due richieste con lo stesso oggetto chain.

java.lang.IllegalStateException: network interceptor [email protected] must call proceed() exactly once 

mi chiedo se non v'è una soluzione pulita a questo problema di richiesta di rete riprovare all'interno di OkHttp Interceptor?

Grazie

public final class ApplicationApiHeaders implements Interceptor { 
    private static final String AUTHORIZATION = "Authorization"; 
    private TokenProvider mProvider; 

    public ApplicationApiHeaders(TokenProvider provider) { 
     mProvider = provider; 
    } 

    @Override 
    public Response intercept(Chain chain) throws IOException { 
     Token token = mProvider.getApplicationToken(); 
     String bearerToken = "Bearer " + token.getAccessToken(); 

     System.out.println("Token: " + bearerToken); 
     Request request = chain.request(); 
     request = request.newBuilder() 
       .addHeader(AUTHORIZATION, bearerToken) 
       .build(); 

     Response response = chain.proceed(request); 
     if (!response.isSuccessful() && isForbidden(response.code())) { 
      Token freshToken = mProvider.invalidateAppTokenAndGetNew(); 
      String freshBearerToken = freshToken.getAccessToken(); 

      Request newRequest = chain.request(); 
      newRequest = newRequest.newBuilder() 
        .addHeader(AUTHORIZATION, freshBearerToken) 
        .build(); 

      response = chain.proceed(newRequest); 
     } 

     return response; 
    } 

    private static boolean isForbidden(int code) { 
     return code == HttpURLConnection.HTTP_FORBIDDEN; 
    } 
} 

risposta