【发布时间】:2012-09-12 16:44:09
【问题描述】:
我需要将一个JAXB 生成的对象编组到String。问题是它没有@XmlRootElement 注释。它不是根元素。 XSD 中的元素如下所示:
<xs:complexType name="CompletedAssessmentInstance">
<xs:complexContent mixed="false">
<xs:extension base="tns:AssessmentInstance">
<xs:sequence>
<xs:element minOccurs="0" name="CompletionDate" type="xs:dateTime"/>
<xs:element minOccurs="0" name="CustomResultsXML" nillable="true" type="xs:string"/>
<xs:element minOccurs="0" name="NormedScores" nillable="true" type="tns:NormedScores"/>
<xs:element minOccurs="0" name="RawScore" type="xs:decimal"/>
<xs:element minOccurs="0" name="TimeTaken" type="xs:int"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="CompletedAssessmentInstance" nillable="true" type="tns:CompletedAssessmentInstance"/>
tns 前缀指向这个命名空间:xmlns:tns="http://www.cubiksonline.com/2009/08/AssessmentProvider"
我发现我可以用JAXB 编组不XML 根元素:
public static String completedAssessmentInstanceToString(CompletedAssessmentInstance assessmentInstance)
throws AssessmentException {
try {
Marshaller marshaller = jc.createMarshaller();
StringWriter writer = new StringWriter();
QName qname = new QName(
"http://www.cubiksonline.com/2009/08/AssessmentProvider",
"CompletedAssessmentInstance");
JAXBElement<CompletedAssessmentInstance> rootElement = new JAXBElement<CompletedAssessmentInstance>(
qname,
CompletedAssessmentInstance.class,
assessmentInstance);
marshaller.marshal(rootElement, writer);
return writer.toString();
} catch (JAXBException ex) {
LOGGER.error("JAXB Exception occurred.", ex);
throw new AssessmentException(RequestStatusValue.InvalidProjectConfiguration,
"Unable to marshal the CompletedAssessmentInstance data: " + assessmentInstance, ex);
}
}
我正在像这样初始化我的 JAXB 上下文:
private static JAXBContext jc = createJaxbContext();
private static JAXBContext createJaxbContext() {
try {
ClassLoader cl = com.cubiksonline._2009._08.assessmentprovider.ObjectFactory.class.getClassLoader();
return JAXBContext.newInstance("com.cubiksonline._2009._08.assessmentprovider", cl);
} catch (JAXBException ex) {
LOGGER.error("Failed to create JAXB context: ", ex);
return null;
}
}
这个包:com.cubiksonline._2009._08.assessmentprovider 是包含所有JAXB 生成的类的包,包括CompletedAssessmentInstance。问题是当marshaller.marshal(rootElement, writer); 被调用时,我得到以下异常:
Caused by: javax.xml.bind.MarshalException
- with linked exception:
[javax.xml.bind.JAXBException: com.cubiksonline._2009._08.assessmentprovider.CompletedAssessmentInstance is not known to this context]
at com.sun.xml.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:318)
at com.sun.xml.bind.v2.runtime.MarshallerImpl.marshal(MarshallerImpl.java:244)
at javax.xml.bind.helpers.AbstractMarshallerImpl.marshal(AbstractMarshallerImpl.java:95)
at com.groupgti.esb.assessments.cubiks.CubiksFactory.completedAssessmentInstanceToString(CubiksFactory.java:272)[647:com.groupgti.esb.online.tests.cubiks:1.2.0.SNAPSHOT]
... 40 more
Caused by: javax.xml.bind.JAXBException: com.cubiksonline._2009._08.assessmentprovider.CompletedAssessmentInstance is not known to this context
at com.sun.xml.bind.v2.runtime.XMLSerializer.reportError(XMLSerializer.java:246)
at com.sun.xml.bind.v2.runtime.XMLSerializer.reportError(XMLSerializer.java:261)
at com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl$1.serializeBody(ElementBeanInfoImpl.java:144)
at com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl$1.serializeBody(ElementBeanInfoImpl.java:189)
at com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl.serializeBody(ElementBeanInfoImpl.java:316)
at com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl.serializeRoot(ElementBeanInfoImpl.java:323)
at com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl.serializeRoot(ElementBeanInfoImpl.java:72)
at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsRoot(XMLSerializer.java:494)
at com.sun.xml.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:315)
... 43 more
Caused by: javax.xml.bind.JAXBException: com.cubiksonline._2009._08.assessmentprovider.CompletedAssessmentInstance is not known to this context
at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getBeanInfo(JAXBContextImpl.java:625)
at com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl$1.serializeBody(ElementBeanInfoImpl.java:141)
... 49 more
有谁知道问题出在哪里?
【问题讨论】:
-
由于您使用的是 JAXB RI,
toString()在其实现JAXBContext时将输出所有映射的类。您能否检查以确保包含com.cubiksonline._2009._08.assessmentprovider.CompletedAssessmentInstance。此外,由于 JAXB 是一个规范 (JSR-222),您可以尝试另一种实现,例如 EclipseLink MOXy(我是 MOXy 负责人),看看这是否只是 JAXB RI 中的一个错误。 -
这很奇怪,因为当我在 JAXBContext 上执行 toString 时,它只列出了 9 个类,在这个包中大约有 50 个类,并且这个类 com.cubiksonline._2009._08.assessmentprovider.CompletedAssessmentInstance 不包括在内。我已经找到了解决方案。我不得不像这样初始化 JAXB 上下文: JAXBContext.newInstance(CompletedAssessmentInstance.class) 但我仍然不明白为什么 JAXB 不加载指定包中的所有类。
-
您可能在 JAXB RI 中发现了一个错误。您可以尝试更新版本或 JAXB (JSR-222) 的替代实现来确认。
-
我正在使用 cxf-codegen-plugin:2.6.0,如果我将版本更改为 cxf-codegen-plugin:2.4.2 一切正常,我会看到所有来自 JAXBContext 的类。但是我查看了依赖关系树,发现它们都使用组 ID:com.sun.xml.bind 工件 ID:jaxb-impl 版本:2.1.13。这是相同的版本。
-
好的,所以它似乎是
cxf-codegen-plugin中的一个错误,而不是 JAXB 参考实现。我建议向 CXF 提交错误。
标签: java maven jaxb wsdl2java jaxb2-maven-plugin