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 屬性指定消息內容。