后端数据校验

后台开发需要对传进来的对象进行参数校验, 有专门的校验工具 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, 长度需要在532之间
植物名: test, 长度需要在532之间

在 Spring MVC 中使用

public Result update(@Valid PoiPlant plant, BindingResult bindingResult)

这里一个 @Valid 的参数后必须紧挨着一个 BindingResult 参数, 否则 spring 会在校验不通过时直接抛出异常.

级联验证

对象内部包含另一个对象作为属性, 属性上加 @Valid, 可以验证作为属性的对象内部的验证

@ConstraintComposition 组合校验规则

自定义校验规则

参考文献