簡體   English   中英

如何使用相同的JAXB類編組和解編入不同的名稱空間?

[英]How can I use same JAXB class to marshall and unmarshall into different namespaces?

注意:這是在Java 7中。而且,我沒有使用JAXB從架構生成任何東西。 我僅/僅希望使用JAXB對現有的SOAP消息進行反序列化。 因此,JAXB bean是“手寫的”。

我正在嘗試使用JAXB反序列化以下XML。 沒有作為字符串訪問它。 相反,我將其作為org.w3c.dom.Element對象獲取:

<SynchInfo xmlns="urn:InitronSOAPService">
    <HandshakeInfo>
        <dnsName>foo.bar</dnsName>
        <ip>1.2.3.4</ip>
        <id>TheId</id>
        <key>SomeKey</key>
        <version>1.0</version>
    </HandshakeInfo>
</SynchInfo>

但是我也想將HandshakeInfo實例編組到SOAPBody ,它是屬於不同名稱空間的消息的一部分。

我首先嘗試編寫一個完全不提及名稱空間的HandshakeInfo類:

@XmlRootElement(name = "HandshakeInfo")
@XmlAccessorType(XmlAccessType.NONE)
final private static class HandshakeInfo
{
    private String version;
    private String id;
    private String key;
    private String ip;
    private String dnsName;

    public String getVersion() {
        return version;
    }

    @XmlElement(name = "version")
    public void setVersion(String version) {
        this.version = version;
    }

    public String getId() {
        return id;
    }

    @XmlElement(name = "id")
    public void setId(String id) {
        this.id = id;
    }

    public String getKey() {
        return key;
    }

    @XmlElement(name = "key")
    public void setKey(String key) {
        this.key = key;
    }

    public String getIp() {
        return ip;
    }

    @XmlElement(name = "ip")
    public void setIp(String ip) {
        this.ip = ip;
    }

    public String getDnsName() {
        return dnsName;
    }

    @XmlElement(name = "dnsName")
    public void setDnsName(String dnsName) {
        this.dnsName = dnsName;
    }
}

但是,當我使用它嘗試反序列化包含HandshakeInfo元素的Element對象時,出現以下異常:

javax.xml.bind.UnmarshalException: unexpected element (uri:"urn:InitronSOAPService", local:"HandshakeInfo"). Expected elements are <{}HandshakeInfo>
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:647)
...

因此,然后我嘗試將, namespace="urn:InitronSOAPService"到類中的所有元素和屬性注釋(在本例中為無)。 (或者,在package-info.java文件中使用@XmlSchema注釋。)該方法用於反序列化該名稱空間中的該元素。

但是,當我嘗試使用該類序列化到另一個名稱空間時,我(並非完全意外)得到了以下內容:

<SomeMessage xmlns="urn:differentNamespace">
    <ns5:HandshakeInfo xmlns:ns5="urn:InitronSOAPService">
        <ns5:dnsName>foo.bar</ns5:dnsName>
        <ns5:ip>1.2.3.4</ns5:ip>
        <ns5:id>TheId</ns5:id>
        <ns5:key>SomeKey</ns5:key>
        <ns5:version>1.0</ns5:version>
    </ns5:HandshakeInfo>
</SomeMessage>

那不是我想要的 我希望序列化的東西成為urn:differentNamespace

那么,有什么方法可以在多個名稱空間中使用相同的JAXB類? 還是我不得不保留多個類的副本,而每個副本都必須標注在適當的命名空間中?

我已經看到了一些使用過濾器等的技巧,但是這些技巧似乎是假設正在從流或文件中讀取XML或將XML寫入其中。 再次,對於解組,我正在使用org.w3c.dom.Element對象;對於解組,我正在使用SOAPBody對象。

我看到以下選項:

  • 使用MOXy XML綁定並將映射從注釋移到XML資源中。 然后,您可以為不同的名稱空間定義和加載不同的資源。
  • 使用XSLT在解組之前對XML進行預處理/在進行編組之后進行后處理。 在XSLT中,重命名空間是一項瑣碎的任務。
  • 使用JAXB RI的自定義AnnotationReader可以“偽造”從注解中讀取的名稱空間。 您只需要調整從包中讀取的名稱空間,就不會太難。

AnnotationReader解決方案有點“棘手”,還將您與JAXB RI綁定在一起。 XML綁定將要求您以XML格式重寫注釋,並將您與MOXy綁定(我認為)。 XSLT非常優雅,但是會使處理速度變慢。 而且,您必須使用XSLT進入處理鏈。

所有選項都各有利弊,您必須針對具體情況仔細考慮它們。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM