4. 分组验证
Bean Validation 支持分组验证,这允许您根据不同的业务场景来定义不同的验证规则。
-
@Validated(group) : 用于控制器方法参数,指定一组验证规则。
-
@GroupSequence(groups) : 指定验证的顺序。
4.1.定义分组
下面是一个使用分组验证的示例:
java
import jakarta.validation.groups.Default;
public interface UserGroups {
interface Registration extends Default {}
interface Login extends Default {}
}
4.2.设置验证规则
java
import com.yuan.springvalidationdemo.valid.UserGroups;
import jakarta.validation.GroupSequence;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
@GroupSequence({UserGroups.Registration.class, UserGroups.Login.class})
public class User2 {
@NotBlank(groups = UserGroups.Registration.class, message = "用户名在注册时不能为空")
@Size(min = 5, max = 20, groups = {UserGroups.Registration.class, UserGroups.Login.class}, message = "用户名长度应在5到20个字符之间")
private String username;
@NotBlank(groups = UserGroups.Registration.class, message = "密码在注册时不能为空")
@Size(min = 8, max = 32, groups = {UserGroups.Registration.class, UserGroups.Login.class}, message = "密码长度应在8到32个字符之间")
private String password;
@Email(groups = UserGroups.Registration.class, message = "邮箱格式不正确")
private String email;
// 构造函数、getter 和 setter 省略
}
在这个示例中,User2
类定义了两个验证组:Registration
和 Login
。username
和 password
字段分别在不同的组中有不同的验证规则。当验证用户注册时,Registration
组的规则会被应用;当验证用户登录时,Login
组的规则会被应用。
4.3.Controller
java
import com.yuan.springvalidationdemo.domain.User2;
import com.yuan.springvalidationdemo.valid.UserGroups;
import jakarta.validation.Valid;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController3 {
@PostMapping("/register3")
public ResponseEntity<String> register(@Valid @RequestBody User2 user, BindingResult result) {
if (result.hasErrors()) {
// 如果有验证错误,则返回错误信息
StringBuilder errorMessage = new StringBuilder();
result.getFieldErrors().forEach(error -> {
errorMessage.append(error.getDefaultMessage()).append("\n");
});
return ResponseEntity.badRequest().body(errorMessage.toString());
}
// 保存用户
return ResponseEntity.ok("注册成功");
}
@PostMapping("/login3")
@Validated({UserGroups.Login.class})
public ResponseEntity<String> login(@Valid @RequestBody User2 user, BindingResult result) {
if (result.hasErrors()) {
// 如果有验证错误,则返回错误信息
StringBuilder errorMessage = new StringBuilder();
result.getFieldErrors().forEach(error -> {
errorMessage.append(error.getDefaultMessage()).append("\n");
});
return ResponseEntity.badRequest().body(errorMessage.toString());
}
// 登录逻辑
return ResponseEntity.ok("登录成功");
}
}
通过 @Validated({UserGroups.Login.class})
指定验证 分组规则
5. 自定义注解
可以创建自定义注解来定义特定的验证逻辑。
- @Constraint(validatedBy = MyValidator.class) : 定义自定义注解时使用,指定自定义验证器类。
5.1. 定义验证注解
java
import jakarta.validation.Constraint;
import jakarta.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = UniqueUsernameValidator.class)
@Documented
public @interface UniqueUsername {
String message() default "用户名必须唯一";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
5.2. 实现自定义验证器
java
import com.yuan.springvalidationdemo.service.impl.UserServiceImpl;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class UniqueUsernameValidator implements ConstraintValidator<UniqueUsername, String> {
@Autowired
private UserServiceImpl userService;
@Override
public boolean isValid(String username, ConstraintValidatorContext context) {
return !userService.existsByUsername(username);
}
5.3. 使用注解
java
import com.yuan.springvalidationdemo.valid.UniqueUsername;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
public class User3 {
@NotBlank(message = "用户名不能为空")
@Size(min = 5, max = 20, message = "用户名长度应在5到20个字符之间")
@UniqueUsername
private String username;
@NotBlank(message = "密码不能为空")
private String password;
// 构造函数、getter 和 setter 省略
}