1. 概述

Hibernate Validator 是 Bean Validation 规范的实现之一,除了支持 JSR 标准的校验注解外,它还提供了一些额外的、专属于 Hibernate Validator 的约束注解。这些注解在某些特定场景下非常实用,比如校验信用卡号、货币金额、字符串长度、URL、HTML 安全性等。

本文将带你了解这些非标准但非常实用的 Hibernate Validator 约束注解,并给出使用示例。


2. Hibernate Validator 环境搭建

要使用 Hibernate Validator 的特定约束,首先需要在项目中引入它的依赖:

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

⚠️ 注意:Hibernate Validator 并不依赖于 Hibernate ORM,所以即使你不使用 Hibernate ORM,也可以放心使用其校验功能。

此外,部分注解的使用依赖于特定库(如 Java Money、JSoup 等),我们会根据具体注解说明是否需要额外依赖。


3. 校验与金额相关的值

3.1 校验信用卡号

Hibernate Validator 提供了 @CreditCardNumber 注解,用于校验信用卡号是否符合 Luhn 算法 的校验规则。

✅ 说明:

  • 该注解仅校验数字是否通过 Luhn 算法,不校验长度、格式等;
  • 默认不允许非数字字符,但可以通过参数 ignoreNonDigitCharacters = true 忽略空格、横线等非数字字符。

示例代码:

@CreditCardNumber(ignoreNonDigitCharacters = true)
private String lenientCreditCardNumber;

验证示例:

validations.setLenientCreditCardNumber("7992-7398-713");
Set<ConstraintViolation<Validations>> violations = validator.validateProperty(validations, "lenientCreditCardNumber");
assertTrue(violations.isEmpty());

3.2 校验货币金额

使用 @Currency 注解可以校验一个 MonetaryAmount 类型的金额是否符合指定的货币类型(如 EUR、USD 等)。

⚠️ 注意:该注解依赖 Java Money 实现(如 javax.money),需确保项目中引入了相关依赖。

示例代码:

@Currency("EUR")
private MonetaryAmount balance;

验证示例:

bean.setBalance(Money.of(new BigDecimal(100.0), Monetary.getCurrency("EUR")));
Set<ConstraintViolation<Bean>> violations = validator.validateProperty(bean, "balance");
assertEquals(0, violations.size());

4. 校验数值范围

4.1 数值与货币范围

Hibernate Validator 提供了 @Range 注解,用于同时指定一个字段的最小值和最大值,功能类似于 @Min + @Max 的组合。

✅ 支持类型包括:

  • 基本类型及其包装类
  • BigInteger / BigDecimal
  • MonetaryAmount

示例代码:

@Range(min = 0, max = 100)
private BigDecimal percent;

4.2 时间持续时间范围

Hibernate Validator 提供了 @DurationMin@DurationMax 注解,用于校验 Duration 类型的时间间隔是否在指定范围内。

✅ 支持单位:纳秒、微秒、毫秒、秒、分钟、小时、天。

示例代码:

@DurationMin(days = 1, hours = 2)
@DurationMax(days = 2, hours = 1)
private Duration duration;

✅ 可选参数:inclusive = false 表示边界值不包含在内。

示例:

@DurationMax(minutes = 30, inclusive = false)

5. 校验字符串

5.1 字符串长度

Hibernate Validator 提供了两个注解用于校验字符串长度:

  • @Length:基于字符数(String.length()
  • @CodePointLength:基于 Unicode 码点数(更准确)

示例代码:

@Length(min = 1, max = 3)
private String someString;

@CodePointLength(min = 1, max = 3)
private String anotherString;

例如字符串 "aa\\uD835\\uDD0A" 包含 4 个字符,但只有 3 个码点。


5.2 数字字符串校验

除了 @CreditCardNumber,Hibernate Validator 还提供了以下用于校验数字字符串的注解:

注解 用途说明
@LuhnCheck 通用 Luhn 校验,支持子串校验
@Mod10Check Mod 10 校验(常用于条形码)
@Mod11Check Mod 11 校验(常用于 ISBN)
@ISBN 校验 ISBN 编号
@EAN 校验 EAN 条形码

示例代码(LuhnCheck):

@LuhnCheck(startIndex = 0, endIndex = Integer.MAX_VALUE, checkDigitIndex = -1)
private String someString;

5.3 URL 与 HTML 校验

校验 URL

使用 @URL 注解可以校验字符串是否为合法的 URL,并可指定协议、主机、端口等。

示例代码:

@URL(protocol = "https")
private String url;

校验 HTML 安全性

使用 @SafeHtml 注解可以校验 HTML 是否“安全”,即不含脚本标签等危险内容。

⚠️ 注意:需要引入 JSoup 库。

示例代码:

@SafeHtml
private String html;

还可以通过 whitelistadditionalTags 等参数自定义允许的标签和属性。


6. 其他实用约束

Hibernate Validator 还提供了一些其他实用的约束注解:

注解 用途说明
@UniqueElements 校验集合中元素是否唯一
@ScriptAssert 通过脚本(如 Nashorn)校验对象整体状态
国家/地区约束 如巴西、波兰的身份证、税号等校验(见文档)

示例代码(@ScriptAssert):

@ScriptAssert(lang = "nashorn", script = "_this.valid")
public class AdditionalValidations {
    private boolean valid = true;
    // getter/setter
}

验证示例:

bean.setValid(false);
Set<ConstraintViolation<Bean>> violations = validator.validate(bean);
assertEquals(1, violations.size());

7. 总结

Hibernate Validator 在 Bean Validation 规范之外,提供了许多实用的校验注解,适用于金融、字符串处理、时间、HTML 安全等多种场景。

这些注解简化了校验逻辑,避免了手动编写复杂验证逻辑的麻烦。

完整代码示例可在 GitHub 仓库 中找到。


原始标题:Hibernate Validator Specific Constraints | Baeldung