通过OkHttp拦截器进行拦截并重试调用 [英] Intercept and retry call by means of OkHttp Interceptors

查看:1007
本文介绍了通过OkHttp拦截器进行拦截并重试调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

但是OkHttp抛出一个异常,该异常指出您无法使用相同的chain对象发出两个请求.

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

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

我想知道在OkHttp Interceptor内部重试网络请求的问题是否存在一种干净的解决方案?

I wonder if there is a clean solution to this problem of retrying network request inside of 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;
    }
}

推荐答案

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

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

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

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

这篇关于通过OkHttp拦截器进行拦截并重试调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆