利用Hibernate Validator实现对Bean的参数验证

Bean Validation类库比较

    最近写工程的时候想把对Bean的属性验证加上,就和Grails里面对Domain里面每个值有个验证那样。但自己动手想写的漂亮工作量也不小,想来这么基础的工作肯定有人做过了。上网查了一下就找到jsr303的标准,果然有很成熟的实现类库。看了一圈感觉比较好的有三个,分别是Hibernate Validator、apache bval、spring validator。

    1. spring validator:其实我本来很看好,应该与spring有很好的集成,但是上官网看了一下有点失望,直接使用很麻烦,要一个个写定义文件,比较特色的是与spring mvc集成,可以在Controller层实现验证。

    2. apache bval:也是自己用apache的东西用习惯了,比较倾向于用这个,上官网一看,近期还被提成Top Project了,兴奋的打开文档页就惊呆了,居然大片空白。想必用的人还很少,上手也太有挑战了。

    3. Hibernate Validator:这个大家推荐的比较多,是JBoss的开源项目(近两年发现JBoss出了不少好项目),看了一下文档,非常详细,使用的方法也是我最喜欢的注解。仔细看了一下,就是验证和原先想的出入较大,它必须显示的生产一个Validator对象再去验证Bean对象,仔细想想这样确实也灵活些。

Hibernate Validator的使用

    根据官网的例子走了一下,很快就跑通了。但是发现一个细节问题,开始怎么运行都报Log4j找不到TRACK,后来发现原来log4j必须用log4j-1.2.16.jar或以上版本。

    我用的也很简单,都是一些基本的数据边界验证即可,加上声明的bean非常漂亮。为了简化代码,我把Validator又简单封装了一下。贴一下代码吧,供大家参考。

摘选的Bean代码:

  
  
  
  
  1. public class User { 
  2.      
  3.     @Email(message="邮箱格式验证失败"
  4.     @Size(max=32, message="邮箱长度不能超过32个字符"
  5.     private String email;       // 用户的邮箱 
  6.  
  7.     @NotBlank(message="昵称不能为空"
  8.     @Size(min=4, max=16, message="昵称长度必须在4到16个字符之间"
  9.     private String nickname;    // 昵称 
  10.      
  11.     @NotBlank(message="密码不能为空"
  12.     @Size(min=6, max=16, message="密码长度必须在6个字符至16个字符"
  13.     private String password;    // 登录密码 
  14.      
  15.     public User validate() { 
  16.         ValidateUtil.validate(this); 
  17.         return this
  18.     } 
  19.  
  20.     // 后面省略 
  21.     // ...... 
  22.  

封装的Validator:

  
  
  
  
  1. public class ValidateUtil { 
  2.      
  3.     private static Validator validator; // 它是线程安全的 
  4.  
  5.     static { 
  6.         ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); 
  7.         validator = factory.getValidator(); 
  8.     } 
  9.      
  10.     public static <T> void validate(T t) { 
  11.         Set<ConstraintViolation<T>> constraintViolations = validator.validate(t); 
  12.         if(constraintViolations.size() > 0) { 
  13.             String validateError = ""
  14.             for(ConstraintViolation<T> constraintViolation: constraintViolations) { 
  15.                 validateError += constraintViolation.getMessage() + ";"
  16.             } 
  17.             throw new ValidateException(validateError); 
  18.         } 
  19.     } 
  20.      

 

Android环境的使用

    我本打算是在java和android环境都用起来的,但是折腾了大半天,发现java.beans.Introspector是Hibernate Validator用到的一个核心类,但是这个类缺没有包含在android环境中。对比了一下才发现,android里面有很多j2se的类被裁减了,这也解释了为什么有些jar在android环境下就不能运行。

无奈之下的解决办法:
    1. 改用了Validator 4.2.0的版本,这个版本至少Log类没用到这个,是slf4j的。在调用的地方统一加了系统验证,如果是Dalvik环境就不进行验证。代码如:if(System.getProperty("java.vm.name").equals("Dalvik"))
    2. 在网上搜索了很久,有人提到用jarjar重新打包有可能可以解决,找了点资料看了一下,稍微有点麻烦,有空试一下,如果搞定了再贴出来。

 

参考资料:
1. http://docs.jboss.org/hibernate/validator/4.3/reference/en-US/html/

你可能感兴趣的:(JSR303)