• @Valid与@Validated区别和详细使用及参数注解校验大全


    一、@Validated和@Valid的区别

    都必须在controller添加此注解不然校验注解不会生效

    分组

    @Validated:提供了一个分组功能,可以在入参验证时,根据不同的分组采用不同的验证机制,没有添加分组属性时,默认验证没有分组的验证属性
    @Valid:作为标准JSR-303规范,还没有吸收分组的功能

    位置

    @Validated:可以用在类型、方法和方法参数上。但是不能用在成员属性(字段)上,如果@Validated注解在成员属性上,则会报不适用于field错误
    @Valid:可以用在方法、构造函数、方法参数和成员属性(字段)上,两者是否能用于成员属性(字段)上直接影响能否提供嵌套验证的功能

    嵌套验证

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

    1.分组举例

    定义分组接口

    public interface IGroupA {
    }
    
    public interface IGroupB {
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    定义校验参数Bean

    public class StudentBean{
       //只在分组为IGroupB的情况下进行验证
       @Min(value = 18, message = "年龄不能小于18岁", groups = {IGroupB.class})
    }
    
    • 1
    • 2
    • 3
    • 4

    controller层

    @RestController
    public class CheckController {
        @PostMapping("stuA")
        public String addStuA(@Validated({IGroupA.class}) @RequestBody StudentBean studentBean){
            return "add studentA success";
        }
        
        @PostMapping("stuB")
        public String addStuB(@Validated({IGroupB.class}) @RequestBody StudentBean studentBean){
            return "add studentB success";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    同时调用两个方法,传入参数为age=15
    addStuA方法结果为:age:15 add studentA success
    addStuA方法结果为:age:年龄不能小于18
    
    • 1
    • 2
    • 3

    注意!

    当不分配groups,则每次都要进行验证
    对一个参数需要多种验证方式时,可通过分配不同的组

    2.组序列

    默认情况下 不同级别的约束验证是无序的,但是在一些情况下,顺序验证却是很重要
    一个组可以定义为其他组的序列,使用它进行验证的时候必须符合该序列规定的顺序
    在使用组序列验证的时候,如果序列前边的组验证失败,则后面的组将不再给予验证

    举例:定义组序列

    @GroupSequence({Default.class, IGroupA.class, IGroupB.class})
    public interface IGroup {
    }
    
    • 1
    • 2
    • 3

    需要校验的Bean,分别定义IGroupA对age进行校验,IGroupB对email进行校验:

    public class StudentBean implements Serializable {
    
       @NotBlank(message = "用户名不能为空")
       private String name;
    
       //只在分组为IGroupB的情况下进行验证
       @Min(value = 18, message = "年龄不能小于18岁", groups = {IGroupA.class})
       private Integer age;
    
       @Pattern(regexp = "^((13[0-9])|(14[5,7,9])|(15([0-3]|[5-9]))|(166)|(17[0,1,3,5,6,7,8])|(18[0-9])|(19[8|9]))\\d{8}$", message = "手机号格式错误")
       private String phoneNum;
    
       @Email(message = "邮箱格式错误", groups = {IGroupB.class})
       private String email;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    测试代码:

    @RestController
    public class CheckController {
       @PostMapping("stu")
       public String addStu(@RequestBody @Validated({IGroup.class}) StudentBean studentBean){
          return "add student success";
       }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    测试结果:只对IGroupA定义的错误进行了校验,IGroupB没有进行校验

    3.嵌套校验

    一个待验证的pojo类,其中还包含了待验证的对象,需要在待验证对象上注解@Valid,才能验证待验证对象中的成员属性,这里不能使用@Validated

    举例:约束校验的bean

    public class TeacherBean {
       @NotEmpty(message = "老师姓名不能为空")
       private String teacherName;
       @Min(value = 1, message = "学科类型从1开始计算")
       private int type;
    }
    
    public class StudentBean implements Serializable {
    
       @NotBlank(message = "用户名不能为空")
       private String name;
    
       //只在分组为IGroupB的情况下进行验证
       @Min(value = 18, message = "年龄不能小于18岁", groups = {IGroupA.class})
       private Integer age;
    
       @Pattern(regexp = "^((13[0-9])|(14[5,7,9])|(15([0-3]|[5-9]))|(166)|(17[0,1,3,5,6,7,8])|(18[0-9])|(19[8|9]))\\d{8}$", message = "手机号格式错误")
       private String phoneNum;
    
       @Email(message = "邮箱格式错误", groups = {IGroupB.class})
       private String email;
    
       @NotNull(message = "任课老师不能为空")
       @Size(min = 1, message = "至少有一个老师")
       private List<TeacherBean> teacherBeanList;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    注意:这里对teacherBeans只校验了NotNull, 和 Size,并没有对teacher信息里面的字段进行校验
    这里teacher中的type是不符合约束要求的,但是能检测通过,是因为在student中并没有做嵌套校验。
    可以在teacherBeans中加上 @Valid

    @Valid
    @NotNull(message = "任课老师不能为空")
    @Size(min = 1, message = "至少有一个老师")
    private List<TeacherBean> teacherBeanList;
    
    • 1
    • 2
    • 3
    • 4

    这种情况下就对TeacherBean中的参数进行了校验

    二、校验注解

    //必须为null
    @Null
    //不能为null
    @NotNull
    //只能作用在String上,不能为null,而且调用trim()后,长度必须大于0
    @NotBlank
    //用在集合类上,不能为null,并且长度必须大于0
    @NotEmpty
    
    //用于boolean字段,必须为true
    @AssertTrue
    //用于boolean字段,必须为false
    @AssertFalse
    
    //必须为数字,其最小值必须大于等于指定的值
    @Min(value)  eg: @Min(100) or @Min(value = 100, message = "最小值为100")
    //必须为数字,其最大值必须小于等于指定的值
    @Max(value)
    
    //支持Decimal, 只能大于或等于该值
    @DecimalMin(value)
    //支持Decimal, 只能小于或等于该值
    @DecimalMax(value)
    
    //数字必须在范围内
    @Range  eg:@Range(min =1 ,max = 100, message = "范围为1-100")
    //大小必须在范围内
    @Size eg:@Size(min=5, max=10, message="字符串或数组的长度必须在5-10之间")
    
    //校验小数,小数点前支持多少位,小数点后支持多少位
    @Digits(integer=6,fraction=2, message="小数点前支持6位,小数点后支持2位")
    
    //必须是一个过去的日期
    @Past
    //必须是一个将来的日期
    @Future
    
    //必须符合指定的正则表达式
    @Pattern(value)
    
    //必须是电子邮件地址
    @Email
    
    //字符创长度必须在规定范围内,只能用于字符串
    @Length(min=,max=)
    
    //字符串非空
    @NotEmpty
    
    //对信用卡号进行一个大致的验证
    @CreditCardNumber
    
    //检查是否是一个有效的URL,如果提供了protocol,host等,则该URL还需满足提供的条件
    @URL(protocol=,host,port)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
  • 相关阅读:
    【MRC复习 微博项目再次预热 Objective-C语言】
    axios
    java ssm教师工作量统计系统
    【云计算赛项】职业技能竞赛--容器开发部分例题K8s编排部署WebMall
    AI工程化—— 如何让AI在企业多快好省的落地?
    安装rabbitmq图文详情记录
    逍遥自在学C语言 位运算符 "|" 的5种高级用法
    如何快速区分GPT-3.5 与GPT-4?
    DOCTYPE是什么,有何作用、 使用方式、渲染模式、严格模式和怪异模式的区别?
    Python爬虫实战(进阶篇)—7获取每日菜价(附完整代码)
  • 原文地址:https://blog.csdn.net/weixin_45265547/article/details/126296607