gpt4 book ai didi

jaxb - JAXB 解码期间发生 InstantiationException(抽象基类,带有 @XmlSeeAlso 具体子类)

转载 作者:行者123 更新时间:2023-12-03 01:50:56 27 4
gpt4 key购买 nike

我遇到如下 JAXB 解码错误。foo.bar.Base 是一个抽象类,带有 @XmlSeeAlso 注释,其中列出了 foo.bar.SubBase (它是 foo.bar.Base 的具体子类)

上述两个类都可以从主/入口类静态访问:com.example.Request

JAXBContext 是使用包字符串变量创建的:

JAXBContext.newInstance("com.example",...);

上面创建的 JAXBContext 正确列出了所有三个类:com.example.Request, foo.bar.Base and foo.bar.SubBase as "classes known to this JAXBContext"

但是在下面的解码调用期间它在运行时失败..我无法弄清楚这里出了什么问题。

unmarshaller.unmarshal(<some-DOM-Element-Instance>, com.example.Request.class);

任何指点将不胜感激!谢谢!

堆栈跟踪是:

    Caused by: javax.xml.bind.UnmarshalException: Unable to create an instance of foo.bar.Base  - with linked exception: [java.lang.InstantiationException]

at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:642)

at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:254)

at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.createInstance(UnmarshallingContext.java:609)

at com.sun.xml.bind.v2.runtime.unmarshaller.StructureLoader.startElement(StructureLoader.java:181)

at com.sun.xml.bind.v2.runtime.unmarshaller.XsiTypeLoader.startElement(XsiTypeLoader.java:76)

at com.sun.xml.bind.v2.runtime.unmarshaller.ProxyLoader.startElement(ProxyLoader.java:55)

at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:481)

at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:459)

at com.sun.xml.bind.v2.runtime.unmarshaller.InterningXmlVisitor.startElement(InterningXmlVisitor.java:71)

at com.sun.xml.bind.v2.runtime.unmarshaller.SAXConnector.startElement(SAXConnector.java:148)

at com.sun.xml.bind.unmarshaller.DOMScanner.visit(DOMScanner.java:239)

at com.sun.xml.bind.unmarshaller.DOMScanner.visit(DOMScanner.java:276)

at com.sun.xml.bind.unmarshaller.DOMScanner.visit(DOMScanner.java:245)

at com.sun.xml.bind.unmarshaller.DOMScanner.scan(DOMScanner.java:122)

at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:314)

at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:293)

Caused by: java.lang.InstantiationException

at sun.reflect.InstantiationExceptionConstructorAccessorImpl.newInstance(InstantiationExceptionConstructorAccessorImpl.java:30)

at java.lang.reflect.Constructor.newInstance(Constructor.java:513)

at com.sun.xml.bind.v2.ClassFactory.create0(ClassFactory.java:123)

at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.createInstance(ClassBeanInfoImpl.java:261)

at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.createInstance(UnmarshallingContext.java:603)

... 69 more

编辑@Blaise和@Ross

非常感谢 Blaise 和 Ross 的指点。我想我应该在这里包含正在处理的模式。相关架构如下所示:

    <xs:complexType name="Request">
<xs:sequence>
<xs:element name="selectedBase" form="unqualified" nillable="true" type="xs:anyType" minOccurs="0"/>
<xs:element name="selectedSubBase" form="unqualified" nillable="true" type="ns1:SubBase" minOccurs="0"/>
</xs:sequence>
</xs:complexType>


<xs:complexType name="Base">
<xs:sequence>
<xs:element name="ID" form="unqualified" nillable="true" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="SubBase">
<xs:complexContent>
<xs:extension base="ns1:Base">
<xs:sequence>
<xs:element name="subBaseElement" form="unqualified" nillable="true" type="xs:anyType" minOccurs="0"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>

因此架构没有替换组定义(所以我猜 @XmlElementRef 不适用于此处,或者它仍然有效吗?),但正在使用扩展。有效负载将是:

<ns:Request>
<selectedBase>123</selectedBase>
<selectedSubBase>
<ID>321</ID>
<subBaseElement>123</subBaseElement>
</selectedSubBase>
</ns:Request>

因此,有效负载中出现的元素是 <selectedSubBase>而不是<selectedBase xsi:type="ns:SubBase"/>

那么这里适用哪种策略?

最佳答案

@XmlSeeAlso 注释用作一种便利机制,告诉您的 JAXB impl 还应该为引用的类创建元数据。虽然它最常用于指定子类,但它不是配置继承关系的机制。

由于 JAXB 正在尝试实例化抽象父类(super class) (foo.bar.Base) 的实例,因此您的 XML 消息似乎没有包含足够的信息来指定正确的子类型被解码。

这可以通过 xsi:type 属性来完成:

您还可以使用替换组 (@XmlElementRef),其中元素名称用于确定适当的子类型:

JAXB 实现(例如 EclipseLink JAXB (MOXy) )还包含用于处理继承的扩展:

如果您想完全忽略继承关系,可以使用 @XmlTransient 注释:

关于jaxb - JAXB 解码期间发生 InstantiationException(抽象基类,带有 @XmlSeeAlso 具体子类),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7415659/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com