Bean驗證使用兩種XML描述符,第一個描述了作為META-INF/validation.xml提供的Bean驗證配置。第二個描述限制聲明,并與注解聲明方法緊密比對。
文章目錄
-
- 7.1、限制定義和限制聲明
-
- 7.1.1 在XML中聲明限制
-
- 7.1.1.1、類級别重寫
- 7.1.1.2、字段級别重寫
- 7.1.1.3、屬性級别重寫
-
- 7.1.14、限制聲明
- 7.1.2、覆寫XML中的限制定義
- 7.1.3、轉換值的字元串表示形式
- 7.1.4、XML 模式
- 7.2、Configuration schema(配置模式)
7.1、限制定義和限制聲明
- Bean驗證使你可以通過XML而不是注解來聲明限制,您可以忽略通過注解聲明的限制,也可以将XML視為在注解限制之上添加其他限制。雖然無法通過XML定義新的限制,但是您可以重新定義與給定限制定義關聯的ConstraintValidtor類的清單。
- 基于注解的限制聲明和基于XML的限制聲明之間沒有差別: 他們被認為是等效的, 并且Bean驗證提供程式應将其視為等效。規範的其餘部分金将注解稱為驗證中繼資料:應将其作為注解或其等效的XML描述符讀取。
- 特别是在浏覽中繼資料時,Bean驗證提供程式必須確定通過ConstraintDescriptor.getAnnotation()提供與XML聲明對應的注解執行個體。注解元素以及ConstraintValidator.getAttributes() 必須反映XML聲明中描述的值(請參見第7.1.3節)。同樣,ConstraintDescriptor.getConstraintValidatorClasses()必須反映基于XML的限制定義覆寫(請參見7.1.2節)。
- 給定的類在所有XML映射描述符中不得重複描述。在給定的類描述中。給定的限制定義不得在所有XML映射描述中多次重寫,如果在給定的驗證部署中違反了任何這些規則,則在ValidatorFactory的建立過程中将引發ValidationException.
- 該模式在第7.1.4節中提供。
7.1.1 在XML中聲明限制
- 如果設定了default-package, 則将所有未描述包的類名(包括注解)視為default-package所描述的包的一部分。
- 給定的JavaBean由Bean元素描述。類名是必填項,預設情況胸,對于XML中描述的類,将忽略通過注解表示的所有限制聲明。您可以通過在bean 上使用ignore-annotation="false"來強制Bean驗證同時考慮注解和XML限制聲明。
- 提示:
-
忽略注解設定既不是繼承來自類層次結構,也不是由類層次結構繼承。換句話說,它僅适用于目前bean。
-
- 如果類的名稱确實引用了類路徑中不存在的類,則會引發ValidationException.
- 例子7.1 bean聲明的XML
-
<constraint-mappings xmlns="http://jboss.org/xml/ns/javax/validation/mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation= "http://jboss.org/xml/ns/javax/validation/mapping validation-mapping-1.0.xsd"> <default-package>com.acme.app.domain</default-package> <bean class="Customer" ignore-annotations="false"> [...] </bean> <bean class="com.acme.common.model.Address"> [...] </bean> </constraint-mappings>
-
7.1.1.1、類級别重寫
- 通過class元素描述類級别的注解,如果聲明了ignore-annotations,則Bean驗證必須接受此元素的顯式值。如果未聲明,則考慮在封裝bean元素中定義的預設值。
- 當ignore-annoations為true時,此類的類級别Bean驗證注解(包括@GroupSequence)将被忽略。當ignore-annotations為false時:
- 添加了XML聲明的限制和注解中聲明的限制,并形成了類級别聲明限制的清單。
- 除非明确使用group-sequence元素,否則将考慮@GroupSequence
- 例子7.2 class級别聲明
-
<constraint-mappings xmlns="http://jboss.org/xml/ns/javax/validation/mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation= "http://jboss.org/xml/ns/javax/validation/mapping validation-mapping-1.0.xsd"> <default-package>com.acme.app.domain</default-package> <bean class="Customer" ignore-annotations="false"> <class ignore-annotations="true"> [...] </class> </bean> <bean class="com.acme.common.model.Address"> <class> [...] </class> </bean> </constraint-mappings>
-
7.1.1.2、字段級别重寫
- 字段級别注解通過field元素描述,name屬性對應于所有考慮字段的名稱。如果聲明了ignore-annotations, 則Bean驗證必須必須此元素的顯式值。如果未聲明,則考慮在封裝bean元素中定義的預設值。
- 當ignore-annotation為true時,将忽略目标字段上的字段級Bean驗證注解(包括@Valid).當ignore-annotaions為false時:
- 添加了XML聲明的限制和注解聲明的限制,并形成了字段級聲明限制的清單。
- 除非顯式使用有效元素,否則将考慮@Valid.請注意,禁用标記為@Valid的字段的級聯的唯一方法是使用ignore-annotation=true
- 如果字段名稱與給定bean中的字段不對應,則會引發ValidationException.
- 例子7.3、字段級聲明
-
<constraint-mappings xmlns="http://jboss.org/xml/ns/javax/validation/mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation= "http://jboss.org/xml/ns/javax/validation/mapping validation-mapping-1.0.xsd"> <default-package>com.acme.app.domain</default-package> <bean class="Customer" ignore-annotations="false"> <field name="firstName"> [...] </field> <field name="orders"> <valid/> [...] </field> </bean> </constraint-mappings>
-
7.1.1.3、屬性級别重寫
- 屬性級别的注解通過getter元素進行描述。name屬性對應于3.1.2節中定義的屬性名稱(例如。getter字元串getAge() 将具有作為相應的描述符。 如果聲明了ignore-annotations,則Bean驗證必須接受此元素的顯式值。如果未聲明,則考慮在封裝bean元素中定義的預設值。
- 當ignore-annotations為true時,将忽略目标屬性上的屬性級Bean驗證注解(包括@Valid)。當ignore-annotations為false時:
- 如果屬性名稱與給定bean中的屬性不對應,則會引發ValidationException異常。
- 例子7.4、屬性級别聲明
-
<constraint-mappings xmlns="http://jboss.org/xml/ns/javax/validation/mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation= "http://jboss.org/xml/ns/javax/validation/mapping validation-mapping-1.0.xsd"> <default-package>com.acme.app.domain</default-package> <bean class="Customer" ignore-annotations="false"> <getter name="firstName"> [...] </getter> <getter name="orders"> <valid/> [...] </getter> </bean> </constraint-mappings>
-
7.1.14、限制聲明
- 一個新的限制聲明由constraint元素表示,annotation屬性是表示限制的注解名稱。消息,組和載體分别由message, groups 和 payload元素表示。
- 其他自定義注解元素由element表示,name屬性是強制性 的,代表限制聲明中元素的名稱。不允許使用"message",“groups” 和 "payload"名稱,而應使用message, groups 或payload元素替代,否則引發ValidationException異常。
- 如果元素表示原生類型,類或枚舉,則其值的字元串表示形式将放置在元素本身中。有關從字元串到類型的轉換規則的詳細說明,請參見第7.1.3節。
- 如果元素表示原生數組類型,類數組或枚舉數組,則每個值的字元串表示形式将放在元素本身下方的value元素中。
- 如果元素表示注解,那麼将annotation元素用于辨別注解并将其放置在element下,注解元素包含element元素。
- 如果元素表示注解數組,則将一個或多個注解元素放置在element下。
- 注解定義中具有預設值的元素不必以XML表示: 在這種情況下将使用預設值。如果XML限制聲明缺少必須元素,或者如果XML限制聲明包含的元素不是限制定義的一部分,則會引發ValidationException.
- 例子7.5、限制聲明
-
<constraint-mappings xmlns="http://jboss.org/xml/ns/javax/validation/mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation= "http://jboss.org/xml/ns/javax/validation/mapping validation-mapping-1.0.xsd"> <default-package>com.acme.app.domain</default-package> <bean class="Customer" ignore-annotation="false"> <field name="firstName"> <!-- @LooksLike(patterns={ @Pattern(value="myRegExp", flag=PatternFlag.INSENSITIVE), @Pattern(value="my2ndRegExp") }) --> <constraint annotation="com.acme.app.constraint.LooksLike"> <element name="patterns"> <annotation> <element name="value">myRegExp</element> <element name="flag"> <value>INSENSITIVE</value> </element> </annotation> <annotation> <element name="value">my2ndRegExp</element> </annotation> </element> </constraint> </field> <field name="orders"> <valid/> <[email protected](value={0,20}--> <element name="value"> <value>0</value> <value>20</value> </element> </field> <getter name="orders"> <valid/> <!-- @Size(message="Size is limited", groups={Default.class}, max=30) --> <constraint annotation="javax.validation.constraint.Size"> <message>Size is limited</message> <groups> <value>com.acme.app.model.LightValidation</value> <value>javax.persistence.Default</value> </groups> <payload> <value>com.acme.app.model.WARN</value> </payload> <element name="max">30</element> </constraint> </getter> </bean> </constraint-mappings>
-
7.1.2、覆寫XML中的限制定義
- 限制定義(即表示限制的注解)不能完全用XML表示,但是可以更改與給定限制關聯的ConstraintValidator的清單。
- 限制定義由constraint-definition元素表示。annotation屬性表示要更改的限制注解, validated-by元素表示與限制關聯的ConstraintValidator實作的(有序)清單。
- 如果include-existing-validator設定為false,則忽略在限制注解上定義的ConstraintValidator。 如果設定為true, 則将XML中描述的ConstraintValidator清單與注解中描述的ConstraintValidator清單連起來,以形成一個新的ConstraintValidator數組進行評估。基于注解的ConstraintValidator在數組中基于XML的ConstraintValidator之前。新清單由ConstraintDescriptor.getConstraintValidatorClasses()傳回。
- 例子7.6、重寫限制定義
-
<constraint-mappings xmlns="http://jboss.org/xml/ns/javax/validation/mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation= "http://jboss.org/xml/ns/javax/validation/mapping validation-mapping-1.0.xsd"> <default-package>com.acme.app.domain</default-package> <bean class="com.acme.common.model.Address"> [...] </bean> <constraint-definition annotation="javax.validation.constraints.Size"> <validated-by include-existing-validators="true"> <value>com.acme.app.constraint.SizeValidatorForDictonary</value> </validated-by> </constraint-definition> <constraint-definition annotation="AcmeOrderNumber"> [...] </constraint-definition> </constraint-mappings>
-
7.1.3、轉換值的字元串表示形式
- 基本資料類型,Class和Enum在XML描述中表示為字元串,數組的元素由value元素表示。
- byte 是根據Byte.parseByte(String)中定義的規則表示的。
- short 是根據 Short.parseShort(String)中定義的規則表示的。
- int 是根據 Integer.parseInteger(String)中定義的規則表示的。
- long 是根據 Long.parseLong(String)中定義的規則表示的。
- float 是根據 Float.parseFloat(String)中定義的規則表示的
- double 是根據 Double.parseDouble(String)中定義的規則表示的。
- boolean 是根據 Boolean.parseBoolean(String)中定義的規則表示的
- char 是根據定義的規則表示的:
- 字元串必須是一個字元長
- 從字元串中提取的字元是傳回的char
- Class由該類的完全限定的類名稱表示。請注意,如果原始字元串沒有正确包名,則将考慮預設包名
- enum是根據enum.name()值
- 如果任何字元串表示形式與其對應的類型表示形式都不比對,則會引發ValidationException
7.1.4、XML 模式
- 本節包含用于限制映射的XML模式
-
<?xml version="1.0" encoding="UTF-8"?> <xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://jboss.org/xml/ns/javax/validation/mapping" xmlns:xs="http://www.w3.org/2001/XMLSchema" version="1.0"> <xs:element name="constraint-mappings" type="map:constraint-mappingsType" xmlns:map="http://jboss.org/xml/ns/javax/validation/mapping"/> <xs:complexType name="payloadType"> <xs:sequence> <xs:element type="xs:string" name="value" maxOccurs="unbounded" minOccurs="0"/> </xs:sequence> </xs:complexType> <xs:complexType name="groupsType"> <xs:sequence> <xs:element type="xs:string" name="value" maxOccurs="unbounded" minOccurs="0"/> </xs:sequence> </xs:complexType> <xs:complexType name="groupSequenceType"> <xs:sequence> <xs:element type="xs:string" name="value" maxOccurs="unbounded" minOccurs="0"/> </xs:sequence> </xs:complexType> <xs:complexType name="constraint-mappingsType"> <xs:sequence> <xs:element type="xs:string" name="default-package" minOccurs="0"/> <xs:element type="map:beanType" <xs:element name="bean" maxOccurs="unbounded" minOccurs="0" xmlns:map="http://jboss.org/xml/ns/javax/validation/mapping"/> type="map:constraint-definitionType" name="constraint-definition" maxOccurs="unbounded" minOccurs="0" xmlns:map="http://jboss.org/xml/ns/javax/validation/mapping"/> </xs:sequence> </xs:complexType> <xs:complexType name="validated-byType"> <xs:sequence> <xs:element type="xs:string" name="value" maxOccurs="unbounded" minOccurs="0"/> </xs:sequence> <xs:attribute type="xs:boolean" name="include-existing-validators" use="optional"/> </xs:complexType> <xs:complexType name="constraintType"> <xs:sequence> <xs:element type="xs:string" name="message" minOccurs="0"/> <xs:element type="map:groupsType" name="groups" minOccurs="0" xmlns:map="http://jboss.org/xml/ns/javax/validation/mapping"/> <xs:element type="map:payloadType" name="payload" minOccurs="0" xmlns:map="http://jboss.org/xml/ns/javax/validation/mapping"/> <xs:element type="map:elementType" name="element" maxOccurs="unbounded" minOccurs="0" xmlns:map="http://jboss.org/xml/ns/javax/validation/mapping"/> </xs:sequence> <xs:attribute type="xs:string" name="annotation" use="required"/> </xs:complexType> <xs:complexType name="elementType" mixed="true"> <xs:sequence> <xs:element type="xs:string" name="value" maxOccurs="unbounded" minOccurs="0"/> <xs:element type="map:annotationType" name="annotation" maxOccurs="unbounded" minOccurs="0" xmlns:map="http://jboss.org/xml/ns/javax/validation/mapping"/> </xs:sequence> <xs:attribute type="xs:string" name="name" use="required"/> </xs:complexType> <xs:complexType name="classType"> <xs:sequence> <xs:element type="map:groupSequenceType" name="group-sequence" minOccurs="0" xmlns:map="http://jboss.org/xml/ns/javax/validation/mapping"/> <xs:element type="map:constraintType" name="constraint" maxOccurs="unbounded" minOccurs="0" xmlns:map="http://jboss.org/xml/ns/javax/validation/mapping"/> </xs:sequence> <xs:attribute type="xs:boolean" name="ignore-annotations" use="optional"/> </xs:complexType> <xs:complexType name="beanType"> <xs:sequence> <xs:element type="map:classType" name="class" minOccurs="0" xmlns:map="http://jboss.org/xml/ns/javax/validation/mapping"> </xs:element> <xs:element type="map:fieldType" name="field" minOccurs="0" maxOccurs="unbounded" xmlns:map="http://jboss.org/xml/ns/javax/validation/mapping"/> <xs:element type="map:getterType" name="getter" minOccurs="0" maxOccurs="unbounded" xmlns:map="http://jboss.org/xml/ns/javax/validation/mapping"/> </xs:sequence> <xs:attribute type="xs:string" name="class" use="required"/> <xs:attribute type="xs:boolean" name="ignore-annotations" use="optional"/> </xs:complexType> <xs:complexType name="annotationType"> <xs:sequence> <xs:element type="map:elementType" name="element" maxOccurs="unbounded" minOccurs="0" xmlns:map="http://jboss.org/xml/ns/javax/validation/mapping"/> </xs:sequence> </xs:complexType> <xs:complexType name="getterType"> <xs:sequence> <xs:element type="xs:string" name="valid" minOccurs="0" fixed=""/> <xs:element type="map:constraintType" name="constraint" minOccurs="0" maxOccurs="unbounded" xmlns:map="http://jboss.org/xml/ns/javax/validation/mapping"/> </xs:sequence> <xs:attribute type="xs:string" name="name" use="required"/> <xs:attribute type="xs:boolean" name="ignore-annotations" use="optional"/> </xs:complexType> <xs:complexType name="constraint-definitionType"> <xs:sequence> <xs:element type="map:validated-byType" name="validated-by" xmlns:map="http://jboss.org/xml/ns/javax/validation/mapping"/> </xs:sequence> <xs:attribute type="xs:string" name="annotation" use="required"/> </xs:complexType> <xs:complexType name="fieldType"> <xs:sequence> <xs:element type="xs:string" name="valid" minOccurs="0" fixed=""/> <xs:element type="map:constraintType" name="constraint" minOccurs="0" maxOccurs="unbounded" xmlns:map="http://jboss.org/xml/ns/javax/validation/mapping"/> </xs:sequence> <xs:attribute type="xs:string" name="name" use="required"/> <xs:attribute type="xs:boolean" name="ignore-annotations" use="optional"/> </xs:complexType> </xs:schema>
-
7.2、Configuration schema(配置模式)
- XML配置在META-INF/validation.xml中設定,該檔案是可選的,遵循XML模式,如下所示:
-
<?xml version="1.0" encoding="UTF-8"?> <xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://jboss.org/xml/ns/javax/validation/configuration" xmlns:xs="http://www.w3.org/2001/XMLSchema" version="1.0"> <xs:element name="validation-config" type="config:validation-configType" xmlns:config="htt <xs:complexType name="validation-configType"> <xs:sequence> <xs:element type="xs:string" name="default-provider" minOccurs="0"/> <xs:element type="xs:string" name="message-interpolator" minOccurs="0"/> <xs:element type="xs:string" name="traversable-resolver" minOccurs="0"/> <xs:element type="xs:string" name="constraint-validator-factory" minOccurs="0"/> <xs:element type="xs:string" name="constraint-mapping" maxOccurs="unbounded" minOc <xs:element type="config:propertyType" name="property" maxOccurs="unbounded" minOc </xs:sequence> </xs:complexType> <xs:complexType name="propertyType"> <xs:simpleContent> <xs:extension base="xs:string"> <xs:attribute name="name" use="required" type="xs:string"/> </xs:extension> </xs:simpleContent> </xs:complexType> </xs:schema>
- 有關基于XML的配置的更多資訊,請參見第4.4.6節
-