Hibernate项目中不仅有ORM一个框架,这里介绍的是它的另一个框架Validator,用来验证实体类是否满足需求。Validator实现了Java的一项标准Bean Validation。
如果使用Maven,就需要在pom.xml中添加如下一段,Hibernate需要Java EL表达式,因此需要添加EL的依赖项。
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.3.4.Final</version>
</dependency>
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>2.2.4</version>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>javax.el</artifactId>
<version>2.2.4</version>
</dependency>
如果使用Gradle,需要将上面的依赖项转换一下。
compile group: 'org.hibernate', name: 'hibernate-validator', version: '5.3.4.Final'
compile group: 'javax.el', name: 'javax.el-api', version: '3.0.1-b04'
compile group: 'org.glassfish.web', name: 'javax.el', version: '2.2.6'
添加依赖之后,就可以在实体类中添加条件注解了。常用的几个注解如下:
注解 | 作用 |
---|---|
AssertTrue | 布尔值为真 |
AssertFalse | 布尔值为假 |
Null | 引用为空 |
NotNull | 引用不为空 |
NotEmpty | 字符串引用和值都不是空 |
Min | 数字的最小值 |
Max | 数字的最大值 |
Past | 日期必须是过去 |
Future | 日期必须是未来 |
Pattern | 字符串必须匹配正则表达式 |
Valid | 递归验证引用 |
Size | 验证字符串是否在Size范围内 |
验证字符串是否是一个有效的电子邮箱 | |
URL | 字符串是否是一个有效的URL |
需要注意最后两个注解是Hibernate Validator自定义的,假如使用其他的Bean Validation实现,可能没有这两个注解。
下面向两个实体类添加了验证注解,其他方法已经省略了。和JPA注解一样,如果验证注解添加到字段上,Hibernate就会直接读取字段的值。如果注解到Getter方法上,Hibernate就会调用方法取得值。在一个类中不要同时应用这两种方式,会导致重复验证的问题。如果在一个集合上应用Valid注解, Hibernate就会递归验证集合中的每一个元素。
public class Author {
@NotNull
@Size(min = 6, max = 15)
@Pattern(regexp = "([a-zA-Z]+\d*)+")
private String username;
@NotNull
@Size(min = 6, max = 20)
private String password;
@NotNull
private String nickname;
@Email
private String email;
@Min(0)
private int age;
@Size(max = 500)
private String address;
@Past
@NotNull
private Date birthday;
@Valid
@NotNull
private List<Article> articles = new ArrayList<>();
}
public class Article {
@NotNull
private String title;
@NotNull
private String content;
@NotNull
private Author author;
@Past
private Date createTime;
@Past
private Date modifyTime;
}
向实体类添加了验证注解之后,我们就可以开始验证了。首先需要构造一个ValidatorFactory,然后使用构造出的ValidatorFactory生成一个Validator,然后调用这个Validator的validate方法,就可以验证实体类了。validate方法会返回一个Set<ConstraintViolation>,每一个ConstraintViolation都是一个验证结果,如果实体类没有错误,那么这个集合的大小就是0,表示验证通过。如果存在错误,我们就可以通过这个集合来查看存在什么错误。
public class ValidatorTest {
private static ValidatorFactory factory;
private static Validator validator;
private static Logger logger;
@BeforeClass
public static void init() {
factory = Validation.buildDefaultValidatorFactory();
validator = factory.getValidator();
logger = LoggerFactory.getLogger(ValidatorTest.class);
}
@AfterClass
public static void clean() {
factory.close();
}
@Test
public void testKindsOfErrors() {
Author author = new Author();
author.setUsername("123");
author.setPassword("1234");
author.setAddress("");
author.setEmail("");
author.setArticles(null);
author.setAge(-20);
Set<ConstraintViolation<Author>> set = validator.validate(author);
for (ConstraintViolation<Author> c : set) {
logger.info(c.toString());
}
}
@Test
public void testAllRight() {
Author author = new Author();
author.setUsername("yitian");
author.setPassword("12345678");
author.setAddress("");
author.setNickname("");
author.setEmail("yitian@yitian.com");
author.setBirthday(new Date());
Set<ConstraintViolation<Author>> set = validator.validate(author);
for (ConstraintViolation<Author> c : set) {
logger.info(c.toString());
}
Assert.assertEquals(0, set.size());
}
@Test
public void testOneProperty() {
Author author = new Author();
author.setUsername("yitian");
Set<ConstraintViolation<Author>> set = validator.validateProperty(author, "username");
for (ConstraintViolation<Author> c : set) {
logger.info(c.toString());
}
}
@Test
public void testCustomMessage() {
Article article = new Article();
LocalDate date = LocalDate.of(2099, 1, 1);
article.setModifyTime(Date.from(date.atStartOfDay(ZoneId.systemDefault()).toInstant()));
Set<ConstraintViolation<Article>> set = validator.validateProperty(article, "modifyTime");
for (ConstraintViolation<Article> c : set) {
logger.info(c.toString());
}
}
}
以上就是一个简单的验证的例子。通过这个例子,大家应该明白了Hibernate Validator的基本内容。很多框架比如Spring也提供了相关的内容,能方便的将Hibernate Validator整合到项目中。如果希望了解更多信息,可以查看一下它们的相关文档。这里就起到一个抛砖引玉的作用。