http code 202 :
The request has been accepted for processing, but the processing has not been completed.
這時候,服務器給你的body是空的,如果你使用去解析為json,那么,恭喜你
java.io.EOFException: End of input at line 1 column 1
在前面等著你
一個比較好的理解就是,服務器接受了你的請求,但是現在來不及處理,需要你等會試試。對于這種狀態碼,OkHttp并沒有為我們處理,jake大神也回答如是:
Paste_Image.png
這個issue在這里:
https://github.com/square/retrofit/issues/1554
我個人的解決辦法是如此:
- 寫一個攔截器,攔截這種202的狀態碼.
- 然后我們本身又使用的
rxjava
這個強大的框架去配合Retrofit
,這時候,我遇到這種狀態嗎的是時候,去重試即可,具體的攔截器如下:
public class CreateInterceptor implements Interceptor {
public static final int HTTP_CODE_ACCEPT = 202; //請求成功,但沒有處理
@Override
public Response intercept(Chain chain) throws IOException {
Response response = chain.proceed(chain.request()); //如果401了,會先執行TokenAuthenticator
Logger.e("CreateInterceptor request url "+response.request().url());
Logger.e("CreateInterceptor response code "+response.code());
if (response.code() == HTTP_CODE_ACCEPT) {
CreateInterceptorExceptioin interceptorExceptioin = new CreateInterceptorExceptioin();
interceptorExceptioin.setErrorCode(HTTP_CODE_ACCEPT);
interceptorExceptioin.setRetry_after(response.header("Retry-After"));
throw interceptorExceptioin;
}
return response;
}
public class CreateInterceptorExceptioin extends Error{
private int errorCode;
private String retry_after;
public int getErrorCode() {
return errorCode;
}
public void setErrorCode(int errorCode) {
this.errorCode = errorCode;
}
public String getRetry_after() {
return retry_after;
}
public void setRetry_after(String retry_after) {
this.retry_after = retry_after;
}
}
}
然后,在build的時候
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.addInterceptor(new CreateInterceptor());//攔截202,直接返回錯誤哦
OkHttpClient okHttpClient = builder.build();
再將上述 build出來的OkHttpClient
設置給 Retrofit
即可。
new Retrofit.Builder().client(....)...
那么,最最重要的,如何去重試呢?
實際上,我也是參考了網上的一個例子 ,在我的另外一篇文章中有提到這個技巧:android中使用Rxjava一些有意思的代碼集合 ,在第17條那里,參照這個原理,略微改了改,這里的代碼如下:
public static final class RetryWhen202Happen implements Func1<Observable<? extends Throwable>, Observable<?>> {
private final int _maxRetries;
private final int _retryDelayMillis;
private int _retryCount;
public RetryWhen202Happen(final int maxRetries, final int retryDelayMillis) {
_maxRetries = maxRetries;
_retryDelayMillis = retryDelayMillis;
_retryCount = 0;
}
@Override
public Observable<?> call(Observable<? extends Throwable> inputObservable) {
return inputObservable.flatMap(new Func1<Throwable, Observable<?>>() {
@Override
public Observable<?> call(Throwable throwable) {
if (++_retryCount < _maxRetries && throwable instanceof CreateInterceptor.CreateInterceptorExceptioin) {
// When this Observable calls onNext, the original
// Observable will be retried (i.e. re-subscribed)
Log.e("RetryWhen202Happen", "call: "+_retryCount);
return Observable.timer(_retryCount * _retryDelayMillis, TimeUnit.MILLISECONDS);
}
return Observable.error(throwable);
}
});
}
}
最后:我們使用rxjava
提供的retryWhen
即可。
retryWhen.png