JAXB 学习
😄 @Auther: sizaif
📆 2021-06-06 21:13:30
[TOC]
说明
Java XML绑定体系结构(JAXB)通过JAXB应用程序的示例介绍了Java XML绑定体系结构(JAXB)技术。
在阅读本教程之前
要理解和使用XML绑定Java体系结构(JAXB)教程中的信息,您应该了解以下技术:
- Java编程语言及其开发环境
- 可扩展标记语言
本教程只详细研究JAXB特有的代码。
JAXB概论
用于XML绑定的Java体系结构(JAXB)提供了一种快速而方便的方法来绑定XML模式和Java表示,使得Java开发人员可以很容易地在Java应用程序中合并XML数据和处理函数。作为此过程的一部分,JAXB提供了将XML实例文档编组(读取)为Java内容树,然后将Java内容树编组(写入)为XML实例文档的方法。JAXB还提供了一种从Java对象生成XML模式的方法。
AXB 2.0包含了JAXB 1.0的几个重要改进:
- 支持所有W3C XML Schema特性。(JAXB 1.0没有为某些W3C XML Schema特性指定绑定。)
- 通过添加
javax.xml.bind.annotation
包来控制这种绑定,支持将java绑定到xml。(JAXB 1.0指定了XML模式到java的映射,但没有指定java到XML模式的映射。) - 显著减少了生成的模式派生类的数量。
- 通过JAXP 1.3验证api提供的额外验证功能。
- 较小的运行时库。
本课描述JAXB体系结构、函数和核心概念,并提供示例和使用JAXB的逐步过程。
JAXB架构
本节描述JAXB处理模型中的组件和交互。
结构概述
下图显示了组成JAXB实现的组件。
图:JAXB体系结构概述
JAXB实现由以下架构组件组成:
- 模式编译器:将源模式绑定到一组从模式派生的程序元素。绑定由基于xml的绑定语言描述。
- 模式生成器:将一组现有的程序元素映射到派生的模式。映射是由程序注释描述的。
- 绑定运行时框架:提供解组(读取)和编组(写入)操作,以便使用模式派生的或现有的程序元素访问、操作和验证XML内容。
JAXB绑定过程
下图显示了JAXB绑定过程中发生的事情。
图:JAXB绑定过程中的步骤
JAXB数据绑定过程中的一般步骤是:
- 生成类(
Generate classes
):将XML模式用作JAXB绑定编译器的输入,以基于该模式生成JAXB类。 - 编译类(
Compile classes
):必须编译所有生成的类、源文件和应用程序代码。 - 解组(
Unmarshal
):根据源模式中的约束编写的XML文档由JAXB绑定框架解组。请注意,JAXB还支持从文件和文档以外的源(如DOM节点、字符串缓冲区、SAX源等)对XML数据进行解组。 - 生成内容树(
Generate content tree
):解组过程生成从生成的JAXB类实例化的数据对象的内容树;这个内容树表示源XML文档的结构和内容。 - 验证(可选)😦
Validate (optional)
)解组过程涉及在生成内容树之前验证源XML文档。注意,如果在步骤6中修改了内容树,还可以使用JAXB Validate操作在将内容编组回XML文档之前验证更改。 - 过程内容(
Process content
):通过使用绑定编译器生成的接口,客户机应用程序可以修改Java内容树表示的XML数据。 - 封装(
Marshal
):将处理过的内容树封送到一个或多个XML输出文档。可以在编组前对内容进行验证。
More About Unmarshalling
解组(Unmarshalling
)为客户机应用程序提供了将XML数
据转换为jaxb派生的Java对象
的能力。即 从xml -> java object
More About Marshalling
Marshalling 为客户端应用程序提供将jaxb派生的Java对象
树转换为XML
数据的能力。 即从 java object -> xml
默认情况下,Marshalle
r在生成XML数据时使用UTF-8
编码。
客户机应用程序不需要在编组之前验证Java内容树。也不要求Java内容树相对于其原始模式是有效的,以便将其编组为XML数据。
More About Validation
Validation 是验证XML文档是否满足模式中表示的所有约束的过程
JAXB 1.0在编组时提供验证,并在JAXB内容树上支持按需验证。JAXB 2.0只允许在解组和编组时进行验证。web服务处理模型在读取数据时是宽松的,而在写出数据时是严格的。为了满足该模型,在封送时间中添加了验证,以便用户可以确认在修改JAXB表单中的文档时没有使XML文档失效。
表示 XML 内容
本节描述 JAXB 如何将 XML 内容表示为 Java 对象。
XML 模式的 Java 表示
JAXB 支持在 Java 包中对生成的类进行分组。一个包包含以下内容:
- 从 XML 元素名称派生或由绑定定制指定的 Java 类名称。
- 一个
ObjectFactory的
类,它是用来返回一个必然的Java类的实例的工厂。
绑定 XML 模式
本节介绍 JAXB 使用的默认 XML-to-Java 绑定。所有这些绑定都可以通过使用自定义绑定声明来全局或逐个覆盖。有关默认 JAXB 绑定的完整信息,请参阅 JAXB 规范。
简单类型定义
使用简单类型定义的模式组件通常绑定到 Java 属性。因为有不同种类的架构组件,以下 Java 属性属性(架构组件通用)包括:
- 基础类型
- 集合类型,如果有
- 谓词
其余的 Java 属性属性是使用简单
类型定义在模式组件中指定的。
默认数据类型绑定
以下部分解释了默认的 schema-to-Java、 JAXBElement
和 Java-to-schema 数据类型绑定。
Schema-to-Java Mapping
Java语言提供了比XML模式更丰富的数据类型集,下表提供了JAXB中XML数据类型到Java数据类型的映射。
XML Schema Type | Java Data Type |
---|---|
xsd:string |
java.lang.String |
xsd:integer |
java.math.BigInteger |
xsd:int |
int |
xsd.long |
long |
xsd:short |
short |
xsd:decimal |
java.math.BigDecimal |
xsd:float |
float |
xsd:double |
double |
xsd:boolean |
boolean |
xsd:byte |
byte |
xsd:QName |
javax.xml.namespace.QName |
xsd:dateTime |
javax.xml.datatype.XMLGregorianCalendar |
xsd:base64Binary |
byte[] |
xsd:hexBinary |
byte[] |
xsd:unsignedInt |
long |
xsd:unsignedShort |
int |
xsd:unsignedByte |
short |
xsd:time |
javax.xml.datatype.XMLGregorianCalendar |
xsd:date |
javax.xml.datatype.XMLGregorianCalendar |
xsd:g |
javax.xml.datatype.XMLGregorianCalendar |
xsd:anySimpleType |
java.lang.Object |
xsd:anySimpleType |
java.lang.String |
xsd:duration |
javax.xml.datatype.Duration |
xsd:NOTATION |
javax.xml.namespace.QName |
表:XML模式内置数据类型的JAXB映射
JAXBElement对象
当XML内容的派生Java表示不能推断XML元素信息时,将提供一个JAXBElement对象。该对象具有获取和设置对象名称和对象值的方法。
Java-to-Schema Mapping
下表显示了Java类到XML数据类型的默认映射。
Java Class | XML Data Type |
---|---|
java.lang.String |
xs:string |
java.math.BigInteger |
xs:integer |
java.math.BigDecimal |
xs:decimal |
java.util.Calendar |
xs:dateTime |
java.util.Date |
xs:dateTime |
javax.xml.namespace.QName |
xs:QName |
java.net.URI |
xs:string |
javax.xml.datatype.XMLGregorianCalendar |
xs:anySimpleType |
javax.xml.datatype.Duration |
xs:duration |
java.lang.Object |
xs:anyType |
java.awt.Image |
xs:base64Binary |
javax.activation.DataHandler |
xs:base64Binary |
javax.xml.transform.Source |
xs:base64Binary |
java.util.UUID |
xs:string |
表:XML数据类型到Java类的JAXB映射
自定义生成的类和 Java 程序元素
以下部分描述了如何定制生成的 JAXB 类和 Java 程序元素。
Schema-to-Java
自定义JAXB绑定声明使您能够在XML模式中特定于XML的约束之外自定义生成的JAXB类,以包括特定于java的细化,例如类和包名映射。
JAXB 提供了两种自定义 XML 模式的方法:
- 作为源 XML 模式中的内联注释
- 作为传递给 JAXB 绑定编译器的外部绑定定制文件中的声明
本文档后面提供了展示如何定制 JAXB 绑定的代码示例。
Java-to-Schema
javax.xml.bind.annotation
包中定义的 JAXB 注释可用于自定义 Java 程序元素到 XML 模式的映射。下表总结了可用于 Java 包的 JAXB 注释。
表:与 Java 包关联的 JAXB 注释
下表总结了可以与Java类一起使用的JAXB注释。
表:与 Java 类关联的 JAXB 注释
下表总结了可用于 Java枚举
类型的JAXB 注释。
表:与 Java枚举
类型关联的 JAXB 注释
下表总结了可用于 Java 属性和字段的 JAXB 注释。
表:与 Java 属性和字段关联的 JAXB 注释
下表总结了可用于对象工厂的 JAXB 注释。
表:与对象工厂关联的 JAXB 注释
下表总结了可与适配器一起使用的 JAXB 注释。
表:与适配器关联的 JAXB 注释
JAXB Examples
以下部分描述了如何使用 JAXB RI 包中包含的示例应用程序。JAXB RI 包可从 http://jaxb.java.net 获得。下载并安装 JAXB RI 包。这些示例位于jaxb-ri-install /samples/
目录中。这些示例演示并建立在关键的 JAXB 特性和概念之上。按照显示的顺序执行这些程序。
阅读完本节后,您应该对 JAXB 感到很舒服,您可以:
-
从 XML 模式生成 JAXB Java 类
-
使用模式派生的 JAXB 类来解组和编组 Java 应用程序中的 XML 内容
-
使用派生架构的 JAXB 类创建 Java 内容树
-
在解组和运行时验证 XML 内容
-
自定义 JAXB 模式到 Java 的绑定
本文档描述了三组示例:
- 基本示例(Modify Marshal、Unmarshal Validate)演示了基本的 JAXB 概念,例如使用默认设置和绑定解组、编组和验证 XML 内容。
- 自定义示例(自定义内联、数据类型转换器、外部自定义)演示了自定义 XML 模式到 Java 对象的默认绑定的各种方法。
- java-to-schema 示例展示了如何使用注释将 Java 类映射到 XML 模式。
注意: 基本和自定义示例基于采购订单场景。每个都使用一个 XML 文档po.xml
,它是针对 XML 模式po.xsd 编写的
。这些文档来自 W3C XML Schema Part 0: Primer,由 David C. Fallside 编辑。
基本和自定义示例目录包含几个基本文件:
po.xsd
是 XML 模式,用作 JAXB 绑定编译器的输入,将从模式派生的 JAXB Java 类生成。对于自定义内联和数据类型转换器示例,此文件包含内联绑定自定义。po.xml
是包含示例 XML 内容的采购订单 XML 文件,它是每个示例中解组到 Java 内容树中的文件。该文件在每个示例中几乎相同;有细微的内容差异来突出不同的 JAXB 概念。Main.java
是每个示例的主要 Java 类。build.xml
是一个为您提供方便的 Ant 项目文件。使用 Ant 工具自动生成、编译和运行模式派生的 JAXB 类。该的build.xml
文件跨越例子变化。inline-customize
示例中的MyDatatypeConverter.java
是一个 Java 类,用于提供自定义数据类型转换。- 外部定制示例中的
binding.xjb
是一个外部绑定声明文件,它被传递到 JAXB 绑定编译器以定制默认的 JAXB 绑定。
下表简要描述了基本的、定制的和 java-to-schema JAXB 示例。
Example Name | Description |
---|---|
Modify Marshal | 演示如何修改Java内容树。 |
Unmarshal Validate | 演示如何在解组期间启用验证 |
表:定制JAXB示例
Example Name | Description |
---|---|
Customize Inline | 演示如何通过在 XML 模式中使用内联注释来自定义默认 JAXB 绑定。 |
Datatype Converter | 说明 XML simpleType 定义到 Java 数据类型的替代、更简洁的绑定,类似于自定义内联示例。 |
External Customize | 说明如何使用外部绑定声明文件将只读模式的绑定自定义传递给 JAXB 绑定编译器。 |
表:java到模式的JAXB示例
Example Name | Description |
---|---|
Create Marshal | 演示如何使用 ObjectFactory 类创建 Java 内容树并将其编组为 XML 数据。它还演示了如何向 JAXB 列表属性添加内容。 |
XmlAccessorOrder | 说明如何在 Java 类中使用@XmlAccessorOrder 和@XmlType.propOrder 映射注释来控制 Java 类型编组或解组 XML 内容的顺序。 |
XmlAdapter | 说明如何使用接口XmlAdapter 和注释@XmlJavaTypeAdapter 提供 XML 内容进出HashMap (字段)的自定义映射,该字段使用整数 ( int ) 作为键,将字符串 ( String ) 作为值。 |
XmlAttribute | 说明如何使用注解@XmlAttribute 定义要作为 XML 属性处理的属性或字段。 |
XmlRootElement | 说明如何使用注释@XmlRootElement 为相应类的 XML 架构类型定义 XML 元素名称。 |
XmlSchemaType Class | 说明如何使用注释@XmlSchemaType 自定义属性或字段到 XML 内置类型的映射。 |
XmlType | 说明如何使用注释@XmlType 将类或枚举 类型映射到 XML 架构类型。 |
下表描述了基本示例的这些类及其与源XML模式的特定绑定。
表:Schema-to-Java
绑定
Schema-Derived JAXB Classes
下一节将简要解释JAXB绑定编译器为示例生成的以下各个类的功能:
- [
Items
Class](#Items` Class) - [
ObjectFactory
Class](#ObjectFactory` Class) - [
PurchaseOrderType
Class](# Class) - [
USAddress
Class](#USAddress` Class)
Items
Class
In Items.java
:
- 该
项目
类是部分primer.po
包。 - 该类为
Items
和ItemType
提供公共接口。 - 此类实例化中的内容绑定到 XML ComplexTypes
Items
及其子元素ItemType
。 Item
提供了getItem()
方法。ItemType
提供以下方法:getPartNum();
setPartNum(String value);
getComment();
setComment(java.lang.String value);
getUSPrice();
setUSPrice(java.math.BigDecimal value);
getProductName();
setProductName(String value);
getShipDate();
setShipDate(java.util.Calendar value);
getQuantity();
setQuantity(java.math.BigInteger value);
ObjectFactory
Class
In ObjectFactory.java
:
- 所述
的ObjectFactory
类是部分primer.po
包。 ObjectFactory
提供了工厂方法,用于在 Java 内容树中实例化表示 XML 内容的 Java 接口。- 方法名称是通过连接生成的:
- 字符串常量
create
。 - 所有外部 Java 类名称,如果 Java 内容接口嵌套在另一个接口中。
- Java 内容接口的名称。
- 字符串常量
例如,在这种情况下,对于 Java 接口prime.po.Items.ItemType
,ObjectFactory
创建方法createItemsItemType()
。
PurchaseOrderType
Class
In PurchaseOrderType.java
:
- 所述
PurchaseOrderType
类是部分primer.po
包。 - 此类实例化中的内容绑定到名为
PurchaseOrderType
的 XML 架构子元素。 PurchaseOrderType
是一个公共接口,提供以下方法:getItems();
setItems(primer.po.Items value);
getOrderDate();
setOrderDate(java.util.Calendar value);
getComment();
setComment(java.lang.String value);
getBillTo();
setBillTo(primer.po.USAddress value);
getShipTo();
setShipTo(primer.po.USAddress value);
USAddress
Class
In USAddress.java
:
- 的
校舍地址
类是部分primer.po
包。 - 此类实例化中的内容绑定到名为
USAddress
的 XML 模式元素。 USAddress
是一个公共接口,提供以下方法:getState();
setState(String value);
getZip();
setZip(java.math.BigDecimal value);
getCountry();
setCountry(String value);
getCity();
setCity(String value);
getStreet();
setStreet(String value);
getName();
setName(String value);
基本示例
本节介绍了基本 JAXB 示例(Modify Marshal、Unmarshal Validate),这些示例演示了如何:
- 将 XML 文档解组为 Java 内容树并访问其中包含的数据
- 修改 Java 内容树
- 使用
ObjectFactory
类创建 Java 内容树,然后将其编组为 XML 数据 - 在解组期间执行验证
- 在运行时验证 Java 内容树
Modify Marshal Example
Modify Marshal示例演示了如何修改Java内容树。
-
该JAXB里安装
/samples/modify-marshal/src/Main.java
类声明导入三种标准的Java类,五JAXB绑定框架类和的primer.po
包:import java.io.FileInputStream; import java.io.IOException; import java.math.BigDecimal; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBElement; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; import primer.po.*;
-
创建了一个
JAXBContext
实例来处理在prime.po
中生成的类JAXBContext jc = JAXBContext.newInstance( "primer.po" );
-
创建了一个
Unmarshaller
实例,并解组
了po.xml
文件。Unmarshaller u = jc.createUnmarshaller(); PurchaseOrder po = (PurchaseOrder) u.unmarshal(new FileInputStream("po.xml"));
-
set
方法用于修改内容树的地址
分支中的信息。USAddress address = po.getBillTo(); address.setName("John Bob"); address.setStreet("242 Main Street"); address.setCity("Beverly Hills"); address.setState("CA"); address.setZip(new BigDecimal address.setName("John Bob"); address.setStreet("242 Main Street"); address.setCity("Beverly Hills"); address.setState("CA"); address.setZip(new BigDecimal("90210"));
-
创建了一个
Marshaller
实例,并将更新的 XML 内容编组到system.out
。所述的setProperty
API用于指定输出编码; 在这种情况下,它是格式化的(人类可读的)XML。Marshaller m = jc.createMarshaller(); m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); m.marshal(po, System.out);
Building and Running the Modify Marshal Example Using Ant
要使用 Ant 编译和运行 Modify Marshal 示例,请在终端窗口中,转到jaxb-ri-install /samples/modify-marshal/
目录并键入以下内容:
ant
Unmarshal Validate Example
Unmarshal Validate 示例演示了如何在解组期间启用验证。请注意,JAXB 在解组期间提供验证功能,但在编组期间不提供。验证在更多关于验证中进行了更详细的解释 。
-
该JAXB里安装
/samples/unmarshal-validate/src/Main.java
类声明为一个标准的Java类,十JAXB绑定框架类和进口primer.po
包:import java.io.File; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.bind.UnmarshalException; import javax.xml.bind.Unmarshaller; import javax.xml.bind.ValidationEvent; import javax.xml.bind.ValidationEventHandler; import javax.xml.bind.ValidationEventLocator; import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI; import javax.xml.validation.SchemaFactory; import javax.xml.validation.Schema; import primer.po.*;
-
创建了一个
JAXBContext
实例来处理在prime.po
包中生成的类。JAXBContext jc = JAXBContext.newInstance("primer.po");
-
一个
Unmarshaller
的实例被创建。Unmarshaller u = jc.createUnmarshaller();
-
默认的 JAXB
Unmarshaller ``ValidationEventHandler
已启用以向system.out
发送验证警告和错误。默认配置会导致解组操作在遇到第一个验证错误时失败。u.setValidating( true );
-
尝试将
po.xml
文件解组为 Java 内容树。出于本示例的目的,po.xml
文件包含故意错误PurchaseOrder po = (PurchaseOrder)u.unmarshal( new FileInputStream("po.xml"));
-
默认验证事件处理程序处理验证错误,生成输出到
system.out
,然后抛出异常.} catch( UnmarshalException ue ) { System.out.println("Caught UnmarshalException");} catch( JAXBException je ) { je.printStackTrace();} catch( IOException ioe ) { ioe.printStackTrace();}
Building and Running the Unmarshal Validate Example Using Ant
要使用 Ant 编译和运行 Unmarshal Validate 示例,请在终端窗口中,转到jaxb-ri-install /samples/unmarshal-validate/
目录并键入以下内容:
ant