Java-to-Schema 示例
原文: https://docs.oracle.com/javase/tutorial/jaxb/intro/j2schema.html
Java-to-Schema 示例演示如何使用注释将 Java 类映射到 XML 模式。
j2s-create-marshal 示例
j2s-create-marshal 示例说明了 Java 到模式的数据绑定。它演示了 JAXB 注释类的编组和解组,还展示了如何使用从 JAXB 映射类生成的模式文件在解组时启用 JAXP 1.3 验证。
使用以下命令生成模式文件bc.xsd
:
schemagen src/cardfile/*.java
cp schema1.xsd bc.xsd
注意schema1.xsd
被复制到bc.xsd
; schemagen
不允许您指定所选的架构名称。
使用 Ant 构建并运行 j2s-create-marshal 示例
要在终端窗口中使用 Ant 编译和运行 j2s-create-marshal 示例,请转到 jaxb-ri-install / samples / j2s-create-marshal /
目录,输入以下内容:
ant
j2s-xmlAccessorOrder 示例
j2s-xmlAccessorOrder 示例显示了如何使用@XmlAccessorOrder
和@XmlType.propOrder
注释来指定 XML 内容由 Java 类型编组和解组的顺序。
使用 Java 到模式映射,JavaBean 的属性和字段将映射到 XML 模式类型。类元素映射到 XML Schema 复杂类型或 XML Schema 简单类型。当前未指定生成的模式类型的默认元素顺序,因为 Java 反射不会强制返回订单。缺乏可靠的元素排序会对应用程序的可移植性产生负面影响您可以使用两个注释@XmlAccessorOrder
和@XmlType.propOrder
来定义必须可跨 JAXB 供应器移植的应用程序的架构元素排序。
使用@XmlAccessorOrder
Annotation 定义模式元素排序
@XmlAccessorOrder
注释强加了两种元素排序算法之一, AccessorOrder.UNDEFINED
或AccessorOrder.ALPHABETICAL
。 AccessorOrder.UNDEFINED
是默认设置。顺序取决于系统的反射实现。 AccessorOrder.ALPHABETICAL
算法按照java.lang.String.CompareTo(String anotherString)
确定的字典顺序对元素进行排序。
您可以在类对象上为注释类型ElementType.PACKAGE
定义@XmlAccessorOrder
注释。当在包上定义@XmlAccessorOrder
注释时,格式化规则的范围对于包中的每个类都是活动的。在类上定义时,该规则对该类的内容有效。
包中可以有多个@XmlAccessorOrder
注释。最内层(类)注释优先于外部注释。例如,如果在包上定义@XmlAccessorOrder(AccessorOrder.ALPHABETICAL)
并且在该包中的类上定义了@XmlAccessorOrder(AccessorOrder.UNDEFINED)
,则生成的内容该类的模式类型将以未指定的顺序排列,并且包中每个其他类的生成的模式类型的内容将按字母顺序排列。
使用@XmlType
Annotation 定义模式元素排序
可以为类定义@XmlType
注释。 @XmlType
注释中的注释元素propOrder()
使您能够在生成的模式类型中指定内容顺序。在类上使用@ XmlType.propOrder
批注指定内容顺序时,必须在参数列表中指定类中的所有公共属性和公共字段。您希望不在参数列表中的任何公共属性或字段必须使用@XmlAttribute
或@XmlTransient
注释进行注释。
@XmlType.propOrder
的默认内容顺序为{}
或{“”}
,未激活。在这种情况下,活动@XmlAccessorOrder
注释优先。当@XmlType.propOrder
注释指定类内容顺序时,它优先于类或包上的任何活动@XmlAccessorOrder
注释。如果在类上指定了@XmlAccessorOrder
和@ XmlType.propOrder(A,B,...)
注释,则propOrder
始终优先于注释语句的顺序。例如,在以下代码段中, @XmlAccessorOrder
注释位于@ XmlType.propOrder
注释之前。
@XmlAccessorOrder(AccessorOrder.ALPHABETICAL)
@XmlType(propOrder={"name", "city"})
public class USAddress {
// ...
public String getCity() {return city;}
public void setCity(String city) {this.city = city;}
public String getName() {return name;}
public void setName(String name) {this.name = name;}
// ...
}
在以下代码段中, @ XmlType.propOrder
注释位于@XmlAccessorOrder
注释之前。
@XmlType(propOrder={"name", "city"})
@XmlAccessorOrder(AccessorOrder.ALPHABETICAL)
public class USAddress {
// ...
public String getCity() {return city;}
public void setCity(String city) {this.city = city;}
public String getName() {return name;}
public void setName(String name) {this.name = name;}
// ...
}
在这两种情况下, propOrder
优先,并生成以下相同的模式内容:
<xs:complexType name="usAddress">
<xs:sequence>
<xs:element
name="name"
type="xs:string"
minOccurs="0"/>
<xs:element
name="city"
type="xs:string"
minOccurs="0"/>
</xs:sequence>
</xs:complexType>
示例中的模式内容排序
采购订单代码示例使用包和类级别的@XmlAccessorOrder
注释以及类上的@ XmlType.propOrder
注释来演示模式内容排序的效果。
类package-info.java
将@XmlAccessorOrder
定义为包的ALPHABETICAL
。类PurchaseOrderType
中的公共字段shipTo
和billTo
受此规则在生成的模式内容顺序中受到影响。类USAddress
在类上定义@ XmlType.propOrder
注释,该注释演示了生成的模式中用户定义的属性顺序取代ALPHABETICAL
顺序。
生成的模式文件可以在 jaxb-ri-install / samples / j2s-xmlAccessorOrder / build / schemas /
目录中找到。
使用 Ant 构建并运行 j2s-xmlAccessorOrder 示例
要在终端窗口中使用 Ant 编译和运行 j2s-xmlAccessorOrder 示例,请转到 jaxb-ri-install / samples / j2s-xmlAccessorOrder /
目录并键入以下内容:
ant
j2s-xmlAdapter 示例
j2s-xmlAdapter 示例演示了如何使用XmlAdapter
接口和@XmlJavaTypeAdapter
注释来提供 XML 内容到HashMap
的自定义映射(字段)使用int
作为键, String
作为值。
接口XmlAdapter
和注释@XmlJavaTypeAdapter
用于在解组和编组期间对数据类型进行特殊处理。有多种 XML 数据类型,其表示不容易映射到 Java(例如, xs:DateTime
和xs:Duration
),以及不映射的 Java 类型适当地进入 XML 表示。例如, java.util.Collection
(如List
)和java.util.Map
(如HashMap
)的实现或者用于非 JavaBean 类。
XmlAdapter
接口和@XmlJavaTypeAdapter
注释是为这些情况提供的。这种组合提供了一种便携式机制,用于在 Java 应用程序中读写 XML 内容。
XmlAdapter
接口定义了数据读写的方法。
/*
* ValueType - Java class that provides an
* XML representation of the data.
* It is the object that is used for marshalling and
* unmarshalling.
*
* BoundType - Java class that is used to
* process XML content.
*/
public abstract class XmlAdapter<ValueType,BoundType> {
// Do-nothing constructor for the derived classes.
protected XmlAdapter() {}
// Convert a value type to a bound type.
public abstract BoundType unmarshal(ValueType v);
// Convert a bound type to a value type.
public abstract ValueType marshal(BoundType v);
}
您可以使用@XmlJavaTypeAdapter
注释将特定XmlAdapter
实现与目标
类型, PACKAGE
, FIELD
相关联], METHOD
, TYPE
或PARAMETER
。
j2s-xmlAdapter 示例演示了如何使用XmlAdapter
将 XML 内容映射到(自定义) HashMap
中。 HashMap
对象,篮子
,在类KitchenWorldBasket
中,使用int
类型的键和类型String [的值
。这些数据类型应反映在读取和写入的 XML 内容中,因此 XML 内容应如下例所示:
<basket>
<entry key="9027">glasstop stove in black</entry>
<entry key="288">wooden spoon</entry>
</basket>
为 Java 类型HashMap
生成的默认架构不反映所需的格式。
<xs:element name="basket">
<xs:complexType>
<xs:sequence>
<xs:element
name="entry"
minOccurs="0"
maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element
name="key"
minOccurs="0"
type="xs:anyType"/>
<xs:element
name="value"
minOccurs="0"
type="xs:anyType"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
在默认的HashMap
模式中,键和值都是元素,并且是数据类型anyType
。 XML 内容如下所示:
<basket>
<entry>
<key>9027</key>
<value>glasstop stove in black</value>
</entry>
<entry>
<key>288</key>
<value>wooden spoon</value>
</entry>
</basket>
为解决此问题,该示例使用两个 Java 类, PurchaseList
和PartEntry
,它们反映了解组和编组内容所需的模式格式。为这些类生成的 XML 模式如下:
<xs:complexType name="PurchaseListType">
<xs:sequence>
<xs:element
name="entry"
type="partEntry"
nillable="true"
maxOccurs="unbounded"
minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="partEntry">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute
name="key"
type="xs:int"
use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
类AdapterPurchaseListToHashMap
实现XmlAdapter
接口。在类KitchenWorldBasket
中, @XmlJavaTypeAdapter
注释用于将AdapterPurchaseListToHashMap
与字段HashMap
篮子
配对。这种配对导致AdapterPurchaseListToHashMap
的编组或解组方法被调用KitchenWorldBasket
上的任何相应的编组或解组动作。
使用 Ant 构建并运行 j2s-xmlAdapter 示例
要在终端窗口中使用 Ant 编译和运行 j2s-xmlAdapter 示例,请转到 jaxb-ri-install / samples / j2s-xmlAdapter /
目录并键入以下内容:
ant
j2s-xmlAttribute 示例
j2s-xmlAttribute 示例显示如何使用@XmlAttribute
批注定义要作为 XML 属性处理的属性或字段。
@XmlAttribute
批注将字段或 JavaBean 属性映射到 XML 属性。实现以下规则:
- 静态 final 字段映射到 XML 固定属性。
- 当字段或属性是集合类型时,集合类型的项必须映射到模式简单类型。
- 当字段或属性不是集合类型时,类型必须映射到模式简单类型。
遵循 JavaBean 编程范例时,属性由字段名称上的get
和设置
前缀定义。
int zip;
public int getZip(){return zip;}
public void setZip(int z){zip=z;}
在 bean 类中,您可以选择在以下三个组件之一上设置@XmlAttribute
注释:字段,setter 方法或 getter 方法。如果在字段上设置@XmlAttribute
注释,则必须重命名 setter 方法,否则编译时会出现命名冲突。如果在其中一个方法上设置@XmlAttribute
注释,则必须在 setter 或 getter 方法上设置,但不能在两者上设置。
XmlAttribute 示例演示如何在静态 final 字段,字段而不是相应的 bean 方法之一,bean 属性(方法)和字段上使用@XmlAttribute
注释。除了集合类型。在类USAddress
中,字段,国家和 zip 被标记为属性。 setZip
方法被禁用以避免编译错误。属性状态被标记为 setter 方法的属性。您可以使用 getter 方法。在类PurchaseOrderType
中,字段cCardVendor
是非集合类型。它符合简单类型的要求;它是enum
类型。
使用 Ant 构建并运行 j2s-xmlAttribute 示例
要使用 Ant 编译并运行 j2s-xmlAttribute 示例,请在终端窗口中转到 jaxb-ri-install / samples / j2s-xmlAttribute /
目录并键入以下内容:
ant
j2s-xmlRootElement 示例
j2s-xmlRootElement 示例演示了如何使用@XmlRootElement
批注为相应类的 XML 模式类型定义 XML 元素名称。
@XmlRootElement
注释将类或枚举
类型映射到 XML 元素。每个用于解组和编组的顶级 Java 类型至少需要一个元素定义。如果没有元素定义,则没有 XML 内容处理的起始位置。
@XmlRootElement
注释使用类名作为默认元素名称。您可以使用注释属性名称
更改默认名称。如果这样做,指定的名称将用作元素名称和类型名称。元素和类型名称的通用模式实践是不同的。您可以使用@XmlType
注释来设置元素类型名称。
@XmlRootElement
批注的 namespace 属性用于定义元素的命名空间。
使用 Ant 构建并运行 j2s-xmlRootElement 示例
要在终端窗口中使用 Ant 编译和运行 j2s-xmlRootElement 示例,请转到 jaxb-ri-install / samples / j2s-xmlRootElement /
目录并键入以下内容:
ant
j2s-xmlSchemaType 示例
j2s-xmlSchemaType 示例演示如何使用注释@XmlSchemaType
来自定义属性或字段到 XML 内置类型的映射。
@XmlSchemaType
注释可用于将 Java 类型映射到 XML 内置类型之一。在将 Java 类型映射到九种日期/时间原始数据类型之一时,此注释最有用。
当在包级别定义@XmlSchemaType
注释时,标识需要 XML 内置类型名称和相应的 Java 类型类。字段或属性上的@XmlSchemaType
定义优先于包定义。
XmlSchemaType 类示例显示如何在包级别,字段和属性上使用@XmlSchemaType
批注。文件TrackingOrder
有两个字段, orderDate
和deliveryDate
,它们被定义为XMLGregorianCalendar
类型。生成的模式将这些元素定义为 XML 内置类型gMonthDay
。此关系在文件package-info.java
中的包上定义。文件中的字段
shipDateTrackingOrder
也被定义为XMLGregorianCalendar
类型,但@XmlSchemaType
注释语句覆盖包定义并指定字段为日期
。属性方法getTrackingDuration
定义要定义为基本类型持续时间
而不是 Java 类型String
的模式元素。
使用 Ant 构建并运行 j2s-xmlSchemaType 示例
要使用 Ant 编译并运行 j2s-xmlSchemaType 示例,请在终端窗口中转到 jaxb-ri-install / samples / j2s-xmlSchemaType /
目录并键入以下内容:
ant
j2s-xmlType 示例
j2s-xmlType 示例演示了@XmlType
注释的使用。 @XmlType
注释将类或枚举
类型映射到 XML 架构类型。
类必须具有公共零参数构造器或静态零参数工厂方法才能通过此批注进行映射。在解组期间使用这些方法之一来创建类的实例。工厂方法可以位于工厂类或现有类中。
关于解组使用哪种方法有一个优先顺序:
- 如果在注释中标识了工厂类,则还必须标识该类中的相应工厂方法,并且将使用该方法。
- 如果在注释中标识了工厂方法但未标识工厂类,则工厂方法必须位于当前类中。即使存在公共零参数构造器方法,也使用工厂方法。
- 如果注释中未标识工厂方法,则该类必须包含公共零参数构造器方法。
在此示例中,工厂类为多个类提供零 arg 工厂方法。类OrderContext
上的@XmlType
注释引用工厂类。 unmarshaller 在此类中使用已识别的工厂方法。
public class OrderFormsFactory {
public OrderContext newOrderInstance() {
return new OrderContext()
}
public PurchaseOrderType {
newPurchaseOrderType() {
return new newPurchaseOrderType();
}
}
@XmlType(name="oContext",
factoryClass="OrderFormsFactory",
factoryMethod="newOrderInstance")
public class OrderContext {
public OrderContext() {
// ...
}
}
}
在此示例中,工厂方法在类中定义,该类还包含标准类构造。因为定义了factoryMethod
值并且没有定义factoryClass
,所以在解组期间使用工厂方法newOrderInstance
。
@XmlType(name="oContext",
factoryMethod="newOrderInstance")
public class OrderContext {
public OrderContext() {
// ...
}
public OrderContext newOrderInstance() {
return new OrderContext();
}
}
使用 Ant 构建并运行 j2s-xmlType 示例
要在终端窗口中使用 Ant 编译和运行 j2s-xmlType 示例,请转到 jaxb-ri-install / samples / j2s-xmlType /
目录并键入以下内容:
ant