SpringBoot日常:校验使用之@Validated和@Valid

前言

Spring Validation验证框架对参数的验证机制提供了@Validated(Spring’s JSR-303规范,是标准JSR-303的一个变种),javax提供了@Valid(标准JSR-303规范),配合BindingResult可以直接提供参数验证结果。其中对于字段的特定验证注解比如@NotNull等。
在检验Controller的入参是否符合规范时,使用@Validated或者@Valid在基本验证功能上没有太多区别。但是在分组、注解地方、嵌套验证等功能上两个有所不同。

注解使用

@Validated

可以用在类型、方法和方法参数上,但是不能用在成员属性(字段)上

@Valid:

可以用在方法、构造函数、方法参数和成员属性(字段)上(支持嵌套验证)

两者是否能用于成员属性(字段)上直接影响能否提供嵌套验证的功能。

参数嵌套验证

我们创建一个企业发票入参类CompanyInvoiceParam 和发票具体详情类Invoice,另外,为了方便验证返回的错误信息,添加一个全局异常类GlobalExceptionHandler ,创建controller测试接口testValid

@RestControllerAdvice
public class GlobalExceptionHandler  {

    @ResponseStatus(HttpStatus.BAD_REQUEST) //设置状态码为 400
    @ExceptionHandler({MethodArgumentNotValidException.class})
    public String paramExceptionHandler(MethodArgumentNotValidException e) {
        BindingResult exceptions = e.getBindingResult();
        // 判断异常中是否有错误信息,如果存在就使用异常中的消息,否则使用默认消息
        if (exceptions.hasErrors()) {
            List<ObjectError> errors = exceptions.getAllErrors();
            if (!errors.isEmpty()) {
                // 这里列出了全部错误参数,按正常逻辑,只需要第一条错误即可
                FieldError fieldError = (FieldError) errors.get(0);
                return fieldError.getDefaultMessage();
            }
        }
        return "请求参数错误";
    }
}

1、 入参仅添加@Validated

@Data
public class CompanyInvoiceParam implements Serializable {

    @NotBlank(message = "企业名称不得为空不能为空")
    private String companyName;

    @NotNull(message = "发票数据不得为空")
    private List<Invoice> invoiceList;
}

@Data
public class Invoice implements Serializable {

    @NotNull(message = "发票金额不得为空")
    private BigDecimal amount;
}
@PostMapping(value = "/testValid", produces = MediaType.APPLICATION_JSON_VALUE)
public void testValid(@Validated @RequestBody CompanyInvoiceParam companyInvoiceParam) {
    System.out.println("入参校验");
}

测试结果
发票数据为空,能够正常校验
在这里插入图片描述
嵌套的发票数据里的字段为空,无法校验
在这里插入图片描述

2、 入参仅添加@Valid

@Data
public class CompanyInvoiceParam implements Serializable {

    @NotBlank(message = "企业名称不得为空不能为空")
    private String companyName;

    @NotNull(message = "发票数据不得为空")
    private List<Invoice> invoiceList;
}

@Data
public class Invoice implements Serializable {

    @NotNull(message = "发票金额不得为空")
    private BigDecimal amount;
}
@PostMapping(value = "/testValid", produces = MediaType.APPLICATION_JSON_VALUE)
public void testValid(@Valid @RequestBody CompanyInvoiceParam companyInvoiceParam) {
    System.out.println("入参校验");
}

测试结果
发票数据为空,能够正常校验(同1一样)
在这里插入图片描述
嵌套的发票数据里的字段为空,无法校验(同1一样)
在这里插入图片描述

3、 入参仅添加@Validated,内嵌字段上用@Valid

@Data
public class CompanyInvoiceParam implements Serializable {

    @NotBlank(message = "企业名称不得为空不能为空")
    private String companyName;

	@Valid
    @NotNull(message = "发票数据不得为空")
    private List<Invoice> invoiceList;
}

@Data
public class Invoice implements Serializable {

    @NotNull(message = "发票金额不得为空")
    private BigDecimal amount;
}
@PostMapping(value = "/testValid", produces = MediaType.APPLICATION_JSON_VALUE)
public void testValid(@Validated @RequestBody CompanyInvoiceParam companyInvoiceParam) {
    System.out.println("入参校验");
}

测试结果
发票数据为空,能够正常校验
在这里插入图片描述
嵌套的发票数据里的字段为空,能够正常校验
在这里插入图片描述

总结

● @Validated:用在方法入参上无法单独提供嵌套验证功能。不能用在成员属性(字段)上,也无法提示框架进行嵌套验证。能配合嵌套验证注解@Valid进行嵌套验证。

● @Valid:用在方法入参上无法单独提供嵌套验证功能。能够用在成员属性(字段)上,提示验证框架进行嵌套验证。能配合嵌套验证注解@Valid进行嵌套验证。

若有嵌套的类参数验证,需要在字段上加上@Valid,controller接口入参用@Valid或@Validated都可以

  • 18
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值