Bean Validation 技术规范特性概述
http://www.ibm.com/developerworks/cn/java/j-lo-beanvalid/
JSR303 规范(Bean Validation 规范)提供了对 Java EE 和 Java SE 中的 Java Bean 进行验证的方式。该规范主要使用注解的方式来实现对 Java Bean 的验证功能,并且这种方式会覆盖使用 XML 形式的验证描述符,从而使验证逻辑从业务代码中分离出来,如图 2 所示。
图 2. Java Bean 验证模型示意图
JSR303 规范提供的 API 是 Java Bean 对象模型的一般扩展,它并不局限于某一层或者某一编程模型,在服务器端和客户端都可使用,其最大的特点就是易用而且灵活。
Hibernate Validator 4.0 是 JSR303 规范的参考实现,本文所有示例代码均使用该参考实现。
下面给出一个 Bean Validation 的简单示例(清单 1):
清单 1:
?
约束注解应用的目标元素类型包括 METHOD, FIELD, TYPE, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER。METHOD 约束相关的 getter 方法;FIELD 约束相关的属性;TYPE 约束具体的 Java Bean;ANNOTATION_TYPE 用在组合约束中;该规范同样也支持对参数(PARAMETER)和构造器(CONSTRUCTOR)的约束。
验证时的组别属性将在本文第三大部分中组与组序列中详细介绍。
有效负载通常用来将一些元数据信息与该约束注解相关联,常用的一种情况是用负载表示验证结果的严重程度。
清单 4 给出一个验证字符串非空的约束注解的定义:
清单 4:
?
实现多值约束只需要在定义约束注解的同时定义一个 List(@interface List{})。使用该约束注解时,Bean Validation 将 value 数组里面的每一个元素都处理为一个普通的约束注解,并对其进行验证,所有约束条件均符合时才会验证通过。
清单 9 定义了一个约束注解,它用来验证某一字符串是否包含指定的内容。
清单 9:
- Bootstrapping 相关接口
Bootstrapping 相关接口提供 ValidatorFactory 对象,该对象负责创建 Validator(验证器)实例,该实例即是 Bean Validation 客户端用来进行约束验证的主体类。Bootstrapping 相关接口主要包括 5 类,如表 2 所示:
表 2. Bootstrapping 相关接口及其作用接口 作用 javax.validation.validation Bean Validation 规范的 API 默认提供该类,是整个 API 的入口,用来产生 Configuraton 对象实例,并启动环境中 ValidationProvider 的具体实现。 javax.validation.ValidationProviderResolver 返回执行上下文环境中所有的 BeanValidationProviders 的列表,并对每一个 BeanValidationProvider 产生一个对象实例。BeanValidation 规范提供一个默认的实现。 javax.validation.spi.ValidationProvider 具体的 BeanValidationProvider 实现需要实现该接口。该接口用来生成具体的 Congfiguration 接口的实现。 javax.validation.Configuration 收集上下文环境中的配置信息,主要用来计算如何给定正确的 ValidationProvider,并将其委派给 ValidatorFactory 对象。 javax.validation.ValidatorFactory 从一个具体的 BeanValidationProvider 中构建 Validator 的实例。
Validator 接口
该接口(javax.validation.Validator)定义了验证实例的方法,主要包括三种,如表 2 所示:
表 3. Validator 接口中的方法及其作用方法名 作用 <T> Set<ConstraintViolation<T>> validate(T object, Class<?>... groups) 该方法用于验证一个给定的对象 <T>Set<ConstraintViolation<T>> validateProperty(T object, String propertyName, Class<?>...groups) 该方法用于验证给定对象中的字段或者属性 <T> Set<ConstraintViolation<T>> validateValue(Class<T> beanType, String propertyName, Object value, Class<?>... groups) 该方法用于验证给定对象中的属性的具体值
上述两类接口完成验证器的初始化工作,下面使用清单 20 解释上述接口,在本文的示例中均使用 Hibernat Validator4.0 作为参考实现,因此上述两类接口的具体实现均是 Hibernat Validator4.0 包中的类。
清单 20:
ValidatorFactory vf = Validation.buildDefaultValidatorFactory(); Validator validator = vf.getValidator();
清单 20 使用默认的方式创建验证工厂(ValidatorFactory),类 Validation 会检索类路径下面所有的 jar 文件,使用 ValidationProviderResolver 接口的默认实现 DefaultValidationProviderResolver(Bean Validation 规范提供该类)查找 META-INF/services/ 目录中的 javax.validation.spi.ValidationProvider 文件 , 在 Hibernate Validator4.0 中该文件中声明 org.hibernate.validator.HibernateValidator 类为 ValidationProvider 的具体实现,因此 Validation 调用 HibernateValidator 类创建 Configuration 接口的实例,在 Hibernate Validator4.0 中,该实例为 ConfigurationImpl。最后由 ConfigurationImpl 类产生 ValidatorFactory 的实例,在 HibernateValidator4.0 中为 ValidatorFactoryImpl 类。
如果类路径中存在着多个该规范的实现,这就要用到 Configuration 接口去显示指定要使用的具体实现,然后再产生 ValidatorFactory 的实例。如清单 21 所示:
清单 21:
Configuration<HibernateValidatorConfiguration> config = Validation.byProvider(HibernateValidator.class).configure(); ValidatorFactory vf = config.buildValidatorFactory(); Validator validator = vf.getValidator();
如果想实现符合自身业务逻辑的 BeanValidationProvider 检索规则,只需要实现接口 ValidationProviderResolver,而不是仅使用规范提供的默认实现。如清单 22 所示:
清单 22:
Configuration<?> config=Validation.byDefaultProvider().providerResolver( new MyValidationProviderResolver()).configure(); ValidatorFactory vf = config.buildValidatorFactory(); Validator validator = vf.getValidator();
清单 22 中 MyValidationProviderResolver 就是自定义的检索规则,负责告诉 BeanValidation 如何在具体环境中进行 BeanValidationProvider 的查找。
ConstraintViolation 接口该接口(javax.validation.ConstraintViolation)用来描述某一验证的失败信息。对某一个实体对象进行验证的时候,会返回 ConstraintViolation 的集合,如清单 23 所示:
清单 23:
Set<ConstraintViolation<Employee>> set = validator.validate(employee); for (ConstraintViolation<Employee> constraintViolation : set) { System.out.println(constraintViolation.getMessage()); }
MessageInterpolator 接口
该接口(javax.validation.MessageInterpolator)用来将验证过程中的失败消息以可读的方式传递给客户端使用者。Bean Validation 规范提供一个默认的消息解析接口,用户可自定义符合自身业务需求的消息解析机制,只需实现该接口即可,如清单 24 所示。
清单 24:
Configuration<?> config = Validation.byDefaultProvider().configure(); config.messageInterpolator(new MyMessageInterpolator(config .getDefaultMessageInterpolator()));
其中 MyMessageInterpolator 就是自定义的消息解析器,用来完成特定的逻辑。
Bean Validation 规范的输出消息默认从类路径下的 ValidationMessage.properties 文件中读取,用户也可以在约束注解声明的时候使用 message 属性指定消息内容。
回页首
结束语
Bean Validation 规范使用注解的方式使 Java Bean 的验证机制更加灵活而且高效。本文对该规范进行了简单的介绍,旨在为 Java Bean 中业务逻辑验证机制的程序开发提供一个有益的参考。
?
回页首
下载