使用 Retrofit 时重试机制的最佳实践是什么?
What is the best practices for retry mechanism while using Retrofit?
问题陈述:
我在我的应用程序中使用 Retrofit 进行 API 调用。目前我有 20 多个 Retrofit 接口,具有不同的 Callbacks
。目前,当应用程序在这些接口中的任何一个(比如 UpdateUserAPI
)中接收到 INVALID_SESSION_ID
时,我必须通过调用 AccessTokenAPI
.
来获得新的 ACCESS_TOKEN
建议方法:
当应用在 UpdateUserAPI
中的 Callback
中接收到 INVALID_SESSION_ID
时,调用 AccessTokenAPI
以获取新的 ACCESS_TOKEN
。在接收到新的 ACCESS_TOKEN
后,post 与新的 ACCESS_TOKEN
的实际调用(初始参数在 UpdateUserAPI
中)。但这需要在实现UpdateUserAPI
的class中保存参数。此外,我只需要重试一次 ACCESS_TOKEN
,这应该被处理。
实现上述要求的最佳方法是什么?
创建您自己的 TokenInterceptor
public class TokenInterceptor implements Interceptor
然后设置为你的okktpclient
Interceptor tokenInterceptor = new TokenInterceptor(provideUserLoginDao(appDatabase));
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.addInterceptor(tokenInterceptor)
.writeTimeout(50, TimeUnit.SECONDS)
.retryOnConnectionFailure(true)
.build();
此 post 中的有用信息还有:Refreshing OAuth token using Retrofit without modifying all calls
创建您自己的自定义拦截器并检查您的 token/session_id 是否有效。如果您的 session_id 已过期,然后点击您的 updateUserAPI 以获取新 ID 并将此 ID 设置在 header 或您想要的位置。这是一些代码示例。
RefreshTokenInterceptor
public static class RInterceptor implements Interceptor {
@Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request request = chain.request();
Response response = chain.proceed(request);
try {
if (response.code() == 410) {
Response r = null;
try {
r = makeTokenRefreshCall(request, chain);
} catch (JSONException e) {
e.printStackTrace();
}
return r;
}
} catch (Exception e) {
e.printStackTrace();
}
return response;
}
}
private static Response makeTokenRefreshCall(Request req, Interceptor.Chain chain) throws JSONException, IOException {
/* fetch refreshed token, some synchronous API call, whatever Because we are responsible to return new response */
refreshTokenSync();
Request newRequest;
newRequest = req.newBuilder().header("authorization", NEW_TOKEN)/*.post(req.body())*/.build();
return chain.proceed(newRequest);
}
RESTClient
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.readTimeout(50, TimeUnit.SECONDS)
.writeTimeout(55, TimeUnit.SECONDS)
.connectTimeout(50, TimeUnit.SECONDS)
.retryOnConnectionFailure(true)
.addInterceptor(new NetworkInterceptor())
.build();
问题陈述:
我在我的应用程序中使用 Retrofit 进行 API 调用。目前我有 20 多个 Retrofit 接口,具有不同的 Callbacks
。目前,当应用程序在这些接口中的任何一个(比如 UpdateUserAPI
)中接收到 INVALID_SESSION_ID
时,我必须通过调用 AccessTokenAPI
.
ACCESS_TOKEN
建议方法:
当应用在 UpdateUserAPI
中的 Callback
中接收到 INVALID_SESSION_ID
时,调用 AccessTokenAPI
以获取新的 ACCESS_TOKEN
。在接收到新的 ACCESS_TOKEN
后,post 与新的 ACCESS_TOKEN
的实际调用(初始参数在 UpdateUserAPI
中)。但这需要在实现UpdateUserAPI
的class中保存参数。此外,我只需要重试一次 ACCESS_TOKEN
,这应该被处理。
实现上述要求的最佳方法是什么?
创建您自己的 TokenInterceptor
public class TokenInterceptor implements Interceptor
然后设置为你的okktpclient
Interceptor tokenInterceptor = new TokenInterceptor(provideUserLoginDao(appDatabase));
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.addInterceptor(tokenInterceptor)
.writeTimeout(50, TimeUnit.SECONDS)
.retryOnConnectionFailure(true)
.build();
此 post 中的有用信息还有:Refreshing OAuth token using Retrofit without modifying all calls
创建您自己的自定义拦截器并检查您的 token/session_id 是否有效。如果您的 session_id 已过期,然后点击您的 updateUserAPI 以获取新 ID 并将此 ID 设置在 header 或您想要的位置。这是一些代码示例。
RefreshTokenInterceptor
public static class RInterceptor implements Interceptor {
@Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request request = chain.request();
Response response = chain.proceed(request);
try {
if (response.code() == 410) {
Response r = null;
try {
r = makeTokenRefreshCall(request, chain);
} catch (JSONException e) {
e.printStackTrace();
}
return r;
}
} catch (Exception e) {
e.printStackTrace();
}
return response;
}
}
private static Response makeTokenRefreshCall(Request req, Interceptor.Chain chain) throws JSONException, IOException {
/* fetch refreshed token, some synchronous API call, whatever Because we are responsible to return new response */
refreshTokenSync();
Request newRequest;
newRequest = req.newBuilder().header("authorization", NEW_TOKEN)/*.post(req.body())*/.build();
return chain.proceed(newRequest);
}
RESTClient
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.readTimeout(50, TimeUnit.SECONDS)
.writeTimeout(55, TimeUnit.SECONDS)
.connectTimeout(50, TimeUnit.SECONDS)
.retryOnConnectionFailure(true)
.addInterceptor(new NetworkInterceptor())
.build();