尝试解组xml时的类强制转换异常?

Vid*_*dar 51 java jaxb jaxb2

试图通过这里的类投射异常:

FooClass fooClass = (FooClass ) unmarshaller.unmarshal(inputStream);
Run Code Online (Sandbox Code Playgroud)

抛出此异常:

java.lang.ClassCastException: javax.xml.bind.JAXBElement
Run Code Online (Sandbox Code Playgroud)

我不明白这个 - 因为这个类是由xjc.bat工具生成的 - 它生成的类我根本没有改变 - 所以这里应该没有转换问题 - unmarshaller应该真的给我一个类可以投射到FooClass.

关于我做错了什么的任何想法?

Jon*_*eet 112

是否FooClassXmlRootElement注释?如果没有,请尝试:

Source source = new StreamSource(inputStream);
JAXBElement<FooClass> root = unmarshaller.unmarshal(source, FooClass.class);
FooClass foo = root.getValue();
Run Code Online (Sandbox Code Playgroud)

这是基于非官方的JAXB指南.

  • 为什么JAXB编译器首先没有在我的类中放置XmlRootElement注释 - 因为我找不到它.你的代码有效 - 但我想知道更多 - 也就是说它为什么有效? (2认同)
  • @splash:编辑. (2认同)

Rah*_*kur 16

在JAXBElement上使用JAXBIntrospector来获取类似>>的schemaObject

JAXBContext jaxbContext = JAXBContext.newInstance(Class.forName(className));
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
Object schemaObject = JAXBIntrospector.getValue(unmarshaller.unmarshal(new ByteArrayInputStream(xmlString.getBytes())));
Run Code Online (Sandbox Code Playgroud)

请参阅:JAXB unmarshaller.unmarshal何时返回JAXBElement <MySchemaObject>或MySchemaObject?

  • 这个解决方案很简单,适用于演员 (3认同)

Gau*_*v B 15

我今天遇到了同样的问题,在这里看到了答案,做了一些研究,并期待我最通用的解决方案是使用JAXBIntrospector.因此 -

FooClass fooClass = (FooClass ) unmarshaller.unmarshal(inputStream);
Run Code Online (Sandbox Code Playgroud)

应该写成

FooClass fooClass = (FooClass) JAXBIntrospector.getValue(unmarshaller.unmarshal(inputStream));
Run Code Online (Sandbox Code Playgroud)

或者甚至更好,使它更通用 -

T t = (T) JAXBIntrospector.getValue(unmarshaller.unmarshal(inputStream));
Run Code Online (Sandbox Code Playgroud)


Vid*_*dar 9

有关更全面的解释,请阅读本文.事实证明,您的XSD必须正确设置,即必须有一些根元素包含所有其他元素.

XJC确实尝试将@XmlRootElement注释放在我们从复杂类型生成的类上.确切的条件有点难看,但基本的想法是,如果我们可以静态地保证复杂类型不会被多个不同的标签名称使用,我们就说@XmlRootElement.