OkHttp自定义重试次数
本文主要应用了OkHttp的Interceptor来实现自定义重试次数
虽然OkHttp自带retryOnConnectionFailure(true)方法可以实现重试,但是不支持自定义重试次数,所以有时并不能满足我们的需求。
#1.自定义重试拦截器:
/**
* 重试拦截器
*/
public class RetryIntercepter implements Interceptor { public int maxRetry;//最大重试次数
private int retryNum = ;//假如设置为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.测试场景类:
public class RetryTest {
String mUrl = "https://www.baidu.com/";
OkHttpClient mClient;
@Before
public void setUp() {
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
mClient = new OkHttpClient.Builder()
.addInterceptor(new RetryIntercepter())//重试
.addInterceptor(logging)//网络日志
.addInterceptor(new TestInterceptor())//模拟网络请求
.build();
}
@Test
public void testRequest() throws IOException {
Request request = new Request.Builder()
.url(mUrl)
.build();
Response response = mClient.newCall(request).execute();
System.out.println("onResponse:" + response.body().string());
}
class TestInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
String url = request.url().toString();
System.out.println("url=" + url);
Response response = null;
if (url.equals(mUrl)) {
String responseString = "{\"message\":\"我是模拟的数据\"}";//模拟的错误的返回值
response = new Response.Builder()
.code()
.request(request)
.protocol(Protocol.HTTP_1_0)
.body(ResponseBody.create(MediaType.parse("application/json"), responseString.getBytes()))
.addHeader("content-type", "application/json")
.build();
} else {
response = chain.proceed(request);
}
return response;
}
}
}
#3.输出结果:
retryNum=
--> GET https://www.baidu.com/ HTTP/1.1
--> END GET
url=https://www.baidu.com/
<-- null https://www.baidu.com/ (13ms)
content-type: application/json {"message":"我是模拟的数据"}
<-- END HTTP (-byte body)
retryNum=
--> GET https://www.baidu.com/ HTTP/1.1
--> END GET
url=https://www.baidu.com/
<-- null https://www.baidu.com/ (0ms)
content-type: application/json {"message":"我是模拟的数据"}
<-- END HTTP (-byte body)
retryNum=
--> GET https://www.baidu.com/ HTTP/1.1
--> END GET
url=https://www.baidu.com/
<-- null https://www.baidu.com/ (0ms)
content-type: application/json {"message":"我是模拟的数据"}
<-- END HTTP (-byte body)
retryNum=
--> GET https://www.baidu.com/ HTTP/1.1
--> END GET
url=https://www.baidu.com/
<-- null https://www.baidu.com/ (0ms)
content-type: application/json {"message":"我是模拟的数据"}
<-- END HTTP (-byte body)
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())来实现重试机制
public class RetryWithDelay implements Func1<Observable<? extends Throwable>, Observable<?>> {
private final int maxRetries;
private final int retryDelayMillis;
private int retryCount;
public RetryWithDelay(int maxRetries, int retryDelayMillis) {
this.maxRetries = maxRetries;
this.retryDelayMillis = retryDelayMillis;
}
@Override
public Observable<?> call(Observable<? extends Throwable> attempts) {
return attempts
.flatMap(new Func1<Throwable, Observable<?>>() {
@Override
public Observable<?> call(Throwable throwable) {
if (++retryCount <= maxRetries) {
// When this Observable calls onNext, the original Observable will be retried (i.e. re-subscribed).
LogUtil.print("get error, it will try after " + retryDelayMillis + " millisecond, retry count " + retryCount);
return Observable.timer(retryDelayMillis,
TimeUnit.MILLISECONDS);
}
// Max retries hit. Just pass the error along.
return Observable.error(throwable);
}
});
}
}
OkHttp自定义重试次数的更多相关文章
- Dubbo重试次数
服务超时后重试次数[retries],不包含第一次调用,0代表不重试 *我们应该在幂等方法上设置重试次数[查询.删除.修改],在非幂等方法上禁止设置重试次数. ★幂等:指多次运行方法所产生的最终效果是 ...
- 一个带重试次数的curl 函数
<?php/** * [curl 带重试次数] * @param [type] $url [访问的url] * @param [type] $post [$POST参数] * @param in ...
- SpringCloud Feign 之 超时重试次数探究
SpringCloud Feign 之 超时重试次数探究 上篇文章,我们对Feign的fallback有一个初步的体验,在这里我们回顾一下,Fallback主要是用来解决依赖的服务不可用或者调用服务失 ...
- Redis解决“重试次数”场景的实现思路
很多地方都要用到重试次数限制,不然就会被暴力破解.比如登录密码. 下面不是完整代码,只是伪代码,提供一个思路. 第一种(先声明,这样写有个bug) import java.text.MessageFo ...
- python重试次数装饰器
目录 重试次数装饰器 重试次数装饰器 前言, 最近在使用tornado框架写Restful API时遇到很多的问题. 有框架的问题, 有异步的问题. 虽然tornado 被公认为当前python语言最 ...
- Shiro密码重试次数限制
如在 1 个小时内密码最多重试 5 次,如果尝试次数超过 5 次就锁定 1 小时,1 小时后可再次重试,如果还是重试失败,可以锁定如 1 天,以此类推,防止密码被暴力破解.我们通过继承 HashedC ...
- 使用Python请求http/https时设置失败重试次数
设置请求时的重试规则 import requests from requests.adapters import HTTPAdapter s = requests.Session() a = HTTP ...
- python requests 配置超时及重试次数
import requests from requests.adapters import HTTPAdapter s = requests.Session() s.mount('http://', ...
- springcloud超时时间与重试次数配置
#hystrix配置hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=120000ribbon.Conn ...
随机推荐
- SAP的这三款CRM解决方案,您能区分清楚么
我的一位同事, John Burton, 在2017年12月底写过一篇博文:Explaining SAP's portfolio of "CRM Service" related ...
- java中重载一定在一个类里面吗?
虽然这些概念在翻译成中文的过程中,有很多不同的翻译方式但本质上只有两种说法,就是Override和Overload其中,Overload一般都被翻译成重载而Override的翻译就乱七八糟了,所谓覆盖 ...
- 用Token令牌维护微服务之间的通信安全的实现
在微服务架构中,如果忽略服务的安全性,任由接口暴露在网络中,一旦遭受攻击后果是不可想象的. 保护微服务键安全的常见方案有:1.JWT令牌(token) 2.双向SSL 3.OAuth 2.0 等 本文 ...
- 在实战中使用Sass和Compass
第三章 无需计算玩转CSS网格布局 3.1 网格布局介绍 3.2 使用网格布局 3.2.1 术语 1 术语名 定义 是否涉及HTML标签 2 列 内容度量的垂直单位 否 3 容器 构成一个网格布局的H ...
- zoj 3228:Searching the String
Description Little jay really hates to deal with string. But moondy likes it very much, and she's so ...
- hdu_4463(最小生成树)
hdu_4463(最小生成树) 标签: 并查集 题目链接 题意: 求一个必须包含一条路径的最小生成树 题解: 把那条边初始化成0 保证这条边一定会被选 #include<cstdio> # ...
- js闭包的真正理解
<高级程序设计>上,这样说:当在函数内部定义了其他函数时候,就创建了闭包.闭包有权访问包含函数内部的所有变量. 这个说的太晦涩了,而且我觉得很容易理解错,闭包就是一个嵌套函数嘛?但是我觉得 ...
- TF-IDF_MapReduceJava代码实现思路
TF-IDF 1. 概念 2. 原理 3. java代码实现思路 数据集: 三个MapReduce 第一个MapReduce:(利用ik分词器,将一篇博文,也就是一条记录 ...
- dedecms织梦网站图片集上传图片出现302错误图片提示怎么解决 已测
时间:2016-01-20 来源:未知 作者:模板之家 阅读:次 小编今天上传织梦网站模板的时候,在图片集里面选择上传图片的时候,弹出302错误提示,当是真的是郁闷了,试了好几次,开始还以为是图片过大 ...
- js立体旋转展示效果
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...