Hibernate Validator簡單使用


介紹

JSR-303 是JAVA EE6 中的一項子規范,叫做Bean Validation,Hibernate Validator 是 Bean Validation 的參考實現,提供了 JSR 303 規范中所有內置 constraint 的實現,除此之外還有一些附加的 constraint。

簡單校驗

添加maven依賴

<dependency>
      <groupId>org.hibernate.validator</groupId>
      <artifactId>hibernate-validator</artifactId>
      <version>6.0.17.Final</version>
</dependency>

hibernate-validator還依賴以下兩個

<dependency>
      <groupId>javax.el</groupId>
      <artifactId>javax.el-api</artifactId>
      <version>3.0.0</version>
</dependency>
<dependency>
      <groupId>org.glassfish</groupId>
      <artifactId>javax.el</artifactId>
      <version>3.0.0</version>
</dependency>

實體類

@AllArgsConstructor
@NoArgsConstructor
@Setter
@Getter
public class User {

  @NotBlank(message = "用戶名不能為空")
  private String username;
  @NotBlank(message = "密碼不能為空")
  private String password;
  @NotBlank(message = "密碼不能為空")
  @Pattern(regexp = "^1([34578])\\d{9}$", message = "手機號格式錯誤")
  private String mobile;
  @NotBlank(message = "性別不能為空")
  private String gender;
  @NotNull(message = "年齡不能為空")
  @Range(min = 5, max = 90, message = "年齡必須在5-90之間")
  private Integer age;

  private List<Address> addressList;

  @AllArgsConstructor
  @NoArgsConstructor
  @Setter
  @Getter
  static class Address {

    private String province;
    private String city;
    private String region;
  }
}
public class Client {

  public static void main(String[] args) {
    Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
    User user = new User();
    Set<ConstraintViolation<User>> constraintViolationSet = validator.validate(user);
    for (ConstraintViolation<User> constraintViolation : constraintViolationSet) {
      System.out.println(constraintViolation.getMessage());
    }
  }

}

Validation會通過SPI的方式找到所有ValidationProvider接口的實現,自然就找到hibernate-validator的實現HibernateValidator了。

當然我們也可以自己指定實現,自定義配置

public class Client {

  public static void main(String[] args) {
    Validator validator = Validation.byProvider(HibernateValidator.class)
        .configure()
        .failFast(true) //有一個失敗就停止檢查
        .buildValidatorFactory()
        .getValidator();
    User user = new User();
    Set<ConstraintViolation<User>> constraintViolationSet = validator.validate(user);
    for (ConstraintViolation<User> constraintViolation : constraintViolationSet) {
      System.out.println(constraintViolation.getMessage());
    }
  }

}

級聯校驗

實體類

@AllArgsConstructor
@NoArgsConstructor
@Setter
@Getter
public class User {

  @NotBlank(message = "用戶名不能為空")
  private String username;
  @NotBlank(message = "密碼不能為空")
  private String password;
  @NotBlank(message = "密碼不能為空")
  @Pattern(regexp = "^1([34578])\\d{9}$", message = "手機號格式錯誤")
  private String mobile;
  @NotBlank(message = "性別不能為空")
  private String gender;
  @NotNull(message = "年齡不能為空")
  @Range(min = 5, max = 90, message = "年齡必須在5-90之間")
  private Integer age;

  @Valid
  @NotEmpty(message = "地址不能為空")
  private List<Address> addressList;

  @AllArgsConstructor
  @NoArgsConstructor
  @Setter
  @Getter
  static class Address {

    @NotBlank(message = "省不能為空")
    private String province;
    @NotBlank(message = "市不能為空")
    private String city;
    @NotBlank(message = "區不能為空")
    private String region;
  }
}

使用Valid注解實現級聯校驗

public class Client {

  public static void main(String[] args) {
    Validator validator = Validation.byProvider(HibernateValidator.class)
        .configure()
        .failFast(false) //有一個失敗就停止檢查
        .buildValidatorFactory()
        .getValidator();
    User user = new User();
    user.setAddressList(Collections.singletonList(new Address()));
    Set<ConstraintViolation<User>> constraintViolationSet = validator.validate(user);
    for (ConstraintViolation<User> constraintViolation : constraintViolationSet) {
      System.out.println(constraintViolation.getMessage());
    }
  }

}

分組校驗

實體類

@AllArgsConstructor
@NoArgsConstructor
@Setter
@Getter
public class User {

  @NotBlank(message = "用戶名不能為空")
  private String username;
  @NotBlank(message = "密碼不能為空")
  private String password;
  @NotBlank(message = "密碼不能為空")
  @Pattern(regexp = "^1([34578])\\d{9}$", message = "手機號格式錯誤")
  private String mobile;
  @NotBlank(message = "性別不能為空")
  private String gender;
  @NotNull(message = "年齡不能為空")
  @Range(min = 18, max = 90, message = "年齡必須在18-90之間", groups = Adult.class)
  @Range(min = 5, max = 17, message = "年齡必須在5-17之間", groups = Minor.class)
  private Integer age;

  private List<Address> addressList;

  @AllArgsConstructor
  @NoArgsConstructor
  @Setter
  @Getter
  static class Address {

    private String province;
    private String city;
    private String region;
  }

  /**
   * 成年人
   */
  interface Adult {
  }

  /**
   * 未成年人
   */
  interface Minor {
  }
}

不設置分組,默認為Default分組

public class Client {

  public static void main(String[] args) {
    Validator validator = Validation.byProvider(HibernateValidator.class)
        .configure()
        .failFast(false) //有一個失敗就停止檢查
        .buildValidatorFactory()
        .getValidator();
    User user = new User();
    user.setAge(7);
    Set<ConstraintViolation<User>> constraintViolationSet = validator
        .validate(user, Default.class, Adult.class); // 設置要校驗的分組
    for (ConstraintViolation<User> constraintViolation : constraintViolationSet) {
      System.out.println(constraintViolation.getMessage());
    }
  }

}

不設置也會添加一個默認分組Default

自定義校驗器

校驗注解

/**
 * 當前值必須在給定的列表中
 */
@Target({FIELD})
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = {ListRangeValidatorForString.class})
public @interface ListRange {

  String message() default "";

  Class<?>[] groups() default {};

  Class<? extends Payload>[] payload() default {};

  String[] value() default {};
}

校驗器

public class ListRangeValidatorForString implements ConstraintValidator<ListRange, String> {

  private String[] range;

  @Override
  public void initialize(ListRange listRange) {
    this.range = listRange.value();
  }

  @Override
  public boolean isValid(String value, ConstraintValidatorContext context) {
    if (Objects.isNull(value)) {
      return true;
    }
    return Arrays.asList(range).contains(value);
  }
}

實體類

@AllArgsConstructor
@NoArgsConstructor
@Setter
@Getter
public class User {

  @NotBlank(message = "用戶名不能為空")
  private String username;
  @NotBlank(message = "密碼不能為空")
  private String password;
  @NotBlank(message = "密碼不能為空")
  @Pattern(regexp = "^1([34578])\\d{9}$", message = "手機號格式錯誤")
  private String mobile;
  @NotBlank(message = "性別不能為空")
  @ListRange(value = {"male", "female"}, message = "性別必須在[male,female]之間")
  private String gender;
  @NotNull(message = "年齡不能為空")
  @Range(min = 5, max = 90, message = "年齡必須在5-90之間")
  private Integer age;

  private List<Address> addressList;

  @AllArgsConstructor
  @NoArgsConstructor
  @Setter
  @Getter
  static class Address {

    private String province;
    private String city;
    private String region;
  }
}

性別必須在male和female之間

public class Client {

  public static void main(String[] args) {
    Validator validator = Validation.byProvider(HibernateValidator.class)
        .configure()
        .failFast(false) //有一個失敗就停止檢查
        .buildValidatorFactory()
        .getValidator();
    User user = new User();
    user.setAge(7);
    user.setGender("ss");
    Set<ConstraintViolation<User>> constraintViolationSet = validator.validate(user);
    for (ConstraintViolation<User> constraintViolation : constraintViolationSet) {
      System.out.println(constraintViolation.getMessage());
    }
  }

}

hibernate-validator會先找內置的注解校驗器,找不到就找自定義的校驗器。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM