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;
还可以通过 whitelist
、additionalTags
等参数自定义允许的标签和属性。
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 仓库 中找到。