问题
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