结论:

Spring validation验证框架对入参实体进行嵌套验证必须在相应属性(字段)加上@Valid而不是@Validated

Spring Validation验证框架对参数的验证机制提供了@Validated(Spring's JSR-303规范,是标准JSR-303的一个变种),javax提供了@Valid(标准JSR-303规范),配合BindingResult可以直接提供参数验证结果。其中对于字段的特定验证注解比如@NotNull等网上到处都有,这里不详述

在检验Controller的入参是否符合规范时,使用@Validated或者@Valid在基本验证功能上没有太多区别。但是在分组、注解地方、嵌套验证等功能上两个有所不同:

1. 分组

@Validated:提供了一个分组功能,可以在入参验证时,根据不同的分组采用不同的验证机制,这个网上也有资料,不详述。@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不能为空")
@Size(min = 1, message = "至少要有一个属性")
private List<Prop> props;
}

Item带有很多属性,属性里面有属性id,属性值id,属性名和属性值,如下所示:

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;
}

属性这个实体也有自己的验证机制,比如属性和属性值id不能为空,属性名和属性值不能为空等。

现在我们有个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>中有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不能为空")
@Size(min = 1, message = "props至少要有一个自定义属性")
private List<Prop> props;
}

然后我们在ItemController的addItem函数上再使用@Validated或者@Valid,就能对Item的入参进行嵌套验证。此时Item里面的props如果含有Prop的相应字段为空的情况,Spring Validation框架就会检测出来,bindingResult就会记录相应的错误。

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

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

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

————————————————
版权声明:本文为CSDN博主「花郎徒结」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_27680317/article/details/79970590

Spring校验:@Validated和@Valid区别的更多相关文章

  1. @Validated和@Valid区别:Spring validation验证框架对入参实体进行嵌套验证必须在相应属性(字段)加上@Valid而不是@Validated

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

  2. @Validated和@Valid区别

    注解地方 @Validated:可以用在类型.方法和方法参数上.但是不能用在成员属性(字段)上 @Valid:可以用在方法.构造函数.方法参数和成员属性(字段)上 两者是否能用于成员属性(字段)上直接 ...

  3. @Validated和@Valid的区别?校验级联属性(内部类)

    每篇一句 NBA里有两大笑话:一是科比没天赋,二是詹姆斯没技术 相关阅读 [小家Java]深入了解数据校验:Java Bean Validation 2.0(JSR303.JSR349.JSR380) ...

  4. @Validated和@Valid校验参数、级联属性、List

    @Validated和@Valid的区别 在Controller中校验方法参数时,使用@Valid和@Validated并无特殊差异(若不需要分组校验的话): @Valid:标准JSR-303规范的标 ...

  5. 参数验证 @Validated 和 @Valid 的区别

    来源:blog.csdn.net/qq_27680317/article/details/79970590 整编:Java技术栈(公众号ID:javastack) Spring Validation验 ...

  6. 用spring的@Validated注解和org.hibernate.validator.constraints.*的一些注解在后台完成数据校验

    这个demo主要是让spring的@Validated注解和hibernate支持JSR数据校验的一些注解结合起来,完成数据校验.这个demo用的是springboot. 首先domain对象Foo的 ...

  7. Spring BeanFactory与FactoryBean的区别及其各自的详细介绍于用法

    Spring BeanFactory与FactoryBean的区别及其各自的详细介绍于用法 1. BeanFactory BeanFactory,以Factory结尾,表示它是一个工厂类(接口),用于 ...

  8. spring校验相关

    转载:http://elim.iteye.com/blog/1812584 对于任何一个应用而言在客户端做的数据有效性验证都不是安全有效的,这时候就要求我们在开发的时候在服务端也对数据的有效性进行验证 ...

  9. spring拦截器-过滤器的区别

    1.  理解 拦截器 :是在面向切面编程的时候,在你的 service 或者一个方法前调用一个方法,或者在方法后调用一个方法:比如动态代理就是拦截器的简单实现,在你调用方法前打印出字符串(或者做其它业 ...

  10. JSR-303 结合spring 校验

    使用注解 一.准备校验时使用的JAR validation-api-1.0.0.GA.jar:JDK的接口: hibernate-validator-4.2.0.Final.jar是对上述接口的实现: ...

随机推荐

  1. body传参和query传参

    get请求只能传query参数,query参数都是拼接在请求地址上的.post可以传body和query两种形式的参数. get请求在url中传送的参数是有长度限制的,而post没有限制.get比po ...

  2. ubuntu无法进入图形界面可以进入终端

    ubuntu开机后无法进入图形界面解决办法:    进入命令行模式,执行下面的命令: rm /etc/X11/xorg.conf cp /etc/X11/xorg.conf.failsafe /etc ...

  3. android 获取手机的唯一id,获取当前时间,获取两位随机数

    //获取机器的唯一id public static String getDeviceID() { String deviceID= ""; try{ //一共13位 如果位数不够可 ...

  4. ANT+JMETER+Jenkins 接口自动化

    Linux环境下搭建:ANT+JMETER+Jenkins 接口自动化 一.准备环境: 1.下载 JDK1.8 JDK下载地址:https://www.oracle.com/java/technolo ...

  5. docker命令自动补全

    1.安装bash-completion yum install -y bash-completion 2.重新连接docker 服务器使docker补全命令生效,或者建立新的远程连接docker服务器 ...

  6. B站小白STM32项目 第9课卡在OneNet_DevLink() 解决办法

    笔者在看这一集的时候,自己在emq官方上购买了服务器,于是就换成了自己的服务器和相应的mqtts端口, 买了两个服务器,但最后都卡在OneNet_DevLink() :要么连接不成功,要么显示连接申请 ...

  7. 在MyBatis-Plus整合dynamic-datasource @DS失效

    因为是事务导致的 解决方案: 1.删除事务 2.使用分布式事务 3.修改事务的传播机制 3.使用DS的本地事务 @DSTransactional 但切记不可和Spring的事务共存 附传播机制 事务传 ...

  8. Software--EB--Project 身份验证

    2018-01-09  16:57:51 身份验证服务 应该有两种形式得身份验证机制: 1. 在其他网站上又 Web 账号得顾客在注册或登陆到该网站时候应该能够使用这些账号. 2.没有的顾客或者希望新 ...

  9. vscode - plug - scss转css

    vscode - plug - scss转css 参考资料 sass笔记(完结)安装,使用,vscode中设置easy sass,嵌套,变量,混合,循环,分支 vscode配置 easy sass E ...

  10. python 发送 application/x-www-form-urlencoded 类型的数据包

    在网上百度了很多,坑的要死,基本不咋好用,自己多尝试了几遍,成功实现了. data 的构建方式 data = f"page={page}&sign={sign}&t={t}& ...