Hibernate 验证器文档
前言:
Annotations 是为域对象指定一个不变约束的便利而优雅的途径.例如通过它,你可以表示一个属性不应该是Null值,账户余额绝对不能是负值,等等。这些域模型的约束通过注释它的属性声明在bean自身。验证器可以读取这些注释并检查约束违反性。验证机制可以在没有重复这些规则的情况下在应用程序的不同层里执行(表示层,数据访问层).Hibernate验证器在遵循DRY规则的情况下设计.
Hibernate 验证器工作在两个级别。首先,它能检测位于内存的类实例的约束违反性.其次,它可以把约束应用在hibernate的元模型中并且把它们应用在生成的数据库中.
每一个约束注释都与一个为检查实体实例而实现的验证器对应关联。一个验证器也可以可选的应用约束到hibernate元模型,允许hibernate生成DDL来表达这些约束。利用合适的事件监听器,你可以通过hibernate在插入或更新的时候检查约束性。Hibernate验证器没有限定在必须配合hibernate执行验证。你也可以容易的把它用在其他java的持久化提供者上面(实现了实体监听器).
在运行期检查实例时,hibernate验证器把有关违反验证的信息放在一个InvalidValue类型的数组里返回.在其他信息中,InvalidValue所包含的错误描述消息可以嵌入参数值和注释绑定,并且消息字符串可以以资源文件的形式提供.
第一章 定义约束
1.1 什么是约束
约束是一个给定的元素(可以使field,property,或bean)所必须遵循的规则.规则的语义可以由注释表达。约束通常有一些属性用来参数化约束限制。这些约束应用到被注释的元素。
1.2 内建约束
与Hibernate 验证器一起内建了一些约束,他们已经覆盖了大多数基本的数据检查,当然我们后来会看到,你不一定使用它们,你可以在一分钟内写出你自己的约束。
表 1.1. 内建约束
注释
用于
运行时检查
Hibernate Metadata 兼容
@Length(min=, max=)
property (字符串)
检查是字符串长度范围
列长度被设置到最大
@Max(value=)
property (数字,或代表数字的字符串)
检查值是否=或<max
在列上添加一个约束
@Min(value=)
property (数字,或代表数字的字符串)
检查值是否=或>min
在列上添加一个约束
@NotNull
property
是否null
列不为null
@NotEmpty
property
字符串不空或非NULl
链接不空或非null
对字符列非null约束
@Past
property (date 或 calendar)
检查是否日期在过去
在列上添加一个约束
@Future
property (date 或 calendar)
检查是否日期在将来
无
@Pattern(regex="regexp", flag=) or @Patterns( {@Pattern(...)} )
property (字符串)
检查是否属性匹配规则表达式给定的匹配标志 (see java.util.regex.Pattern )
无
@Range(min=, max=)
property (数字,或代表数字的字符串)
是否值min<=value<=max
在列上添加一个约束
@Size(min=, max=)
property (数组, 集合, map)
Min<=Size<=max
无
@AssertFalse
property
检查方法计算到false (多用在代码里检查约束)
无
@AssertTrue
property
检查方法计算到true (多用在代码里检查约束)
none
@Valid
property (对象)
在一个关联对象上递归的执行检验.如果对象是一个数组或者集合,对象将被递归的检验. 如果对象是一个map,元素将被递归的验证.
none
@Email
property (String)
检查是否字符创符合email规范
none
@CreditCardNumber
property (String)
字符串是否一个格式好的信誉卡号码(derivative of the Luhn algorithm)
none
@Digits
property (数字,或代表数字的字符串)
数字是否符合整数部分和小数部分的精度
定义列精度和范围
@EAN
property (字符串)
字符是否是格式化的 EAN 或者 UPC-A 编码
none
@Digits
property (numeric or string representation of a numeric)
check whether the property is a number having up to integerDigits integer digits and fractionalDigits fractonal digits
define column precision and scale
1.3.错误消息
随Hibernate 验证器一起的有一个被翻译成十种语言的默认错误消息(如果没有你所在地区的语言,请发送给我们一个补丁)你可以通过创建一个ValidatorMessages.properties( ValidatorMessages_loc.properties )文件覆盖这些消息,甚至当你在写你的验证器注释的时候你可以添加你自己的消息集合。如果hibernate验证器在你的资源文件里或者ValidatorMessage里不能找到一个key的对应值,那么他将返回默认的内建值。
作为选择,当你程序化在一个bean上检查验证规则或者你要一个完全不同的修改机制时你可以提供一个资源绑定,你可以提供一个org.hibernate.validator.MessageInterpolator接口的实现。
1.4. 定义你的约束
扩展内建的约束集合非常容易,任何约束有两个固定的部分:约束描述器(注释)
和约束验证器(实现的类)下面是一个简单的用户定义的描述器,
@ValidatorClass(CapitalizedValidator.class)
@Target(METHOD)
@Retention(RUNTIME)
@Documented
public @interface Capitalized {
CapitalizeType type() default Capitalize.FIRST;
String message() default "has incorrect capitalization"
}
Type 是一个描述属性如何被使用的参数,这是一个用户的参数完全依赖注释业务
Message用来描述约束违反强制性的默认字符串,你可以硬编码或者部分或者全部利用资源绑定机制。参数值将被注入消息里面当{parameter}字符串被找到(在我们的例子Capitalization is not {type} 将产生 Capitalization is not FIRST )把所有字符串都放在属性文件ValidatorMessages.properties是个好的实践.
@ValidatorClass(CapitalizedValidator.class)
@Target(METHOD)
@Retention(RUNTIME)
@Documented
public @interface Capitalized {
CapitalizeType type() default Capitalize.FIRST;
String message() default "{validator.capitalized}";
}
#in ValidatorMessages.properties
validator.capitalized = Capitalization is not {type}
然后你可以看见{}符号是递归的
为了链接一个描述器到他的验证器实现我们用@ValidatorClass元注释验证器类必须命名一个实现了Validator<ConstraintAnnotation>的类。
public class CapitalizedValidator
implements Validator<Capitalized>, PropertyConstraint {
private CapitalizeType type;
//part of the Validator<Annotation> contract,
//allows to get and use the annotation values
public void initialize(Capitalized parameters) {
type = parameters.type();
}
//part of the property constraint contract
public boolean isValid(Object value) {
if (value==null) return true;
if ( !(value instanceof String) ) return false;
String string = (String) value;
if (type == CapitalizeType.ALL) {
return string.equals( string.toUpperCase() );
}
else {
String first = string.substring(0,1);
return first.equals( first.toUpperCase();
}
}
}
isValid()方法应该返回false如果约束已经被违反,更多的例子请参考内建验证器实现.
我们明白属性级别的验证,但是你可以写一个bean级别的验证注释。替代于接受返回的实例属性,bean自身将被传进验证器。为了激活验证检查,仅仅替代的注释bean自身。在单元测试里有一个小的例子。
如果你的约束可以在一些属性或者类型上被应用多次(用不同的参数)你可以用下面的注释形式
@Target(METHOD)
@Retention(RUNTIME)
@Documented
public @interface Patterns {
Pattern[] value();
}
@Target(METHOD)
@Retention(RUNTIME)
@Documented
@ValidatorClass(PatternValidator.class)
public @interface Pattern {
String regexp();
}
基本上,注释以一个验证器注释数组的形式包含值属性
1.5 注释域模型
由于你现在已经熟悉了注释,下面语法应该是非常熟悉的
public class Address {
private String line1;
private String line2;
private String zip;
private String state;
private String country;
private long id;
// a not null string of 20 characters maximum
@Length(max=20)
@NotNull
public String getCountry() {
return country;
}
// a non null string
@NotNull
public String getLine1() {
return line1;
}
//no constraint
public String getLine2() {
return line2;
}
// a not null string of 3 characters maximum
@Length(max=3) @NotNull
public String getState() {
return state;
}
// a not null numeric string of 5 characters maximum
// if the string is longer, the message will
//be searched in the resource bundle at key 'long'
@Length(max=5, message="{long}")
@Pattern(regex="[0-9]+")
@NotNull
public String getZip() {
return zip;
}
// should always be true
@AssertTrue
public boolean isValid() {
return true;
}
// a numeric between 1 and 2000
@Id @Min(1)
@Range(max=2000)
public long getId() {
return id;
}
}
然而这个例子仅仅演示了共用的属性验证,你也可以以可见的形式注释
@MyBeanConstraint(max=45
public class Dog {
@AssertTrue private boolean isMale;
@NotNull protected String getName() { ... };
...
}
也可以注释接口,hibernate验证器将检查所有实现此接口的子类或子接口通过一个给定的bean来读取合适的验证注释。
public interface Named {
@NotNull String getName();
...
}
public class Dog implements Named {
@AssertTrue private boolean isMale;
public String getName() { ... };
}
Dog类的Name属性将被检查null约束
第一章 使用验证框架
Hibernate验证器有意被用来实现多层数据验证,这些数据约束位于仅一个地方(被注释的域模型)并且在应用的不同层被检查。
这章我们将涵盖hibernate验证器在不同层的使用
2.1数据库模式级别验证
Out of the box ,hibernate验证器将把你为你的实体定义的约束传进映射元数据,例如,如果你实体的一个属性被注释为@NotNull 他的列将被声明为 not null 在由hibernate生成的 DDL 里。
使用 hbm2ddl,域模型约束将被在数据库中表示。
如果 ,因为某些原因,这些特征需要禁用,设置
hibernate.validator.apply_to_ddl 为 false
2.2 ORM 集成
Hibernate 验证器与hibernate和所有纯java的持久化提供者集成。
2.2.1基于hibernate事件的验证
Hibernate验证器已经内置两个hibernate事件监听器,任何时候一个PreInsertEvent 或者 PreUpdateEvent事件发生,监听器将确认这个实例的所
有约束并且在当任何约束被违反的时候抛出一个异常。一般地,对象将在由hibernate进行的插入和更新前被检查。这个将被级联的应用。这是激活验证流程最方便和容易的途径。在验证违反发生时,事件将抛出一个包含了用来描述每个失败消息的InvalidValues类型的数组的InvalidStateException类型的运行期异常。
如果hibernate 验证器被放在类路径里,Hibernate Annonations(或Hibernate EntityManager)将透明的使用他,如果由于某些原因需要禁用这个集成特征设置hibernate.validator.autoregister_listeners 为 false
注意:如果beans没有用验证注释注释,将不会有运行时性能消耗
在这种情况下你需要手工为hibernate设置事件监听器,下面是配置
<hibernate-configuration>
...
<event type="pre-update">
<listener
class="org.hibernate.validator.event.ValidateEventListener"/>
</event>
<event type="pre-insert">
<listener
class="org.hibernate.validator.event.ValidateEventListener"/>
</event>
</hibernate-configuration>
2.2.2 基于事件的java持久化验证
Hibernate 验证器与hibernate在基于事件的验证上没有关联,一个java持久化实体监听器是可用的。任何时候一个被监听的实体被持久化或者更新,hibernate验证器将确认所有此实体实例的约束并且在约束别违反的时候抛出异常,一般地,对象将在由java持久化提供者进行的插入和更新前被检查。这个将被级联的应用。在验证违反发生时,事件将抛出一个包含了用来描述每个失败消息的InvalidValues类型的数组的InvalidStateException类型的运行期异常。
如何使一个类可验证
@Entity
@EntityListeners( JPAValidateListener.class )
public class Submarine {
...
}
注意:与hibernate事件相比 java 持久化监听器有两个缺点。你需要为每个可验证的实体定义一个实体监听器。由你的提供者生成的DDL 将不会反射这些约束.
2.3 应用程序级别的验证
Hibernate 验证器可被应用到代码的任何地方
ClassValidator personValidator = new ClassValidator( Person.class );
ClassValidator addressValidator = new ClassValidator( Address.class, ResourceBundle.getBundle("messages", Locale.ENGLISH) );
InvalidValue[] validationMessages = addressValidator.getInvalidValues(address);
前两行为类检查预备hibernate验证器,第一个的错误消息依赖于内嵌的hibernate验证器,第二个用一个资源文件的错误消息。执行一次并且缓存这些验证器实例是好的实践。
第三行实际上验证了address类的实例并且返回了一个InvalidValues类型的数组。应用程序逻辑将能重激活到失败。
你也可以检查一个属性而非整个bean 这对属性对属性的用户交互是有用的。
ClassValidator addressValidator = new ClassValidator( Address.class, ResourceBundle.getBundle("messages", Locale.ENGLISH) );
//only get city property invalid values
InvalidValue[] validationMessages = addressValidator.getInvalidValues(address, "city");
//only get potential city property invalid values
InvalidValue[] validationMessages = addressValidator.getPotentialInvalidValues("city", "
Paris
")
2.4 表示层验证
当使用jsf和jboss seam 时,你可以触发验证流程在表示层使用seam的jsf标签
<s:validate> 和 <s:validateAll/> 让约束表示在模型里,违反出现在表示层。
<h:form>
<div>
<h:messages/>
</div>
<s:validateAll>
<div>
Country:
<h:inputText value="#{location.country}" required="true"/>
</div>
<div>
Zip code:
<h:inputText value="#{location.zip}" required="true"/>
</div>
<div>
<h:commandButton/>
</div>
</s:validateAll>
</h:form>
不久将来,将添加Ajax4JSF 到循环将带来客户端验证利用一对附加的jsf标签,避免验证定义重复。请看jboss seam 更多信息。
2.5. 验证信息
作为一个验证信息携带者,hibernate提供了一个InvalidValue类型的数组,每一个InvalidValue 有许多方法来描述独立的发布
As a validation information carrier, hibernate provide an array of InvalidValue. Each InvalidValue has a buch of methods describing the individual issues.
getBeanClass() 得到失败的bean类型
getBean()retrieves the failing instance (if any ie not when using getPotentianInvalidValues())
getValue() retrieves the failing value
getMessage() retrieves the proper internationalized error message
getRootBean() retrieves the root bean instance generating the issue (useful in conjunction with @Valid), is null if getPotentianInvalidValues() is used.
getPropertyPath() retrieves the dotted path of the failing property starting from the root bean
原文来在:http://www.duduwolf.com/wiki/2007/345.html 注意:版权归原作者所有
分享到:
- 2008-02-27 09:57
- 浏览 7346
- 评论(1)
- 论坛回复 / 浏览 (0 / 9261)
- 查看更多
相关推荐
本篇将通过实例和讲解来详细介绍 Hibernate Validation 的使用方法和核心概念。 **1. 安装与引入** 在 Maven 项目中,可以通过添加以下依赖来引入 Hibernate Validation: ```xml <groupId>javax.validation ...
文档列举了引用 Hibernate Validation各注解的用法,完成对实体约束验证的配置。
而Hibernate Validation则是Java世界中用于数据验证的主流库,它基于JSR 303和JSR 349标准,提供了丰富的验证规则和易于使用的API。在Spring MVC中集成Hibernate Validation,可以实现对输入数据的有效性检查,从而...
其次,Hibernate Validation是Java Bean Validation的标准实现,它提供了一种在运行时验证对象属性的方法。Resin服务器支持Hibernate Validation,允许开发者对输入数据进行细粒度的验证,确保数据的完整性和一致性...
Hibernate Validator是Hibernate项目的一部分,主要提供了对Java Bean Validation规范的实现。此规范是在Java平台上定义了一套注解和API来校验数据的完整性和准确性。Bean Validation是一种声明式的数据验证方式,...
Bean Validation 规范对 Java Bean 的验证流程如下:在实际使用中调用 Validator.validate(JavaBeanInstance) 方法后,Bean Validation 会查找在 JavaBeanInstance上所有的约束声明,对每一个约束调用对应的约束验证...
这主要是通过使用Hibernate Validator来实现数据的验证,它是一个遵循JSR 303(Java Bean Validation)和JSR 349(Java Bean Validation 1.1)标准的实现。本教程将详细介绍如何在Spring MVC中配置并使用Hibernate ...
1. **约束注解**:Hibernate Validation提供了多种内置的约束注解,如`@NotNull`、`@Size`、`@Min`、`@Max`等,可以直接在bean的属性上使用,以声明验证规则。 2. **自定义验证注解**:除了预定义的注解,开发者还...
JAVA中通过Hibernate-Validation进行参数验证 JAVA中通过Hibernate-Validation进行参数验证是JAVA服务器端代码开发中的一种常用技术。在开发JAVA服务器端代码时,我们会遇到对外部传来的参数合法性进行验证,而...
Hibernate允许开发人员在Java应用程序中使用面向对象的方式操作数据库,消除了传统的JDBC代码与SQL之间的繁琐对接。在这个文档中,我们将深入探讨其核心概念、配置、实体管理以及查询语言等方面。 首先,文档会讲解...
`validation`通常指的是Hibernate Validation框架,这是一个符合JSR 303和JSR 349标准的Java Bean验证实现。它允许开发者定义一组约束规则,并在运行时自动检查这些规则,如果违反规则,就会抛出异常。这个框架不仅...
总结来说,"javax.validation-1.0.0.GA.jar"是Java Bean Validation API的实现,与Hibernate Validator一起,为Java应用提供了强大的数据验证能力。配合JSR 94,可以构建出灵活且可扩展的验证和业务规则处理系统。在...
- **XML配置文件**:介绍Hibernate配置文件的结构和用法。 #### 四、持久化类(Persistent Classes) - **POJO简单示例** - **为持久化字段声明访问器和是否可变的标志**:解释了如何通过getter和setter方法暴露实体...
Spring Validator则集成了Hibernate Validator,使得我们可以利用Spring的依赖注入和AOP特性轻松地在Spring应用中使用Bean Validation。在Spring配置中启用Validator后,我们可以在Service层或者Controller层进行...
5. **数据校验**:Validation是Java中用于数据验证的框架,如使用JSR-303/JSR-349(Bean Validation)标准,我们可以为实体类的属性添加校验注解,如@NotNull、@Size、@Pattern等,然后在导入数据时,通过Validator...
《Hibernate Validator 使用指南》 Hibernate Validator 是一个强大的Java Bean验证框架,它基于JSR-303(Bean Validation)标准,提供了丰富的验证规则和自定义约束能力,使得开发者能够更方便地对Java对象进行...
这时可以通过`Validation.byProvider().configure().buildValidatorFactory()`的方式,明确指出使用Hibernate Validator或其他特定的验证提供器。 #### 简单示例解析 下面是一个简单的Bean Validation使用示例: ...
### Java EE 6 中 Bean Validation (JSR 303) 深度解析 #### 一、Bean Validation 概览 ...对于任何希望提升 Java 应用程序质量的开发者来说,掌握 Bean Validation 的使用方法都是非常有价值的。
3. **hibernate-validator.jar**:实现了JSR 303/349 Bean Validation规范,用于验证实体对象的属性。它可以与Hibernate一起使用,提供数据校验功能。 4. **javassist.jar**:这是一个代码生成和转换库,Hibernate...