<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Ryan's Java world!

    something about Java and opensource!

    BlogJava 首頁 新隨筆 聯系 聚合 管理
      51 Posts :: 25 Stories :: 59 Comments :: 0 Trackbacks

    任何獲得Matrix授權的網站,轉載請保留以下作者信息和鏈接:
    作者:icess(作者的blog:http://blog.matrix.org.cn/page/icess)
    關鍵字:Hibernate Validator

    在前一篇文章 < Hibernate Validator 簡介 > http://www.matrix.org.cn/resource/article/44/44153_Hibernate%20Validator%20.html中,我們看到了Hibernate Validator的使用方法,和自定義驗證Annotation的實現以及錯誤消息的國際化等常見問題.

    在使用如此優雅的屬性驗證框架的同時,你是否想了解她的細節呢?她究竟是怎么實現的呢? 那么現在就跟隨我來探探她的內核吧!

    Hibernate Validator 可以是一個獨立的驗證框架, 所以看完這篇分析 你可以把她獨立出來作為你的個人驗證框架來使用了 ^_^(如果你有興趣和時間的話). Hibernate Validator 框架里面有兩個主要的類: ClassValidator 和InvalidValue 還有一個接口Validator,在這三個主要的構件中 最主要的就只有一個 那就是ClassValidator.另外兩個是很好理解的..

    現在就讓我們開始吧. 遵循由淺入深的習慣 我們先看看 Validator 接口吧. 其代碼如下:

    import? java.lang.annotation.Annotation;

    /**
    ? *?A?constraint?validator?for?a?particular?annotation
    ? *
    ? *? @author? Gavin?King
    ? */
    public?interface? Validator<A? extends? Annotation>?{
    ?? /**
    ??? *?does?the?object/element?pass?the?constraints
    ??? */
    ?? public?boolean? isValid(Object?value);

    ?? /**
    ??? *?Take?the?annotations?values
    ??? *? @param? parameters
    ??? */
    ?? public?void? initialize(A?parameters);
    }

    Validator接口就是我們自定義約束的實現類要繼承的接口,該接口在< Hibernate Validator 簡介 > http://www.matrix.org.cn/resource/article/44/44153_Hibernate%20Validator%20.html 中已經討論過了,請參考.

    InvalidValue 類 大家看名字就應該可以猜到她的作用了吧. 她就是代表一個沒有通過驗證的錯誤實例.該類定義了一些方法,通過這些方法你可以取得與該Validator Annotation 有關的一些參數,如:她所注釋的屬性的值,錯誤消息等等. 該類的源代碼如下:

    import? java.io.Serializable;

    /**
    ? *?A?single?violation?of?a?class?level?or?method?level?constraint.
    ? *
    ? *? @author? Gavin?King
    ? */
    public?class? InvalidValue? implements? Serializable?{
    ?? private?final? String?message;
    ?? private?final? Object?value;
    ?? private?final? String?propertyName;
    ?? private?final? Class?beanClass;
    ?? private?final? Object?bean;
    ?? private? Object?rootBean;

    ?? public? Object?getRootBean()?{
    ???? return? rootBean;
    ?? }

    ?? public? String?getPropertyPath()?{
    ???? return? propertyPath;
    ?? }

    ?? private? String?propertyPath;

    ?? public? InvalidValue(String?message,?Class?beanClass,?String?propertyName,?Object?value,?Object?bean)?{
    ???? this .message?=?message;
    ???? this .value?=?value;
    ???? this .beanClass?=?beanClass;
    ???? this .propertyName?=?propertyName;
    ???? this .bean?=?bean;
    ???? this .rootBean?=?bean;
    ???? this .propertyPath?=?propertyName;
    ?? }

    ?? public?void? addParentBean(Object?parentBean,?String?propertyName)?{
    ???? this .rootBean?=?parentBean;
    ???? this .propertyPath?=?propertyName?+? "."? +? this .propertyPath;
    ?? }

    ?? public? Class?getBeanClass()?{
    ???? return? beanClass;
    ?? }

    ?? public? String?getMessage()?{
    ???? return? message;
    ?? }

    ?? public? String?getPropertyName()?{
    ???? return? propertyName;
    ?? }

    ?? public? Object?getValue()?{
    ???? return? value;
    ?? }

    ?? public? Object?getBean()?{
    ???? return? bean;
    ?? }

    ?? public? String?toString()?{
    ???? return? propertyName?+? '?'? +?message;
    ?? }

    }

    然后,就讓我們看看最主要的類吧:ClassValidator . 該類代碼有400余行,我都做了詳細的注釋如下:

    import? 該部分省略了;


    /**
    ? *?Engine?that?take?a?bean?and?check?every?expressed?annotation?restrictions
    ? *
    ? *? @author? Gavin?King
    ? */
    public?class? ClassValidator<T>? implements? Serializable?{
    ?? private?static? Log?log?=?LogFactory.getLog(?ClassValidator. class? );
    ?? private?static?final? InvalidValue[]?EMPTY_INVALID_VALUE_ARRAY?=? new? InvalidValue[]{};
    ?? private?final? Class<T>?beanClass;
    ?? private?transient? ResourceBundle?messageBundle;
    ?? private?transient?boolean? defaultResourceBundle;

    ?? private?final?transient? Map<Class,?ClassValidator>?childClassValidators;
    ?? private?transient? List<Validator>?beanValidators;
    ?? private?transient? List<Validator>?memberValidators;
    ?? private?transient? List<Member>?memberGetters;
    ?? private?transient? Map<Validator,?String>?messages;
    ?? private?transient? List<Member>?childGetters;
    ?? private?static?final? String?DEFAULT_VALIDATOR_MESSAGE?=? "org.hibernate.validator.resources.DefaultValidatorMessages" ;


    ?? /**
    ??? *?create?the?validator?engine?for?this?bean?type
    ??? */
    ?? public? ClassValidator(Class<T>?beanClass)?{
    ???? this (?beanClass,? null? );
    ?? }

    ?? /**
    ??? *?create?the?validator?engine?for?a?particular?bean?class,?using?a?resource?bundle
    ??? *?for?message?rendering?on?violation
    ??? */
    ?? public? ClassValidator(Class<T>?beanClass,?ResourceBundle?resourceBundle)?{
    ???? this (?beanClass,?resourceBundle,? new? HashMap<Class,?ClassValidator>()?);
    ?? }

    ?? protected? ClassValidator(
    ?????? Class<T>?beanClass,?ResourceBundle?resourceBundle,?Map<Class,?ClassValidator>?childClassValidators
    ?? )?{
    ???? this .beanClass?=?beanClass;
    ???? this .messageBundle?=?resourceBundle?==? null? ?
    ???????? getDefaultResourceBundle()?:
    ???????? resourceBundle;
    ???? this .childClassValidators?=?childClassValidators;
    ???? initValidator(?beanClass,?childClassValidators,? this .messageBundle?);? //重要的是該初始化函數
    ?? }

    ?? private? ResourceBundle?getDefaultResourceBundle()?{
    ???? ResourceBundle?rb;
    ???? try? {
    ?????? rb?=?ResourceBundle.getBundle(? "ValidatorMessages"? );
    ???? }
    ???? catch (?MissingResourceException?e)?{
    ?????? //the?user?did?not?override?the?default?ValidatorMessages
    ?????? log.debug(? "ResourceBundle?ValidatorMessages?not?found.?Delegate?to?"? +?DEFAULT_VALIDATOR_MESSAGE);
    ?????? rb?=?ResourceBundle.getBundle(?DEFAULT_VALIDATOR_MESSAGE?);
    ???? }
    ???? defaultResourceBundle?=? true ;
    ???? return? rb;
    ?? }

    ?? private?void? initValidator(
    ?????? Class<T>?beanClass,?Map<Class,?ClassValidator>?childClassValidators,
    ?????? ResourceBundle?resourceBundle
    ?? )?{
    ???? beanValidators?=? new? ArrayList<Validator>();? //?保存類級別的驗證約束實現類
    ???? memberValidators?=? new? ArrayList<Validator>();? //?保存方法級別的驗證約束實現類
    ???? memberGetters?=? new? ArrayList<Member>(); //?保存類的成員(字段or方法)和構造函數方法的標識信息
    ???? messages?=? new? HashMap<Validator,?String>();? //?利用Map保存與每個Validator相對應的驗證消息
    ???? childGetters?=? new? ArrayList<Member>(); //??保存子類的成員(字段or方法)和構造函數方法的標識信息

    ???? childClassValidators.put(?beanClass,? this? );? //map?Map<Class,?ClassValidator>?childClassValidators;
    ???? Annotation[]?classAnnotations?=?beanClass.getAnnotations();
    ???? for? (? int? i?=? 0 ;?i?<?classAnnotations.length?;?i++?)?{
    ?????? Annotation?classAnnotation?=?classAnnotations[i];
    ????? Validator?beanValidator?=?createValidator(?classAnnotation?); //根據Annotation來得到Validator,參考對該函數的解釋
    ?????? if? (?beanValidator?!=? null? )?beanValidators.add(?beanValidator?); //保存該Validator
    ???? }
    ???? //build?the?class?hierarchy?to?look?for?members?in
    ???? Collection<Class>?classes?=? new? HashSet<Class>();
    ???? addSuperClassesAndInterfaces(?beanClass,?classes?); //把beanClass的所有超類和實現的接口添加的集合classes中

    ???? //Check?on?all?selected?classes
    ???? for? (?Class?currClass?:?classes?)?{
    ?????? Method[]?methods?=?currClass.getDeclaredMethods(); //?掃描Method上面的注釋
    ?????? for? (? int? i?=? 0 ;?i?<?methods.length?;?i++?)?{
    ???????? Method?method?=?methods[i];
    ???????? createMemberValidator(?method?);? //?創建方法上的約束實現類(Validator),?參考對該函數的解釋
    ???????? Class?clazz?=?method.getReturnType(); //?得到該方法的返回類型
    ???????? createChildValidator(?resourceBundle,?method,?clazz?); //?創建子類的Validator
    ?????? }

    ?????? Field[]?fields?=?currClass.getDeclaredFields();? //?掃描Field上面的注釋,?下面和上面Method的實現一樣
    ?????? for? (? int? i?=? 0 ;?i?<?fields.length?;?i++?)?{
    ???????? Field?field?=?fields[i];
    ???????? createMemberValidator(?field?);
    ???????? Class?clazz?=?field.getType();
    ???????? createChildValidator(?resourceBundle,?field,?clazz?);
    ?????? }
    ???? }
    ?? }

    ?? private?void? addSuperClassesAndInterfaces(Class?clazz,?Collection<Class>?classes)?{
    ???? for? (?Class?currClass?=?clazz;?currClass?!=? null? ;?currClass?=?currClass.getSuperclass()?)?{
    ?????? if? (?!?classes.add(?currClass?)?)? return ;
    ?????? Class[]?interfaces?=?currClass.getInterfaces();
    ?????? for? (Class?interf?:?interfaces)?{
    ???????? addSuperClassesAndInterfaces(?interf,?classes?);
    ?????? }
    ???? }
    ?? }

    ?? /**
    ??? *?創建內嵌類的Validator.?如果該內嵌類被Valid?Annotation?注釋的話則?
    ??? *?創建另外一個ClassValidator
    ??? *? @param? resourceBundle
    ??? *? @param? member
    ??? *? @param? clazz
    ??? */
    ?? private?void? createChildValidator(ResourceBundle?resourceBundle,?Member?member,?Class?clazz)?{
    ???? if? (?(?(AnnotatedElement)?member?).isAnnotationPresent(?Valid. class? )?)?{
    ?????? setAccessible(?member?);
    ?????? childGetters.add(?member?);
    ?????? if? (?!childClassValidators.containsKey(?clazz?)?)?{
    ???????? new? ClassValidator(?clazz,?resourceBundle,?childClassValidators?);
    ?????? }
    ???? }
    ?? }

    ?? /**
    ??? *?利用傳入的Method(實現了AnnotatedElement,?GenericDeclaration,?Member接口)
    ??? *?得到?方法上的Annotations?然后利用私有方法createValidator(Annotation?a)來創建
    ??? *?每一個Annotation?的實現類?Validator?并保存Validator和member
    ??? *? @param? member
    ??? */
    ?? private?void? createMemberValidator(Member?member)?{
    ???? Annotation[]?memberAnnotations?=?(?(AnnotatedElement)?member?).getAnnotations();
    ???? for? (? int? j?=? 0 ;?j?<?memberAnnotations.length?;?j++?)?{
    ?????? Annotation?methodAnnotation?=?memberAnnotations[j];
    ?????? Validator?propertyValidator?=?createValidator(?methodAnnotation?);
    ?????? if? (?propertyValidator?!=? null? )?{
    ???????? memberValidators.add(?propertyValidator?);
    ???????? setAccessible(?member?);? //?設置訪問屬性
    ???????? memberGetters.add(?member?);
    ?????? }
    ???? }
    ?? }

    ?? private?static?void? setAccessible(Member?member)?{
    ???? if? (?!Modifier.isPublic(?member.getModifiers()?)?)?{
    ?????? (?(AccessibleObject)?member?).setAccessible(? true? );
    ???? }
    ?? }

    ?? /**
    ??? *?該方法產生了該Annotation的約束實現類?并初始化該類對應的消息
    ??? */
    ?? private? Validator?createValidator(Annotation?annotation)?{
    ???? try? {
    ?????? //得到ValidatorClass?Annotation?
    ?????? ValidatorClass?validatorClass?=?annotation.annotationType().getAnnotation(?ValidatorClass. class? );
    ?????? if? (?validatorClass?==? null? )?{
    ???????? return?null ;
    ?????? }
    ?????? //?然后?利用ValidatorClass?Annotation?來得到里面的值(即實現該注釋的Class),
    ?????? //再利用Class?構造一個instance
    ?????? Validator?beanValidator?=?validatorClass.value().newInstance();
    ?????? beanValidator.initialize(?annotation?);? //?初始化Annotation中的參數(注意:在自定義約束中該方法有你來實現)
    ?????? String?messageTemplate?=?(String)?annotation.getClass()
    ?????????? .getMethod(? "message" ,?(Class[])? null? )
    ?????????? .invoke(?annotation?);?? //?取得?constraint?descriptor??中的message?的值
    ?????? String?message?=?replace(?messageTemplate,?annotation?);? //?初始化取得的模板消息?請參考?replace函數
    ?????? messages.put(?beanValidator,?message?);? //?把message?放在map中,以便使用
    ?????? return? beanValidator;? //?返回?產生的Validator
    ???? }
    ???? catch? (Exception?e)?{
    ?????? throw?new? IllegalArgumentException(? "could?not?instantiate?ClassValidator" ,?e?);
    ???? }
    ?? }

    ?? public?boolean? hasValidationRules()?{
    ???? return? beanValidators.size()?!=? 0? ||?memberValidators.size()?!=? 0 ;
    ?? }

    ?? /**
    ??? *?apply?constraints?on?a?bean?instance?and?return?all?the?failures.
    ??? */
    ?? public? InvalidValue[]?getInvalidValues(T?bean)?{
    ???? return?this .getInvalidValues(?bean,? new? IdentitySet()?);
    ?? }

    ?? /**
    ??? *?apply?constraints?on?a?bean?instance?and?return?all?the?failures.
    ??? */
    ?? protected? InvalidValue[]?getInvalidValues(T?bean,?Set<Object>?circularityState)?{
    ???? if? (?circularityState.contains(?bean?)?)?{?? //?該if?else?是和Hibernate?Core由關的,
    ?????? return? EMPTY_INVALID_VALUE_ARRAY;? //Avoid?circularity
    ???? }
    ???? else? {
    ?????? circularityState.add(?bean?);
    ???? }

    ???? if? (?!beanClass.isInstance(?bean?)?)?{? //?如果beanClass不是該bean的實例,則拋出異常
    ?????? throw?new? IllegalArgumentException(? "not?an?instance?of:?"? +?bean.getClass()?);
    ???? }

    ???? List<InvalidValue>?results?=? new? ArrayList<InvalidValue>();

    ???? for? (? int? i?=? 0 ;?i?<?beanValidators.size()?;?i++?)?{? //?驗證類級別的約束
    ?????? Validator?validator?=?beanValidators.get(?i?);
    ?????? if? (?!validator.isValid(?bean?)?)?{? //調用isValid方法,如果沒有通過則添加到list<InvalidValue>中
    ???????????????????????? //如果是自定義約束則isValid方法?由你來實現
    ???????? results.add(? new? InvalidValue(?messages.get(?validator?),?beanClass,?null,?bean,?bean?)?);
    ?????? }
    ???? }

    ???? for? (? int? i?=? 0 ;?i?<?memberValidators.size()?;?i++?)?{ //驗證方法級別的約束
    ?????? Member?getter?=?memberGetters.get(?i?);
    ?????? if? (?Hibernate.isPropertyInitialized(bean,?getter.getName()?)?)?{ //???檢查該屬性是否已初始化
    ???????? Object?value?=?getMemberValue(?bean,?getter?); //利用反射?取得該屬性的值
    ???????? Validator?validator?=?memberValidators.get(?i?);? //取得該約束的驗證實現類
    ???????? if? (?!validator.isValid(?value?)?)?{ //調用isValid方法,如果沒有通過則添加到list<InvalidValue>中
    ?????????? String?propertyName?=?getPropertyName(?getter?);
    ?????????? results.add(? new? InvalidValue(?messages.get(?validator?),?beanClass,?propertyName,?value,?bean?)?);
    ???????? }
    ?????? }
    ???? }

    ???? for? (? int? i?=? 0 ;?i?<?childGetters.size()?;?i++?)?{ //?處理子類類
    ?????? Member?getter?=?childGetters.get(?i?);
    ?????? if? (?Hibernate.isPropertyInitialized(bean,?getter.getName()?)?)?{? //檢查該屬性是否已初始化
    ???????? Object?value?=?getMemberValue(?bean,?getter?);
    ???????? if? (?value?!=? null? &&?Hibernate.isInitialized(?value?)?)?{
    ?????????? String?propertyName?=?getPropertyName(?getter?);
    ?????????? InvalidValue[]?invalidValues?=?getClassValidator(?value?)
    ?????????????? .getInvalidValues(?value,?circularityState?); //?通過參數value?得到?Class,?然后由Class作為key????????? //在childClassValidators?map中得到其ClassValidator
    ????????????????????????????????????? //如果不存在?則創建新的?,然后再調用ClassValidator的getInvalidValues方法
    ?????????? //?注意在調用getInvalidValues方法時?用到了circularityState?參數,?當調用循環一周時?返回(遞歸結束)
    ?????????? for? (?InvalidValue?invalidValue?:?invalidValues?)?{
    ???????????? invalidValue.addParentBean(?bean,?propertyName?);
    ???????????? results.add(?invalidValue?);? //添加的結果中
    ?????????? }
    ???????? }
    ?????? }
    ???? }

    ???? return? results.toArray(? new? InvalidValue[results.size()]?);? //返回InvalidValue數組
    ?? }

    ?? /**
    ??? *?通過參數value?得到?Class,?然后由Class作為key?在childClassValidators?map中得到其ClassValidator
    ??? *?如果不存在?則創建新的?然后返回
    ??? *? @param? value
    ??? *? @return
    ??? */
    ?? private? ClassValidator?getClassValidator(Object?value)?{
    ???? Class?clazz?=?value.getClass();
    ???? ClassValidator?validator?=?childClassValidators.get(?clazz?);
    ???? if? (?validator?==? null? )?{? //handles?polymorphism
    ?????? validator?=? new? ClassValidator(?clazz?);
    ???? }
    ???? return? validator;
    ?? }

    ?? /**
    ??? *?Apply?constraints?of?a?particular?property?on?a?bean?instance?and?return?all?the?failures.
    ??? *?Note?this?is?not?recursive.
    ??? *?驗證單個屬性的約束.
    ??? */
    ?? //TODO?should?it?be?recursive??
    ?? public? InvalidValue[]?getInvalidValues(T?bean,?String?propertyName)?{
    ???? List<InvalidValue>?results?=? new? ArrayList<InvalidValue>();

    ???? for? (? int? i?=? 0 ;?i?<?memberValidators.size()?;?i++?)?{
    ?????? Member?getter?=?memberGetters.get(?i?);
    ?????? if? (?getPropertyName(?getter?).equals(?propertyName?)?)?{ //?驗證該屬性的約束
    ???????? Object?value?=?getMemberValue(?bean,?getter?);
    ???????? Validator?validator?=?memberValidators.get(?i?);
    ???????? if? (?!validator.isValid(?value?)?)?{
    ?????????? results.add(? new? InvalidValue(?messages.get(?validator?),?beanClass,?propertyName,?value,?bean?)?);
    ???????? }
    ?????? }
    ???? }

    ???? return? results.toArray(? new? InvalidValue[results.size()]?);
    ?? }

    ?? /**
    ??? *?Apply?constraints?of?a?particular?property?value?of?a?bean?type?and?return?all?the?failures.
    ??? *?The?InvalidValue?objects?returns?return?null?for?InvalidValue#getBean()?and?InvalidValue#getRootBean()
    ??? *?Note?this?is?not?recursive.
    ??? *?驗證?value?是否滿足當前屬性的約束.
    ??? */
    ?? //TODO?should?it?be?recursive?
    ?? public? InvalidValue[]?getPotentialInvalidValues(String?propertyName,?Object?value)?{
    ???? List<InvalidValue>?results?=? new? ArrayList<InvalidValue>();

    ???? for? (? int? i?=? 0 ;?i?<?memberValidators.size()?;?i++?)?{
    ?????? Member?getter?=?memberGetters.get(?i?);
    ?????? if? (?getPropertyName(?getter?).equals(?propertyName?)?)?{
    ???????? Validator?validator?=?memberValidators.get(?i?);
    ???????? if? (?!validator.isValid(?value?)?)?{
    ?????????? results.add(? new? InvalidValue(?messages.get(?validator?),?beanClass,?propertyName,?value,? null? )?);
    ???????? }
    ?????? }
    ???? }

    ???? return? results.toArray(? new? InvalidValue[results.size()]?);
    ?? }

    ?? private? Object?getMemberValue(T?bean,?Member?getter)?{
    ???? Object?value;
    ???? try? {
    ?????? value?=?getValue(?getter,?bean?);
    ???? }
    ???? catch? (Exception?e)?{
    ?????? throw?new? IllegalStateException(? "Could?not?get?property?value" ,?e?);
    ???? }
    ???? return? value;
    ?? }

    ?? private? Object?getValue(Member?member,?T?bean)? throws? IllegalAccessException,?InvocationTargetException?{
    ???? if? (?member? instanceof? Field?)?{
    ?????? return? (?(Field)?member?).get(?bean?);
    ???? }
    ???? else?if? (?member? instanceof? Method?)?{
    ?????? return? (?(Method)?member?).invoke(?bean?);
    ???? }
    ???? else? {
    ?????? throw?new? AssertionFailure(? "Unexpected?member:?"? +?member.getClass().getName()?);
    ???? }
    ?? }

    ?? public? String?getPropertyName(Member?member)?{
    ???? //Do?no?try?to?cache?the?result?in?a?map,?it's?actually?much?slower?(2.x?time)
    ???? String?propertyName;
    ???? if? (?member? instanceof? Field?)?{
    ?????? propertyName?=?member.getName();
    ???? }
    ???? else?if? (?member? instanceof? Method?)?{
    ?????? propertyName?=?member.getName();
    ?????? if? (?propertyName.startsWith(? "is"? )?)?{
    ???????? propertyName?=?Introspector.decapitalize(?propertyName.substring(? 2? )?);
    ?????? }
    ?????? else?if? (?propertyName.startsWith(? "get"? )?)?{
    ???????? propertyName?=?Introspector.decapitalize(?propertyName.substring(? 3? )?);
    ?????? }
    ?????? //do?nothing?for?non?getter?method,?in?case?someone?want?to?validate?a?PO?Method
    ???? }
    ???? else? {
    ?????? throw?new? AssertionFailure(? "Unexpected?member:?"? +?member.getClass().getName()?);
    ???? }
    ???? return? propertyName;
    ?? }

    ?? private? String?replace(String?message,?Annotation?parameters)?{
    ???? StringTokenizer?tokens?=? new? StringTokenizer(?message,? "{}" ,? true? );
    ???? StringBuilder?buf?=? new? StringBuilder(? 30? );
    ???? boolean? escaped?=? false ;
    ???? while? (?tokens.hasMoreTokens()?)?{
    ?????? String?token?=?tokens.nextToken();
    ?????? if? (? "{" .equals(?token?)?)?{
    ???????? escaped?=? true ;
    ?????? }
    ?????? else?if? (? "}" .equals(?token?)?)?{
    ???????? escaped?=? false ;
    ?????? }
    ?????? else?if? (?!escaped?)?{
    ???????? buf.append(?token?);
    ?????? }
    ?????? else? {
    ???????? Method?member;
    ???????? try? {
    ?????????? member?=?parameters.getClass().getMethod(?token,?(Class[])? null? );
    ???????? }
    ???????? catch? (NoSuchMethodException?nsfme)?{
    ?????????? member?=? null ;
    ???????? }
    ???????? if? (?member?!=? null? )?{
    ?????????? try? {
    ???????????? buf.append(?member.invoke(?parameters?)?);
    ?????????? }
    ?????????? catch? (Exception?e)?{
    ???????????? throw?new? IllegalArgumentException(? "could?not?render?message" ,?e?);
    ?????????? }
    ???????? }
    ???????? else?if? (?messageBundle?!=? null? )?{
    ?????????? String?string?=?messageBundle.getString(?token?);
    ?????????? if? (?string?!=? null? )?buf.append(?replace(?string,?parameters?)?);
    ???????? }
    ?????? }
    ???? }
    ???? return? buf.toString();
    ?? }

    ?? /**
    ??? *?apply?the?registred?constraints?rules?on?the?Hibernate?metadata?(to?be?applied?on?DB?schema...)
    ??? * 該方法是與實體類綁定的 不推薦使用 有興趣的讀者可以自己研究一下
    ??? *? @param? persistentClass?Hibernate?metadata
    ??? */
    ?? public?void? apply(PersistentClass?persistentClass)?{?
    ???//源代碼省略
    ?? }

    ?? /**
    ??? *?斷言該bean?是否符合所有約束.?負責拋出異常
    ??? *? @param? bean
    ??? */
    ?? public?void? assertValid(T?bean)?{
    ???? InvalidValue[]?values?=?getInvalidValues(?bean?);
    ???? if? (?values.length?>? 0? )?{
    ?????? throw?new? InvalidStateException(?values?);
    ???? }
    ?? }

    ?? /**
    ??? *?該方法應該是序列化ResourceBundle的?為private方法?但并沒有用到,?不知道為什么?可能以后會有用
    ??? *? @param? oos
    ??? *? @throws? IOException
    ??? */
    ?? private?void? writeObject(ObjectOutputStream?oos)? throws? IOException?{
    ???? ResourceBundle?rb?=?messageBundle;
    ???? if? (?rb?!=? null? &&?!?(?rb? instanceof? Serializable?)?)?{
    ?????? messageBundle?=? null ;
    ?????? if? (?!?defaultResourceBundle?)
    ???????? log.warn(? "Serializing?a?ClassValidator?with?a?not?serializable?ResourceBundle:?ResourceBundle?ignored"? );
    ???? }
    ???? oos.defaultWriteObject();
    ???? oos.writeObject(?messageBundle?);
    ???? messageBundle?=?rb;
    ?? }

    ?? /**
    ??? *?該方法應該是讀取序列化的ResourceBundle的?為private方法?但并沒有用到,不知道為什么?可能以后會有用
    ??? *? @param? ois
    ??? *? @throws? IOException
    ??? *? @throws? ClassNotFoundException
    ??? */
    ?? private?void? readObject(ObjectInputStream?ois)? throws? IOException,?ClassNotFoundException?{
    ???? ois.defaultReadObject();
    ???? ResourceBundle?rb?=?(ResourceBundle)?ois.readObject();
    ???? if? (rb?==? null )?rb?=?getDefaultResourceBundle();
    ???? initValidator(?beanClass,? new? HashMap<Class,?ClassValidator>(),?rb?);
    ?? }
    }

    還記得我們在驗證時候所寫的代碼嗎:

    ? ClassValidator<Person>?classValidator?=? new? ClassValidator<Person>?(Person. class );
    ? InvalidValue[]?validMessages?=?classValidator.getInvalidValues(p);

    只調用了 classValidator的getInvalidValues(p);方法 我們就得到了InvalidValue[]?validMessages, 該方法做了什么事情呢? 有上面的注釋看起來就輕松多了 ^_^.

    首先:在你創建 ClassValidator時, 會調用ClassValidator的構造方法 她一供有三個構造函數 :
    ??

    有兩個構造函數(一個傳遞要驗證的類為參數,一個還要加上你自定義的ResourceBundle)來供我們使用, 還有一個protected 的構造函數. 在構造函數中都做了寫什么呢?

    第一: 把要驗證的類保存起來,第二:決定使用的消息資源,如果你提供了自己的ResourceBundle 就使用自定義消息,否則使用默認的消息資源.第三: 根據java反射機制,利用Annotation初始化所有的驗證約束類,然后驗證是否滿足驗證條件.

    下面我們來關注一下initValidator 方法,看看是如何初始化驗證約束類的. 現在請仔細看看 initValidator 里面的注釋.然后在繼續往下看.^_^

    ? 通過上面的分析,可以看到在 initValidator函數中,初始化了你傳入類的所有的約束Annotations 的相關的東東(如: 其約束驗證實現類, 如果有內嵌的類,如果該類被Valid Annotation注釋的話 也構造一個內嵌類的Validator 并初始化其相關的東東 如此遞歸執行下去).該函數執行完后,可以說構造了一個以你傳入的類為跟的 約束注釋樹(自創的名詞,不了解也沒關系 ^_^),然后由此樹來逐個驗證沒有個約束.此時已經具備驗證約束的條件了.你只有調用classValidator.getInvalidValues(p)方法就可以驗證類p 上的所有約束了.

    ?GetInvalidValues()方法有做了什么呢, 現在你要再回到上面看看她的注釋了? ^_^:

    怎么樣現在知道 GetInvalidValues 做了什么了吧.她就是取出 約束注釋樹中的每一個約束注釋(分為 類注釋, 方法注釋, 屬性注釋 和內嵌類注釋 (也就是類里面的類屬性)),并驗證相應的成員是否滿足該約束注釋的要求,也就是調用Validator的isValid() 方法.最后用不滿足要求的 成員信息構造InvalidValue 數組 并返. ClassValidator 類我們基本上已經講解完了,剩下的該Validatro里面的就是一些內建的約束Annotation和約束驗證實現類了,這些看看前一篇文章就明白怎么回事了.到此 HibernateValidator 框架基本上分析完了. 通過分析該框架.讓我看到了Annotation的一種高級用法的實現機制,和反射機制的巧妙應用,以及幾個巧妙的設計模式(我就不在舉例了 大家可以相互探討一下). 你從中學到了什么呢?

    對想把Hibernate Validator做成一個獨立框架的幾點說明:

    1.去掉apply 函數.

    2. 在getPropertyName 和 getMemberValue 中 如果得到的值為null 則拋出org.hibernate.AssertionFailure異常. 可以重寫該異常,或者從Hibernate源代碼中提取(建議重寫).

    3.用到了Hibernate.isPropertyInitialized(Object o,String name)方法 判斷該類(o)的屬性(name)是否以及加載的, 該函數的doc 注釋為 Check if the property is initialized. If the named property does not exist or is not persistent, this method always returns true.可以替換為判斷該屬性(name)是否為null, null即代表沒有賦初值(可能違反約束);否則驗證該值是否違反約束.

    4.里面還用到了org.hibernate.util.IdentitySet 一個set實現,可以自己實現或者從Hibernate中提取(推薦提取);

    這樣一個獨立的Validation frameWork 就出來了. 不依賴任何第三方代碼,完全可以作為你自己的驗證框架在項目中使用.

    PS: 關于在實體類上(持久化層)使用Validator是否有好處,大家可以到如下連接看看:http://www.hibernate.org.cn/viewtopic.php?t=18131

    我也在Matrix Hibernate 論壇開了一討論貼 請大家走過路過都看看:http://www.matrix.org.cn/thread.shtml?topicId=36657&forumId=23 讓我們更高效的使用 Validator.

     

    ?

    posted on 2006-05-18 15:17 冰雨 閱讀(2124) 評論(0)  編輯  收藏 所屬分類: Opensource

    JSF中文技術文摘
    主站蜘蛛池模板: 成人黄页网站免费观看大全| 99精品在线免费观看| 中文字幕av无码无卡免费| 亚洲爆乳精品无码一区二区三区 | 无码一区二区三区AV免费| 久久亚洲sm情趣捆绑调教| 久草免费福利视频| 亚洲小视频在线观看| a毛片在线还看免费网站| 亚洲第一极品精品无码久久| 国产免费网站看v片在线| 午夜亚洲www湿好大| 亚洲一区二区在线免费观看| 亚洲黄色在线播放| 野花高清在线观看免费完整版中文| 亚洲男人的天堂久久精品| 女人18毛片特级一级免费视频 | 亚洲性色精品一区二区在线| 午夜视频在线在免费| 免费高清A级毛片在线播放| 在线观看亚洲av每日更新| 在线观看特色大片免费网站| 亚洲的天堂av无码| 日本免费网站观看| 黄床大片免费30分钟国产精品| 久久久亚洲精品无码| 无限动漫网在线观看免费| 国产亚洲视频在线观看网址| 亚洲中文字幕无码久久精品1 | 永久黄网站色视频免费直播| 免费国产a理论片| 亚洲av不卡一区二区三区| 一二三四在线播放免费观看中文版视频 | 亚洲成人免费在线| 天天看免费高清影视| 一级做a爱过程免费视频高清| 亚洲欧洲一区二区| 四虎影视永久免费观看网址| 国产一级一毛免费黄片| 亚洲一区二区三区在线网站| 亚洲精品国产精品国自产观看|