JAXBContextAPI详解
javax.xml.bind
类 JAXBContext
java.lang.Object
javax.xml.bind.JAXBContext
public abstract class JAXBContextextends Object
JAXBContext 类提供到 JAXB API 的客户端入口点。它提供了管理实现 JAXB 绑定框架操作所需的 XML/Java 绑定信息的抽象,这些操作包括:解组、编组和验证。
客户端应用程序通常使用以下两种风格的 newInstance 方法之一来获得此类的新实例,但是该方法还有其他可用的特殊形式:
- JAXBContext.newInstance( "com.acme.foo:com.acme.bar" )
JAXBContext 实例是根据冒号分隔的 Java 包名称的列表进行初始化的。每个 java 包都包含 JAXB 映射类、模式派生类和/或用户注释类。此外,java 包可能包含必须处理的 JAXB 包注释。(请参阅 JLS 第 3 版的第 7.4.1 节“包注释”)。 - JAXBContext.newInstance( com.acme.foo.Foo.class )
JAXBContext 实例是使用作为参数传递的类以及可从这些类静态获得的类来实现初始化的。有关详细信息,请参见 newInstance(Class...)。
特别要求:该提供者必须提供包含以下方法签名的实现类:public static JAXBContext createContext( String contextPath, ClassLoader classLoader, Map properties ) throws JAXBException public static JAXBContext createContext( Class[] classes, Map properties ) throws JAXBException以下 JAXB 1.0 要求只是 java 接口/实现绑定的模式所需要的。它不适用于 JAXB 注释类。JAXB 提供者必须在每个包含模式派生类的包中生成一个 jaxb.properties 文件。该属性文件必须包含名为 javax.xml.bind.context.factory 的属性,其值为实现 createContext API 的类的名称。
该提供者提供的类不一定是可分配给 javax.xml.bind.JAXBContext 的,只是必须提供一个实现 createContext API 的类。
此外,提供者必须在执行 marshal 和 unmarshal 方法的任何客户端调用之前调用 DatatypeConverter.setDatatypeConverter api。这在配置将在执行这些操作期间使用的数据类型转换器时是必需的。
解组
Unmarshaller 类使客户端应用程序能够将 XML 数据转换为 Java 内容对象树。unmarshal 方法允许将模式中声明的任何全局 XML 元素解组为实例文档的根。此外,unmarshal 方法允许将未被识别的根元素(该元素具有一个引用了模式中声明的类型定义的 xsi:type 属性值)解组为实例文档的根。JAXBContext 对象允许跨模式集合(已在 contextPath 中列出)合并全局元素和类型定义。因为模式集合中的每个模式可能属于不同的名称空间,所以统一解组上下文的模式应该与名称空间无关。这意味着客户端应用程序能够解组 contextPath 中列出的任何模式实例的 XML 文档。例如:JAXBContext jc = JAXBContext.newInstance( "com.acme.foo:com.acme.bar" ); Unmarshaller u = jc.createUnmarshaller(); FooObject fooObj = (FooObject)u.unmarshal( new File( "foo.xml" ) ); // ok BarObject barObj = (BarObject)u.unmarshal( new File( "bar.xml" ) ); // ok BazObject bazObj = (BazObject)u.unmarshal( new File( "baz.xml" ) ); // error, "com.acme.baz" not in contextPath客户端应用程序还可以显式生成 Java 内容树,而不是解组现有的 XML 数据。对于所有 JAXB 注释值类,应用程序可以使用构造方法来创建内容。对于模式派生的接口/实现类以及未绑定到 JAXB 注释类的元素的创建,应用程序需要访问和了解每个模式派生的 ObjectFactory 类,这些类存在于 contextPath 中包含的每个 java 包中。对于每个模式派生的 java 类,都有一个生成该类型的对象的静态工厂方法。例如,假定在编译模式之后有一个包 com.acme.foo,它包含一个名为 PurchaseOrder 的模式派生接口。为了创建该类型的对象,客户端应用程序将使用如下工厂方法:
com.acme.foo.PurchaseOrder po = com.acme.foo.ObjectFactory.createPurchaseOrder();一旦客户端应用程序有一个模式派生对象的实例,它就可以使用 mutator 方法在该实例上设置内容。
有关生成的 ObjectFactory 类的更多信息,请参阅该规范的第 4.2 节“Java 包”。
特别要求:在包含名为 ObjectFactory 的包所需的所有对象工厂方法以及静态 newInstance( javaContentInterface ) 方法的每个包中,该提供者都必须生成一个类。
编组
Marshaller 类使客户端应用程序能够将 Java 内容树转换回 XML 数据。对使用工厂方法手动创建的内容树进行编组与对作为 unmarshal 操作结果的内容树进行编组没有什么区别。客户端可以将 java 内容树编组回 java.io.OutputStream 或 java.io.Writer 的 XML 数据。编组进程可以生成已注册 ContentHandler 的 SAX2 事件流,也可以生成一个 DOM 节点对象。客户端应用程序控制着输出编码,还控制着是将 XML 数据编组为一个完整的文档还是编组为一个片段。下面是一个解组 XML 文档、然后将其编组回来的简单示例:
JAXBContext jc = JAXBContext.newInstance( "com.acme.foo" ); // unmarshal from foo.xml Unmarshaller u = jc.createUnmarshaller(); FooObject fooObj = (FooObject)u.unmarshal( new File( "foo.xml" ) ); // marshal to System.out Marshaller m = jc.createMarshaller(); m.marshal( fooObj, System.out );
验证
自 JAXB 1.0 以后,验证已经发生了很大的变化。Validator 类已经废弃,成为了一个可选项。这意味着建议您不要使用此类,实际上,根据您的 JAXB 提供者,该类甚至根本不可用。在 JAXB 1.0 运行时系统上进行部署时,依赖 Validator 的 JAXB 1.0 客户端仍然可以正常工作。在 JAXB 2.0 中,Unmarshaller 已包括一些公开 JAXP 1.3 javax.xml.validation 框架的便捷方法。有关详细信息,请参阅 Unmarshaller.setSchema(javax.xml.validation.Schema) API。
JAXB 运行时绑定框架的兼容性
以下 JAXB 1.0 限制仅适用于将模式绑定到接口/实现类。因为此绑定不需要通用的运行时系统,所以 JAXB 客户端应用程序不必尝试混合使用不同的提供者提供的运行时对象(JAXBContext、Marshaller 等)。这并不意味着客户端应用程序是不可移植的,只是意味着客户端必须使用由用来编译模式的同一提供者提供的运行时系统。
- 从以下版本开始:
- JAXB1.0
- 另请参见:
- Marshaller, Unmarshaller, S 7.4.1.1 "Package Annotations" in Java Language Specification, 3rd Edition
字段摘要 | |
---|---|
static String |
JAXB_CONTEXT_FACTORY
属性名称,它包含能够创建新的 JAXBContext 对象的类名称。 |
构造方法摘要 | |
---|---|
protected |
JAXBContext()
|
方法摘要 | ||
---|---|---|
Binder<Node> |
createBinder()
为 W3C DOM 创建一个 Binder。 |
|
|
createBinder(Class<T> domType)
创建一个可用于关联/原地解组/编组操作的 Binder 对象。 |
|
JAXBIntrospector |
createJAXBIntrospector()
创建一个可以用于内省 JAXB 对象的 JAXBIntrospector 对象。 |
|
abstract Marshaller |
createMarshaller()
创建一个可以用来将 java 内容树转换为 XML 数据的 Marshaller 对象。 |
|
abstract Unmarshaller |
createUnmarshaller()
创建一个可以用来将 XML 数据转换为 java 内容树的 Unmarshaller 对象。 |
|
abstract Validator |
createValidator()
已过时。 从 JAXB 2.0 开始 |
|
void |
generateSchema(SchemaOutputResolver outputResolver)
生成此上下文的模式文档。 |
|
static JAXBContext |
newInstance(Class... classesToBeBound)
获得 JAXBContext 类的新实例。 |
|
static JAXBContext |
newInstance(Class[] classesToBeBound,
Map<String,?> properties)
获得 JAXBContext 类的新实例。 |
|
static JAXBContext |
newInstance(String contextPath)
获得 JAXBContext 类的新实例。 |
|
static JAXBContext |
newInstance(String contextPath,
ClassLoader classLoader)
获得 JAXBContext 类的新实例。 |
|
static JAXBContext |
newInstance(String contextPath,
ClassLoader classLoader,
Map<String,?> properties)
获得 JAXBContext 类的新实例。 |
从类 java.lang.Object 继承的方法 |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
字段详细信息 |
---|
JAXB_CONTEXT_FACTORY
public static final String JAXB_CONTEXT_FACTORY
- 属性名称,它包含能够创建新的 JAXBContext 对象的类名称。
- 另请参见:
- 常量字段值
构造方法详细信息 |
---|
JAXBContext
protected JAXBContext()
方法详细信息 |
---|
newInstance
public static JAXBContext newInstance(String contextPath) throws JAXBException
-
获得 JAXBContext 类的新实例。
这是 newInstance 方法的一个便捷方法。它使用当前线程的上下文类加载器。要指定如何使用不同的类加载器,可以通过 Thread.setContextClassLoader() api 设置它,或者使用 newInstance 方法。
- 抛出:
JAXBException
- 如果在创建 JAXBContext 时遇到错误,比如:- 在包中查找 ObjectFactory.class 或 jaxb.index 失败
- 包含在 contextPath 中的全局元素之间出现混淆
- 查找上下文工厂提供者属性的值失败
- 混合使用相同 contextPath 上的不同提供者的模式派生包
newInstance
public static JAXBContext newInstance(String contextPath, ClassLoader classLoader) throws JAXBException
-
获得 JAXBContext 类的新实例。
客户端应用程序必须提供上下文路径,该路径是一个冒号 (':', \u003A) 分隔的 java 包名称列表,它包含模式派生类和/或完全限定的 JAXB 注释类。模式派生的代码是通过为每个包生成的 ObjectFactory.class 在 JAXBContext 中注册的。程序员注释的 JAXB 映射类在 jaxb.index 资源文件中列出,而不是在上下文路径中列出,列出这些类所采用的格式如下所述。注意,java 包可以包含模式派生类和用户注释 JAXB 类。此外,java 包可能包含必须处理的 JAXB 包注释。(请参阅 JLS 第 3 版的第 7.4.1 节“包注释”)。
每个 contextPath 上列出的包都必须满足下面的一个或两个条件,否则将抛出 JAXBException:
- 必须包含 ObjectFactory.class
- 必须包含 jaxb.index
jaxb.index 的格式
该文件应该包含换行符分隔的类名称列表。空格、制表符和空行被忽略。注释字符是 '#' (0x23);每行上的第一个注释字符后面的所有字符都被忽略。文件必须使用 UTF-8 编码。从列出的类中获得的类也可以在 JAXBContext 中注册,正如 newInstance(Class...) 定义的那样。
对 jaxb.index 文件中出现的类名称的限制是:
- 不一定以 ".class" 结尾。
- 类名称与包含 jaxb.index 文件的包相关。只允许使用直接出现在包含 jaxb.index 文件的包中的类。
- 不允许使用完全限定的类名称。只允许与当前包相关的限定类名称指定一个嵌套类或内部类。
为了维护与将 JAXB 1.0 模式绑定到 java 接口/实现的兼容(可通过将模式自定义为 jaxb:globalBindings valueClass="false" 来启用此绑定), JAXB 提供者需要确保上下文路径上的每个包都有一个 jaxb.properties 文件,该文件包含一个 javax.xml.bind.context.factory 属性值,以及解析为相同提供者的所有值。
此要求不适用于 JAXB 注释类。如果 contextPath 上列出的各种包之间存在任何全局 XML 元素名称冲突,则将抛出 JAXBException。
在相同的上下文路径中混合使用从多个 JAXB 提供者中生成的接口/实现绑定可能导致抛出 JAXBException。
- 参数:
contextPath
- 包含模式派生类和/或 java 模式(JAXB 注释)映射类的 java 包名称的列表classLoader
- 此类加载器将用于定位实现类。- 返回:
- 新的 JAXBContext 实例
- 抛出:
JAXBException
- 如果创建 JAXBContext 时遇到错误,如下所示:- 在包中查找 ObjectFactory.class 或 jaxb.index 失败
- 包含在 contextPath 中的全局元素之间出现混淆
- 查找上下文工厂提供者属性的值失败
- 混合使用相同 contextPath 上的不同提供者的模式派生包
newInstance
public static JAXBContext newInstance(String contextPath, ClassLoader classLoader, Map<String,?> properties) throws JAXBException
-
获得 JAXBContext 类的新实例。
多数情况下,这与 newInstance(String, ClassLoader) 相同,但此版本允许传入特定于提供者的属性来配置 JAXBContext 的实例。
属性的解释取决于实现。
- 参数:
contextPath
- 包含模式派生类的 java 包名称的列表classLoader
- 此类加载器将用于定位实现类。properties
- 特定于提供者的属性- 返回:
- 新的 JAXBContext 实例
- 抛出:
JAXBException
- 如果创建 JAXBContext 时遇到错误,如下所示:- 在包中查找 ObjectFactory.class 或 jaxb.index 失败
- 包含在 contextPath 中的全局元素之间出现混淆
- 查找上下文工厂提供者属性的值失败
- 混合使用相同 contextPath 上的不同提供者的模式派生包
- 从以下版本开始:
- JAXB 2.0
newInstance
public static JAXBContext newInstance(Class... classesToBeBound) throws JAXBException
-
获得 JAXBContext 类的新实例。
客户端应用程序必须提供新上下文对象需要识别的类的列表。 新的上下文不仅要识别所有指定的类,还要识别直接/间接从指定类中静态引用的所有类。所引用类的子类或 @XmlTransient 引用类都不用在 JAXBContext 中注册。例如,在下面的 Java 代码中,如果执行 newInstance(Foo.class),则新创建的 JAXBContext 将识别 Foo 和 Bar,但不识别 Zot 或 FooBar:
class Foo { @XmlTransient FooBar c; Bar b; } class Bar { int x; } class Zot extends Bar { int y; } class FooBar { }
因此,典型的客户端应用程序只需指定最高层类,但需要小心。注意,对于每个在 JAXBContext 中注册的 java 包,当存在可选的包注释时,必须对它们进行处理。(请参阅 JLS 第 3 版的第 7.4.1 节“包注释”)。
- 参数:
classesToBeBound
- 将通过新的 JAXBContext 识别的 java 类的列表。可以为空,在这种情况下,将返回只知道规范中定义的类的 JAXBContext。- 返回:
- 新的 JAXBContext 实例。该实例始终是一个非 null 的有效对象。
- 抛出:
JAXBException
- 如果创建 JAXBContext 时遇到错误(但不限于这些错误),如下所示:- 未发现任何 JAXB 实现
- 类以不正确的方式使用了 JAXB 注释
- 类包含有冲突的注释(比如有相同类型名称的两个类)
- JAXB 实现不能查找特定于提供者的带外信息(例如在开发时生成的附加文件)。
IllegalArgumentException
- 如果参数中包含null
(即newInstance(null);
)- 从以下版本开始:
- JAXB 2.0
newInstance
public static JAXBContext newInstance(Class[] classesToBeBound, Map<String,?> properties) throws JAXBException
-
获得 JAXBContext 类的新实例。
可重载 newInstance(Class...) 来配置“属性”,以实例化 JAXBContext。
属性的解释是特定于实现的。
- 参数:
classesToBeBound
- 将通过新 JAXBContext 识别的 java 类的列表。可以为空,在这种情况下,将返回只知道规范中定义的类的 JAXBContext。- 返回:
- 新的 JAXBContext 实例。该实例始终是一个非 null 的有效对象。
- 抛出:
JAXBException
- 如果创建 JAXBContext 时遇到错误(但不限于这些错误),比如:- 未发现任何 JAXB 实现
- 类以不正确的方式使用了 JAXB 注释
- 类包含有冲突的注释(比如有相同类型名称的两个类)
- JAXB 实现不能查找特定于提供者的带外信息(例如在开发时生成的附加文件)。
IllegalArgumentException
- 如果参数中包含null
(即newInstance(null);
)- 从以下版本开始:
- JAXB 2.0
createUnmarshaller
public abstract Unmarshaller createUnmarshaller() throws JAXBException
- 创建一个可以用来将 XML 数据转换为 java 内容树的 Unmarshaller 对象。
- 返回:
- Unmarshaller 对象
- 抛出:
JAXBException
- 如果创建 Unmarshaller 对象时遇到错误
createMarshaller
public abstract Marshaller createMarshaller() throws JAXBException
- 创建一个可以用来将 java 内容树转换为 XML 数据的 Marshaller 对象。
- 返回:
- Marshaller 对象
- 抛出:
JAXBException
- 如果创建 Marshaller 对象时遇到错误
createValidator
public abstract Validator createValidator() throws JAXBException
- 已过时。 从 JAXB 2.0 开始
- Validator 已成为一个可选项,并且在 JAXB 2.0 中已过时。有关详细信息,请参阅 Validator 的 javadoc。
创建一个可用于根据源模式验证 java 内容树的 Validator 对象。
- 返回:
- 一个 Validator 对象
- 抛出:
JAXBException
- 如果创建 Validator 对象时遇到错误
createBinder
public <T> Binder<T> createBinder(Class<T> domType)
- 创建一个可用于关联/原地解组/编组操作的 Binder 对象。
- 参数:
domType
- 选择通过传入其 DOM 节点类获得使用的 DOM API。- 返回:
- 总是返回新的有效 Binder 对象。
- 抛出:
UnsupportedOperationException
- 如果该实现不支持对应于 domType 的 DOM API。- 从以下版本开始:
- JAXB 2.0
createBinder
public Binder<Node> createBinder()
- 为 W3C DOM 创建一个 Binder。
- 返回:
- 总是返回新的有效 Binder 对象。
- 从以下版本开始:
- JAXB 2.0
createJAXBIntrospector
public JAXBIntrospector createJAXBIntrospector()
- 创建一个可以用于内省 JAXB 对象的 JAXBIntrospector 对象。
- 返回:
- 总是返回非 null 的有效 JAXBIntrospector 对象。
- 抛出:
UnsupportedOperationException
- 在 JAXB 1.0 实现上调用此方法将抛出 UnsupportedOperationException。- 从以下版本开始:
- JAXB 2.0
generateSchema
public void generateSchema(SchemaOutputResolver outputResolver) throws IOException
- 生成此上下文的模式文档。
- 参数:
outputResolver
- 此对象控制模式将被发送的输出。- 抛出:
IOException
- 如果 SchemaOutputResolver 抛出 IOException。UnsupportedOperationException
- 在 JAXB 1.0 实现上调用此方法将抛出 UnsupportedOperationException。- 从以下版本开始:
- JAXB 2.0