OkHttp(Retrofit)對(duì)于http狀態(tài)碼202的處理

http code 202 :
The request has been accepted for processing, but the processing has not been completed.

這時(shí)候,服務(wù)器給你的body是空的,如果你使用去解析為json,那么,恭喜你

java.io.EOFException: End of input at line 1 column 1 在前面等著你

一個(gè)比較好的理解就是,服務(wù)器接受了你的請(qǐng)求,但是現(xiàn)在來(lái)不及處理,需要你等會(huì)試試。對(duì)于這種狀態(tài)碼,OkHttp并沒(méi)有為我們處理,jake大神也回答如是:

Paste_Image.png

這個(gè)issue在這里:
https://github.com/square/retrofit/issues/1554

我個(gè)人的解決辦法是如此:

  • 寫一個(gè)攔截器,攔截這種202的狀態(tài)碼.
  • 然后我們本身又使用的rxjava這個(gè)強(qiáng)大的框架去配合Retrofit,這時(shí)候,我遇到這種狀態(tài)嗎的是時(shí)候,去重試即可,具體的攔截器如下:

public class CreateInterceptor implements Interceptor {
    public static final int HTTP_CODE_ACCEPT = 202;                     //請(qǐng)求成功,但沒(méi)有處理

    @Override
    public Response intercept(Chain chain) throws IOException {
        Response response = chain.proceed(chain.request());  //如果401了,會(huì)先執(zhí)行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的時(shí)候

OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.addInterceptor(new CreateInterceptor());//攔截202,直接返回錯(cuò)誤哦
OkHttpClient okHttpClient = builder.build();

再將上述 build出來(lái)的OkHttpClient 設(shè)置給 Retrofit 即可。

new Retrofit.Builder().client(....)...

那么,最最重要的,如何去重試呢?

實(shí)際上,我也是參考了網(wǎng)上的一個(gè)例子 ,在我的另外一篇文章中有提到這個(gè)技巧:android中使用Rxjava一些有意思的代碼集合 ,在第17條那里,參照這個(gè)原理,略微改了改,這里的代碼如下:

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
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容