[英]Retrofit: How do I retry the request again from okhttp interceptor?
我創建了一個攔截器。 在某些情況下,我想重試請求 'n' 次,我該怎么做?
class NetworkErrorHandler constructor(): Interceptor {
//Central error handling block for errors which has impact all over the app
override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request()
var response = chain.proceed(request)
return
when (response.code) {
401 -> {
response
}
200 ->{
response
}
else -> {
var tryCount = 0
while (tryCount < 3) {
try {
response = chain.proceed(request)
tryCount++
}catch (e: java.lang.Exception){
tryCount++
}
}
response
}
}
}
}
它給了我這個錯誤:
Suppressed: java.lang.IllegalStateException: network interceptor must call proceed() exactly once
如果是,我是否必須在這里執行此操作,然后怎么做?
我認為您從另一個問題中引導自己如何使用 OkHttp/Retrofit 重試 HTTP 請求? (如果沒有,我建議你這樣做)。 您的代碼的問題是您的 while 僅受 trycount 的限制,而不受響應結果的限制。 嘗試在那里添加有關響應狀態的驗證,因此它不會並行執行 .proceed 方法兩次。
// try the request
Response response = chain.proceed(request);
int tryCount = 0;
while (!response.isSuccessful() && tryCount < 3) {
所以我能夠通過使用這條線從攔截器進行另一個調用
response.close()
chain.call().clone().execute()
根據問題的完整代碼:
//Central error handling block for errors which has impact all over the app
class NetworkErrorHandler constructor(): Interceptor {
var tryCount = 0
override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request()
var response = chain.proceed(request)
return
when(response.code) {
401 - > {
response
}
200 - > {
response
}
else - > {
if (tryCount < 3) {
Thread.sleep(2000)
tryCount++
response.close()
chain.call().clone().execute()
}
response.newBuilder()
.code(401) // Whatever code
.body("".toResponseBody(null)) // Whatever body
.protocol(Protocol.HTTP_2)
.message("Network Error")
.request(chain.request())
.build()
}
}
}
這就是我的處理方式:
@Slf4j
public class HttpRetryInterceptor implements Interceptor {
@Override
public @NotNull Response intercept(Chain chain) throws IOException {
log.error("Making request for the first time.");
var request = chain.request();
Response response = null;
boolean responseOK = false;
byte tryCount = 0;
while (!responseOK && tryCount < 3) {
try {
Thread.sleep(5000 * tryCount);
response = chain.proceed(request);
log.info("Response is: {}",response);
log.info("Response message: {}",response.message());
responseOK = response.isSuccessful();
}catch (Exception e){
e.printStackTrace();
log.error("Request was not successful: {} . Retrying." , tryCount);
}finally{
assert response != null;
response.close();
tryCount++;
}
}
return response != null ? response : chain.proceed(request);
}
}
然后我將我的攔截器添加到我的客戶端,如下所示: new OkHttpClient.Builder().addInterceptor(new HttpRetryInterceptor()).build()
借助Failsafe 的 OkHttp支持和適用於您的場景的 RetryPolicy,這非常容易:
RetryPolicy<Response> retryPolicy = RetryPolicy.<Response>builder()
.handleResultIf(r -> r.code() != 401 && r.code() != 200)
.withMaxAttempts(3)
.build();
Call call = client.newCall(request);
FailsafeCall failsafeCall = FailsafeCall.with(retryPolicy).compose(call);
// Execute with retries
Response response = failsafeCall.execute();
使用.interceptors()
來使用Application Interceptor
而不是.networkInterceptors()
允許多次調用.proceed()
。 更多信息: https ://square.github.io/okhttp/interceptors/
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.