java 通过 OkHttp Interceptors 拦截重试调用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28536522/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 13:46:27  来源:igfitidea点击:

Intercept and retry call by means of OkHttp Interceptors

javaretrofitokhttpinterceptor

提问by Araz Abishov

I need to retry request inside of OkHttp Interceptor. For example there is incoming request which needs Authorizationtoken. If Authorizationtoken is expired, server returns response with 403code. In this case I am retrieving a new token and trying to make call again by using the same chainobject.

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

But OkHttp throws an exception, which states that you cannot make two requests with the same chainobject.

但是 OkHttp 抛出了一个异常,指出不能用同一个chain对象发出两个请求。

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

I wonder if there is a clean solution to this problem of retrying network request inside of OkHttp Interceptor?

我想知道在内部重试网络请求的问题是否有一个干净的解决方案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;
    }
}

回答by Jake Wharton

Use .interceptors()instead of .networkInterceptors()which are allowed to call .proceed()more than once.

使用.interceptors()代替.networkInterceptors()which 允许.proceed()多次调用。

For more information see: https://square.github.io/okhttp/interceptors/

更多信息请参见:https: //square.github.io/okhttp/interceptors/