日常项目中,偶尔会使用到静态内部类。平时对字段做非空校验时,一般会使用javax的注解,如:
java
@NotNull(message = "xxx")
如何对静态内部类中的字段做非空校验呢?我是这样写的:
java
package cn.uni.boot.module.business.controller.app.finance.verification.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
@Data
public class AppVerificationSubmitReqVo {
// ...
@Schema(description = "选择商品")
@NotNull(message = "商品不能为空")
private ProductInfo product;
@Data
@Valid
public static class ProductInfo{
@Schema(description = "xx商品id")
@NotNull(message = "xx商品id不能为空")
private Long bankProductId;
@Schema(description = "xx商品id")
private Long cProductId;
}
}
然后发现实际运行时,静态内部类中的字段并没有被成功校验,如'bankProductId'为null时依然可以通过。
查阅相关资料,发现:
@Valid 是用于「触发级联校验」的注解,它必须加在引用嵌套对象的字段上,而不是加在类定义上。
Bean Validation(如 Hibernate Validator)不会读取目标类上的 @Valid 注解来决定是否校验它 ------ 它只看父对象中引用该对象的字段是否标注了 @Valid。
可以把 @Valid 想象成一个"检查许可":
控制器说:"我要校验 AppVerificationSubmitReqVo。"
校验器检查它的字段:
codeId → 有 @NotNull → 检查。
product → 是一个对象 → 看看这个字段有没有 @Valid?
有 → 好,进去检查 ProductInfo 里面的约束。
没有 → 跳过,不管里面写了什么 @NotNull。
所以,@Valid 必须写在字段上,这是规范,不是可选项。
纠正:
java
@Valid // 改到这里
@Schema(description = "选择商品")
@NotNull(message = "商品不能为空")
private ProductInfo product;
@Data
public static class ProductInfo{
@Schema(description = "xxx商品id")
@NotNull(message = "xxx商品id不能为空")
private Long bankProductId;
@Schema(description = "xxx商品id")
private Long cProductId;
}