后台开发需要对传进来的对象进行参数校验, 有专门的校验工具 validation-api. 它是基于 JSR-303 标准开发出来的, 使用注解方式实现, 及其方便, 但这只是一个接口, 没有具体的实现. hibernate-validator 是一个 hibernate 独立的包, 可以直接引用, 它实现了 validation-api, 同时做了扩展, 非常强大.
校验规则
javax.validation.constraints
Constraint | 可用数据类型 | 详细介绍 |
---|---|---|
@Null |
任意类型 | 必须为 null |
@NotNull |
任意类型 | 必须不为 null |
@NotEmpty |
string, collection, map or array | 字符串必须非空 |
@NotBlank |
string | 字符串去掉前后空格后, 必须非空 |
@Email |
string | 必须为电子邮箱 |
@Pattern |
string | 必须符合指定的正则表达式 |
@AssertFalse |
boolean | 必须为 False |
@AssertTrue |
boolean | 必须为 True |
@Positive |
数值类型 | 必须为正数 |
@PositiveOrZero |
数值类型 | 必须为正数或零 |
@Negative |
数值类型 | 必须为负数 |
@NegativeOrZero |
数值类型 | 必须为负数或零 |
@Max(value) |
数值类型 | 必须为数字, 且不大于指定的最大值 |
@Min(value) |
数值类型 | 必须为数字, 且不小于指定的最小值 |
@DecimalMax(value) |
数值类型 | 必须为数字, 且不大于指定的最大值 |
@DecimalMin(value) |
数值类型 | 必须为数字, 且不小于指定的最小值 |
@Digits(integer, fraction) |
数值类型 | 字符串是否符合指定的格式, integer 指定整数精度, fraction 指定小数精度 |
@Past |
日期时间 | 必须为过去的日期 |
@PastOrPresent |
日期时间 | 必须为过去或现在的日期 |
@Future |
日期时间 | 必须为将来的日期 |
@FutureOrPresent |
日期时间 | 必须为将来或现在的日期 |
@Size(min, max) |
string, collection, map or array | 集合对象长度必须在指定的范围 |
org.hibernate.validator.constraints
Constraint | 可用数据类型 | 详细介绍 |
---|---|---|
@EAN |
string | 必须为商品条形码, 默认是 EAN-13 |
@ISBN |
string | 必须为书籍 ISBN 码 |
@Length(min, max) |
string | 字符串的长度必须在指定的范围内 |
@CodePointLength(min, max) |
string | 校验Unicode 中的 code point 的长度是否在注解的最大最小值之间 |
@Range(min, max) |
数值类型 | 必须在指定的范围内 |
@Currency |
MonetaryAmount | 必须为指定的货币单位 |
@CreditCardNumber |
string | 必须为信用卡, 通过 Luhn checksum 测试 |
@LuhnCheck |
string | 校验数字是否满足 Luhn 校验算法 |
@Mod10Check |
string | 校验数字是否能通过 mod 10 算法 |
@Mod11Check |
string | 校验数字是否能通过 mod 11 算法 |
@SafeHtml |
string | 校验字段是否含有潜在的威胁片段 |
@ScriptAssert |
string | 校验给定的脚本能否成功根据注解的属性执行 |
@ParameterScriptAssert |
string | 方法级别, 校验给定的脚本能否成功根据注解的属性执行 |
@URL(protocol, host, port, regexp) |
string | 根据RFC2396来校验是否是一个有效的 URL |
@UniqueElements |
collection | 校验集合含有独一无二的元素 |
@DurationMax |
short | 最长时长 |
@DurationMin |
short | 最短时长 |
使用方法
直接使用
定义 Bean
@Data
@ToString(of = {"id", "name", "altName"})
public class PoiPlant implements Serializable {
private static final long serialVersionUID = -354255909978410198L;
private Integer id;
@NotBlank(message = "{plant.name}{javax.validation.constraints.NotBlank.message}")
@Length(min = 5, max = 32, message = "{plant.name}: ${validatedValue}, {org.hibernate.validator.constraints.Length.message}")
private String name;
private String altName;
private String content;
}
自定义校验错误信息, 在 resources
中增加 ValidationMessages.properties
文件, 内容如下:
plant.name=\u690d\u7269\u540d
用单元测试, 进行验证校验
PoiPlant plant = new PoiPlant();
Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
// 校验整个 Bean
validator.validate(plant).forEach(System.out::println);
// 校验类的某个字段
validator.validateValue(PoiPlant.class, "name", "test").forEach(System.out::println);
输出结果
植物名不能为空
植物名: a, 长度需要在5和32之间
植物名: test, 长度需要在5和32之间
在 Spring MVC 中使用
public Result update(@Valid PoiPlant plant, BindingResult bindingResult)
这里一个 @Valid
的参数后必须紧挨着一个 BindingResult
参数, 否则 spring 会在校验不通过时直接抛出异常.
级联验证
对象内部包含另一个对象作为属性, 属性上加 @Valid
, 可以验证作为属性的对象内部的验证
@ConstraintComposition
组合校验规则