gpt4 book ai didi

java - JAXBContext.newInstance 变体

转载 作者:IT老高 更新时间:2023-10-28 21:01:46 26 4
gpt4 key购买 nike

我正在 JAXBContext 类中试验各种形式的 newInstance 方法(我使用的是 Oracle JDK 1.7 附带的默认 Sun JAXB 实现)。

我不清楚何时可以将具体类与 ObjectFactory 类传递给 newInstance 方法。我应该注意,我使用 JAXB 纯粹是为了解析 XML 文件,即仅在 XML->Java 方向上。

这是证明我的观点的绝对最少的代码:

xsd 文件

<?xml version="1.0" encoding="UTF-8"?>
<schema elementFormDefault="qualified"
xmlns ="http://www.w3.org/2001/XMLSchema"
xmlns:a ="http://www.example.org/A"
targetNamespace="http://www.example.org/A">
<element name="root" type="a:RootType"></element>

<complexType name="RootType">
<sequence>
<element name="value" type="string"></element>
</sequence>
</complexType>
</schema>

鉴于上述 XSD,以下 JAXBInstance.newInstance 调用成功地创建了可以解析示例 a.xml 文件的上下文:

  • jc = JAXBContext.newInstance("example.a");
  • jc = JAXBContext.newInstance(example.a.ObjectFactory.class);
  • jc = JAXBContext.newInstance(example.a.RootType.class, example.a.ObjectFactory.class);

但是,在运行时单独传递 example.a.RootType.class 会失败并出现 javax.xml.bind.UnmarshalException:

jc = JAXBContext.newInstance(example.a.RootType.class); // this fails at runtime.

谁能解释一下?我尝试这些 JAXBContext::newInstance 变体的原因是我偶然发现了 this problem其中接受的答案包括“基于单个类而不是对象工厂构建 JAXB 上下文”的选项。我正在使用的示例 a.xmlJAXB Java 代码在文章末尾。

使用的示例 a.xml

<?xml version="1.0" encoding="UTF-8"?>
<a:root xmlns:a="http://www.example.org/A"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.example.org/A A.xsd">
<a:value>foo</a:value>
</a:root>

JAXB解析代码

public static void main (String args[]) throws JAXBException, FileNotFoundException {
JAXBContext jc = null;
message("using package context (press any key:)");
jc = JAXBContext.newInstance("example.a");
work(jc); // SUCCEEDS

message("using Object factory (press any key):");
jc = JAXBContext.newInstance(example.a.ObjectFactory.class);
work(jc); // SUCCEEDS

message("using class enumeration (press any key):");
try {
jc = JAXBContext.newInstance(example.a.RootType.class);
work(jc); // FAILS
} catch (javax.xml.bind.UnmarshalException e) {
e.printStackTrace();
}

message("using class enumeration and Object factory too (press any key):");
jc = JAXBContext.newInstance(example.a.RootType.class, example.a.ObjectFactory.class);
work(jc); // SUCCEEDS

}

private static void work(JAXBContext jc) throws JAXBException, FileNotFoundException {
Unmarshaller u = jc.createUnmarshaller();
RootType root = ((JAXBElement<RootType>)u.unmarshal( new FileInputStream( "a.xml" ))).getValue();
System.out.println( root.getValue() );
}

最佳答案

从 XML Schema 生成的 JAXB 模型

从 XML 模式生成的模型创建 JAXBContext 时,我始终建议在生成的类的包名上执行此操作。

JAXBContext jc = JAXBContext.newInstance("example.a");

最好使用带有 ClassLoader 参数的 newInstance 方法。当您从 Java SE 迁移到 Java EE 环境时,这将为您省去烦恼。

JAXBContext jc = JAXBContext.newInstance("example.a", example.a.ObjectFactory.class.getClassLoader());

当您在包名称上创建 JAXBContext 时,JAXB impl 假定您从 XML 模式生成模型并拉入 ObjectFactory 类,因为它总是生成使用此名称用 @XmlRegistry 注释的类。

从 Java 模型开始

这是我建议人们使用获取类的 newInstance 方法的时候。当从 JAXB 类引导 JAXBContext 时,名为 ObjectFactory 的类没有什么特别之处。 ObjectFactory 的角色可以由任何使用 @XmlRegistry 注释的类来扮演,因此它不会被自动查找。这就是为什么您的用例在您明确引用 ObjectFactory 时有效,而在您没有时失败的原因。

关于java - JAXBContext.newInstance 变体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16860759/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com