3

我需要将一个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"

我发现我可以这样做来编组不是XML根元素JAXB

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

有谁知道问题可能出在哪里?

4

1 回答 1

2

我找到了解决此问题的方法。我必须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.0习惯从文件生成类WSDL,我注意到如果我将版本更改为cxf-codegen-plugin:2.4.2使用类加载器一切正常。如果我能找到问题,我会在这里发布解决方案。

于 2012-09-20T12:11:03.420 回答