简体   繁体   English

如果名称空间声明在SOAP信封上,如何使用JAXB解组SOAP响应?

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

JAXB can only unmarshall an XML if the soap envelope has already been removed. 如果已删除soap信封,则JAXB只能解组XML。 However, the SOAP response I'm trying to unmarshall has its namespace declaration on the soap envelope. 但是,我试图解组的SOAP响应在soap信封上有它的名称空间声明。 If I remove the soap envelope, the namespace declaration will also be removed. 如果我删除soap信封,名称空间声明也将被删除。 As such the prefix of the tags will be referring to none. 因此,标签的前缀将指无。 This causes JAXB to throw an error. 这会导致JAXB抛出错误。 How can I unmarshall a SOAP response using JAXB if the namespace is declared on the SOAP envelope? 如果在SOAP信封上声明名称空间,如何使用JAXB解组SOAP响应?

A similar sample of the XML that I need to unmarshall is below: 我需要解组的类似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>

This is what happens if I remove the soap envelope: 如果我移除肥皂信封会发生这种情况:

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

If I removed the soap envelope, the namespace declaration will also be gone. 如果我删除了soap信封,名称空间声明也将消失。 JAXB won't be able to unmarshall the above xml because the namespace definition for the prefix "ns" is missing. JAXB将无法解组上述xml,因为缺少前缀“ns”的命名空间定义。 As such it will return a "The prefix "ns" for element "ns:getNumberResponse" is not bound." 因此,它将返回"The prefix "ns" for element "ns:getNumberResponse" is not bound." error message. 错误信息。 How do I fix it? 我如何解决它?

Please note that I'm using JDK 1.5. 请注意我使用的是JDK 1.5。 I'm not sure if there is a way to solve this in JDK 1.6. 我不确定在JDK 1.6中是否有办法解决这个问题。 I was able to use JAXB because I downloaded the required jars for using JAXB. 我能够使用JAXB,因为我下载了使用JAXB所需的jar。

You can use a StAX parser to parse the SOAP message and then advance the XMLStreamReader to the getNumberResponse element and use the unmarshal method that takes a class parameter. 您可以使用StAX解析器来解析SOAP消息,然后将XMLStreamReader推进到getNumberResponse元素,并使用带有类参数的unmarshal方法。 A StAX parser is included in Java SE 6, but you will need to download one for Java SE 5. Woodstox is a popular StAX parser. Java SE 6中包含StAX解析器,但您需要为Java SE 5下载一个.Stickstox是一种流行的StAX解析器。

Response 响应

package forum11465653;

public class Response {

    private long number;

    public long getNumber() {
        return number;
    }

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

}

Demo 演示

An XMLStreamReader has a NamespaceContext . XMLStreamReader具有NamespaceContext The NamespaceContext knows all the active namespace declarations for the current level. NamespaceContext知道当前级别的所有活动命名空间声明。 Your JAXB (JSR-222) implementation will be able to leverage this to get the necessary information. 您的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());
    }

}

Output 产量

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

You could parse the whole SOAP message using a DOM parser, which would be able to resolve all the namespaces at parse time. 您可以使用DOM解析器解析整个SOAP消息,该解析器能够在解析时解析所有命名空间。 Then extract the element you require from the resulting DOM tree and pass that to the unmarshaller. 然后从生成的DOM树中提取所需的元素,并将其传递给unmarshaller。

DomDemo 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());
    }

}

Output 产量

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM