feiniaojin/graceful-response

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

Closed this issue · 5 comments

OPbjO commented

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

您好,我们在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

您好,我们在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

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

MethodArgumentNotValidException是BindException的子类