feiniaojin / graceful-response

Spring Boot接口响应处理解决方案,提供统一返回值封装、全局异常处理、自定义异常错误码、参数校验增强、断言增强等功能
https://doc.feiniaojin.com
MIT License
1.09k stars 164 forks source link

参数级联校验失败时ValidationExceptionAdvice反射获取注解异常 #24

Closed OPbjO closed 11 months ago

OPbjO commented 11 months ago

graceful版本:3.1.0

测试代码:

TestController

@RestController
@RequestMapping(value = "/test")
@Slf4j
public class TestController {

    @PostMapping("/validated")
    public void validated(@RequestBody @Validated JobInfoRequest jobInfoRequest) {
        log.info("jobInfoRequest={}", JSON.toJSONString(jobInfoRequest));
    }
}

校验参数对象,其中JobDetail对象进行级联校验

@Data
public class JobInfoRequest {

    @NotBlank(message = "岗位名称不能为空")
    @ValidationStatusCode(code = "501")
    private String jobName;

    @Valid
    @NotNull(message = "详细信息不能为空")
    @ValidationStatusCode(code = "501")
    private JobDetail jobDetail;

}

@Data
public class JobDetail {

    @NotNull(message = "薪水不能为空")
    @Min(value = 3000, message = "不能低于300元")
    @ValidationStatusCode(code = "501")
    private BigDecimal pay;

    @NotNull(message = "招聘人数不能为空")
    @Min(value = 1, message = "至少招聘1人")
    @ValidationStatusCode(code = "501")
    private Integer headCount;

    private Date updateTime;
}

post请求参数

{
  "jobName": "程序员",
  "jobDetail": {
    "pay": 2000.50,
    "headCount": 20,
    "updateTime": "2023-09-30 20:34:08"
  }
}

pay最小值为3000,校验失败,抛出MethodArgumentNotValidException,进入com.feiniaojin.gracefulresponse.advice.ValidationExceptionAdvice全局异常处理器。

在com.feiniaojin.gracefulresponse.advice.ValidationExceptionAdvice#fromBindException第118行,使用反射获取校验失败字段时,外部对象持有的内部对象字段报错,所以fieldName=jobDetail.pay,但是target.getClass()获得的是外部对象JobInfoRequest.class,因此无法获取到jobDetail.pay字段,抛出异常NoSuchFieldException。

image

image

feiniaojin commented 11 months ago

系统提示:您的邮件被腾讯邮箱判定为垃圾邮件,请编辑后重新发送!

feiniaojin commented 11 months ago

您好,我们在ExampleController下的validatePropertyType方法中测试,并没有发现您提供的这个问题,欢迎提供进一步信息帮助排查。

https://github.com/feiniaojin/graceful-response-example/blob/3.2.0-boot2/src/main/java/com/feiniaojin/gracefuresponse/example/controller/ExampleController.java

image image
OPbjO commented 11 months ago

您好,我们在ExampleController下的validatePropertyType方法中测试,并没有发现您提供的这个问题,欢迎提供进一步信息帮助排查。

https://github.com/feiniaojin/graceful-response-example/blob/3.2.0-boot2/src/main/java/com/feiniaojin/gracefuresponse/example/controller/ExampleController.java

image image

我测试用的版本是graceful-response 3.1.0,你给的示例代码工程里面用的包是3.2.0-boot2,其中我报错的代码类ValidationExceptionAdvice和3.1.0的版本比较有变化,可能就是因为这个,所以高版本的不会报错。另外目前中央仓库3.2.0-boot2还没有。 image

OPbjO commented 11 months ago

@feiniaojin 3.1.0代码: image 3.2.0-boot2代码: image 处理异常的顺序变了

feiniaojin commented 11 months ago

MethodArgumentNotValidException是BindException的子类