Skip to main content
Version: 1.5.x

成功/失败条件

Forest 对每个请求都会判断其发送和响应结果是否成功。

成功,就会去执行OnSuccess回调函数和拦截器中的onSuccess方法,并返回响应结果。

失败,则会进行重试,如果该请求不允许重试,或者达到了最大重试次数限制,则会调用OnError回调函数,和拦截器中的onError方法。

默认成功/失败条件#

Forest 提供了默认的请求成功/失败条件,其逻辑如下:

  1. 判断是否在发送和等待响应的过程中出现异常,如: 网络连接错误、超时等
  2. 在取得响应结果后,判断其响应状态码是否在正常范围内 (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() 获取业务数据        // 再更具业务数据判断是否成功    }}
特别注意

successWhen方法的逻辑代码中,千万不能调用 res.isSuccess()!res.isError() 进行判断

不然会引起死循环

第二步,挂上 @Success 注解#

public interface MyClient {    /**     * 挂上了 @Success 注解     * <p>该方法的请求是否成功     * <p>以自定义成功条件类 MySuccessCondition 的判断方法为准     *      * @return 请求响应结果     */    @Get("/")    @Success(condition = MySuccessCondition.class)    String sendData();}

若调用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();
}

此时,不管是调用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();}

全局请求成功/失败条件#

在 spring boot 环境下,可以在 application.yml 等全局配置文件中设置全局的请求成功/失败条件

forest:    # MySuccessCondition 为您自定义的 SuccessWhen 实现类    # 通过 forest.success-when 属性配置全局请求成功/失败条件类    success-when: com.your.site.MySuccessCondition

在其它环境可以通过ForestConfiguration对象的setSuccessWhenClass(Class<? extends SuccessWhen> successWhenClass)进行设置

// 获取默认全局配置对象ForestConfiguration configuration = Forest.config();// MySuccessCondition 为您自定义的 SuccessWhen 实现类// 调用 setSuccessWhenClass 设置全局请求成功/失败条件类configuration.setSuccessWhenClass(com.your.site.MySuccessCondition.class);

手动设置请求成功/失败条件#

文档导航

ForestRequest 对象如何手动设置请求成功/失败条件,请参见《请求设置对象成功/失败条件