JAXBContext.newInstance变体

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

我不清楚只需将具体类与ObjectFactory类传递给newInstance方法即可。 我应该注意到,我正在使用JAXB纯粹用于解析XML文件,即仅在XML-> Java方向。

这是展示我观点的绝对最小代码:

xsd文件

         

鉴于上述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变体的原因是我偶然发现了这个问题 ,其中接受的答案包括“基于个别类而不是对象工厂构建JAXB上下文”的选项。 我正在使用的示例a.xmlJAXB Java代码在post的末尾。

示例使用了a.xml

   foo  

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)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类的newInstance方法。 从JAXB类引导JAXBContext ,名为ObjectFactory的类没有什么特别之处。 ObjectFactory的角色可以由任何使用@XmlRegistry注释的类来播放,因此不会自动查找。 这就是为什么你的用例在你明确引用ObjectFactory时工作的原因,而在你没有引用时失败了。