我想将服务器的响应更改为423 -> 401,然后使用Authenticator调用refreshToken。
The method is called if response code is 401
但是为什么该方法 Authenticator.authenticate(Route route, Response response)
在我的情况下没有被调用?
OkHttpClient
OkHttpClient httpClient = new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.writeTimeout(60, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS)
.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
//Adding token to request
Request request = chain.request();
Request.Builder builder = request.newBuilder();
builder.header("Authorization", "access_token");
return chain.proceed(builder.build());
}
})
.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
//changing response code from server 423 -> 401
Request request = chain.request();
Response response = chain.proceed(request);
if (response.code() == 423)
return response.newBuilder().code(401).build();
return response;
}
})
.authenticator(new Authenticator() {
//THE METHOD IS NOT CALLED, WHY?
@Override
public Request authenticate(Route route, Response response) throws IOException {
// Refresh access_token using a synchronous api request
String newAccessToken = refreshToken();
saveNewToken(newAccessToken)
// Add new header to rejected request and retry it
return response.request().newBuilder()
.header("Authorization", newAccessToken)
.build();
}
})
.build();
改造界面:
ApiService mApiService = new Retrofit.Builder()
.baseUrl(serverHostUrl)
.client(httpClient)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create(gson))
.build()
.create(ApiService.class);
最佳答案
我认为这里的问题是应用程序拦截器
和网络拦截器
之间的区别。您可以阅读所有相关内容here并且应该这样做,因为存在相当大的差异。
就您的情况而言,简而言之,我认为您在 OkHttp
检查状态代码并尝试运行身份 validator 后更改了响应代码。因此,解决方案是使用网络拦截器而不是像现在这样的应用程序拦截器来更改状态代码。
如果你看method getResponseWithInterceptorChain从 RealCall.java 中,您将看到拦截器堆栈是通过首先添加所有应用程序拦截器,然后添加一些内部拦截器,最后添加网络拦截器来构建的。您将看到其中一个内部拦截器是 RetryAndFollowUpInterceptor这似乎处理验证码 here .
看来正在发生的事情是你提出了你的要求。改变代码的拦截器在链上运行并调用。该请求将遍历所有剩余的拦截器,但让我们重点关注 RetryAndFollowUpInterceptor
。这个将追随你的并在链条中继续前进。它收到响应并收到代码为 423
的响应,并且不会执行任何重新身份验证操作。然后它会返回,现在你的拦截器正在运行。它看到响应代码 423
并更改它,但这不会再次运行 RetryAndFollowUpInterceptor
。
正如您所看到的,您似乎在应用程序中更改代码得太晚或太高了。您必须确保在 RetryAndFollowUpInterceptor 有机会查看响应代码之前执行此操作,而使用网络拦截器可以更轻松地完成此操作。除了简单的状态代码之外,您还必须处理更多的事情,但这是可能的。
希望这有帮助
关于java - 为什么不调用改造 validator ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48459111/