Graceful Response

功能

  • 统一返回值封装
  • void返回类型封装
  • 全局异常处理
  • 参数校验错误码
  • 自定义响应体,适应不同项目的需求
  • 断言增强并且填充错误码和异常信息到Response
  • 异常别名,适配外部异常
  • 例外请求放行
  • 第三方组件适配(Swagger、actuator、FastJson序列化等)

配置

<dependency>
    <groupId>com.feiniaojin</groupId>
    <artifactId>graceful-response</artifactId>
    <version>4.0.1-boot3</version>
</dependency>

启动类添加注解

@EnableGracefulResponse

统一返回值封装

graceful-response:
  # 响应风格设置
  response-style: 1
@RestController
@RequestMapping("/demo")
public class demo {

    @RequestMapping("/test0")
    public void test0(){
        //return "hello world!";
    }

    @GetMapping("/test1")
    public int test1(){
        return 999;
    }
}

返回值

这里返回值为String类型的话,并不会被封装,不知道是什么原因,其他类型都可以

后续再Q&A作者提到了,因为每个队伍对String的处理方式都不一样,推荐Map<key,value>的形式进行返回

image-20240522103937380

全局异常、自定义异常处理

全局异常

@GetMapping("/test2")
    public int test2(){
        throw new RuntimeException();
    }

image-20240522104337007

可定义错误code和msg

graceful-response:
  # 响应风格设置
  response-style: 1
  default-error-code: 5000
  default-error-msg: 系统异常

自定义异常

定义异常

@ExceptionMapper(code = "5001", msg = "密码错误")
public final class PasswordErrorException extends  RuntimeException{
}

// controller
@GetMapping("/test3")
    public void test3(){
        throw new PasswordErrorException();
    }

image-20240522104926425

异常通用工具类

2.1版本开始,新增了GracefulResponseException异常类,用户只需要抛出该异常即可

为简化使用,从2.1版本开始提供了GracefulResponse通用工具类,在需要抛出GracefulResponseException时,只需要调用raiseException方法即可。

@GetMapping("/test7")
public void test7(){
    GracefulResponse.raiseException("6001", "自定义异常信息-用户不存在");
}

image-20240522140146164

替换异常信息

创建自定义异常,采用 @ExceptionMapper注解修饰,注解的 code属性为返回码,msg属性为错误提示信息,msgReplaceable设置为true

并且,重新其构造方法,提供包含message的入参

@ExceptionMapper(code = "5002", msg = "用户不存在", msgReplaceable = true)
public final class UserEmptyException extends RuntimeException{
    public UserEmptyException(){

    }

    public UserEmptyException(String message){
        super(message);
    }
    public UserEmptyException(String message, Throwable cause) {
        super(message, cause);
    }

    public UserEmptyException(Throwable cause) {
        super(cause);
    }

    public UserEmptyException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
}

controller

@GetMapping("/test4")
public void test4(){
    throw new UserEmptyException("自定义异常信息-用户不存在");
}

image-20240522105718019

参数校验错误码

实体类校验参数

@Data
@AllArgsConstructor
@NoArgsConstructor
@Valid
public class UserInfoDTO {

    @NotNull(message = "userName is null !")
    @Length(min = 6, max = 12, message = "userName length is not between 6 and 12 !")
    @ValidationStatusCode(code = "6001")
    private String name;
}

name字段任意一项校验不通过时,接口将会返回异常码6001和校验注解中的message

@PostMapping("/test5")
public void test5(@Valid @RequestBody UserInfoDTO userInfoDTO){

}

image-20240522111728350

image-20240522111745630

Controller层校验参数

暂时未调通

注意:@ValidationStatusCode校验参数对象字段的情况,code取值顺序为:会先取字段上的注解,再去该属性所在对象的类上的注解,再取全局配置的参数异常码gr.default-Validate-ErrorCode,最后取默认的全局默认的错误码(默认code=1)

@GetMapping("/test6")
@ValidationStatusCode(code = "5006")
public void test6(@NotNull(message = "name不能为空") String name){

}

image-20240522135050130

错误码设置未生效

放行Controller封装

单个方法放行

@GetMapping("/test8")
@ExcludeFromGracefulResponse
public int test8(){
    return 10;
}

包级别放行

graceful-response:
  exclude-packages:
    - com.lizhiadmin.pro.module.*

该配置表明com.lizhiadmin.pro.module包下的所有controller均不会被Graceful Response进行自动处理

路径级别放行

用户可以通过配置graceful-response.exclude-urls,声明某些路径需要跳过不进行处理。

对于 /a/b/c,假如要把路径中有/b/的请求进行放行,则可以配置为/**/b/**

返回值类型放行

用户可以通过配置graceful-response.exclude-return-types,声明某些返回值类型需要跳过不进行处理

graceful-response:
  exclude-return-types: com.feiniaojin.gracefuresponse.example.dto.UserInfoView

异常别名

参考

作者github仓库
我的学习示例代码