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;}@Overridepublic 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     @Test
18     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         @Override
29         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=1
11 --> GET https://www.baidu.com/ HTTP/1.1
12 --> END GET
13 url=https://www.baidu.com/
14 <-- 400 null https://www.baidu.com/ (0ms)
15 content-type: application/json
16 
17 {"message":"我是模拟的数据"}
18 <-- END HTTP (35-byte body)
19 retryNum=2
20 --> GET https://www.baidu.com/ HTTP/1.1
21 --> END GET
22 url=https://www.baidu.com/
23 <-- 400 null https://www.baidu.com/ (0ms)
24 content-type: application/json
25 
26 {"message":"我是模拟的数据"}
27 <-- END HTTP (35-byte body)
28 retryNum=3
29 --> GET https://www.baidu.com/ HTTP/1.1
30 --> END GET
31 url=https://www.baidu.com/
32 <-- 400 null https://www.baidu.com/ (0ms)
33 content-type: application/json
34 
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         @Override
13         public Observable<?> call(Observable<? extends Throwable> attempts) {
14             return attempts
15                     .flatMap(new Func1<Throwable, Observable<?>>() {
16                         @Override
17                         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 }

 


更多专业前端知识,请上 【猿2048】www.mk2048.com

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/363569.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Ruby的库路径

irb下打入p $即显示出来 如: irb(main):003:0* p $: ["c:/ruby/lib/ruby/site_ruby/1.8", "c:/ruby/lib/ruby/site_ruby/1.8/i386-msvcrt", "c:/ruby/lib/ruby/site_ruby", "c:/ruby/lib/ruby/1.8", "c:/ruby/lib/ruby/1.8/i38 …

【快报】基于K2 BPM的新一代协同办公门户实践交流会

2014年2月28日&#xff0c;“基于BPM的新一代协同办公门户”用户实践交流活动在深圳金茂JW万豪酒店3楼Meet Room IV举办。本次会议由K2携手微软共同举办&#xff0c;邀请到的参会企业都是K2 的BPM老客户或对BPM新一代协同办公门户非常感兴趣的新朋友&#xff0c;他们有&#xf…

80个让你笑爆肚皮的程序员段子,不好笑算我输!

阅读本文大概需要 12 分钟。 1、折磨 对程序员的一般折磨&#xff1a;离奇的需求&#xff0c;对程序员的超级折磨&#xff1a;改三次需求~~~ 2、开发时间 项目经理说&#xff1a;给你三个人&#xff0c;多久可以完成&#xff1f;程序员&#xff1a;3个月&#xff01;那五个人呢…

Spring Integration Java DSL示例–使用Jms名称空间工厂进一步简化

在较早的博客文章中&#xff0c;我谈到了虚拟卢布戈德堡流程&#xff0c;该流程通过一系列复杂的步骤将字符串变成大写&#xff0c;本文的前提是引入Spring Integration Java DSL&#xff0c;作为通过xml配置文件定义集成流程的替代方法。 感谢Artem Bilan &#xff0c;在写完…

冯诺依曼计算机结构教案,冯诺依曼结构的计算机-同济大学精品课程.PPT

冯诺依曼结构的计算机-同济大学精品课程* 第一章 概 述 同济大学软件学院 课程的内容&#xff1a; 1&#xff0e;介绍单计算机系统的硬件组成 (内部结构、工作机制) 2&#xff0e;计算机自动工作的原理 3&#xff0e;在对工作原理了解的基础上&#xff0c;讲述有关计算机设 计的…

非安装版的PostgreSQL8.3.3的首次使用经历

第一次用Postgre&#xff0c;已经是好多年以前了&#xff0c;隐约记得是在linux下边&#xff0c;build半天&#xff0c;然后手动配置库文件之类。 今天在整理资料的时候发现&#xff0c;Postgre出现了解压缩直接使用的版本&#xff0c;上边注明了for expert only. 呵呵&#xf…

腾讯TBS X5 WebView的简单使用

工作中经常涉及H5网页的加载工作&#xff0c;最多使用的就是安卓系统控件WebView&#xff0c;但是当网页内容比较多的时候&#xff0c;需要等待很久才能加载完&#xff0c;加载完后用户才能看到网页中的内容&#xff0c;这样用户需要等很久&#xff0c;体验很差。 那能不能边加…

针对新手的Java EE7和Maven项目–第5部分–使用Arquillian / Wildfly 8进行单元测试

从前面的部分恢复 第1 部分 &#xff0c; 第2 部分 &#xff0c; 第3 部分 &#xff0c; 第4部分 &#xff0c; 这是第一篇“额外”的帖子&#xff0c;基于我正在此系列博客文章上“构建”的Maven JavaEE7演示项目。 我们已经定义了一个坚实的结构和一些模块。 在这样的应用程…

C/S,B/S的区别与联系

C/S 是Client/Server 的缩写。服务器通常采用高性能的PC、工作站或小型机&#xff0c;并采用 大型数据库系统&#xff0c;如Oracle、Sybase、Informix 或SQL Server。客户端需要安装专用的客户 端软件。 B/&#xff33;是Brower/Server 的缩写&#xff0c;客户机上只要安装一个…

五年级下册电子计算机与多媒体,语文人教版五年级下册《电子计算机与多媒体》.doc...

《电子计算机与多媒体》教学设计沈彦坤 石家庄市鹿泉区石井乡封庄小学?一、概述??语文&#xff0c;五年级五年级下册&#xff0c;第一课时熟悉课文内容,学会生字,理解新词意思&#xff0c;学习课文1-3段。了解计算机的产生与发展&#xff0c;了解什么是多媒体,计算机与多媒体…

Airflow安装与使用

# Airflow 1.10安装本次安装Airflow版本为1.10&#xff0c;其需要依赖Python和DB&#xff0c;本次选择的DB为Mysql。本次安装组件及版本如下&#xff1a;Airflow 1.10.0Python 3.6.5Mysql 5.7# 整体流程1. 建表2. 安装3. 配置4. 运行5. 配置任务启动scheduleairflow schedul…

Wordpress安装

Wordpress是一种用PHP语言和MySQL的数据库的开源的免费Blog引擎&#xff0c;用户可以在支持PHP和MySQL数据库的服务器上建立自己的Blog,它具有非常强大的功能和成千上万的插件和模板主题。安装步骤如下(本文以Wordpress2.6中文版为例): (1) 在MySQL中创建Wordpress库&#xff0…

python 内置标准库socketserver模块的思考

socketserver模块简化了编写网络服务器的任务, 在很大程度上封装了一些操作, 你可以看成是事件驱动型的设计, 这很不错。它定义了两个最基本的类--服务器类 BaseServer, 请求处理类 BaseRequestHandler. BaseServer 基本服务器类封装了基本的一些socket操作, socket原语中对so…

关于素数的一些定理

1.何谓素数&#xff1f; 指在一个大于1的整数中&#xff0c;如果一个数只能整除1与本身&#xff0c;则该数为素数&#xff08;质数&#xff09;&#xff0c;否则为合数。 1既不是素数也不是合数 2.素数个数无限多 3.所有大于2的素数都可以唯一的表示为两个平方数之差 pa^2-b^2(…

教师节的感触

刚喝了点酒&#xff0c;因为今天是教师节&#xff0c;我觉得博客是一个很好的平台&#xff0c;可以把自己的一些感想就是的发表出来。把音乐放出来一 边写着博客是一种很自我的感觉&#xff0c;可以在微酣的时候把自己的点滴感受好好的梳理一下倒是一种不错的方式。这是自己第一…

Spring 4.1和Java 8:java.util.Optional

由于Spring 4.1的Java 8的的java.util.Optional &#xff0c;容器对象可能会或可能不包含非空值&#xff0c;支持与RequestParam &#xff0c; RequestHeader和MatrixVariable 。 使用Java 8的java.util.Optional请确保参数永远不会为null 。 请求参数 在此示例中&#xff0c;…

计算机网络层实验路由表苏州科技,苏州科技大学计算机网络实验报告课案.docx...

苏州科技大学计算机网络实验报告课案苏州科技学院 电子信息实验中心实验报告课  程计算机网络原理学    名徐金玮班  级计算机1312专  业计算机科学与技术指导教师陶滔学年 / 学期2015~2016学年第一学期实验一 物理层实验实验项目性质&#xff1a;设计性  计划学…

Fibonacci again and again

Fibonacci again and again http://acm.hdu.edu.cn/showproblem.php?pid1848 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 12494 Accepted Submission(s): 5439 Problem Description任何一个大学生对菲波那…

使用闭包的方式实现一个累加函数 addNum

使用闭包的方式实现一个累加函数 addNum&#xff0c;参数为 number 类型&#xff0c;每次返回的结果 上一次计算的值 传入的值&#xff0c;如&#xff1a; addNum(10); //10 addNum(12); //22 addNum(30); //52 写法一 1 function sum(numberOne) {2 var count…

妈妈的菜谱-豉油鸡

我妈周末来我家&#xff0c;给我做一道豉油鸡&#xff0c;我记录下来&#xff0c;分享给大家 1、下午四点半左右&#xff0c;我、老弟以及亲妈&#xff0c;到隔壁市场鸡场&#xff0c;挑选了一只类似的芦花阉鸡活鸡&#xff0c;价格是17块钱每斤&#xff0c;大概三斤多点&#…