代码之家  ›  专栏  ›  技术社区  ›  Araz Abishov

通过OkHttp拦截器拦截并重试调用

  •  44
  • Araz Abishov  · 技术社区  · 9 年前

    我需要在中重试请求 OkHttp Interceptor 。例如,有传入请求需要 Authorization 代币如果 批准 令牌已过期,服务器返回响应 403 密码在本例中,我正在检索一个新令牌,并尝试使用该令牌再次进行调用 chain 对象

    但是OkHttp抛出了一个异常,该异常表示不能用相同的方法发出两个请求 链条 对象

    java.lang.IllegalStateException: network interceptor org.app.api.modules.ApplicationApiHeaders@559da2 must call proceed() exactly once
    

    我想知道是否有一个干净的解决方案来解决在 OkHttp拦截器 ?

    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;
        }
    }
    
    1 回复  |  直到 5 年前
        1
  •  67
  •   Pablo Johnson    4 年前

    使用 .interceptors() 而不是 .networkInterceptors() 允许呼叫的 .proceed() 不止一次。

    有关详细信息,请参阅: https://square.github.io/okhttp/interceptors/