@Valid vs @Validated
概述
@Valid 和 @Validated 的区别有以下几点:
- @Valid 是 jsr 380 规范中定义的,而 @Validated 则是 spring 框架特有的;
- @Validated 支持分组校验;
- @Valid 可用于嵌套校验。
以上是不同点,但是这两个注解都是用来完成 Bean 校验的。
分组校验
在项目中,我们有时候会遇到引导页面,这种页面分为多步,每一步收集一组相关信息。例如用户注册页面,第一步收集用户基本信息,如:用户名、密码;第二步收集扩展信息,如:性别、年龄和爱好等。这些都是用户信息,所以服务端我们用 UserInfo 统一收集这些信息。
为了支持分组,需要为每个分组定义一个 interface,用于标识分组:
// 该分组用于标识用户基本信息
public interface UserBasicInfo {
}
// 该分组用于标识用户扩展信息
public interface UserExtendInfo {
}
紧接着定一个收集用户信息的 POJO,该 POJO 将会使用到上面的分组:
public class UserInfo {
@NotBlank(message = "用户名不能为空", groups = UserBasicInfo.class)
private String name;
@NotBlank(message = "密码不能为空", groups = UserBasicInfo.class)
private String password;
// 以下是扩展信息部分,注意 groups 值为 UserExtendInfo.class
@Size(min = 18, max = 120, groups = UserExtendInfo.class)
private int age;
@NotBlank(message = "爱好不能为空", groups = UserExtendInfo.class)
private String hobby;
@NotBlank(message = "性别不能为空", groups = UserExtendInfo.class)
private String gender;
// 篇幅关系,省略 getter/setter
}
再下来,就是 controller 方法中使用 @Validated 注解配合之前为标识分组而定义的 interface 完成校验:
@RestController
public class UserController {
@PostMapping("/basicInfo")
public String validateBasicInfo(@Validated(UserBasicInfo.class) UserInfo info) {
// 注意 @Validated 注解使用了 UserBasicInfo.class
// ...
}
@PostMapping("/extendInfo")
public String validateExtendInfo(@Validated(UserExtendInfo.class) UserInfo info) {
// ...
}
}
之所以使用分组校验是因为每一步只校验某个分组的信息,其他信息为空,如果不使用分组,肯定校验失败。
注:从 spring boot 2.3 开始需要引入 spring-boot-starter-validation。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
嵌套校验
嵌套校验就是所谓 nested validation。这里假设一个订单信息 OrderInfo,OrderInfo 包含了用户信息 Customer,校验的时候我们需要校验包含在订单信息中的用户信息,做法很简单,只需要给 customer 字段上添加一个 @Valid 注解即可。
public class Customer {
@NotBlank(message = "customer id required")
private String id;
}
public class OrderInfo {
// 为了支持嵌套校验,这里需要在嵌套对象上使用 @Valid 注解
@Valid
@NotNull(message = "customer info required")
private Customer customer;
}
在 controller 方法中我们可以使用 @Valid 也可以使用 @Validated。
@PostMapping("/order")
public void createOrder(@Valid OrderInfo info) {
//...
}
jsr 308 实现
jsr 308 只是一个 bean 校验的规范,spring 中默认使用的实现是 hibernate-validator。
有问题吗?点此反馈!
温馨提示:反馈需要登录