BeanValidation技術(shù)規(guī)范特性概述_第1頁(yè)
BeanValidation技術(shù)規(guī)范特性概述_第2頁(yè)
BeanValidation技術(shù)規(guī)范特性概述_第3頁(yè)
BeanValidation技術(shù)規(guī)范特性概述_第4頁(yè)
BeanValidation技術(shù)規(guī)范特性概述_第5頁(yè)
已閱讀5頁(yè),還剩12頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、BeanValidation技術(shù)規(guī)范特性概述簡(jiǎn)介:數(shù)據(jù)驗(yàn)證Java分層結(jié)構(gòu)的應(yīng)用開發(fā)中占據(jù)著重要位置。JavaEE6提出了BeanValidation規(guī)范,使用注解的方式對(duì)JavaBean亞行約朿驗(yàn)證,不局限于某一層次或者某一編程模型,靈活易用。本文將向您系統(tǒng)的介紹該規(guī)范的各種特性。標(biāo)記本文!發(fā)布日期:20年3月240級(jí)別:中級(jí)概述BeanValidation規(guī)范Bean是JavaBean的縮寫,在Java分層架回的實(shí)際應(yīng)用中,從表示層到持久化層,每一層都需要對(duì)JavaBean進(jìn)行業(yè)務(wù)符合性驗(yàn)證,如圖1所示。然而對(duì)亍商一個(gè)JavaBean的對(duì)象,在每一層都需要實(shí)現(xiàn)同樣的驗(yàn)證邏輯時(shí),這將是一項(xiàng)耗

2、時(shí)且容易誘發(fā)錯(cuò)誤的做法。BeanValidation規(guī)范的目標(biāo)就是避免多層驗(yàn)證的重復(fù)性。事實(shí)上,開發(fā)者更傾向于將驗(yàn)證規(guī)則直接放到JavaBean本身,使用注解的方式進(jìn)行驗(yàn)證規(guī)則的設(shè)計(jì)。圖I.Java分層驗(yàn)證結(jié)構(gòu)示意圖JSR303規(guī)范(BeanValidation規(guī)范)提供了對(duì)JavaEE和JavaSE中的JavaBean進(jìn)行驗(yàn)證的方式。該規(guī)范主要使用注解的方式來實(shí)現(xiàn)對(duì)JavaBean的驗(yàn)證功能,并且這種方式會(huì)覆蓋使用形式的驗(yàn)證描述符,從而使驗(yàn)證邏輯從業(yè)務(wù)代碼中分離出來,如圖2所示。圖2.JavaBean驗(yàn)證模型示意圖JAVA(JavaBean魚迺JSR303規(guī)范提供的API是JavaBean對(duì)

3、彖模型的一般擴(kuò)展,它并不局限于某一層或者某一編程模型,在服務(wù)器端和客戶端都可使用,其最大的特點(diǎn)就是易用而且靈活。HibernateValidator4.0是JSR303規(guī)范的參考實(shí)現(xiàn)之一,本文所有示例代碼均使用該參考實(shí)現(xiàn)。下面給出一個(gè)BeanValidation的簡(jiǎn)單示例(淸單1):清單1:publicclassEmployeeNotNull(message=TheidofemployeecannotbenullM)privateIntegerid;NotNull(message=Thenameofemployeecannotbenulln)Size(min=1,max=10zmessage=

4、nThesizeofemployee1snamemustbetween1and10)privateStringname;publicintgetld()returnid;publicvoidsetId(intid)thisid=id;publicStringgetName()returnname;publicvoidsetName(Stringname)=name;publicstaticvoidmain(Stringargs)Employeeemployee=newEmployee();employeesetName(nZhangGuanNan);ValidatorFactoryvf=Val

5、idation.buildDefaultValidatorFactory();Validatorvalidator=vfgetValidator();SetConstraintViolationset=validatorvalidate(employee);for(ConstraintViolationconstraintviolation:set)System.outiprintin(constraintViolationgGtMGSscge();運(yùn)行該示例的輸出結(jié)果為:Thesizeofemployeesnamemustbetween1and10Theidofemployeecannotb

6、enull從示例中可以看出,BeanValidation使用注解(NotNull和Size)的方式對(duì)字段id和name進(jìn)行了約束聲明,當(dāng)該JavaBean被實(shí)際使用時(shí),相關(guān)的驗(yàn)證器就會(huì)對(duì)該類的實(shí)例進(jìn)行驗(yàn)證確保其符合該約束聲明。完成JavaBean的驗(yàn)證通??煞譃槿缦滤膫€(gè)步驟:約束注解的定義約束驗(yàn)證規(guī)則(約朿驗(yàn)證器)約束注解的聲明約束驗(yàn)證流程本文第二大部分將詳細(xì)介紹約束注解的定義和約束驗(yàn)證規(guī)則:第三大部分將詳細(xì)介紹約束注解的聲明和約束驗(yàn)證流程;第四大部分將介紹JSR303規(guī)范提供的APL約束的定義約束注解BeanValidation規(guī)范對(duì)約束的定義包括兩部分,一是約朿注解,淸單1中的NotNul

7、l就是約束注解:二是約束驗(yàn)證器,每一個(gè)約束注解都存在對(duì)應(yīng)的約束驗(yàn)證器,約束驗(yàn)證器用來驗(yàn)證具體的JavaBean是否滿足該約束注解聲明的條件。在JavaBean中,對(duì)某一方法、字段、屬性或其組合形式等進(jìn)行約束的注解,即為約束注解,如淸單2所示:清單2:NotNull(message=nTheidofemployeecannotbenull11)privateIntegerid;淸單2的含義為:對(duì)于字段id,在JavaBean的實(shí)例中值不能為空。對(duì)于每一個(gè)約束注解,在實(shí)際使用前必須有相關(guān)定義。JSR303規(guī)范默認(rèn)提供了幾種約束注解的定義(見表1),我們也可以擴(kuò)展規(guī)范提供的API,實(shí)現(xiàn)符合口身業(yè)務(wù)需

8、求的約束注解表1.BeanValidation規(guī)范內(nèi)嵌的約束注解定義約束注解名稱約束注解說明NullNotNull驗(yàn)證對(duì)彖是否為空驗(yàn)證對(duì)彖是否為非空AssertTrue驗(yàn)證Boolean對(duì)象是否為trueAssertFalse驗(yàn)證Boolean對(duì)象是否為falseMinMax驗(yàn)證Number和String對(duì)象是否大等于指定的值驗(yàn)證Number和String對(duì)象是否小等于指定的值DecimalMin驗(yàn)證Number和String對(duì)象是否大等于指定的值,小數(shù)存在梢度DecimalMax驗(yàn)證Number和String對(duì)象是否小等于指定的值,小數(shù)存在梢度SizeDigitsPast驗(yàn)證對(duì)彖(Array

9、,Collection,Map,String)長(zhǎng)度是否在給定的范用之內(nèi)驗(yàn)證Number和String的構(gòu)成是否合法驗(yàn)證Date和Calendar對(duì)象是否在當(dāng)前時(shí)間之前Future驗(yàn)證Date和Calendar對(duì)象是否在當(dāng)前時(shí)間之后Pattern驗(yàn)證String對(duì)象是否符合生刎吏辿弐的規(guī)則約束注解和普通的注解一樣,一個(gè)典型的約束注解的定義應(yīng)該至少包括如下內(nèi)容(淸單3):清單3:Target()/約束注解應(yīng)用的目標(biāo)元素類型Retention()/約束注解應(yīng)用的時(shí)機(jī)GConstraint(validatedBy=)/與約朿注解關(guān)聯(lián)的驗(yàn)證器publicQinterfaceConstraintNazne

10、Stringmessage()defaultn;/約束注解驗(yàn)證時(shí)的輸出消息Classgroups()default;/約束注解在驗(yàn)證時(shí)所屬的組別Classpayload()default;/約束注解0勺有效負(fù)載約束注解應(yīng)用的目標(biāo)元素類型包括METHOD,FIELD,TYPE,ANNOTATION_TYPE,CONSTRUCTOR,PARAMETERoMETHOD約束相關(guān)的getter方法;FIELD約束相關(guān)的屬性;TYPE約束具體的JavaBean:ANNOTATION_TYPE用在組合約束中:該規(guī)范同樣也支持對(duì)參數(shù)(PARAMETER)和構(gòu)造器(CONSTRUCTOR)的約束。驗(yàn)證時(shí)的組別屬

11、性將在本文第三大部分中組與組序列中詳細(xì)介紹。有效負(fù)載通常用來將一些疋纓邨信息與該約束注解相關(guān)聯(lián),常用的一種情況是用負(fù)載表示驗(yàn)證結(jié)果的嚴(yán)重程度。清單4給出一個(gè)驗(yàn)證字符串非空的約束注解的定義:清單4:Target(METHOD,FIELD,ANNOTATION_TYPEzCONSTRUCTOR,PARAMETER)Retention(RUNTIME)DocumentedConstraint(validatedBy=NotEmptyValidator.cless)publicinterfaceNotEmptyStringmessage()defaultnthisstringmaybeemptyM;C

12、lassgroups()default;Classpayload()default);約束注解定義完成后,需要同時(shí)實(shí)現(xiàn)與該約束注解關(guān)聯(lián)的驗(yàn)證器。約束驗(yàn)證器的實(shí)現(xiàn)需要擴(kuò)展JSR303規(guī)范提供的接口javax.validation.ConstraintValidatoro淸單5給出該接口。清單5:publicinterfaceConstraintValidatorvoidinitialize(AconstraintAnnotation);booleanisValid(TvaluezConstraintValidatorContextcontext);該接口有兩個(gè)方法,方法initialize對(duì)驗(yàn)證

13、器進(jìn)行實(shí)例化,它必須在驗(yàn)證器的實(shí)例在使用之詢被調(diào)用,并保證止確初始化驗(yàn)證器,它的參數(shù)是約束注解:方法isValid是進(jìn)行約束驗(yàn)證的主體方法,其中value參數(shù)代表需要驗(yàn)證的實(shí)例,context參數(shù)代表約束執(zhí)行的上下文環(huán)境。對(duì)于淸單4定義的約束注解,清單6給出了與該注解對(duì)應(yīng)的驗(yàn)證器的實(shí)現(xiàn)。清單6:publicclassNotEmptyValidatorimplementsConstraintValidatorpublicvoidinitialize(NotEmptyparameters)publicbooleanisValid(Stringstring,ConstraintValidatorCo

14、ntextconstraintValidatorContext)if(string=null)returnfalse;elseif(string丄ength()1)returnfalse;elsereturntrue;至此,一個(gè)可以聲明并使用的約束注解已經(jīng)定義完畢,清單7將給出該約束注解在實(shí)際程序中的使用。為節(jié)省篇幅,這里只給出針對(duì)淸單1的增加和修改內(nèi)容,未給出全部的示例代碼,您可以在本文的附錄中獲得全部的代碼。清單7:首先在淸單1中的類Employee中加入字段company和相應(yīng)的getter和setter方法:NotEmptyprivateStringcompany;然后在main函數(shù)中

15、加入如下代碼淸單:Stringcompany=newString();employeesetcompany(company);再次運(yùn)行該程序,輸岀結(jié)果為:TheidofemployeecannotbenullthisstringmaybeemptyThesizeofemployee1snamemustbetween1and10多值約束下面介紹BeanValidation規(guī)范的一個(gè)特性,多值約束(MultipleConstraints):對(duì)于同一個(gè)目標(biāo)元素,在進(jìn)行約束注解聲明時(shí)可以同時(shí)使用不同的屬性達(dá)到對(duì)該目標(biāo)元素進(jìn)行多值驗(yàn)證的目的。如淸單8所示:清單8:publicinterfaceConst

16、raintiVazneStringmessage()defaultnM;Classgroups()default;Classpayload()default);Target(METHOD,FIELD,ANNOTATION_TYPE,CONSTRUCTOR,PARAMETER)Retention(RUNTIME)DocumentedQinterfaceListConstraintNa/nevalue();實(shí)現(xiàn)多值約束只需要在定義約束注解的同時(shí)定義一個(gè)List(interfaceList)。使用該約束注解時(shí),BeanValidation將value數(shù)組里面的每一個(gè)元素都處理為一個(gè)普通的約束注解,并

17、對(duì)其進(jìn)行驗(yàn)證,所有約束條件均符合時(shí)才會(huì)驗(yàn)證通過。清單9定義了一個(gè)約束注解,它用來驗(yàn)證某一字符串是否包含指定的內(nèi)容。清單9:Target(METHOD,FIELD,ANNOTATION_TYPEzCONSTRUCTOR,PARAMETER)Retention(RUNTIME)Documented(Constraint(validatedBy=PatternOfStringValidatorclass)publicinterfacePatternOfStringStringmustContainLetter();Stringmessage()defaultnthispatternmaynotber

18、ightM;Classgroups()default;Classpayload()default);(Target(METHOD,FIELD,ANNOTATION_TYPE)Retention(RUNTIME)QinterfaceListPatternOfStringvalue();該約束注解對(duì)應(yīng)的驗(yàn)證器如淸單10所示:清單10:publicclassPatternOfStringValidatorimplementsConstraintValidatorprivateStringletterIn;publicvoidinitialize(PatternOfStringparameters)t

19、hisletterln=parametersmustContainLetter();publicbooleanisValid(Stringstring,ConstraintVaiidatorContextconstraintValidatorContext)if(stringcobtains(letterIn)returntrue;returnfalse;如果想驗(yàn)證某一字符串是否同時(shí)包含兩個(gè)子串,那么多值約束就顯得比較重要了,淸單將詳細(xì)給出多值約束的使用。清單11:在清單1中的類Employee中增加如下字段place以及相應(yīng)的getter和setter方法:Fdt:tGrnOfStringL

20、ist(PatternOfString(mustContainLetter=HCHn,message=HItdoesnotbelongtoChina11),PatternOfString(mustContainLetter=ffMainLandn/message=MItdoesnotbelongtoMainLand11)privateStringplace;然后在main函數(shù)中加入如下代碼淸單:Stringplace=HCn;employeesetPlace(place);Stringplace=HCn;employeesetPlace(place);再次運(yùn)行該程序,ItdoesnotItdo

21、esnot輸岀結(jié)果為:belongbelongmaybetoMainLandtoChinaemptycannotbenullthisstringTheidofemployeeThesizeofemployee1snamemustbetween1and10如果將place賦值為Stringplace=PHINA”,則輸岀結(jié)果為:thisstringmaybeemptyTheidofemployeecannotbenullItdoesnotbelongtoMainLandThesizeofemployeesnamemustbetween1and10可見,該約束會(huì)對(duì)聲明的兩個(gè)約束注解分別進(jìn)行驗(yàn)證,只

22、要存在不符合約束驗(yàn)證規(guī)則的JavaBean實(shí)例,就將產(chǎn)生相應(yīng)的驗(yàn)證失敗信息。約束注解聲明的時(shí)候可以根據(jù)不同的約束值使用message參數(shù)給出不同的輸出信息。組合約束下面介紹BeanValidation規(guī)范中另一個(gè)重要的特性:組合約束。BeanValidation規(guī)范允許將不同的約束進(jìn)行組合來創(chuàng)建級(jí)別較髙且功能較多的約束,從而避免原子級(jí)別約束的重復(fù)使用。如淸單4定義的約束注解NotEmpty,是用來判斷一個(gè)字符串在非空的基礎(chǔ)上長(zhǎng)度至少為1,其實(shí)際意義等同于NotNull和Size(min=1)的組合形式,因此可以將NotEmpty約束定義為組合約束NotEmpty2,如淸單12所示:清單12:N

23、otNullSize(min=1)Target(METHOD,FIELD,ANNOTATION_TYPEzCONSTRUCTOR,PARAMETER)Retention(RUNTIME)DocumentedConstraint(validatedBy=NotEmptyValidator2class)publicinterfaceNotEmpty2Stringmessage()defaultnthisstringmaybeemptyM;Classgroups()default;Classpayload()default);Target(METHOD,FIELD,ANNOTATION_TYPE)R

24、etention(RUNTIME)QinterfaceListNotEmpty2value();實(shí)際使用中NotEmpty2約束注解可以得到與NotEmpty約束注解同樣的驗(yàn)證結(jié)果?;仨?yè)if約束的聲明和驗(yàn)證流程本文第二大部分介紹了如何定義約束注解和驗(yàn)證器,本章主要介紹如何在JavaBean中應(yīng)用存在定義的約束注解,主要包括兩部分:一是約束的聲明;二是約束的驗(yàn)證流程。在需要進(jìn)行約束的目標(biāo)元素前面用注解的方式即可聲明約束,這意味著該目標(biāo)元素必須滿足該約束的驗(yàn)證條件。如淸單13即在字段id上聲明了約束NotNull:清單13:NotNull(message=nTheidofemployeecanno

25、tbenull11)privateIntegerid;該目標(biāo)元素在具體實(shí)例中被賦值后,BeanValidation就會(huì)調(diào)用相關(guān)的流程進(jìn)行驗(yàn)證。具體使用方式可以參見淸單14所示,其中所涉及的接口將在本文第四大部分詳細(xì)介紹。清單14:ValidatorFactoryvf=ValidationbuildDefbu丄tVc丄idatorFactory();Validatorvalidator=vfgetValidator();SetConstraintViolationset=validatorvalidate(JavaBeanInstance);for(ConstraintViolationcons

26、traintviolation:set)System.out:printin(constraintViolationgGtMGSsege();BeanValidation規(guī)范對(duì)JavaBean的驗(yàn)證流程如下:在實(shí)際使用中調(diào)用Validator.validate(J3M3e刖/s怡門ce)方法后,BeanValidation會(huì)査找在JavaBeanlnstance上所有的約束聲明,對(duì)每一個(gè)約束調(diào)用對(duì)應(yīng)的約束驗(yàn)證器進(jìn)行驗(yàn)證,最后的結(jié)果由約束驗(yàn)證器的isValid方法產(chǎn)生,如果該方法返回true,則約束驗(yàn)證成功,否則驗(yàn)證失敗。驗(yàn)證失敗的約束將產(chǎn)生約束違規(guī)對(duì)象(ConstaintViolation的實(shí)

27、例)并放到約束違規(guī)列表中。驗(yàn)證完成后所有的驗(yàn)證失敗信息均能在該列表中査找并輸出。詢提條件BeanValidation規(guī)范規(guī)定在對(duì)JavaBean進(jìn)行約束驗(yàn)證前,目標(biāo)元素必須滿足以下條件:I如果驗(yàn)證的是屬性(getter方法),那么必須遵從JavaBean的命名習(xí)慣(JavaBeans規(guī)范);|靜態(tài)的字段和方法不能進(jìn)行約朿驗(yàn)證:|約束適用于接口和基類:|約束注解定義的目標(biāo)元素可以是字段、屬性或者類型等;|可以在類或者接口上使用約束驗(yàn)證,它將對(duì)該類或?qū)崿F(xiàn)該接口的實(shí)例進(jìn)行狀態(tài)驗(yàn)證:|字段和屬性均可以使用約束驗(yàn)證,但是不能將相同的約束重復(fù)聲明在字段和相關(guān)屬性(字段的getter方法)上。ObjectG

28、raph驗(yàn)證除了支持JavaBean的實(shí)例驗(yàn)證外,BeanValidation規(guī)范同樣支持ObjectGraph的驗(yàn)證。ObjectGraph即為對(duì)彖的拓?fù)浣Y(jié)構(gòu),如對(duì)象之間的引用關(guān)系。如果類A引用類B,則在對(duì)類A的實(shí)例進(jìn)行約朿驗(yàn)證時(shí)也需要對(duì)類B的實(shí)例進(jìn)行約束驗(yàn)證,這就是驗(yàn)證的級(jí)聯(lián)性。當(dāng)對(duì)Java語(yǔ)言中的集合、數(shù)組等類型進(jìn)行驗(yàn)證時(shí)也需要對(duì)該類型的每一個(gè)元素進(jìn)行驗(yàn)證。完成級(jí)聯(lián)驗(yàn)證的方式就是使用Valid注解,如淸單15所示:清單15:publicclassPersonNotEmptyprivateStringname;publicStringgetName()returnname;publicvo

29、idsetName(Stringname)this.n&me=name;publicclassOrderValidprivatePersonperson;publicPersongetPerson()returnperson;publicvoidsetPerson(Personperson)this.person=person;在對(duì)Order的實(shí)例進(jìn)行驗(yàn)證時(shí),只有當(dāng)在Order引用的對(duì)象Personiwifii聲明了注解Valid,才對(duì)Person中name字段的NotEmpty注解進(jìn)行驗(yàn)證,否則將不予驗(yàn)證。組BeanValidation規(guī)范中一個(gè)重要的概念,就是組和組序列。組定義了約束的子集

30、。對(duì)于一個(gè)給定的ObjectGraph結(jié)構(gòu),有了組的概念,則無需對(duì)該ObjectGraph中所有的約束進(jìn)行驗(yàn)證,只需要對(duì)該組定義的一個(gè)子集進(jìn)行驗(yàn)證即可。完成組別驗(yàn)證需要在約束聲明時(shí)進(jìn)行組別的聲明,否則使用默認(rèn)的組Default.class.組使用接口的方式進(jìn)行定義,淸單16給出了如何定義組并使用組進(jìn)行約束驗(yàn)證。清單16:publicinterfaceGroupApublicclassUserNotEmpty(message=nfirstnamemaybeemptyn)privateStringfirstname;NotEmpty(message=nmiddlenamemaybeemptyn,g

31、roups=Defaultclass)privateStringmiddlename;NotEmpty(message=nlastnamemaybeemptyn,groups=GroupA.class)privateStringlastname;publicstaticvoidmain(Stringargs)Useruser=newUser();ValidatorFactoryvf=Validation.buildDefaultValidatorFactory();Validatorvalidator=vfgetValidator();SetConstraintViolationset=val

32、idatorvalidate(user,GroupAcless);for(ConstraintViolationconstraintviolation:set)System.outprintin(constraintViolationgGtMGSsege();在類Use中需要驗(yàn)證的字段上聲明驗(yàn)證時(shí)所屬的組別屬性,如(groups二GoupA.class),然后在main函數(shù)中調(diào)用validator.validate(user,GroupA.class)方法,在此必須指定需要驗(yàn)證的組別。如果不顯示指明,則是默認(rèn)的組別。如淸單16,驗(yàn)證器只會(huì)驗(yàn)證類User的lastname字段,如果使用valid

33、ator.validate(user),則會(huì)使用Default.class組別,從而驗(yàn)證fistname和middlename字段。需要注意的是:組也有繼承的屬性。對(duì)某一組別進(jìn)行約束驗(yàn)證的時(shí)候,也會(huì)對(duì)其所繼承的基類進(jìn)行驗(yàn)證。組可以進(jìn)行隱式定義,其好處是可以不必在約束聲明的時(shí)候顯式聲明組別屬性,如清單16中的(groups=GroupA.class)。淸單17給出了一個(gè)隱式定義的組接口(Animal),其中包含對(duì)相應(yīng)屬性(getter方法)的約束聲明。相應(yīng)的JavaBean(Dog)實(shí)現(xiàn)了該接口。清單17:publicinterfaceAnimalNotEmptyStringgetName();

34、NotEmptyStringgetName();NotEmptyStringgetOwnerName();NotEmptyStringgetOwnerName();publicclassDogimplementsAnimalpublicclassDogimplementsAnimalprivateStringname;privateStringownername;privateStringtype;privateStringownername;privateStringtype;publicvoidsetType(Stringtype)this.type=type;publicStringge

35、tName()returnnull;publicStringgetOwnerName()returnnull;NotEmpty(message=ntypeofthedogmaybeemptyn)publicStringgetType()returntype;這樣在對(duì)類Dog的實(shí)例進(jìn)行驗(yàn)證的時(shí)候,如果使用默認(rèn)的組別(Default.class),則name,ownername和type都將進(jìn)行驗(yàn)證:如果使用Animal的組別,如淸單18所示,則只會(huì)對(duì)name和ownername屬性進(jìn)行驗(yàn)證。清單18:publicstaticvoidmain(Stringargs)Dogdog=newDog();

36、ValidatorFactoryvf=Validation.buildDefaultValidatorFactory();Validatorvalidator=vfgetValidator();SetConstraintViolationset=validatorvalidate(dog,Animalclass);for(ConstraintViolationconstraintviolation:set)System.outiprintin(constraintViolationgetMGSsdge();輸出結(jié)果為:thisstringmaybeemptythisstringmaybeemp

37、ty組序列默認(rèn)情況下,不同組別的約束驗(yàn)證是無序的,然而在某些情況下,約束驗(yàn)證的順序卻很重要,如下面兩個(gè)例子:(1)第二個(gè)組中的約束驗(yàn)證依賴于一個(gè)穩(wěn)定狀態(tài)來運(yùn)行,而這個(gè)穩(wěn)定狀態(tài)是由第一個(gè)組來進(jìn)行驗(yàn)證的。(2)某個(gè)組的驗(yàn)證比較耗時(shí),CPU和內(nèi)存的使用率相對(duì)比較大,最優(yōu)的選擇是將其放在最后進(jìn)行驗(yàn)證。因此,在進(jìn)行組驗(yàn)證的時(shí)候尚需提供一種有序的驗(yàn)證方式,這就提岀了組序列的概念。一個(gè)組可以定義為其他組的序列,使用它進(jìn)行驗(yàn)證的時(shí)候必須符合該序列規(guī)定的順序。在使用組序列驗(yàn)證的時(shí)候,如果序列前邊的組驗(yàn)證失敗,則后面的組將不再給予驗(yàn)證。清單19聲明了組GroupA.class,GroupB.class和Group

38、.class,其中default,GroupA,GroupB均為Group的序列。清單19:publicinterfaceGroupApublicinterfaceGroupBGroupSequence(Defaultclass,GroupAclass/GroupBclass)publicinterfaceGrouppublicclassUserNotEmpty(message=nfirstnamemaybeemptyn)privateStringfirstname;NotEmpty(message=nmiddlenamemaybeemptyn,groups=Defaultclass)priv

39、ateStringmiddlename;NotEmpty(message=nlastnamemaybeemptyn/groups=GroupA.class)privateStringlastname;NotEmpty(message=ncountrymaybeemptyMzgroups=GroupBclass)privateStringcountry;publicstaticvoidmain(Stringargs)Useruser=newUser();ValidatorFactoryvf=ValidationbuildDefaultValidatorFactory();Validatorval

40、idator=vfgetValidator();SetConstraintViolationset=validatorvalidate(user,Groupclass);for(ConstraintViolationconstraintviolation:set)System.outprintin(constraintViolationgGtMessdge();清單19中main函數(shù)的輸出結(jié)果為:middlenamemaybeemptyfirstnamemaybeempty從輸出結(jié)果可以看出,該驗(yàn)證將不再為屬于GoupA和GroupB的約束進(jìn)行驗(yàn)證,因?yàn)閷儆诮M序列(Group.class)中前

41、而位置的Default組驗(yàn)證失敗。只有當(dāng)在main函數(shù)加入如下代碼片段使屬于Default組別的驗(yàn)證通過后,方可進(jìn)行后續(xù)組別(GoupA,GroupB)的驗(yàn)證。user.setFirstname(nfirstname);user.setMiddlename(nmidlenameM);穿透驗(yàn)證器(TrvesablePoperty)穿透驗(yàn)證器主要適用于JPA規(guī)范,JPA規(guī)范提供一種惰性連接屬性,允許實(shí)體對(duì)彖的某些字段被延遲加載,這些被延遲加載的字段需要JPA從底層麴庫(kù)中獲取。BeanValidation規(guī)范通過TraversableResolver接口來控制這類字段的存取性。在實(shí)際使用中需要先竊用

42、汝接口中的isReachable()方法,如果返回tue,則證明該屬性是可存取的,方可進(jìn)行屬性的約束驗(yàn)證。同樣,在進(jìn)行級(jí)聯(lián)驗(yàn)證時(shí),也需要首先確定所引用的字段或者屬性的可存取性方可進(jìn)行約束的級(jí)聯(lián)驗(yàn)證?;仨?yè)首BeanValidation規(guī)范接口及其可擴(kuò)展的實(shí)現(xiàn)本文詢ihi的章節(jié)介紹了如何定義約束注解以及如何使用約束進(jìn)行JavaBean驗(yàn)證。對(duì)于第三部分中提到的約束驗(yàn)證流程中的接口,本章將給予詳細(xì)的介紹。BeanValidation規(guī)范允許用戶定制個(gè)性化的約朿驗(yàn)證,并給出了4大類接口供擴(kuò)展使用。本章將結(jié)合BeanValidation規(guī)范的參考實(shí)現(xiàn)HibernateValidator4.0進(jìn)行說明。圖

43、3給出了BeanValidation規(guī)范的API以及Hibenate4.0相關(guān)實(shí)現(xiàn)之間的關(guān)系示意圖。圖3.BeanValidation接口以及Hibernate4.0接口實(shí)現(xiàn)示意圖(査看大圖)IiViMjIlatBootstrapping相關(guān)接口Bootstrapping相關(guān)接口提供ValidatoFactory對(duì)彖,該對(duì)象負(fù)責(zé)創(chuàng)建Validator(驗(yàn)證器)實(shí)例,該實(shí)例即是BeanValidation客戶端用來進(jìn)行約束驗(yàn)證的主體類。Bootstrapping相關(guān)接口主要包括5類,如表2所示:表2.Bootstrapping相關(guān)接口及其作用接口作用BeanValidation規(guī)范的API默認(rèn)提

44、供該類,是整個(gè)API的入javax.validation.validation口,用來產(chǎn)生Configuraton對(duì)象實(shí)例,并啟動(dòng)環(huán)境中Validationprovider的具體實(shí)現(xiàn)。返回執(zhí)行上下文環(huán)境中所有的BeanValidationProviders的列javax.validation.ValidationPovideResolver表,并對(duì)每一個(gè)BeanValidationProvider產(chǎn)生一個(gè)對(duì)彖實(shí)例。BeanValidation規(guī)范提供一個(gè)默認(rèn)的實(shí)現(xiàn)。javax.validation.spi.ValidationProviderjavax.validation.Configura

45、tionjavax.validation.ValidatorFactory具體的BeanValidationProvider實(shí)現(xiàn)需要實(shí)現(xiàn)該接口。該接口用來生成具體的javax.validation.spi.ValidationProviderjavax.validation.Configurationjavax.validation.ValidatorFactory收集上下文環(huán)境中的配置信息,主要用來計(jì)算如何給定止確的Validationprovider,并將其委派給ValidatoFactoy對(duì)彖。從一個(gè)具體的BeanValidationProvider中構(gòu)建Validator的實(shí)例。Val

46、idator接口該接口(javax.validation.Validator)定義了驗(yàn)證實(shí)例的方法,主要包括三種,如表2所示:表3.Validator接口中的方法及其作用作用該方法用于驗(yàn)證一個(gè)給作用該方法用于驗(yàn)證一個(gè)給定的對(duì)象Setvalidate(Tobject,Class.groups)SetConstraintViolationTvalidateProperty(Tobject,StringpropertyName,該方法用于驗(yàn)證給定對(duì)Class.groups)象中的字段或者屬性SetConstraintViolationTvalidateValue(ClassbeanType,Stri

47、ng該方法用于驗(yàn)證給定對(duì)propertyName,Objectvalue,Class.groups)彖中的屬性的具體值上述兩類接口完成驗(yàn)證器的初始化工作,下面使用淸單20解釋上述接口,在本文的示例中均使用HibematValidator4.0作為參考實(shí)現(xiàn),因此上述兩類接口的具體實(shí)現(xiàn)均是HibematValidato4.0包中的類。清單20:ValidatorFactoryvf=Validation.buildDefaultVelidetorFectory();Validatorvalidator=vfgetValidator();頁(yè)碼,頁(yè)碼, /17淸單20使用默認(rèn)的方式創(chuàng)建驗(yàn)證工廠(Vali

48、datorFactory),類Validation會(huì)檢索類路徑下面所有的ja文件,使用ValidationPovideResolve接口的默認(rèn)實(shí)現(xiàn)DefaultValidationProviderResolver(BeanValidation規(guī)范提供該類)査找META-INF/services/錄中的javax.validation.spi.ValidationProvider文件,在HibernateValidato4.0中該文件中聲明og.hibenate.validato.HibenateValidato類為Validationprovider的具體實(shí)現(xiàn),因此Validation調(diào)用Hi

49、bernateValidator類創(chuàng)建Configuration接口的實(shí)例,在HibernateValidato4.0中,該實(shí)例為ConfigurationlmpL最后由ConfigurationImpl類產(chǎn)生ValidatorFactory的實(shí)例,在HibenateValidato4.0中為ValidatoFactorylmpl類。如果類路徑中存在著多個(gè)該規(guī)范的實(shí)現(xiàn),這就要用到Configuration接口去顯示指定要使用的具體實(shí)現(xiàn),然后再產(chǎn)生ValidatorFactory的實(shí)例。如淸單21所示:清單21:Configurationconfig=ValidationbyFrovider(HibernateValidatoi.clcss)configure();ValidatorFactoryvf=conf

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論