如何将 SOAP XML 解组为 Java 对象

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26097760/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 01:50:31  来源:igfitidea点击:

How to unmarshall SOAP XML to Java Object

javaxmlsoapjaxb

提问by srinath

while trying to unmarshall my soap XML to JAXB object am getting the following error.

在尝试将我的soap XML 解组为JAXB 对象时,出现以下错误。

We are getting error that expected element is none. Should anything specific be done while unmarshalling the SOAP XML.

我们收到预期元素为 none 的错误。在解组 SOAP XML 时是否应该执行任何特定操作。

javax.xml.bind.JAXBContext jaxbContext = (javax.xml.bind.JAXBContext) JAXBContext.newInstance(Class.forName(requestName));
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
StringReader reader = new StringReader(SoapXmlString);          
reqInfo = unmarshaller.unmarshal(reader);

Am getting the following error :

收到以下错误:

 javax.xml.bind.UnmarshalException: unexpected element (uri:"http://schemas.xmlsoap.org/soap/envelope/", local:"Envelope"). Expected elements are (none)
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:642)
    at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:254)
    at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:249)
    at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedChildElement(Loader.java:116)
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext$DefaultRootLoader.childElement

and here is the sample XML

这是示例 XML

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v2="http://example.com/v2">
       <soapenv:Header/>
       <soapenv:Body>
          <v2:createSession>
             <v2:client>
                <!--Optional:-->
                <v2:name>?</v2:name>
                <!--Optional:-->
                <v2:clientId>?</v2:clientId>
                <!--Optional:-->
                <v2:requestId>?</v2:requestId>
             </v2:client>
             <!--Optional:-->
             <v2:oldSessionId>?</v2:oldSessionId>
             <!--Optional:-->
             <v2:clientIp>?</v2:clientIp>
             <!--Optional:-->
             <v2:clientIpStatus>?</v2:clientIpStatus>
             <!--Optional:-->
             <v2:superBYOBFlow>?</v2:superBYOBFlow>
             <!--Optional:-->
             <v2:FlowParams>?</v2:FlowParams>
             <!--Optional:-->
             <v2:deviceInfo>?</v2:deviceInfo>
          </v2:createSession>
       </soapenv:Body>
    </soapenv:Envelope>

Please do help .

请帮忙。

采纳答案by Adam

I don't think you're taking the SOAP envelope into account... Your generated JAXB Unmarshaller won't know anything about the Body or Envelope tags, it will be expecting your createSession to be the root element hence the "unexpected element" error.

我认为您没有将 SOAP 信封考虑在内......您生成的 JAXB Unmarshaller 不会知道有关 Body 或 Envelope 标签的任何信息,它将期望您的 createSession 成为根元素,因此是“意外元素”错误。

You need to extract the content from the Envelope first, you can do this with message.getSOAPBody().extractContentAsDocument() if you create a SOAPMessage object from your content first.

您需要先从信封中提取内容,如果您首先从您的内容创建 SOAPMessage 对象,则可以使用 message.getSOAPBody().extractContentAsDocument() 执行此操作。

It's quite fiddly to do, here's a working example from my blog

做起来很繁琐,这是我博客中的一个工作示例

String example =
        "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"><soapenv:Header /><soapenv:Body><ns2:farm xmlns:ns2=\"http://adamish.com/example/farm\"><horse height=\"123\" name=\"glue factory\"/></ns2:farm></soapenv:Body></soapenv:Envelope>";
SOAPMessage message = MessageFactory.newInstance().createMessage(null,
        new ByteArrayInputStream(example.getBytes()));
Unmarshaller unmarshaller = JAXBContext.newInstance(Farm.class).createUnmarshaller();
Farm farm = (Farm)unmarshaller.unmarshal(message.getSOAPBody().extractContentAsDocument());

It seems that if you don't declare your namespace in your schema .xsd file then you'll see the error you have.

似乎如果您没有在架构 .xsd 文件中声明您的命名空间,那么您将看到您遇到的错误。

I created a dummy schema with a root element createSession and by adding the targetNamespace attribute and regenerating the JAXB classes the error disappeared

我创建了一个带有根元素 createSession 的虚拟模式,通过添加 targetNamespace 属性并重新生成 JAXB 类,错误消失了

<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema
     xmlns:xs="http://www.w3.org/2001/XMLSchema"
     targetNamespace="http://example.com/v2"> <!-- targetNamespace essential for JAXB to work-->
    <xs:element name="createSession">  
        <xs:complexType>
            <xs:attribute name="foo" type="xs:string" use="required" />
        </xs:complexType>
    </xs:element>
</xs:schema>