🍓 成功/失败条件
Forest 对每个请求都会判断其发送和响应结果是否成功。
成功,就会去执行OnSuccess
回调函数和拦截器中的onSuccess
方法,并返回响应结果。
失败,则会进行重试,如果该请求不允许重试,或者达到了最大重试次数限制,则会调用OnError
回调函数,和拦截器中的onError
方法。
# 默认成功/失败条件
Forest 提供了默认的请求成功/失败条件,其逻辑如下:
- 判断是否在发送和等待响应的过程中出现异常,如: 网络连接错误、超时等
- 在取得响应结果后,判断其响应状态码是否在正常范围内 (
100
~399
)
以上两条判断条件如有一条不满足,则就判定为请求失败,否则为成功。
默认的判断条件可以满足绝大部分场景的需要,也比较符合HTTP协议标准的规范,但也存在一些特殊场景,并不以HTTP标准为判断逻辑,这时候就需要用户进行自定义的请求成功/失败条件的判断了。
# 自定义成功/失败条件
这里举一个栗子,除了正常的异常判断外,当响应码为203
的时候判断为请求失败。这样的条件如何定义请看如下代码:
# 使用 @Success 注解
# 第一步,先要定义 SuccessWhen 接口的实现类
// 自定义成功/失败条件实现类
// 需要实现 SuccessWhen 接口
public class MySuccessCondition implements SuccessWhen {
/**
* 请求成功条件
* @param req Forest请求对象
* @param res Forest响应对象
* @return 是否成功,true: 请求成功,false: 请求失败
*/
@Override
public boolean successWhen(ForestRequest req, ForestResponse res) {
// req 为Forest请求对象,即 ForestRequest 类实例
// res 为Forest响应对象,即 ForestResponse 类实例
// 返回值为 ture 则表示请求成功,false 表示请求失败
return res.noException() && // 请求过程没有异常
res.statusOk() && // 并且状态码在 100 ~ 399 范围内
res.statusIsNot(203); // 但不能是 203
// 当然在这里也可以写其它条件,比如 通过 res.getResult() 或 res.getContent() 获取业务数据
// 再更具业务数据判断是否成功
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
特别注意
在successWhen
方法的逻辑代码中,千万不能调用 res.isSuccess()
或 !res.isError()
进行判断
不然会引起死循环
# 第二步,挂上 @Success
注解
public interface MyClient {
/**
* 挂上了 @Success 注解
* <p>该方法的请求是否成功
* <p>以自定义成功条件类 MySuccessCondition 的判断方法为准
*
* @return 请求响应结果
*/
@Get("/")
@Success(condition = MySuccessCondition.class)
String sendData();
}
2
3
4
5
6
7
8
9
10
11
12
若调用sendData()
方法后,返回的状态码为 203, 就会被认为是请求失败,如果设置了重试次数大于0,就会去执行重试任务。
若没有重试次数可用,则进入 onError 请求失败流程
# 接口上的成功/失败条件
@Success
注解也可以挂在interface
接口类上,代表其下的所有请求方法都设置为此自定义条件
/**
* interface 上挂了 @Success 注解
* <p>该接口类下的所有方法都依据
* <p>自定义的 MySuccessCondition 请求成功条件类
* <p>为请求是否成功的判定条件
*/
@Success(condition = MySuccessCondition.class)
public interface MyClient {
@Get("/test1")
String sendData1();
@Get("/test2")
String sendData2();
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
此时,不管是调用sendData1()
还是sendData2()
方法,都会依据 MySuccessCondition 的判定条件为准
如果其中有一个方法想以另一种逻辑作为请求成功/失败的判断条件,可以在那个方法上加上@Success
注解
/**
* interface 上挂了 @Success 注解
* <p>该接口类下的所有方法都依据
* <p>自定义的 MySuccessCondition1 请求成功条件类
* <p>为请求是否成功的判定条件
* <p>除非该方法定义了自己的请求成功条件
*/
@Success(condition = MySuccessCondition1.class)
public interface MyClient {
// 以 MySuccessCondition1 作为成功判断条件
@Get("/test1")
String sendData1();
// 以 MySuccessCondition1 作为成功判断条件
@Get("/test2")
String sendData2();
// 以 MySuccessCondition2 作为成功判断条件
@Get("/test3")
@Success(condition = MySuccessCondition2.class)
String sendData3();
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 全局请求成功/失败条件
在 spring boot 环境下,可以在 application.yml
等全局配置文件中设置全局的请求成功/失败条件
forest:
# MySuccessCondition 为您自定义的 SuccessWhen 实现类
# 通过 forest.success-when 属性配置全局请求成功/失败条件类
success-when: com.your.site.MySuccessCondition
2
3
4
在其它环境可以通过ForestConfiguration
对象的setSuccessWhenClass(Class<? extends SuccessWhen> successWhenClass)
进行设置
// 获取默认全局配置对象
ForestConfiguration configuration = Forest.config();
// MySuccessCondition 为您自定义的 SuccessWhen 实现类
// 调用 setSuccessWhenClass 设置全局请求成功/失败条件类
configuration.setSuccessWhenClass(com.your.site.MySuccessCondition.class);
2
3
4
5
# 手动设置请求成功/失败条件
文档导航
ForestRequest
对象如何手动设置请求成功/失败条件,请参见《请求设置对象成功/失败条件》