首页 > 解决方案 > 使用 @XmlElementRef 注释的元素未显示在 JAXB 编组字符串中?

问题描述

的背景

我正在使用一个应用程序,该应用程序使用我们使用 jaxws-maven-plugin 检索和生成的数据结构与外部应用程序通信。我们能够接收 XML 文档并使用 JAXB 和它们提供给我们的类结构将它们解组为 java 对象。但是,当我们将这些对象重新编组为字符串以保留在数据库中以供将来调试时,我们会丢失信息。

我们用来转换的对象片段:

/*the "root" object*/
//XML tags indicating field access, name, and prop order
public class PersonAppResObj {
    @XmlElement(name = "ApplicationObj", required = true)
    protected ApplicationObj application;
    @XmlElement(name = "ContactInfo", required = true)
    protected List<ContactInfo> contactInfo;
    ...
}
//XML tags indicating field access, name, and prop order
public class ApplicationObj extends other.pkg.ApplicationObj {
    @XmlElement(name = "PrimaryApplicant")
    protected List<XObj> primaryApplicant;
    ...
}
package other.pkg
//XML tags indicating field access, name, and prop order
public class ApplicationObj extends GenericApp {
    @XmlElementRef(name="Applicant", namespace="http://pkg.com/1/pkgs", type=JAXBElement.class, required=false)
    protected List<JAXBElement<? extends Applicant>> applicant;
    @XmlElement(name = "ApplicationPrimaryContact", required = true)
    protected XObj applicationPrimaryContact;
    ...
}

以下代码片段是一个在 JAXB 元素和字符串之间转换的简单 Kotlin 对象,以及对该对象的测试:

object Converter {
    fun xmlToXObj(respString: String): XObj? {
        val jaxbContext = JAXBContext.newInstance(ResponseRoot().javaClass)
        val unmarshaller = jaxbContext.createUnmarshaller()
        unmarshaller.setEventHandler {
            println(it.message)
            true
        }
        return (unmarshaller.unmarshal(ByteArrayInputStream(respString.toByteArray())) as ResponseRoot).xObj
    }
    fun xobjToXML(resp: XObj): String {
        val responseRoot = ResponseRoot(); responseRoot.xobj = resp
        val resMarsh = JAXBContext.newInstance(responseRoot.javaClass).createMarshaller()
        val resStream = ByteArrayOutputStream()
        resMarsh.marshal(responseRoot, resStream)
        return String(resStream.toByteArray())
    }
}
//autowired var feClient fetches info from other application
    @Test
    fun readWrite() {
        val rawResponse = feClient.fetchApp("AA", "1A")
        val xmlString = Converter.xobjToXML(rawResponse)
        val parsedResponse = Converter.xmlToXObj(xmlString)
        val parsedTwiceXML = Converter.xobjToXML(parsedResponse!!)
        println(xmlString)
        println(parsedTwiceXML)
    }

现在,问题的真正主体:当我运行 readWrite 测试时,我丢失了以下Applicant信息other.pkg.ApplicationObj

//println(xmlString)
<ns4:PersonAppResObj>
            <ns4:ApplicationObj>
                <ns4:Applicant ns1:id="Applicant1">
                ...
                <ns3:PrimaryContact ns1:ref="primaryContact"/>

//println(parsedTwiceXML)
<ns4:PersonAppResObj>
            <ns4:ApplicationObj>
                <ns3:PrimaryContact ns1:ref="primaryContact"/>
                //no applicant to be found

控制台中出现的错误是 unexpected element (uri:"...", local:"Applicant"). Expected elements are <{...}PrimaryFilerPerson>,<{...}JointFilerPerson>,<{...}ApplicationPrimaryContact>,<{...}ApplicationMultipleIndicator>,<{...}Applicant>

主要问题

控制台中出现了两个类似的错误,并且这些元素也丢失了。当我查看生成的类文件中的这些对象时,所有 3 个未显示的元素都用@XmlElementRef.

首先,什么可能导致这个问题?这只是编组器没有找到引用对象的情况吗?

其次,有没有办法在不编辑生成的对象的情况下解决这个问题?如果没有,我能做什么而不改变 xml 的外观?

标签: javakotlinjaxbmarshalling

解决方案


推荐阅读