校验是Web应用程序中的常见任务之一,Spring框架提供了很多方便的校验注解,如@NotNull
、@Size
等等。但是,在实际应用中,很少有只需要校验单一属性就能满足业务需求,通常需要校验多个属性组合而成的复杂条件。在这种情况下,Spring Boot的@GroupSequenceProvider注解可以派上用场。本文将为您介绍如何使用@GroupSequenceProvider注解进行bean多属性联合校验,并提供两个示例代码。
1.添加依赖
在使用Spring Boot的校验注解时,需要添加spring-boot-starter-validation
依赖。在Maven中,可以这样引入:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
2.创建实体类
接下来,我们创建一个实体类User
,其中包含多个校验属性:
public class User {
@NotNull(message = "用户名不能为空")
@Size(min = 3, max = 20, message = "用户名长度必须在3-20个字符之间")
private String username;
@NotNull(message = "密码不能为空")
@Size(min = 6, max = 20, message = "密码长度必须在6-20个字符之间")
private String password;
@NotNull(message = "手机号不能为空")
@Pattern(regexp = "^1[3|4|5|7|8][0-9]\\d{8}$", message = "手机号格式不正确")
private String phone;
@NotNull(message = "邮箱不能为空")
@Email(message = "邮箱格式不正确")
private String email;
}
该实体类中包括四个属性:username
、password
、phone
、email
,每一个属性都添加了校验注解。
3.创建@GroupSequenceProvider注解
接下来,我们创建一个UserGroupSequenceProvider
类,用于指定校验顺序:
public class UserGroupSequenceProvider implements DefaultGroupSequenceProvider<User> {
@Override
public List<Class<?>> getValidationGroups(User user) {
List<Class<?>> groups = new ArrayList<>();
groups.add(User.class);
if (!StringUtils.isEmpty(user.getUsername())) {
groups.add(UsernameValidation.class);
}
if (!StringUtils.isEmpty(user.getPassword())) {
groups.add(PasswordValidation.class);
}
if (!StringUtils.isEmpty(user.getPhone())) {
groups.add(PhoneValidation.class);
}
if (!StringUtils.isEmpty(user.getEmail())) {
groups.add(EmailValidation.class);
}
return groups;
}
}
该类实现了Spring框架的DefaultGroupSequenceProvider
接口,其中的getValidationGroups
方法通过对判断User实例的各个属性是否为空,来决定校验顺序。
除了User.class
外,另外定义了四种组:UsernameValidation.class
、PasswordValidation.class
、PhoneValidation.class
和EmailValidation.class
。
4.创建各个校验组
我们在User
实体类中新建四个接口,来定义各自的校验规则:
public interface UsernameValidation {}
public interface PasswordValidation {}
public interface PhoneValidation {}
public interface EmailValidation {}
5.编写Controller层代码
最后,在Controller层中注入@Valid
注解,同时在参数中指定校验的组:
@PostMapping("/users")
public ResponseEntity<User> createUser(@Validated({UsernameValidation.class, PasswordValidation.class, PhoneValidation.class, EmailValidation.class}) @RequestBody User user) {
// TODO: 业务逻辑处理
return ResponseEntity.ok(user);
}
以上代码中,我们指定了User
实例必须满足UsernameValidation.class
、PasswordValidation.class
、PhoneValidation.class
和EmailValidation.class
四个组校验的规则。
示例1:不同属性的校验规则顺序不同
@RunWith(SpringRunner.class)
@SpringBootTest
public class UserTest {
@Autowired
private Validator validator;
@Test
public void test() {
User user = new User();
user.setUsername("user");
user.setEmail("123");
user.setPassword("123456");
user.setPhone("123");
Set<ConstraintViolation<User>> violations = validator.validate(user);
for (ConstraintViolation<User> violation : violations) {
System.out.println(violation.getMessage());
}
}
}
以上代码中,我们通过JUnit测试的方式来模拟校验过程。其中,用户的username
和phone
属性不满足校验规则,会输出两条相应的提示信息:
用户名长度必须在3-20个字符之间
手机号格式不正确
示例2:不同属性的校验规则顺序相同
接着,我们通过JUnit测试演示不同属性的校验规则顺序相同的情况:
@RunWith(SpringRunner.class)
@SpringBootTest
public class UserTest {
@Autowired
private Validator validator;
@Test
public void test() {
User user = new User();
user.setUsername("user");
user.setPassword("123456");
user.setPhone("15555555555");
user.setEmail("123@qq.com");
Set<ConstraintViolation<User>> violations = validator.validate(user);
for (ConstraintViolation<User> violation : violations) {
System.out.println(violation.getMessage());
}
}
}
以上代码中,我们把用户的所有属性都设置为合法值,即使不同属性的校验规则顺序相同,也不会出现任何错误提示信息。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:SpringBoot @GroupSequenceProvider注解实现bean多属性联合校验的示例代码 - Python技术站