1. Hibernate Validator介绍
1.1 背景
在任何时候,当你要处理一个应用程序的业务逻辑,数据校验是你必须要考虑和面对的事情。应用程序必须通过某种手段来确保输入进来的数据从语义上来讲是正确的。在通常的情况下,应用程序是分层的,不同的层由不同的开发人员来完成。很多时候同样的数据验证逻辑会出现在不同的层,这样就会导致代码冗余和一些管理的问题,比如说语义的一致性等。为了避免这样的情况发生,最好是将验证逻辑与相应的域模型进行绑定。
Bean Validation 为 JavaBean 验证定义了相应的元数据模型和API。缺省的元数据是 Java Annotations,通过使用 XML 可以对原有的元数据信息进行覆盖和扩展。Bean Validation 是一个运行时的数据验证框架,在验证之后验证的错误信息会被马上返回。
Hibernate Validator 是 Bean Validation 的参考实现 . Hibernate Validator 提供了 JSR 303 规范中所有内置 constraint 的实现,除此之外还有一些附加的 constraint。
1.2 Bean Validation 中的 constraint
1.3 Hibernate Validator 附加的 constraint
1.4 Hibernate Validator 的优点
a) 验证逻辑与业务逻辑之间进行了分离,降低了程序耦合度;
b) 统一且规范的验证方式,无需你再次编写重复的验证代码;
c) 你将更专注于你的业务,将这些繁琐的事情统统丢在一边。
2. Hibernate Validator实践
2.1 引入相关jar包
maven依赖:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>4.2.0.Final</version>
</dependency>
2.2 SpringMvc中配置
本篇文章的demo是基于springmvc的,需要进行相关配置。
2.3 为JavaBean添加constraint
如图为User添加了几个constraint:对name添加了不为空和长度的约束;对sex添加了自定义的约束,后面会加以介绍;对role的约束为对象内嵌约束。JSR-303的校验是基于注解的,它内部已经定义好了一系列的限制注解,我们只需要把这些注解标记在需要验证的实体类的属性上或是其对应的get方法上。
2.4 自定义的 constraint
如图定义了一个ValidSex的注解,而且该注解上标注了@Constraint注解,使用@Constraint注解标注表明我们定义了一个用于限制的注解。@Constraint注解的validatedBy属性用于指定我们定义的当前限制类型需要被哪个ConstraintValidator进行校验。在上面代码中我们指定了ValidSex限制类型的校验类是ValidSexValidator。另外需要注意的是我们在定义自己的限制类型的注解时有三个属性是必须定义的,如上面代码所示的message、groups和payload属性。
2.5 自定义的 constraint实现类
如图,ConstraintValidator是使用了泛型的。它一共需要指定两种类型,第一个类型是对应的initialize方法的参数类型,第二个类型是对应的isValid方法的第一个参数类型。从上面的两个方法我们可以看出initialize方法是可以获取到当前的限制类型的属性,isValid方法是用于进行校验的。
2.6 对参数进行校验
在上图中我们可以看到我们定义了一个LoginController,该Controller有一个处理validator操作的处理器方法validator,它需要接收客户端发送的一个User对象,我们就是要利用前面的Validator对该User对象进行校验。首先我们可以看到我们validator方法接收的参数user是用@Valid进行标注的。另外我们的处理器方法必须给定包含Errors的参数,这可以是Errors本身,也可以是它的子类BindingResult,使用了Errors参数就是告诉Spring关于表单对象数据校验的错误将由我们自己来处理,否则Spring会直接抛出异常。这样当我们请求处理器方法validator时就会对user对象进行校验,并把相关的校验信息存放到当前的Errors对象中。接着我们就可以在我们的处理器方法中根据是否有校验异常信息来做不同的操作。在上面代码中我们定义了在有异常信息的时候就跳转到登陆页面。这样我们就可以在登陆页面上通过errors标签来展示这些错误信息了。
2.7 注意事项
a) 如果验证的是属性(getter 方法),那么必须遵从 Java Bean 的命名习惯(JavaBeans 规范);
b) 静态的字段和方法不能进行约束验证;
c) 约束适用于接口和基类;
d) 约束注解定义的目标元素可以是字段、属性或者类型等;
e) 可以在类或者接口上使用约束验证,它将对该类或实现该接口的实例进行状态验证;
f) 字段和属性均可以使用约束验证,但是不能将相同的约束重复声明在字段和相关属性(字段的 getter 方法)上。
结束语:善待身边每一个人,因为,是他们成就了你的人生。
可爱博主:AlanLee
博客地址:http://www.cnblogs.com/AlanLee
本文出自博客园,欢迎大家加入博客园。