• @Validated和@Valid 区别


    Spring Validation验证框架对参数的验证机制提供了@Validated(Spring’s JSR-303规范,是标准JSR-303的一个变种),javax提供了@Valid(标准JSR-303规范),

    配合BindingResult可以直接提供参数验证结果。

    注意:@Validated和@Valid只是用来验证的两个注解,而对于以下的检验类型是JSR检验类型,Spring Validation验证框架已经整合了。

    分类方式一:

    JSR303定义的校验类型(参考文档:@Validated和@Valid区别_@validated @valid-CSDN博客 )


    空检查
    @Null 验证对象是否为null
    @NotNull 验证对象是否不为null, 无法查检长度为0的字符串
    @NotBlank 检查约束字符串是不是Null还有被Trim的长度是否大于0,只对字符串,且会去掉前后空格.
    @NotEmpty 检查约束元素是否为NULL或者是EMPTY.

    Booelan检查
    @AssertTrue 验证 Boolean 对象是否为 true
    @AssertFalse 验证 Boolean 对象是否为 false

    长度检查
    @Si***=, max=) 验证对象(Array,Collection,Map,String)长度是否在给定的范围之内
    @Length(min=, max=) 验证注解的元素值长度在min和max区间内

    日期检查
    @Past 验证 Date 和 Calendar 对象是否在当前时间之前
    @Future 验证 Date 和 Calendar 对象是否在当前时间之后
    @Pattern 验证 String 对象是否符合正则表达式的规则

    数值检查,建议使用在Stirng,Integer类型,不建议使用在int类型上,因为表单值为“”时无法转换为int,但可以转换为Stirng为"",Integer为null
    @Min 验证 Number 和 String 对象是否大等于指定的值
    @Max 验证 Number 和 String 对象是否小等于指定的值
    @DecimalMax 被标注的值必须不大于约束中指定的最大值. 这个约束的参数是一个通过BigDecimal定义的最大值的字符串表示.小数存在精度
    @DecimalMin 被标注的值必须不小于约束中指定的最小值. 这个约束的参数是一个通过BigDecimal定义的最小值的字符串表示.小数存在精度
    @Digits 验证 Number 和 String 的构成是否合法
    @Digits(integer=,fraction=) 验证字符串是否是符合指定格式的数字,interger指定整数精度,fraction指定小数精度。
    @Range(min=, max=) 验证注解的元素值在最小值和最大值之间
    @Range(min=10000,max=50000,message="range.bean.wage")
    private BigDecimal wage;

    @Valid 递归的对关联对象进行校验, 如果关联对象是个集合或者数组,那么对其中的元素进行递归校验,如果是一个map,则对其中的值部分进行校验.(是否进行递归验证)
    @CreditCardNumber信用卡验证
    @Email  验证是否是邮件地址,如果为null,不进行验证,算通过验证。
    @ScriptAssert(lang= ,script=, alias=)
    @URL(protocol=,host=, port=,regexp=, flags=)

    分类方式二:

    参考文档:https://www.cnblogs.com/codeingthink/p/9237825.html

    java validation 注解【 javax.validation.constraints 包下的】

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    JSR提供的校验注解:        

    @Null   被注释的元素必须为 null @NotNull    被注释的元素必须不为 null @AssertTrue     被注释的元素必须为 true @AssertFalse    被注释的元素必须为 false @Min(value)     被注释的元素必须是一个数字,其值必须大于等于指定的最小值   

    @Max(value)     被注释的元素必须是一个数字,其值必须小于等于指定的最大值   

    @DecimalMin(value)  被注释的元素必须是一个数字,其值必须大于等于指定的最小值   

    @DecimalMax(value)  被注释的元素必须是一个数字,其值必须小于等于指定的最大值   

    @Size(max=, min=)   被注释的元素的大小必须在指定的范围内   

    @Digits (integer, fraction)     被注释的元素必须是一个数字,其值必须在可接受的范围内   

    @Past   被注释的元素必须是一个过去的日期   

    @Future     被注释的元素必须是一个将来的日期   

    @Pattern(regex=,flag=)  被注释的元素必须符合指定的正则表达式

    hiberate validation 注解【org.hibernate.validator.constraints  包下的】

    1

    2

    3

    4

    5

    6

    7

    @Email  被注释的元素必须是电子邮箱地址   

    @Length(min=,max=)  被注释的字符串的大小必须在指定的范围内   

    @NotEmpty   被注释的字符串的必须非空   

    @Range(min=,max=,message=)  被注释的元素必须在合适的范围内

    @URL(protocol=,

    host=,    port=, 

    regexp=, flags=)  合法的url

    主要区分下@NotNull  @NotEmpty  @NotBlank 3个注解的区别:

    @NotNull           任何对象的value不能为null

    @NotEmpty       集合对象的元素不为0,即集合不为空,也可以用于字符串不为null

    @NotBlank        只能用于字符串不为null,并且字符串trim()以后length要大于0

    在检验入参是否符合规范时,使用@Validated或者@Valid在基本验证功能上没有太多区别。但是在分组、注解地方、嵌套验证等功能上两个有所不同:
    作者:程序猿拯救世界
    1.分组
    @Validated:提供了一个分组功能,可以在入参验证时,根据不同的分组采用不同的验证机制。没有添加分组属性时,默认验证没有分组的验证属性。
    伪代码如下:
     

    public interface First{
    }
    public interface Second{
    }
    public class UserModel {
    @NotNull(message = "{id.empty}", groups = { First.class })
    private int id;

    @NotNull(message = "{username.empty}", groups = { First.class, Second.class })
    private String username;

    @NotNull(message = "{content.empty}", groups = { First.class, Second.class })
    private String content;

    public String save(@Validated( { Second.class }) UserModel userModel, BindingResult result) {
    if (result.hasErrors()) {
    return "validate/error";
    }
    return "redirect:/success";
    }

    对一个参数需要多种验证方式时,也可通过分配不同的组达到目的。例:
     

    @NotEmpty(groups = { First.class })
    @Si*** = 3, max = 8, groups = { Second.class })
    private String name;


    分组还支持组序列
    默认情况下,不同组别的约束验证是无序的,然而在某些情况下,约束验证的顺序却很重要,如下面两个例子:(1)第二个组中的约束验证依赖于一个稳定状态来运行,而这个稳定状态是由第一个组来进行验证的。(2)某个组的验证比较耗时,CPU 和内存的使用率相对比较大,最优的选择是将其放在最后进行验证。因此,在进行组验证的时候尚需提供一种有序的验证方式,这就提出了组序列的概念。

    一个组可以定义为其他组的序列,使用它进行验证的时候必须符合该序列规定的顺序。在使用组序列验证的时候,如果序列前边的组验证失败,则后面的组将不再给予验证。


    public interface GroupA {
    }

    public interface GroupB {
    }

    @GroupSequence( { GroupA.class, GroupB.class })
    public interface Group {
    }
    public @ResponseBody String addPeople(@Validated({Group.class}) People p,BindingResult result)   {
    if(result.hasErrors())  {
    return "0";
    }
    return "1";
    }

    @Valid:作为标准JSR-303规范,还没有吸收分组的功能。

    2.注解地方
    @Validated:可以用在类型、方法和方法参数上。但是不能用在成员属性(字段)上

    @Valid:可以用在方法、构造函数、方法参数和成员属性(字段)上

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

    3.嵌套验证
    在比较两者嵌套验证时,先说明下什么叫做嵌套验证。
    比如我们现在有个实体叫做Item:
     

    public class Item {
    @NotNull(message = "id不能为空")
    @Min(value = 1, message = "id必须为正整数")
    private Long id;
    @NotNull(message = "props不能为空")
    @Si*** = 1, message = "至少要有一个属性")
    private List props;
    }

    Item带有很多属性,属性里面有:pid、vid、pidName和vidName,如下所示:

    public class Prop {
    @NotNull(message = "pid不能为空")
    @Min(value = 1, message = "pid必须为正整数")
    private Long pid;
    @NotNull(message = "vid不能为空")
    @Min(value = 1, message = "vid必须为正整数")
    private Long vid;
    @NotBlank(message = "pidName不能为空")
    private String pidName;
    @NotBlank(message = "vidName不能为空")
    private String vidName;
    }
    属性这个实体也有自己的验证机制,比如pid和vid不能为空,pidName和vidName不能为空等。

    现在我们有个ItemController接受一个Item的入参,想要对Item进行验证,如下所示:
     

    @RestController
    public class ItemController {
    @RequestMapping("/item/add")
    public void addItem(@Validated Item item, BindingResult bindingResult) {
    doSomething();
    }
    }

    在上图中,如果Item实体的props属性不额外加注释,只有@NotNull和@Size,无论入参采用@Validated还是@Valid验证,Spring Validation框架只会对Item的id和props做非空和数量验证,不会对props字段里的Prop实体进行字段验证,也就是@Validated和@Valid加在方法参数前,都不会自动对参数进行嵌套验证。也就是说如果传的List中有Prop的pid为空或者是负数,入参验证不会检测出来。

    为了能够进行嵌套验证,必须手动在Item实体的props字段上明确指出这个字段里面的实体也要进行验证。由于@Validated不能用在成员属性(字段)上,但是@Valid能加在成员属性(字段)上,而且@Valid类注解上也说明了它支持嵌套验证功能,那么我们能够推断出:@Valid加在方法参数时并不能够自动进行嵌套验证,而是用在需要嵌套验证类的相应字段上,来配合方法参数上@Validated或@Valid来进行嵌套验证。

    我们修改Item类如下所示:
     

    public class Item {
    @NotNull(message = "id不能为空")
    @Min(value = 1, message = "id必须为正整数")
    private Long id;
    @Valid // 嵌套验证必须用@Valid
    @NotNull(message = "props不能为空")
    @Si*** = 1, message = "props至少要有一个自定义属性")
    private List props;
    }然后我们在ItemController的addItem函数上再使用@Validated或者@Valid,就能对Item的入参进行嵌套验证。此时Item里面的props如果含有Prop的相应字段为空的情况,Spring Validation框架就会检测出来,bindingResult就会记录相应的错误。


    总结一下@Validated和@Valid在嵌套验证功能上的区别:

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

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

  • 相关阅读:
    .Net开发——EFCore
    Java程序设计——反射(Java高级应用)
    Java生成World,Java操作world,Java导出world文档
    B站付费视频使up主掉粉过万
    Vue 3响应式系统全解析:深入ref、reactive、computed、watch及watchEffect
    GEE开发之Modis_LAI数据分析和获取
    ABAP MD5加密 MD5_CALCULATE_HASH_FOR_CHAR
    缓存之缓存简介
    适合开发者使用的6款浏览器,开发者工具很实用
    JavaEE 初阶篇-生产者与消费者模型(线程通信)
  • 原文地址:https://blog.csdn.net/liuchang19950703/article/details/134394517