天天看點

第七章、Java Bean Validation的XML部署描述符

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節