OkHttp自訂重試次數,okhttp自訂重試

來源:互聯網
上載者:User

OkHttp自訂重試次數,okhttp自訂重試

本文主要應用了OkHttp的Interceptor來實現自訂重試次數

雖然OkHttp內建retryOnConnectionFailure(true)方法可以實現重試,但是不支援自訂重試次數,所以有時並不能滿足我們的需求。

#1.自訂重試攔截器:

/** * 重試攔截器 */public class RetryIntercepter implements Interceptor {    public int maxRetry;//最大重試次數    private int retryNum = 0;//假如設定為3次重試的話,則最大可能請求4次(預設1次+3次重試)    public RetryIntercepter(int maxRetry) {        this.maxRetry = maxRetry;    }    @Override    public Response intercept(Chain chain) throws IOException {        Request request = chain.request();        System.out.println("retryNum=" + retryNum);        Response response = chain.proceed(request);        while (!response.isSuccessful() && retryNum < maxRetry) {            retryNum++;            System.out.println("retryNum=" + retryNum);            response = chain.proceed(request);        }        return response;    }}

#2.測試情境類:

 1 public class RetryTest { 2     String mUrl = "https://www.baidu.com/"; 3     OkHttpClient mClient; 4  5     @Before 6     public void setUp() { 7         HttpLoggingInterceptor logging = new HttpLoggingInterceptor(); 8         logging.setLevel(HttpLoggingInterceptor.Level.BODY); 9 10         mClient = new OkHttpClient.Builder()11                 .addInterceptor(new RetryIntercepter(3))//重試12                 .addInterceptor(logging)//部落格13                 .addInterceptor(new TestInterceptor())//類比網路請求14                 .build();15     }16 17     @Test18     public void testRequest() throws IOException {19         Request request = new Request.Builder()20                 .url(mUrl)21                 .build();22         Response response = mClient.newCall(request).execute();23         System.out.println("onResponse:" + response.body().string());24     }25 26     class TestInterceptor implements Interceptor {27 28         @Override29         public Response intercept(Chain chain) throws IOException {30             Request request = chain.request();31             String url = request.url().toString();32             System.out.println("url=" + url);33             Response response = null;34             if (url.equals(mUrl)) {35                 String responseString = "{\"message\":\"我是類比的資料\"}";//類比的錯誤的傳回值36                 response = new Response.Builder()37                         .code(400)38                         .request(request)39                         .protocol(Protocol.HTTP_1_0)40                         .body(ResponseBody.create(MediaType.parse("application/json"), responseString.getBytes()))41                         .addHeader("content-type", "application/json")42                         .build();43             } else {44                 response = chain.proceed(request);45             }46             return response;47         }48     }49 50 }

#3.輸出結果:

 1 retryNum=0 2 --> GET https://www.baidu.com/ HTTP/1.1 3 --> END GET 4 url=https://www.baidu.com/ 5 <-- 400 null https://www.baidu.com/ (13ms) 6 content-type: application/json 7  8 {"message":"我是類比的資料"} 9 <-- END HTTP (35-byte body)10 retryNum=111 --> GET https://www.baidu.com/ HTTP/1.112 --> END GET13 url=https://www.baidu.com/14 <-- 400 null https://www.baidu.com/ (0ms)15 content-type: application/json16 17 {"message":"我是類比的資料"}18 <-- END HTTP (35-byte body)19 retryNum=220 --> GET https://www.baidu.com/ HTTP/1.121 --> END GET22 url=https://www.baidu.com/23 <-- 400 null https://www.baidu.com/ (0ms)24 content-type: application/json25 26 {"message":"我是類比的資料"}27 <-- END HTTP (35-byte body)28 retryNum=329 --> GET https://www.baidu.com/ HTTP/1.130 --> END GET31 url=https://www.baidu.com/32 <-- 400 null https://www.baidu.com/ (0ms)33 content-type: application/json34 35 {"message":"我是類比的資料"}36 <-- END HTTP (35-byte body)37 onResponse:{"message":"我是類比的資料"}

#4.結果分析:
>1. 這裡我用一個TestInterceptor攔截器攔截掉真實的網路請求,實現response.code的自訂
2. 在RetryIntercepter中,通過response.isSuccessful()來對響應碼進行判斷,迴圈調用了多次chain.proceed(request)來實現重試攔截
3. 從輸出中可以看到,一共請求了4次(預設1次+重試3次)。

#5.其它實現方式
如果你是使用OkHttp+Retrofit+RxJava,你也可以使用retryWhen操作符:retryWhen(new RetryWithDelay())來實現重試機制

 1 public class RetryWithDelay implements Func1<Observable<? extends Throwable>, Observable<?>> { 2  3         private final int maxRetries; 4         private final int retryDelayMillis; 5         private int retryCount; 6  7         public RetryWithDelay(int maxRetries, int retryDelayMillis) { 8             this.maxRetries = maxRetries; 9             this.retryDelayMillis = retryDelayMillis;10         }11 12         @Override13         public Observable<?> call(Observable<? extends Throwable> attempts) {14             return attempts15                     .flatMap(new Func1<Throwable, Observable<?>>() {16                         @Override17                         public Observable<?> call(Throwable throwable) {18                             if (++retryCount <= maxRetries) {19                                 // When this Observable calls onNext, the original Observable will be retried (i.e. re-subscribed).20                                 LogUtil.print("get error, it will try after " + retryDelayMillis + " millisecond, retry count " + retryCount);21                                 return Observable.timer(retryDelayMillis,22                                         TimeUnit.MILLISECONDS);23                             }24                             // Max retries hit. Just pass the error along.25                             return Observable.error(throwable);26                         }27                     });28         }29 }

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.