OkHttp(Retrofit)对于http状态码202的处理

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大神也回答如是:

OkHttp(Retrofit)对于http状态码202的处理_第1张图片
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> {

        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 inputObservable) {
            return inputObservable.flatMap(new Func1>() {
                @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即可。

OkHttp(Retrofit)对于http状态码202的处理_第2张图片
retryWhen.png

你可能感兴趣的:(OkHttp(Retrofit)对于http状态码202的处理)