尝试解组xml时类转换exception?

试图在这里通过一个类抛出exception:

FooClass fooClass = (FooClass ) unmarshaller.unmarshal(inputStream); 

抛出这个exception:

 java.lang.ClassCastException: javax.xml.bind.JAXBElement 

我不明白这一点 – 因为这个类是由xjc.bat工具生成的 – 而且它生成的类我根本没有改变 – 所以在这里不应该有任何投射问题 – 反组织者应该真的给我一个类可以转换为FooClass。

任何想法,我做错了什么?

FooClass是否具有XmlRootElement注释? 如果不是,请尝试:

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

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

我今天遇到了同样的问题,在这里看到了答案,做了一些研究,并且在我看来,最通用的解决scheme是使用JAXBIntrospector 。 因此 –

 FooClass fooClass = (FooClass ) unmarshaller.unmarshal(inputStream); 

应该写成

 FooClass fooClass = (FooClass) JAXBIntrospector.getValue(unmarshaller.unmarshal(inputStream)); 

或者甚至更好,使其更通用 –

 T t = (T) JAXBIntrospector.getValue(unmarshaller.unmarshal(inputStream)); 

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

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

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

更完整的解释请阅读这篇文章 。 事实certificate,您的XSD必须正确设置,即必须有一些根元素包含所有其他元素。

XJC确实试图将@XmlRootElement注释放在我们从复杂types生成的类上。 确切的情况有点难看,但基本思想是,如果我们可以静态地保证一个复杂的types不会被多个不同的标签名称使用,我们把@XmlRootElement

我会看看XML文件,并确保它大致是你期望看到的。

我也暂时将代码更改为:

 Object o = unmarshaller.unmarshal(inputStream); System.out.println(o.getClass()); 

如果第一个失败,那么在解组方法中发生类转换,如果成功,那么你可以看到你正在返回的实际类,然后找出为什么它不是你所期望的。

我们花费了太多的时间与JAXB工厂类相处,以满足解组织者的需求。 我们已经知道,在调用JAXB生成的对象工厂的情况下使用unmarshaller工作正常。 希望示例代码能够挽回某人的挫败感:

 System.out.println("Processing generic-type unmarshaller: "); MessageClass mcObject = unmarshalXml(MessageClass.class, msgQryStreamSource, NAMESPACE + "." + "MessageClass"); public static <T> T unmarshalXml(Class<T> clazz, StreamSource queryResults, String contextNamespace) { T resultObject = null; try { //Create instance of the JAXBContext from the class-name JAXBContext jc; jc = JAXBContext.newInstance(Class.forName(clazz.getName())); Unmarshaller u = jc.createUnmarshaller(); resultObject = clazz.cast(u.unmarshal(queryResults)); } //Put your own error-handling here. catch(JAXBException e) { e.printStackTrace(); } catch (ClassCastException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } return clazz.cast(resultObject); } 

在预览的基础上,从同事的答案,以防万一还在寻找答案。

我有我的scheme的根元素被定义为的问题:

 <schema> <element name="foo" type="bar" /> <complexType name="bar" /> </schema> 

因此我得到了一个Cast Exception:

 try { javax.xml.bind.JAXBContext jaxbCtx = javax.xml.bind.JAXBContext.newInstance(mobilityConfigType.getClass().getPackage().getName()); javax.xml.bind.Unmarshaller unmarshaller = jaxbCtx.createUnmarshaller(); File f = FileUtil.toFile(this.getPrimaryFile()); mobilityConfigType = (MobilityModelConfigType)unmarshaller.unmarshal(FileUtil.toFile(this.getPrimaryFile())); } catch (javax.xml.bind.JAXBException ex) { java.util.logging.Logger.getLogger("global").log(java.util.logging.Level.SEVERE, null, ex); //NOI18N } 

我所做的是将try块的第一行更改为:

 javax.xml.bind.JAXBContext jaxbCtx = javax.xml.bind.JAXBContext.newInstance(mobilityConfigType.getClass().getName()); 

这解决了我的问题。

您是否确定FooClass是您通过它的xmlinput源的根元素? Unmarshall将返回由xjc创build的根元素的一个对象。

有时候你有一个带有多个不同根元素的XSD定义(例如WSDL中定义的XSD),在这种情况下,生成的类缺less@XmlRootElement。 所以正如用户mbrauh已经写了,你必须得到JAXBElement的价值。 在我的情况下,我用:

 FooClass request = ((JAXBElement< FooClass >) marshaller.unmarshal(new StreamSource(classPathResource.getInputStream()))).getValue(); 

所以使用generics,你可以很容易地避免双重types的铸造。

指定@XmlRootElement(name =“指定名称”,namespace =“namespace”)来转换对象。

我也遇到了“Javax.xml.bind.JAXBElement无法转换”的错误,发现这个非常简单的解决scheme:

 FooClass fooClass = (FooClass) ((JAXBElement) u.unmarshal(new File("xml/foo.xml")) ).getValue(); 

因为显然,返回了一个JAXBElementtypes的对象,所以你需要改写它的值。

来源: https : //forums.oracle.com/thread/1625944

尝试这个:

 JAXBContext jc = JAXBContext.newInstance(Foo.class); Unmarshaller unmarshaller = jc.createUnmarshaller(); JAXBElement element = (JAXBElement) unmarshaller.unmarshal( new StringReader(xmlString)); Foo foo = (Foo)element;