【问题标题】:Marshal not @XmlRootElement with JAXB to String将不使用 JAXB 的 @XmlRootElement 编组为字符串
【发布时间】: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


【解决方案1】:

我找到了解决此问题的方法。我必须像这样为特定类创建JAXBContext

private static JAXBContext createJaxbContext() {
    try {
        return JAXBContext.newInstance(CompletedAssessmentInstance.class);
    } catch (JAXBException ex) {
        LOGGER.error("Failed to create JAXB context: ", ex);
        return null;
    }
}

这并不能解决问题,它只是一种解决方法。我使用cxf-codegen-plugin:2.6.0WSDL 文件生成类,我注意到如果我将版本更改为cxf-codegen-plugin:2.4.2,使用类加载器一切正常。如果我能找到问题,我会在这里发布解决方案。

【讨论】:

    猜你喜欢
    • 2016-06-20
    • 2015-03-25
    • 1970-01-01
    • 2013-01-24
    • 2015-10-12
    • 2015-07-10
    • 1970-01-01
    • 2018-01-06
    • 2012-09-28
    相关资源
    最近更新 更多