微信登录

数据验证 - 自定义验证 - 编写自定义验证器

Java - Web - Spring 《数据验证 - 自定义验证 - 编写自定义验证器》

在 Java Web 开发中,Spring 框架为我们提供了强大的数据验证功能。除了使用 Spring 内置的验证注解(如 @NotNull@Size 等),有时我们还需要根据特定的业务需求编写自定义验证器。本文将详细介绍如何在 Spring 中编写自定义验证器,并通过一个具体的例子进行演示。

为什么需要自定义验证器?

Spring 内置的验证注解可以满足大部分常见的验证需求,但在一些复杂的业务场景下,这些注解可能无法满足要求。例如,我们需要验证一个字符串是否符合特定的格式,或者验证两个字段之间的逻辑关系等。这时,就需要编写自定义验证器来实现这些复杂的验证逻辑。

编写自定义验证器的步骤

1. 定义自定义验证注解

首先,我们需要定义一个自定义的验证注解,该注解将用于标记需要验证的字段。以下是一个简单的自定义验证注解示例:

  1. import javax.validation.Constraint;
  2. import javax.validation.Payload;
  3. import java.lang.annotation.Documented;
  4. import java.lang.annotation.ElementType;
  5. import java.lang.annotation.Retention;
  6. import java.lang.annotation.RetentionPolicy;
  7. import java.lang.annotation.Target;
  8. @Documented
  9. @Constraint(validatedBy = { CustomValidator.class })
  10. @Target({ ElementType.FIELD })
  11. @Retention(RetentionPolicy.RUNTIME)
  12. public @interface CustomValidation {
  13. String message() default "Invalid value";
  14. Class<?>[] groups() default {};
  15. Class<? extends Payload>[] payload() default {};
  16. }
  • @Constraint:指定用于验证该注解标记字段的验证器类。
  • @Target:指定该注解可以应用的目标元素类型,这里我们指定为字段。
  • @Retention:指定该注解的保留策略,这里我们选择在运行时保留。
  • message():指定验证失败时的错误信息。
  • groups()payload():用于分组验证和负载信息,这里我们暂时不使用。

2. 实现自定义验证器类

接下来,我们需要实现一个自定义验证器类,该类需要实现 javax.validation.ConstraintValidator 接口。以下是一个简单的自定义验证器类示例:

  1. import javax.validation.ConstraintValidator;
  2. import javax.validation.ConstraintValidatorContext;
  3. public class CustomValidator implements ConstraintValidator<CustomValidation, String> {
  4. @Override
  5. public void initialize(CustomValidation constraintAnnotation) {
  6. // 初始化方法,可用于获取注解中的属性值
  7. }
  8. @Override
  9. public boolean isValid(String value, ConstraintValidatorContext context) {
  10. // 验证逻辑
  11. if (value == null) {
  12. return true; // 允许为空值
  13. }
  14. // 假设我们要求字符串长度必须为偶数
  15. return value.length() % 2 == 0;
  16. }
  17. }
  • initialize():初始化方法,可用于获取注解中的属性值。
  • isValid():验证方法,用于实现具体的验证逻辑。如果验证通过,返回 true;否则返回 false

3. 使用自定义验证注解

最后,我们可以在需要验证的字段上使用自定义验证注解。以下是一个简单的实体类示例:

  1. import javax.validation.constraints.NotNull;
  2. public class User {
  3. @NotNull
  4. private String name;
  5. @CustomValidation
  6. private String code;
  7. public User(String name, String code) {
  8. this.name = name;
  9. this.code = code;
  10. }
  11. public String getName() {
  12. return name;
  13. }
  14. public void setName(String name) {
  15. this.name = name;
  16. }
  17. public String getCode() {
  18. return code;
  19. }
  20. public void setCode(String code) {
  21. this.code = code;
  22. }
  23. }

4. 验证数据

在控制器中,我们可以使用 Spring 的 @Valid 注解来触发验证。以下是一个简单的控制器示例:

  1. import org.springframework.validation.BindingResult;
  2. import org.springframework.validation.annotation.Validated;
  3. import org.springframework.web.bind.annotation.PostMapping;
  4. import org.springframework.web.bind.annotation.RequestBody;
  5. import org.springframework.web.bind.annotation.RestController;
  6. import javax.validation.Valid;
  7. @RestController
  8. @Validated
  9. public class UserController {
  10. @PostMapping("/users")
  11. public String createUser(@Valid @RequestBody User user, BindingResult bindingResult) {
  12. if (bindingResult.hasErrors()) {
  13. return "Validation failed: " + bindingResult.getAllErrors().get(0).getDefaultMessage();
  14. }
  15. return "User created successfully";
  16. }
  17. }
  • @Valid:用于触发验证。
  • BindingResult:用于获取验证结果。

总结

通过以上步骤,我们可以在 Spring 中编写自定义验证器来满足复杂的业务验证需求。以下是一个简单的总结表格:

步骤 描述 示例代码
1 定义自定义验证注解 @CustomValidation
2 实现自定义验证器类 CustomValidator
3 使用自定义验证注解 在实体类字段上使用 @CustomValidation
4 验证数据 在控制器中使用 @Valid 注解触发验证

通过这种方式,我们可以灵活地实现各种复杂的验证逻辑,确保输入数据的合法性。希望本文对你在 Spring 中编写自定义验证器有所帮助!