2015-02-16 10 views
22

Ich muss die Anfrage innerhalb von OkHttp Interceptor erneut versuchen. Zum Beispiel gibt es eine eingehende Anfrage, die Authorization Token benötigt. Wenn das Token Authorization abgelaufen ist, gibt der Server die Antwort mit dem Code 403 zurück. In diesem Fall erhalte ich ein neues Token und versuche, den Anruf erneut zu tätigen, indem ich dasselbe chain Objekt verwende.Abfangen und erneut versuchen Aufruf mit OkHttp Interceptors

Aber OkHttp löst eine Ausnahme aus, die besagt, dass Sie mit demselben chain Objekt nicht zwei Anforderungen erstellen können.

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

Ich frage mich, ob es für dieses Problem von retrying Netzwerkanfrag innerhalb von OkHttp Interceptor eine saubere Lösung?

Danke

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; 
    } 
} 

Antwort