通过OkHttp拦截器拦截和重试呼叫

Ara*_*hov 31 java interceptor retrofit okhttp

我需要在里面重试请求OkHttp Interceptor.例如,存在需要Authorization令牌的传入请求.如果Authorization令牌已过期,则服务器返回带403代码的响应.在这种情况下,我正在检索一个新令牌并尝试使用相同的chain对象再次进行调用.

但是OkHttp会抛出一个异常,它声明你不能用同一个chain对象发出两个请求.

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

我想知道是否有一个干净的解决方案来解决内部重试网络请求的问题OkHttp Interceptor

谢谢

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

Jak*_*ton 46

使用.interceptors()而不是.networkInterceptors()允许.proceed()多次调用.

有关更多信息,请参阅:https://github.com/square/okhttp/wiki/Interceptors