1.在controller层方法的形参数前添加@Validated注解,如果有分组校验的场景,则注明分组信息;如果校验不需要分组,可以不注明分组信息;
2.在接收参数的类的属性是对象的字段上添加@Valide注解,这里需要注意的是一定是@Valid , 不是@Validated,因为@Valid的实现是由hibernate-validator提供,有嵌套校验的能力,而@Validated是由spring-validation提供的具体实现方式,@Validated有分组校验的能力,但是没有嵌套校验的能力;(java API规范(JSR303)定义了Bean的校验标准validation-api,但是没有具体的实现,所以各有各的实现,在功能上也是有区别的)
3.嵌套属性类上的约束注解的用法,与用来接收参数的对象属性上的约束注解的用法是一样的;
总结:@Valid的实现是由hibernate-validator提供,有嵌套校验的能力,但是没有分组校验的能力 , @Validated是由spring-validation提供的具体实现方式,@Validated有分组校验的能力 , 但是没有嵌套校验的能力,在使用的过程须特别注意,要根据实际需要进行剪裁 。
@PostMapping("/addStuaAndTeach")public String addStuaAndTeach(@Validated(AddStuAndTeach.class) @RequestBody Student student){System.out.println("学生的工号:"+student.getStuCode()+",学生的老师的姓名:"+student.getTeacher().getTecName());return "success";}
@Datapublic class Teacher {@NotNull(message = "学生的老师姓名不能为空",groups = AddStuAndTeach.class)private String tecName;@NotNull(message = "学生的老师教授科目不能为空",groups = AddStuAndTeach.class)private String subject;}public interface AddStuAndTeach {}
@Datapublic class Student {@NotNull(message = "学生id不能为空",groups = QueryDetail.class)private Integer id;@NotNull(message = "学号不能为空",groups = AddStudent.class)@Length(min = 2, max = 4, message = "学号的长度范围是(2,4)")private String stuCode;@NotNull(message = "姓名不能为空",groups = AddStudent.class)@Length(min = 2, max = 3, message = "姓名的长度范围是(2,3)",groups = AddStudent.class)private String stuName;@Valid@NotNull(message = "学生的老师不能为空",groups = AddStuAndTeach.class)private Teacher teacher;}
分组校验在实际的项目中,可能多个方法使用同一个类来接收参数,但是不同的方法的校验规则又是不同的 , 这个时候就可以使用分组校验的方式来解决这个问题了,spring-validation提供了具体的实现方式 。
1.声明分组用的接口,比如添加和查询详情的时候,校验的规则肯定是不一样的,添加的时候一般不用传id , 由后台自增长生成,查询详情的时候id是必须传的;
2.在controller层方法的校验参数上添加@Validated参数,同时注解里要注明校验参数的分组信息;
3.在校验参数的类上的线束注解上,也要注明校验参数的分组信息;
总结:在接口的入口方法参数上、校验参数上都注明了分组的信息,那么接口被用的时候 , 就可以根据不同的分组信息执行不同约束注解的校验逻辑了,这个能力是spring-validation提供的,所以这种场景下 , controller层方法的上注解要用@Validated,@Valid注解没有这种能力 。
//用于添加场景参数校验分组public interface AddStudent {}
//用于查询详情场景参数校验分组public interface QueryDetail {}
@PostMapping("/add")public Student add(@Validated(AddStudent.class) @RequestBody Student student) {System.out.println(student.getStuName());return student;}@PostMapping("/detail")public String detail(@Validated(QueryDetail.class)@RequestBody Student student){System.out.println("学生id:"+student.getId());return "success";}
@Datapublic class Student {@NotNull(message = "学生id不能为空",groups = QueryDetail.class)private Integer id;@NotNull(message = "学号不能为空",groups = AddStudent.class)@Length(min = 2, max = 4, message = "学号的长度范围是(2,4)")private String stuCode;@NotNull(message = "姓名不能为空",groups = AddStudent.class)@Length(min = 2, max = 3, message = "姓名的长度范围是(2,3)",groups = AddStudent.class)private String stuName;}
【优雅的springboot参数校验,你学会了吗?】
推荐阅读
- JavaScript中的异步处理你知道哪些方法?你用对了吗?
- 一文详解分布式锁的看门狗机制
- Java的TreeMap底层实现原理?
- 你不知道的Websocket协议,这次给你讲明白!
- 解密 Python 如何调用 Rust 编译生成的动态链接库
- Java与MySQL大数据处理的技巧
- 解密Java连接MySQL的最佳实践:选择适合你的方式
- 系统设计概念:生产 Web 应用的架构
- 桃花最佳观赏时间是什么时候 桃花的最佳观赏期是几月几日
- 抖音上的商务合作是什么意思呀 抖音上的商务合作是什么意思