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整合到項目中。如果希望了解更多信息,可以查看一下它們的相關文檔。這里就起到一個拋磚引玉的作用。