Spring3.1 对Bean Validation规范的新支持(方法级别验证)

[-]
  1. 一Bean Validation框架简介
  2. 二Bean Validation在开发中的位置
  3. 四Spring30支持表现层验证
  4. 五Spring30支持依赖注入验证Bean Validation 11草案
  5. 六Spring31支持方法级别验证Bean Validation 11草案

一、Bean Validation框架简介

 写道
Bean Validation standardizes constraint definition, declaration and validation for the Java platform.

大体意思是:Bean Validation 标准化了Java平台的约束定义、描述、和验证。

 

详细了解请参考:http://beanvalidation.org/

 

Bean Validation现在一个有两个规范:

 

1、Bean Validation 1.0(JSR-303)

 写道
This JSR will define a meta-data model and API for JavaBeanTM validation based on annotations, with overrides and extended meta-data through the use of XML validation descriptors.

定义了基于注解方式的JavaBean验证元数据模型和API,也可以通过XML进行元数据定义,但注解将覆盖XML的元数据定义。

 

详细了解请参考:http://jcp.org/en/jsr/detail?id=303

 

JSR-303主要是对JavaBean进行验证,如方法级别(方法参数/返回值)、依赖注入等的验证是没有指定的。因此又有了JSR-349规范的产生。

 

2、Bean Validation 1.1(JSR-349)

 写道
Bean Validation standardizes constraint definition, declaration and validation for the Java platform.

Bean Validation 标准化了Java平台的约束定义、描述、和验证。

 

此规范目前处于草案状态,详细了解请参考:http://jcp.org/en/jsr/detail?id=349.

 

该草案现在主要内容:

方法级别验证支持(验证方法参数和和返回值);

依赖注入验证的支持。

  

对Bean Validation的详细介绍可参考Bean Validation官网查看http://beanvalidation.org/


Spring3.1目前已经完全支持依赖注入验证和方法级别验证的支持,只是不是原生的(规范还是草案)。


Bean Validation 1.0的参考实现有Hibernate Validator(下载地址:http://www.hibernate.org/subprojects/validator.html);1.1还处于草案状态。

 

二、Bean Validation在开发中的位置


 


 

 

上图摘自hibernate validator 参考文档,从图中可以看出,我们可以在任何位置实施验证。

 

1、表现层验证:SpringMVC提供对JSR-303的表现层验证;

2、业务逻辑层验证:Spring3.1提供对业务逻辑层的方法验证(当然方法验证可以出现在其他层,但笔者觉得方法验证应该验证业务逻辑);

3、DAO层验证:Hibernate提供DAO层的模型数据的验证(可参考hibernate validator参考文档的7.3. ORM集成)。

4、数据库端的验证:通过数据库约束来进行;

5、客户端验证支持:JSR-303也提供编程式验证支持。

 

对于DAO层和客户端验证支持不在我们示例范围,忽略,感兴趣的同学可以参考《hibernate validator reference》(有中文)。

  

在测试支持大家需要准备好如下jar包:

validation-api-1.0.0.GA.jar

hibernate-validator-4.2.0.Final.jar

 

四、Spring3.0支持表现层验证

可以参考我的《最新SpringMVC + spring3.1.1 + hibernate4.1.0 集成及常见问题总结》或《SpringMVC 使用JSR-303进行校验 @Valid》。

 

此处不再阐述。

 

五、Spring3.0支持依赖注入验证(Bean Validation 1.1草案)

Spring3.0开始支持对依赖注入的依赖进行验证。Spring对依赖注入验证支持请参考《Spring开闭原则的表现-BeanPostProcessor扩展点-2》中的BeanValidationPostProcessor。

 

示例:

1、Bean组件类定义

Java代码   收藏代码
  1. public class UserModel {  
  2.     @NotNull(message = "user.username.null")  
  3.     @Pattern(regexp = "[a-zA-Z0-9_]{5,10}", message = "user.username.illegal")  
  4.     private String username;  
  5.     @Size(min = 5, max=10, message = "password.length.illegal")  
  6.     private String password;  
  7.     //省略setter/getter  
  8. }  

 2、开启依赖注入验证支持(spring-config-bean-validator.xml)

Java代码   收藏代码
  1. <!--注册Bean验证后处理器-->  
  2. <bean class="org.springframework.validation.beanvalidation.BeanValidationPostProcessor"/>  

 3、Bean的XML配置定义(spring-config-bean-validator.xml)

Java代码   收藏代码
  1. <bean id="user" class="com.sishuok.validator.UserModel">  
  2.     <property name="username" value="@"/>  
  3.     <property name="password" value="#"/>  
  4. </bean>  

 4、测试用例

Java代码   收藏代码
  1. @RunWith(value = SpringJUnit4ClassRunner.class)  
  2. @ContextConfiguration(value = {"classpath:spring-config-bean-validator.xml"})  
  3. public class BeanValidatorTest {  
  4.     @Autowired  
  5.     UserModel user;  
  6.     @Test  
  7.     public void test() {  
  8.     }  
  9. }  

 5、运行测试后,容器启动失败并将看到如下异常:

Java代码   收藏代码
  1. java.lang.IllegalStateException: Failed to load ApplicationContext  
  2. ……  
  3. Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'user' defined in class path resource [spring-config-bean-validator.xml]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanInitializationException: Bean state is invalid: password - password.length.illegal; username - user.username.illegal  
  4. ……  
  5. Caused by: org.springframework.beans.factory.BeanInitializationException: Bean state is invalid: password - password.length.illegal; username - user.username.illegal  

 我们可以看出 用户名验证失败。

 

六、Spring3.1支持方法级别验证(Bean Validation 1.1草案)

Spring3.1开始支持方法级别的验证。Spring对方法级别的验证支持请参考《Spring开闭原则的表现-BeanPostProcessor扩展点-2》中的MethodValidationPostProcessor。

 

有了方法级别验证,我们就能够更加简单的在Java世界进行契约式设计了,关于契约式设计请参考《建造无错软件:契约式设计引论》。

 

没有MethodValidationPostProcessor之前我们可能这样验证:

Java代码   收藏代码
  1. public UserModel get(Integer uuid) {  
  2.     //前置条件  
  3.     Assert.notNull(uuid);  
  4.     Assert.isTrue(uuid > 0"uuid must lt 0");  
  5.   
  6.     //获取 User Model  
  7.     UserModel user = new UserModel(); //此处应该从数据库获取  
  8.   
  9.     //后置条件  
  10.     Assert.notNull(user);  
  11.     return user;  
  12. }  

前置条件和后置条件的书写是很烦人的工作。

 

有了MethodValidationPostProcessor之后我们可以这样验证:

Java代码   收藏代码
  1. public @NotNull UserModel get2(@NotNull @Size(min = 1) Integer uuid) {  
  2.     //获取 User Model  
  3.     UserModel user = new UserModel(); //此处应该从数据库获取  
  4.     return user;  
  5. }  

 

前置条件的验证:在方法的参数上通过Bean Validation注解进行实施;

后置条件的验证:直接在返回值上通过Bean Validation注解进行实施。 

非常好,非常好,自此我们可以在Java世界进行更完美的契约式编程了。

 

示例:

1、Service类定义

Java代码   收藏代码
  1. @Validated      //① 告诉MethodValidationPostProcessor此Bean需要开启方法级别验证支持  
  2. public class UserService {  
  3.     public @NotNull UserModel get2(@NotNull @Min(value = 1) Integer uuid) { //②声明前置条件/后置条件  
  4.         //获取 User Model  
  5.         UserModel user = new UserModel(); //此处应该从数据库获取  
  6.         if(uuid > 100) {//方便后置添加的判断(此处假设传入的uuid>100 则返回null)  
  7.             return null;  
  8.         }  
  9.         return user;  
  10.     }  
  11. }  

 2、开启Spring3.1对方法级别验证支持(spring-config-method-validator.xml)

Java代码   收藏代码
  1. <!--注册方法验证的后处理器-->  
  2. <bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor"/>  

 3、Bean的XML配置定义(spring-config-method-validator.xml)

Java代码   收藏代码
  1. <bean id="userService" class="com.sishuok.validator.UserService"/>  

 4、测试用例

Java代码   收藏代码
  1. @RunWith(value = SpringJUnit4ClassRunner.class)  
  2. @ContextConfiguration(value = {"classpath:spring-config-method-validator.xml"})  
  3. public class MethodValidatorTest {  
  4.     @Autowired  
  5.     UserService userService;  
  6.     @Test  
  7.     public void testConditionSuccess() {//① 正常流程   
  8.         userService.get2(1);  
  9.     }  
  10.     @Test(expected = org.hibernate.validator.method.MethodConstraintViolationException.class)  
  11.     public void testPreCondtionFail() { //②错误的uuid(即前置条件不满足)  
  12.         userService.get2(0);  
  13.     }  
  14.   
  15.     @Test(expected = org.hibernate.validator.method.MethodConstraintViolationException.class)  
  16.     public void testPostCondtionFail() { //③不满足后置条件的返回值  
  17.         userService.get2(10000);  
  18.     }  
  19. }  

通过如上测试,我们可以看出Spring3.1已经非常好的支持契约式编程了。

 

注意,在使用方法级别验证时:

1、由于Bean Validation1.1正处于草案状态,Spring3.1无法支持原生的Bean Validation1.1,在未来的Bean Validation1.1发布时会直接使用原生的。

2、Spring3.1需要使用Hibernate Validator 4.2及更高版本。

 

让我们期待Bean Validation 1.1的发布吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值