Hibernate ClassValidator實(shí)例
Hibernate有很多值得學(xué)習(xí)的地方,這里我們主要介紹Hibernate ClassValidator實(shí)例,包括介紹Spring MVC 控制器使用的 CreditCardValidator等方面。
創(chuàng)建一個(gè)Hibernate ClassValidator實(shí)例
這個(gè)類進(jìn)行實(shí)例化的代價(jià)可能會(huì)很高,因此最好只對(duì)希望進(jìn)行驗(yàn)證的每個(gè)類來進(jìn)行實(shí)例化。一種方法是創(chuàng)建一個(gè)實(shí)用工具類,對(duì)每個(gè)模型對(duì)象存儲(chǔ)一個(gè)Hibernate ClassValidator實(shí)例,如下所示:
處理驗(yàn)證的實(shí)用工具類
- /**
- * Handles validations based on the Hibernate Annotations Validator framework.
- * @author Ted Bergeron
- * @version $Id: AnnotationValidator.java,v 1.5 2006/01/20 17:34:09 ted Exp $
- */
- public class AnnotationValidator {
- private static Log log = LogFactory.getLog(AnnotationValidator.class);
- // It is considered a good practice to execute these lines once and
- // cache the validator instances.
- public static final ClassValidator<Customer> CUSTOMER_VALIDATOR =
- new ClassValidator<Customer>(Customer.class);
- public static final ClassValidator<CreditCard> CREDIT_CARD_VALIDATOR =
- new ClassValidator<CreditCard>(CreditCard.class);
- private static ClassValidator<? extends BaseObject> getValidator(Class<?
- extends BaseObject> clazz) {
- if (Customer.class.equals(clazz)) {
- return CUSTOMER_VALIDATOR;
- }
- else if (CreditCard.class.equals(clazz)) {
- return CREDIT_CARD_VALIDATOR;
- }
- else {
- throw new IllegalArgumentException("Unsupported class was passed.");
- }
- }
- public static InvalidValue[] getInvalidValues(BaseObject modelObject) {
- String nullnullProperty = null;
- return getInvalidValues(modelObject, nullProperty);
- }
- public static InvalidValue[] getInvalidValues(BaseObject modelObject,
- String property) {
- Class<? extends BaseObject>clazz = modelObject.getClass();
- ClassValidator validator = getValidator(clazz);
- InvalidValue[] validationMessages;
- if (property == null) {
- validationMessages = validator.getInvalidValues(modelObject);
- }
- else {
- // only get invalid values for specified property.
- // For example, "city" applies to getCity() method.
- validationMessages = validator.getInvalidValues(modelObject, property);
- }
- return validationMessages;
- }
- }
創(chuàng)建了兩個(gè)Hibernate ClassValidator,一個(gè)用于 Customer,另外一個(gè)用于 CreditCard。這兩個(gè)希望進(jìn)行驗(yàn)證的類可以調(diào)用 getInvalidValues(BaseObject modelObject),會(huì)返回 InvalidValue[]。這則會(huì)返回一個(gè)包含模型對(duì)象實(shí)例錯(cuò)誤的數(shù)組。另外,這個(gè)方法也可以通過提供一個(gè)特定的屬性名來調(diào)用,這樣做會(huì)只返回與該域有關(guān)的錯(cuò)誤。
在使用 Spring MVC 和 Hibernate Validator 時(shí),為信用卡創(chuàng)建一個(gè)驗(yàn)證過程變得非常簡單,如下所示:
Spring MVC 控制器使用的 CreditCardValidator
- /**
- * Performs validation of a CreditCard in Spring MVC.
- *
- * @author Ted Bergeron
- * @version $Id: CreditCardValidator.java,v 1.2 2006/02/10 21:53:50 ted Exp $
- */
- public class CreditCardValidator implements Validator {
- private CreditCardService creditCardService;
- public void setCreditCardService(CreditCardService service) {
- this.creditCardService = service;
- }
- public boolean supports(Class clazz) {
- return CreditCard.class.isAssignableFrom(clazz);
- }
- public void validate(Object object, Errors errors) {
- CreditCard creditCard = (CreditCard) object;
- InvalidValue[] invalids = AnnotationValidator.getInvalidValues(creditCard);
- // Perform "expensive" validation only if no simple errors found above.
- if (invalids == null || invalids.length == 0) {
- boolean validCard = creditCardService.validateCreditCard(creditCard);
- if (!validCard) {
- errors.reject("error.creditcard.invalid");
- }
- }
- else {
- for (InvalidValue invalidValue : invalids) {
- errors.rejectValue(invalidValue.getPropertyPath(),
- null, invalidValue.getMessage());
- }
- }
- }
- }
validate() 方法只需要將 creditCard 實(shí)例傳遞給這個(gè)驗(yàn)證過程,從而返回 InvalidValue 數(shù)組。如果發(fā)現(xiàn)了一個(gè)或多個(gè)這種簡單錯(cuò)誤,那么就可以將 Hibernate 的 InvalidValue 數(shù)組轉(zhuǎn)換成 Spring 的 Errors 對(duì)象。如果用戶已經(jīng)創(chuàng)建了這個(gè)信用卡并且沒有出現(xiàn)任何簡單錯(cuò)誤,就可以將更加徹底的驗(yàn)證委托給服務(wù)層進(jìn)行。這一層可以與商業(yè)服務(wù)提供者一起對(duì)信用卡進(jìn)行驗(yàn)證。
現(xiàn)在我們已經(jīng)看到這個(gè)簡單的模型層注釋是如何平衡到控制器、DAO 和 DBMS 層的驗(yàn)證的。在 Hibernate Doclet 和 Commons Validator 中發(fā)現(xiàn)的驗(yàn)證邏輯的重合現(xiàn)在都已經(jīng)統(tǒng)一到模型中了。盡管這是一個(gè)非常受歡迎的改進(jìn),但是視圖層傳統(tǒng)上來說一直是最需要進(jìn)行詳細(xì)驗(yàn)證的地方。
【編輯推薦】