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 ...
随机推荐
- 2、ABPZero系列教程之拼多多卖家工具 更改数据库为Mysql
因为要部署项目到云服务器,不想在服务器上装SqlServer,所以需要把项目改为Mysql. 项目初始化 1.下载项目压缩包,前面文章已经说到,可以加群到群文件里下载.解压缩下载的项目源码,使用VS2 ...
- H5 调用手机摄像机、相册功能
<input type="file" accept="image/*" capture="camera"> <input ...
- 迭代器中next()的用法
>>> g = (x ** 2 for x in range(10)) >>> next(g) 0 >>> next(g) 1 >>& ...
- JAVA入门(1.JAVA平台应用 2.核心概念:JVM,JDK,JRE 3.搭建JAVA开发环境 4.学习JAVA的原则)
主要内容: 1.JAVA平台应用 2.核心概念:JVM,JDK,JRE 3.搭建JAVA开发环境 4.学习JAVA的原则 JAVA的平台应用 JAVA的平台应用分为3个部分: 一.JAVA SE,主要 ...
- I2C通讯协议
1.基本概念 主机 初始化发送,产生时钟信号和终止发送的器件 从机 被主机寻址的器件 发送器 发送数据到总线的器件 接收器 ...
- eclipse安装java web插件
1 查看eclipse版本 找到eclipse的安装目录,找到readme文件,打开其中的html文件,我的是4.6版本的,代号是oxygen 2 安装 打开eclipse,点击help-Instal ...
- CTF---密码学入门第四题 困在栅栏里的凯撒
困在栅栏里的凯撒分值:10 来源: 北邮天枢战队 难度:易 参与人数:4531人 Get Flag:2124人 答题人数:2285人 解题通过率:93% 小白发现了一段很6的字符:NlEyQd{sef ...
- 2329: [HNOI2011]括号修复
传送魔法 一开始以为可以直接线段树的,好像还是不行……还是得用Spaly,然后就没啥了. #include<cstdio> #include<algorithm> #defin ...
- Codeforces 839A Arya and Bran【暴力】
A. Arya and Bran time limit per test:1 second memory limit per test:256 megabytes input:standard inp ...
- [51nod1671]货物运输
公元2222年,l国发生了一场战争. 小Y负责领导工人运输物资. 其中有m种物资的运输方案,每种运输方案形如li,ri.表示存在一种货物从li运到ri. 这里有n个城市,第i个城市与第i+1个城市相连 ...