java - 如果命名空间声明在 SOAP 信封上,如何使用 JAXB 解码 SOAP 响应?

标签 java xml soap jaxb unmarshalling

只有在 SOAP 信封已被移除时,JAXB 才能解码 XML。但是,我试图解码的 SOAP 响应在 SOAP 信封上有其 namespace 声明。如果我删除 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>

如果我取下 SOAP 信封会发生这种情况:

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

如果我删除了 SOAP 信封,命名空间声明也将消失。 JAXB 将无法解码上述 xml,因为缺少前缀“ns”的命名空间定义。因此,它将返回 “元素“ns:getNumberResponse”的前缀“ns”未绑定(bind)。” 错误消息。我该如何解决?

请注意,我使用的是 JDK 1.5。我不确定在 JDK 1.6 中是否有办法解决这个问题。我能够使用 JAXB,因为我下载了使用 JAXB 所需的 jar。

最佳答案

您可以使用 StAX 解析器来解析 SOAP 消息,然后将 XMLStreamReader 推进到 getNumberResponse 元素并使用采用类参数的 unmarshal 方法。 StAX 解析器包含在 Java SE 6 中,但您需要为 Java SE 5 下载一个。Woodstox是一个流行的 StAX 解析器。

回应

package forum11465653;

public class Response {

    private long number;

    public long getNumber() {
        return number;
    }

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

}

演示

XMLStreamReader 有一个NamespaceContextNamespaceContext 知道当前级别的所有 Activity 命名空间声明。您的 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

关于java - 如果命名空间声明在 SOAP 信封上,如何使用 JAXB 解码 SOAP 响应?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11465653/

相关文章:

java - 如何指定要使用的基于操作系统的 Java 库?

java - 使用一个 POJO 类来处理不同的 xml 响应

java - 使用 hibernate 连接数据库时出错

android - 如何在 Android 上塑造 webview?

PHP、两个连接、VPN 和 SSL

从 SOAPFault 中提取错误消息时出现 java.lang.ClassCastException

ios - ios 中的 soap 需要启用 cookie。如何在 SOAP 头中添加它?

java - 如何排除 bouncycaSTLe weblogic 12c 库

java - 如何将Weld集成到maven项目中?

java - CONSTANT_MethodHandle_info 和 CONSTANT_MethodType_info