Java EE 6核心特征:Bean Validation特性概述(1)(4)
Bean Validation 规范接口及其可扩展的实现
本文前面的章节介绍了如何定义约束注解以及如何使用约束进行 Java Bean 验证。对于第三部分中提到的约束验证流程中的接口,本章将给予详细的介绍。
Bean Validation 规范允许用户定制个性化的约束验证,并给出了 4 大类接口供扩展使用。本章将结合 Bean Validation 规范的参考实现 Hibernate Validator4.0 进行说明。图 3 给出了 Bean
Validation 规范的 API 以及 Hibernate4.0 相关实现之间的关系示意图。
图 3. Bean Validation 接口以及 Hibernate4.0 接口实现示意图(查看大图)
1. 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 的实例。 |
2. Validator 接口
该接口(javax.validation.Validator)定义了验证实例的方法,主要包括三种,如表 2 所示:
表 3. Validator 接口中的方法及其作用
方法名 | 作用 |
该方法用于验证一个给定的对象 | |
该方法用于验证给定对象中的字段或者属性 | |
该方法用于验证给定对象中的属性的具体值 |
上述两类接口完成验证器的初始化工作,下面使用清单 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
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 的查找。
3. ConstraintViolation 接口
该接口(javax.validation.ConstraintViolation)用来描述某一验证的失败信息。对某一个实体对象进行验证的时候,会返回 ConstraintViolation 的集合,如清单 23 所示:
清单 23:
- Set
> set = validator.validate(employee); - for (ConstraintViolation
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 属性指定消息内容。
用户点评