【问题标题】:Unmarshalling SOAP: javax.xml.bind.UnmarshalException: unexpected element (uri:"$URI", local:"getCardsResponse"). Expected elements are <{$URI}return>解组 SOAP:javax.xml.bind.UnmarshalException:意外元素(uri:“$URI”,本地:“getCardsResponse”)。预期的元素是 <{$URI}return>
【发布时间】:2021-09-05 22:23:18
【问题描述】:

我在尝试从已保存用作测试样本的 XML 文件中解组 SOAP 响应时遇到问题。这是堆栈跟踪:

java.lang.RuntimeException: javax.xml.bind.UnmarshalException: unexpected element (uri:"{$URI}", local:"getCardsResponse"). Expected elements are <{{$URI}}return>

    at {$COMPANY}.MarketLoaderTests.unmarshalToGetCardsResponse(MarketLoaderTests.java:108)
    at {$COMPANY}.MarketLoaderTests.unmarshalFromTestSportechSoapFile(MarketLoaderTests.java:114)
    at {$COMPANY}.MarketLoaderTests.runSoapFileThroughMarketLoader(MarketLoaderTests.java:63)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:84)
    at org.testng.internal.MethodInvocationHelper$1.runTestMethod(MethodInvocationHelper.java:200)
    at org.springframework.test.context.testng.AbstractTestNGSpringContextTests.run(AbstractTestNGSpringContextTests.java:172)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.testng.internal.MethodInvocationHelper.invokeHookable(MethodInvocationHelper.java:212)
    at org.testng.internal.Invoker.invokeMethod(Invoker.java:707)
    at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:901)
    at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1231)
    at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:127)
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111)
    at org.testng.TestRunner.privateRun(TestRunner.java:767)
    at org.testng.TestRunner.run(TestRunner.java:617)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:348)
    at org.testng.SuiteRunner.access$000(SuiteRunner.java:38)
    at org.testng.SuiteRunner$SuiteWorker.run(SuiteRunner.java:382)
    at org.testng.internal.thread.ThreadUtil$2.call(ThreadUtil.java:64)
    at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:266)
    at java.util.concurrent.FutureTask.run(FutureTask.java)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:748)
Caused by: javax.xml.bind.UnmarshalException: unexpected element (uri:"{$URI}", local:"getCardsResponse"). Expected elements are <{{$URI}}return>
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:726)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:247)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:242)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedChildElement(Loader.java:109)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext$DefaultRootLoader.childElement(UnmarshallingContext.java:1131)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:556)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:538)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.InterningXmlVisitor.startElement(InterningXmlVisitor.java:60)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.SAXConnector.startElement(SAXConnector.java:153)
    at com.sun.xml.internal.bind.unmarshaller.DOMScanner.visit(DOMScanner.java:229)
    at com.sun.xml.internal.bind.unmarshaller.DOMScanner.scan(DOMScanner.java:112)
    at com.sun.xml.internal.bind.unmarshaller.DOMScanner.scan(DOMScanner.java:95)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:356)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:337)
    at {$COMPANY}.MarketLoaderTests.unmarshalToGetCardsResponse(MarketLoaderTests.java:103)
    ... 30 more

这是我的代码:

  private static SlCardDetailsResp.Cards unmarshalToGetCardsResponse(final String soapResponse) {
    try {
      final SOAPMessage message = MessageFactory.newInstance().createMessage(null,
          new ByteArrayInputStream(soapResponse.getBytes()));
      final SOAPEnvelope envelope = message.getSOAPPart().getEnvelope();
      final SOAPBody body = envelope.getBody();
      final Document soapBodyAsDoc = body.extractContentAsDocument();
      //final DOMSource domSource = new DOMSource(soapBodyAsDoc);
      final JAXBContext jaxbContext = JAXBContext.newInstance(GetCardsResponse.class);

      final Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
      final GetCardsResponse getCardsResponse = (GetCardsResponse) unmarshaller
          .unmarshal(soapBodyAsDoc);
      final SlCardDetailsResp.Cards responseCards = getCardsResponse.getReturn().getCards();
      return responseCards;
    } catch (final Exception ex) {
      throw new RuntimeException(ex);
    }
  }

我在尝试实例化 getCardsResponse 时收到 UnmarshalException。 GetCardsResponse 类是使用对 WSDL 文件执行的绑定脚本生成的。

这是我要解析的 XML 的前 10 行:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <ns2:getCardsResponse xmlns:ns2="{$URI}">
      <return>
        <status>1</status>
        <cards...>
      </return>
    </ns2:getCardsResponse>
  </soap:Body>
</soap:Envelope>

这是我尝试将 SOAP 响应转换为的响应类:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "getCardsResponse", propOrder = {
    "_return"
})
public class GetCardsResponse
    implements Serializable
{

    private final static long serialVersionUID = 1L;
    @XmlElement(name = "return")
    protected SlCardDetailsResp _return;

    /**
     * Gets the value of the return property.
     * 
     * @return
     *     possible object is
     *     {@link SlCardDetailsResp }
     *     
     */
    public SlCardDetailsResp getReturn() {
        return _return;
    }

    /**
     * Sets the value of the return property.
     * 
     * @param value
     *     allowed object is
     *     {@link SlCardDetailsResp }
     *     
     */
    public void setReturn(SlCardDetailsResp value) {
        this._return = value;
    }

}

我做错了什么?

【问题讨论】:

    标签: java xml soap unmarshalling


    【解决方案1】:

    事实证明我需要一个 XMLRootElement 用于 GetCardsResponse,因为我搞砸了绑定。这是我的更新代码:

    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlType(name = "getCardsResponse", propOrder = {
        "_return"
    })
    /** Added this XmlRootElement annotation because the bindings were incorrect, 
     *  which caused an UnmarshallingException when trying to parse the SOAP response.
     */
    @XmlRootElement(name= "getCardsResponse")
    public class GetCardsResponse
        implements Serializable
    {
    
        private final static long serialVersionUID = 1L;
        @XmlElement(name = "return")
        protected SlCardDetailsResp _return;
    
        /**
         * Gets the value of the return property.
         * 
         * @return
         *     possible object is
         *     {@link SlCardDetailsResp }
         *     
         */
        public SlCardDetailsResp getReturn() {
            return _return;
        }
    
        /**
         * Sets the value of the return property.
         * 
         * @param value
         *     allowed object is
         *     {@link SlCardDetailsResp }
         *     
         */
        public void setReturn(SlCardDetailsResp value) {
            this._return = value;
        }
    
    }
    

    另外,我调整了 unmarshalToGetCardsResponse()

    private static SlCardDetailsResp.Cards unmarshalToGetCardsResponse(final String soapResponse) {
        try {
          final SOAPMessage message = MessageFactory.newInstance().createMessage(null,
              new ByteArrayInputStream(soapResponse.getBytes()));
    
          final JAXBContext jaxbContext = JAXBContext.newInstance(GetCardsResponse.class);
    
          final Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
          final GetCardsResponse getCardsResponse = (GetCardsResponse) unmarshaller
              .unmarshal(message.getSOAPBody().extractContentAsDocument());
    
          final SlCardDetailsResp.Cards responseCards = getCardsResponse.getReturn().getCards();
          return responseCards;
        } catch (final Exception ex) {
          throw new RuntimeException(ex);
        }
      }
    

    【讨论】:

    • 你的 pom.xml 看起来怎么样?我实际上不能像你回答的那样从肥皂到对象
    猜你喜欢
    • 2016-07-12
    • 2018-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-08
    相关资源
    最近更新 更多