OkHttp custom retries and okhttp custom retries
This article mainly applies Interceptor of OkHttp to customize the number of retries
Although the retryOnConnectionFailure (true) method provided by OkHttp can achieve retry, it does not support custom retry times, so sometimes it cannot meet our needs.
#1. Custom retry Interceptor:
/*** Retry Interceptor */public class RetryIntercepter implements Interceptor {public int maxRetry; // maximum number of retries private int retryNum = 0; // If set to 3 retries, the maximum number of requests may be 4 (1 + 3 retries by default) 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. test scenario:
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) // retry 12. addInterceptor (logging) // Network Log 13. addInterceptor (new TestInterceptor () // simulates network requests 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(requestcmd.exe cute (); 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 \ ": \" I Am a simulated data \"}"; // The returned value of the simulated error is 36 response = new Response. builder () 37. code (400) 38. request (request) 39. protocol (Protocol. http_defaults 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. output result:
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/(13 ms) 6 content-type: application/json 7 8 {"message": "simulated data"} 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/(0 ms) 15 content-type: application/json16 17 {"message": "I am a simulated data"} 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/(0 ms) 24 content-type: application/json25 26 {"message": "I am a simulated data"} 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/(0 ms) 33 content-type: application/json34 35 {"message": "I am a simulated data"} 36 <-- END HTTP (35-byte body) 37 onResponse: {"message ": "I am a simulated data "}
#4. Result Analysis:
> 1. Here I use a TestInterceptor Interceptor to intercept real network requests and customize response. code.
2. In RetryIntercepter, response. isSuccessful () is used to determine the response code. Multiple chain. proceed (request) are called cyclically to implement retry interception.
3. From the output, we can see that a total of four requests are made (1 request + 3 retries by default ).
#5. Other implementation methods
If you are using OkHttp + pull fit + RxJava, you can also use the retryWhen OPERATOR: retryWhen (new RetryWithDelay () to implement the Retry Mechanism.
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 }