我正在使用类 JAXBContext 中的各种形式的 newInstance 方法进行试验(我正在使用Oracle JDK 1.7附带的默认Sun JAXB实现) .
它's not clear to me when it'可以将具体类与 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,其中接受的答案包括"building the JAXB context based on individual classes rather than object factories"的选项 . 我正在使用的示例 a.xml 和 JAXB 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() );
}
1 回答
JAXB Model Generated from XML Schema
从XML模式生成的模型创建
JAXBContext
时,我总是建议在生成的类的包名称上执行此操作 .使用带有
ClassLoader
参数的newInstance
方法更好 . 当您从Java SE迁移到Java EE环境时,这将为您带来悲伤 .在包名称上创建
JAXBContext
时,JAXB impl假定您从XML模式生成模型并引入ObjectFactory
类,因为它始终使用此名称生成使用@XmlRegistry
注释的类 .Starting from a Java Model
这是我建议人们使用带有类的
newInstance
方法 . 从JAXB类引导JAXBContext
时,名为ObjectFactory
的类没有什么特别之处 .ObjectFactory
的角色可以由任何使用@XmlRegistry
注释的类播放,因此不会自动查找 . 这就是为什么当你明确引用ObjectFactory
时你的用例有效,而当你没有引用时失败了 .