簡體   English   中英

如果名稱空間聲明在SOAP信封上,如何使用JAXB解組SOAP響應?

[英]How to unmarshall SOAP response using JAXB if namespace declaration is on SOAP envelope?

如果已刪除soap信封,則JAXB只能解組XML。 但是,我試圖解組的SOAP響應在soap信封上有它的名稱空間聲明。 如果我刪除soap信封,名稱空間聲明也將被刪除。 因此,標簽的前綴將指無。 這會導致JAXB拋出錯誤。 如果在SOAP信封上聲明名稱空間,如何使用JAXB解組SOAP響應?

我需要解組的類似XML樣本如下:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="http://example.com/">
    <soapenv:Body>
        <ns:getNumberResponse>
            <number>123456789</number>
        </ns:getNumberResponse>
    </soapenv:Body>
</soapenv:Envelope>

如果我移除肥皂信封會發生這種情況:

<ns:getNumberResponse>
    <number>123456789</number>
</ns:getNumberResponse>

如果我刪除了soap信封,名稱空間聲明也將消失。 JAXB將無法解組上述xml,因為缺少前綴“ns”的命名空間定義。 因此,它將返回"The prefix "ns" for element "ns:getNumberResponse" is not bound." 錯誤信息。 我如何解決它?

請注意我使用的是JDK 1.5。 我不確定在JDK 1.6中是否有辦法解決這個問題。 我能夠使用JAXB,因為我下載了使用JAXB所需的jar。

您可以使用StAX解析器來解析SOAP消息,然后將XMLStreamReader推進到getNumberResponse元素,並使用帶有類參數的unmarshal方法。 Java SE 6中包含StAX解析器,但您需要為Java SE 5下載一個.Stickstox是一種流行的StAX解析器。

響應

package forum11465653;

public class Response {

    private long number;

    public long getNumber() {
        return number;
    }

    public void setNumber(long number) {
        this.number = number;
    }

}

演示

XMLStreamReader具有NamespaceContext NamespaceContext知道當前級別的所有活動命名空間聲明。 您的JAXB(JSR-222)實現將能夠利用它來獲取必要的信息。

package forum11465653;

import java.io.FileReader;
import javax.xml.bind.*;
import javax.xml.stream.*;

public class Demo {

    public static void main(String[] args) throws Exception{
        XMLInputFactory xif = XMLInputFactory.newFactory();
        XMLStreamReader xsr = xif.createXMLStreamReader(new FileReader("src/forum11465653/input.xml"));
        xsr.nextTag(); // Advance to Envelope tag
        xsr.nextTag(); // Advance to Body tag
        xsr.nextTag(); // Advance to getNumberResponse tag
        System.out.println(xsr.getNamespaceContext().getNamespaceURI("ns"));

        JAXBContext jc = JAXBContext.newInstance(Response.class);
        Unmarshaller unmarshaller = jc.createUnmarshaller();
        JAXBElement<Response> je = unmarshaller.unmarshal(xsr, Response.class);
        System.out.println(je.getName());
        System.out.println(je.getValue());
    }

}

產量

http://example.com/
{http://example.com/}getNumberResponse
forum11465653.Response@781f6226

您可以使用DOM解析器解析整個SOAP消息,該解析器能夠在解析時解析所有命名空間。 然后從生成的DOM樹中提取所需的元素,並將其傳遞給unmarshaller。

DomDemo

package forum11465653;

import java.io.File;
import javax.xml.bind.*;
import javax.xml.parsers.*;
import javax.xml.transform.dom.DOMSource;
import org.w3c.dom.*;

public class DomDemo {

    public static void main(String[] args) throws Exception{
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setNamespaceAware(true);
        DocumentBuilder db = dbf.newDocumentBuilder();
        Document d = db.parse(new File("src/forum11465653/input.xml"));
        Node getNumberResponseElt = d.getElementsByTagNameNS("http://example.com/", "getNumberResponse").item(0);

        JAXBContext jc = JAXBContext.newInstance(Response.class);
        Unmarshaller unmarshaller = jc.createUnmarshaller();
        JAXBElement<Response> je = unmarshaller.unmarshal(new DOMSource(getNumberResponseElt), Response.class);
        System.out.println(je.getName());
        System.out.println(je.getValue());
    }

}

產量

{http://example.com/}getNumberResponse
forum11465653.Response@19632847

暫無
暫無

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

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