尝试解组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;