当前位置:网站首页>别再乱用了,这才是 @Validated 和 @Valid 的真正区别!!!
别再乱用了,这才是 @Validated 和 @Valid 的真正区别!!!
2022-06-24 19:39:00 【民工哥】
点击下方“Java编程鸭”关注并标星
更多精彩 第一时间直达
概述
@Valid是使用Hibernate validation的时候使用@Validated是只用Spring Validator校验机制使用
说明:java的JSR303声明了
@Valid这类接口,而Hibernate-validator对其进行了实现
@Validation对@Valid进行了二次封装,在使用上并没有区别,但在分组、注解位置、嵌套验证等功能上有所不同,这里主要就这几种情况进行说明。
注解位置
@Validated:用在类型、方法和方法参数上。但不能用于成员属性(field)@Valid:可以用在方法、构造函数、方法参数和成员属性(field)上
如:


如果@Validated注解在成员属性上,则会报不适用于field错误
分组校验
@Validated:提供分组功能,可以在参数验证时,根据不同的分组采用不同的验证机制@Valid:没有分组功能
举例:
定义分组接口:
public interface IGroupA {
}
public interface IGroupB {
}定义需要检验的参数bean:
public class StudentBean implements Serializable{
@NotBlank(message = "用户名不能为空")
private String name;
//只在分组为IGroupB的情况下进行验证
@Min(value = 18, message = "年龄不能小于18岁", groups = {IGroupB.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 = "邮箱格式错误")
private String email;
@MyConstraint
private String className;测试代码:
检验分组为IGroupA的情况
@RestController
public class CheckController {
@PostMapping("stu")
public String addStu(@Validated({IGroupA.class}) @RequestBody StudentBean studentBean){
return "add student success";
}
}测试:

这里对分组IGroupB的就没检验了
如果把测试代码改成下面这样,看看测试结果
@RestController
public class CheckController {
@PostMapping("stu")
public String addStu(@Validated({IGroupA.class, IGroupB.class}) @RequestBody StudentBean studentBean){
return "add student success";
}
}说明:
1、不分 配groups,默认每次都要进行验证
2、对一个参数需要多种验证方式时,也可通过分配不同的组达到目的。
组序列
默认情况下 不同级别的约束验证是无序的,但是在一些情况下,顺序验证却是很重要。
一个组可以定义为其他组的序列,使用它进行验证的时候必须符合该序列规定的顺序。在使用组序列验证的时候,如果序列前边的组验证失败,则后面的组将不再给予验证。
举例:
定义组序列:
@GroupSequence({Default.class, IGroupA.class, IGroupB.class})
public interface IGroup {
}需要校验的Bean,分别定义IGroupA对age进行校验,IGroupB对className进行校验:
public class StudentBean implements Serializable{
@NotBlank(message = "用户名不能为空")
private String name;
@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 = "邮箱格式错误")
private String email;
@MyConstraint(groups = IGroupB.class)
private String className;测试代码:
@RestController
public class CheckController {
@PostMapping("stu")
public String addStu(@Validated({IGroup.class}) @RequestBody StudentBean studentBean){
return "add student success";
}
}测试发现,如果age出错,那么对组序列在IGroupA后的IGroupB不进行校验,即例子中的className不进行校验,结果如下:

嵌套校验
一个待验证的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;
@Min(value = 18, message = "年龄不能小于18岁")
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 = "邮箱格式错误")
private String email;
@MyConstraint
private String className;
@NotNull(message = "任课老师不能为空")
@Size(min = 1, message = "至少有一个老师")
private List<TeacherBean> teacherBeans;注意:
这里对teacherBeans只校验了NotNull, 和 Size,并没有对teacher信息里面的字段进行校验,具体测试如下:

这里teacher中的type明显是不符合约束要求的,但是能检测通过,是因为在student中并没有做 嵌套校验
可以在teacherBeans中加上 @Valid,具体如下:
@Valid
@NotNull(message = "任课老师不能为空")
@Size(min = 1, message = "至少有一个老师")
private List<TeacherBean> teacherBeans;这里再来测试,会发现如下结果:

来源:blog.csdn.net/herojuice/article/
details/86020101
END
看完本文有收获?请转发分享给更多人
关注「Java编程鸭」,提升Java技能
关注Java编程鸭微信公众号,后台回复:码农大礼包 可以获取最新整理的技术资料一份。涵盖Java 框架学习、架构师学习等!
文章有帮助的话,在看,转发吧。
谢谢支持哟 (*^__^*)边栏推荐
- Short video mall system, how does scroll view adapt to the remaining height of the page
- Servlet details
- Data center basic network platform
- 磁盘的结构
- Technology Review: what is the evolution route of container technology? What imagination space is there in the future?
- 【軟件工程】期末重點
- Docker installs MySQL 8.0. Detailed steps
- Learning bit segment (1)
- 上新了,华为云开天aPaaS
- Information update on automatic control principle
猜你喜欢

Genesis public chain and a group of encryption investors in the United States gathered in consensus 2022

Learn more about the practical application of sentinel

Docker 安装 Redis-5.0.12,详细步骤

Ideal L9, new trend of intelligent cockpit

Ansible basic configuration

Seven principles of software design

Description of transparent transmission function before master and slave of kt6368a Bluetooth chip, 2.4G frequency hopping automatic connection

How to extract dates from web pages?

2022-06-10 work record --js- obtain the date n days after a certain date

Technology inventory: Technology Evolution and Future Trend Outlook of cloud native Middleware
随机推荐
DX 的 HLSL 和 GL 的 GLSL的 矩阵构建的行列区别
堆內存分配的並發問題
Redis hop table
AQS source code analysis
OA system -- save the verification code to session
Can AI chat robots replace manual customer service?
如何比较两个或多个分布:从可视化到统计检验的方法总结
2022-06-16 工作记录--JS-判断字符串型数字有几位 + 判断数值型数字有几位 + 限制文本长度(最多展示n个字,超出...)
A pit in try with resources
seven
Rip protocol of dynamic routing protocol
Redis-跳表
See how sparksql supports enterprise data warehouse
进程的通信方式
Code farmers should also understand the IPv4 subnet division of point networks
Data communication and physical network
CSRF and SSRF for web attacks
Publicity of the second batch of shortlisted enterprises! Annual Top100 smart network supplier selection
堆内存分配的并发问题
New features of go1.18: efficient replication, new clone API for strings and bytes standard library