数据校验是贯穿全部应用程序层(从表示层到持久层)的常见任务。一般在每一个层中实现相同的验证逻辑,这是耗时且容易出错的。这里咱们可使用Hibernate Validator来帮助我处理这项任务。对此,Hibernate Validator提供了一些注解来做为数据约束,咱们只须要将这些注解添加到咱们须要校验的属性/参数上面,就能够轻松的完成这项任务。html
常见的注解,这里只是列出了一些常见的属性上面的约束以及他们所拥有的一些属性,更加详细的介绍请看 官方文档。java
注解 | 数据类型 | 属性 | 注解说明 | |
@NotNull | 字符串 | 添加注解的属性不能是null | ||
@NotBlank | 字符串 | 检查字符串是不是null,且去掉空格后长度是不是0 | ||
@AssertTrue | 布尔 | 检查值是不是true | ||
@AssertFalse | 布尔 | 检查值是不是false | ||
@DecimalMax | 数字 | 检查值是否大于设定值 | ||
value | 设置的最大值 | |||
inclusive | 是否等于 | |||
@DecimalMin | 数字 | 检查值是否小于设定值 | ||
value | 设置的最大值 | |||
inclusive | 是否等于 | |||
@Digits | 数字 | 校验数字小数点先后位数 | ||
integer |
小数点前几位 | |||
fraction |
小数点后几位 | |||
字符串 | 校验是否是邮箱 | |||
@Future | 时间 | 检查日期是否是在未来 | ||
@Past | 时间 | 检查日期是否在过去 | ||
@Max | 数字类型 | 是否大于最大值 | ||
@Min | 数字类型 | 是否小于最小值 | ||
@Pattern | 字符串 | 使用正则校验 | ||
@Size | 字符串,集合,数组 | 检查长度 |
看到上面的那么多注解是否是以为很实用呢?有没有想试一试看看好很差用呢?接下来咱们开始写一些代码来用一用,首先咱们须要添加它的依赖。git
<dependency> <groupId>org.hibernate.validator</groupId> <artifactId>hibernate-validator</artifactId> <version>6.0.15.Final</version> </dependency> <dependency> <groupId>org.glassfish</groupId> <artifactId>javax.el</artifactId> <version>3.0.1-b09</version> </dependency>
接下来定义一个Class,而后在他的属性上添加Hibernate Validator提供的一些注解数组
import lombok.Getter; import lombok.Setter; import lombok.ToString; import javax.validation.constraints.*; import java.util.Date; /** * 产品表 * * @author hejiaxuan */ @Getter @Setter @ToString public class Demo { @NotNull @Digits(integer = 0, fraction = 3) private Double aDouble; @Past(message = "time必须在今天以后") private Date time; @Max(value = 5, message = "status不能大于5") @Min(value = 0, message = "status不能小于0") @NotNull(message = "status不能为null") private Integer status; @Size(min = 2, max = 5, message = "name长度必须在2~5之间") @NotBlank(message = "name不能为null") private String name; }
对象定义好了,下面看看怎么用吧。测试
上面的代码中,咱们定义的了一个对象,而且在它的每一个属性上面添加了咱们须要的校验规则(注解)。如今说一个不须要实例化对象就能够测试这些规则的方法, 代码以下:ui
//单独校验Class中的某个属性和值 Set<ConstraintViolation<Demo>> result = validator.validateValue(Demo.class, "name", "hahahaha"); Iterator<ConstraintViolation<Demo>> iterator = result.iterator(); while (iterator.hasNext()) { ConstraintViolation<Demo> next = iterator.next(); //打印校验结果 System.out.println(next.getMessage()); } //运行结果 name长度必须在2~5之间
这里是校验这个对象的全部属性hibernate
//待校验对象 Demo demo = new Demo(); demo.setName("00000000"); demo.setADouble(200.001); demo.setStatus(200); //获得Validator实例 ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); Validator validator = factory.getValidator(); //开始校验 Set<ConstraintViolation<Demo>> result = validator.validate(demo); Iterator<ConstraintViolation<Demo>> iterator = result.iterator(); while (iterator.hasNext()) { ConstraintViolation<Demo> next = iterator.next(); //打印校验结果 System.out.println(next.getMessage()); } //运行结果 name不能为null 不能为null status不能为null
由于对象没有设置任何值,因此校验结果都是 “某某某字段不能为null”,如今咱们给demo对象设置几个值试一下code
demo.setName("00000000"); demo.setADouble(200.001); demo.setStatus(200); //运行结果 数字的值超出了容许范围(只容许在0位整数和3位小数范围内) status不能大于5 name长度必须在2~5之间
这里是校验整个对象的全部属性,可是若是咱们只想校验一个对象里的部分属性怎么办呢?xml
这里是单独校验某一个对象其中的某几个属性,代码以下htm
//第一个参数是要校验的对象,后面的参数是要校验的对象属性名称 Set<ConstraintViolation<Demo>> result = validator.validateProperty( demo, "status" ); //输出结果 status不能大于5
上面讲的都是对象属性的校验,那么怎样对一个方法的入参和出参进行校验呢?这里分为 方法参数的校验 和 返回值的校验。下面咱们先给Demo.java添加一个方法,并添加约束注解:
public class Demo { /** * 要校验的方法 * * @param string * @return */ public @Size(min = 3, max = 10, message = "结果长度在3~10之间") String getString(@NotBlank String string) { return string; } }
//对于方法的校验 ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); ExecutableValidator executableValidator = factory.getValidator().forExecutables(); //实例化对象 Demo object = new Demo(); //获取对应的方法 Method method = Demo.class.getMethod("getString", String.class); //获取它的返回值 Object returnValue = method.invoke(object, "这是方法的参数,要大因而个字"); Set<ConstraintViolation<Demo>> violations = executableValidator.validateReturnValue( object, method, returnValue ); //结果 Iterator<ConstraintViolation<Demo>> iterator = violations.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next().getMessage()); } //执行结果 结果长度在3~10之间
//对于方法的校验 ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); ExecutableValidator executableValidator = factory.getValidator().forExecutables(); //实例化对象 Demo object = new Demo(); //获取对应的方法 Method method = Demo.class.getMethod("getString", String.class); //方法的入参 Object[] parameters = {null}; Set<ConstraintViolation<Demo>> violations = executableValidator.validateParameters( object, method, parameters ); //结果 Iterator<ConstraintViolation<Demo>> iterator = violations.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next().getMessage()); } //执行结果 不能为空