Make a synchronous Retrofit call from inside an OkHttp Interceptor

江枫思渺然 提交于 2019-12-07 04:34:27

问题


I am trying to automatically refresh an auth token if it is expired. I am using the new Interceptor class that was introduced in OkHttp 2.2. In the intercept method I am trying the original request with chain.proceed(request), checking the response code, and if the token is expired I am making a call to a separate Retrofit service, synchronously, to obtain a new token.

The strange thing is, no code past the synchronous call seems to run. If I try debugging with a breakpoint on the synchronous call's line, then do a step-over, I am stopped in Dispatcher.java at :

if (!executedCalls.remove(call)) throw new AssertionError("Call wasn't in-flight!");

Any idea as to what I might be doing wrong here? I could probably just craft a new request by hand, but I am just kind of curious why a Retrofit call doesn't seem to work here.

My Interceptor:

public class ReAuthInterceptor implements Interceptor {

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();

        // try the request
        Response response = chain.proceed(request);

        // if we receive a "401 - Not Authorized" then refresh the auth token and try again
        if (response.code() == 401) {
            // get a new auth token and store it
            UserToken userToken = MobileClient.getOkraService().login(AuthUtil.getUserToken(MSWorksApplication.getContext()));
            AuthUtil.authenticate(MSWorksApplication.getContext(), userToken);

            Log.d("TEST", "TEST TEST TEST");

            // use the original request with the new auth token
            Request newRequest = request.newBuilder().header("Authorization", AuthUtil.getAuthToken(MSWorksApplication.getContext())).build();

            return chain.proceed(newRequest);
        }
        else {
            // the auth token is still good
            return response;
        }
    }
}

回答1:


I had this problem - if you're getting an HTTP response code that would cause Retrofit to call failure() instead of success() an exception will be thrown.

If you wrap

UserToken userToken = MobileClient.getOkraService().login(AuthUtil.getUserToken(MSWorksApplication.getContext()));

in a try/catch(RetrofitError e) you'll be able to execute code after a failure, however I've found this to be quite cumbersome and am still in the process of finding a nicer solution.



来源:https://stackoverflow.com/questions/28226765/make-a-synchronous-retrofit-call-from-inside-an-okhttp-interceptor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!