使用契约优先 Spring-WS 完成 SOAP 的解组异常

发布于 2024-12-10 17:26:00 字数 5546 浏览 0 评论 0原文

我正在尝试编写我的第一个 SOAP Web 服务代码。

我收到 SOAP 响应 Unmarshall failure 这是我映射到 org.springframework.oxm.UnmarshallingFailureException 的响应。 我已将 Spring 配置为使用 Castor (un)marshaller。 问题是我不知道如何找到更具体的原因。

public class SentenceRequest {

public SentenceRequest() {}

private List<String> words = new ArrayList<String>();

public List<String> getWords() {
    return words;
}

public void setWords(List<String> words) {
    this.words = words;
}


public class SentenceResponse {

private String sentence;

public SentenceResponse() {}

public SentenceResponse(String sen) {
    sentence = sen;
}

public String getSentence() {
    return sentence;
}

public void setSentence(String sentence) {
    this.sentence = sentence;
}

Castor 映射:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapping PUBLIC
    "-//EXOLAB/Castor Object Mapping DTD Version 1.0//EN"
    "http://castor.exolab.org/mapping.dtd">
<mapping xmlns="http://castor.exolab.org/">
    <class name="ro.soapservice2.SentenceRequest">
        <map-to xml="SentenceRequest" ns-uri="sentence" ns-prefix="s" />
        <field name="words" collection="arraylist" type="java.util.List" required="true">
            <bind-xml name="word" node="element"></bind-xml>
        </field>
    </class>

    <class name="ro.soapservice2.SentenceResponse">
        <map-to xml="SentenceResponse" ns-uri="sentence" ns-prefix="s" />
        <field name="sentence" type="java.lang.String" required="true">
            <bind-xml name="sentence" node="element" />
        </field>
    </class>
</mapping>

架构(根据两个输入 XML 文件使用 Trang.jar 生成):

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"      targetNamespace="sentence" xmlns:s="sentence">
  <xs:element name="SentenceRequest">
    <xs:complexType>
          <xs:sequence>
        <xs:element maxOccurs="unbounded" ref="s:word"/>
  </xs:sequence>
</xs:complexType>
</xs:element>
  <xs:element name="word" type="xs:string"/>
    <xs:element name="SentenceResponse">
      <xs:complexType>
        <xs:sequence>
          <xs:element ref="s:sentence"/>
        </xs:sequence>
      </xs:complexType>
     </xs:element>
   <xs:element name="sentence" type="xs:string"/>
</xs:schema>

WSDL Spring 生成:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:sch="sentence" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="sentence" targetNamespace="sentence">
  <wsdl:types>
    <xs:schema xmlns:s="sentence" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="sentence">

  <xs:element name="SentenceRequest">
    <xs:complexType>
      <xs:sequence>
        <xs:element maxOccurs="unbounded" ref="s:word"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <xs:element name="word" type="xs:string"/>

  <xs:element name="SentenceResponse">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="s:sentence"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <xs:element name="sentence" type="xs:string"/>

 </xs:schema>
</wsdl:types>

  <wsdl:message name="SentenceResponse">
    <wsdl:part element="tns:SentenceResponse" name="SentenceResponse">
    </wsdl:part>
  </wsdl:message>

  <wsdl:message name="SentenceRequest">
    <wsdl:part element="tns:SentenceRequest" name="SentenceRequest">
    </wsdl:part>
  </wsdl:message>

  <wsdl:portType name="Sentence">
    <wsdl:operation name="Sentence">
      <wsdl:input message="tns:SentenceRequest" name="SentenceRequest">
      </wsdl:input>
      <wsdl:output message="tns:SentenceResponse" name="SentenceResponse">
      </wsdl:output>
    </wsdl:operation>
  </wsdl:portType>

  <wsdl:binding name="SentenceSoap11" type="tns:Sentence">
    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="Sentence">
      <soap:operation soapAction=""/>
      <wsdl:input name="SentenceRequest">
        <soap:body use="literal"/>
      </wsdl:input>
      <wsdl:output name="SentenceResponse">
        <soap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>

  <wsdl:service name="SentenceService">
    <wsdl:port binding="tns:SentenceSoap11" name="SentenceSoap11">
      <soap:address location="http://localhost:8080/soapservice2/services"/>
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>

我发出的 SOAP 请求:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sen="sentence">
<soapenv:Header/>
 <soapenv:Body>
    <sen:SentenceRequest>
       <!--1 or more repetitions:-->
       <sen:word>asd</sen:word>
    </sen:SentenceRequest>
 </soapenv:Body>
</soapenv:Envelope>

I am trying to code my first SOAP web service.

I am getting the SOAP response Unmarshall failure
which is the response i mapped to org.springframework.oxm.UnmarshallingFailureException.
I have configured Spring to use Castor (un)marshaller.
Problem is i don't know how to find a more specific cause.

public class SentenceRequest {

public SentenceRequest() {}

private List<String> words = new ArrayList<String>();

public List<String> getWords() {
    return words;
}

public void setWords(List<String> words) {
    this.words = words;
}


public class SentenceResponse {

private String sentence;

public SentenceResponse() {}

public SentenceResponse(String sen) {
    sentence = sen;
}

public String getSentence() {
    return sentence;
}

public void setSentence(String sentence) {
    this.sentence = sentence;
}

the castor mapping:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapping PUBLIC
    "-//EXOLAB/Castor Object Mapping DTD Version 1.0//EN"
    "http://castor.exolab.org/mapping.dtd">
<mapping xmlns="http://castor.exolab.org/">
    <class name="ro.soapservice2.SentenceRequest">
        <map-to xml="SentenceRequest" ns-uri="sentence" ns-prefix="s" />
        <field name="words" collection="arraylist" type="java.util.List" required="true">
            <bind-xml name="word" node="element"></bind-xml>
        </field>
    </class>

    <class name="ro.soapservice2.SentenceResponse">
        <map-to xml="SentenceResponse" ns-uri="sentence" ns-prefix="s" />
        <field name="sentence" type="java.lang.String" required="true">
            <bind-xml name="sentence" node="element" />
        </field>
    </class>
</mapping>

the schema (generated with Trang.jar based on two input XML files):

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"      targetNamespace="sentence" xmlns:s="sentence">
  <xs:element name="SentenceRequest">
    <xs:complexType>
          <xs:sequence>
        <xs:element maxOccurs="unbounded" ref="s:word"/>
  </xs:sequence>
</xs:complexType>
</xs:element>
  <xs:element name="word" type="xs:string"/>
    <xs:element name="SentenceResponse">
      <xs:complexType>
        <xs:sequence>
          <xs:element ref="s:sentence"/>
        </xs:sequence>
      </xs:complexType>
     </xs:element>
   <xs:element name="sentence" type="xs:string"/>
</xs:schema>

and the WSDL Spring generates:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:sch="sentence" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="sentence" targetNamespace="sentence">
  <wsdl:types>
    <xs:schema xmlns:s="sentence" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="sentence">

  <xs:element name="SentenceRequest">
    <xs:complexType>
      <xs:sequence>
        <xs:element maxOccurs="unbounded" ref="s:word"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <xs:element name="word" type="xs:string"/>

  <xs:element name="SentenceResponse">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="s:sentence"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <xs:element name="sentence" type="xs:string"/>

 </xs:schema>
</wsdl:types>

  <wsdl:message name="SentenceResponse">
    <wsdl:part element="tns:SentenceResponse" name="SentenceResponse">
    </wsdl:part>
  </wsdl:message>

  <wsdl:message name="SentenceRequest">
    <wsdl:part element="tns:SentenceRequest" name="SentenceRequest">
    </wsdl:part>
  </wsdl:message>

  <wsdl:portType name="Sentence">
    <wsdl:operation name="Sentence">
      <wsdl:input message="tns:SentenceRequest" name="SentenceRequest">
      </wsdl:input>
      <wsdl:output message="tns:SentenceResponse" name="SentenceResponse">
      </wsdl:output>
    </wsdl:operation>
  </wsdl:portType>

  <wsdl:binding name="SentenceSoap11" type="tns:Sentence">
    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="Sentence">
      <soap:operation soapAction=""/>
      <wsdl:input name="SentenceRequest">
        <soap:body use="literal"/>
      </wsdl:input>
      <wsdl:output name="SentenceResponse">
        <soap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>

  <wsdl:service name="SentenceService">
    <wsdl:port binding="tns:SentenceSoap11" name="SentenceSoap11">
      <soap:address location="http://localhost:8080/soapservice2/services"/>
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>

the SOAP request i make:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sen="sentence">
<soapenv:Header/>
 <soapenv:Body>
    <sen:SentenceRequest>
       <!--1 or more repetitions:-->
       <sen:word>asd</sen:word>
    </sen:SentenceRequest>
 </soapenv:Body>
</soapenv:Envelope>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

彻夜缠绵 2024-12-17 17:26:00

解决了!
首先,我替换了异常解析器,

org.springframework.ws.soap.server.endpoint.SoapFaultMappingExceptionResolver

它将

org.springframework.ws.soap.server.endpoint.SimpleSoapExceptionResolver

抛出的真正异常放回到 SOAP 响应中。
然后我看到问题出在 Castor xml 映射文件上:

从更改

<field name="words" collection="arraylist" type="java.util.List" required="true">
                <bind-xml name="word" node="element"></bind-xml>
        </field>

<field name="words" collection="arraylist" type="java.lang.String" required="true">
                <bind-xml name="word" node="element"></bind-xml>
        </field>

Solved!
First i replaced my exception resolver from

org.springframework.ws.soap.server.endpoint.SoapFaultMappingExceptionResolver

to

org.springframework.ws.soap.server.endpoint.SimpleSoapExceptionResolver

which puts back in the SOAP response the real exception that was thrown.
Then i saw the problem was at the Castor xml mapping file:

changed from

<field name="words" collection="arraylist" type="java.util.List" required="true">
                <bind-xml name="word" node="element"></bind-xml>
        </field>

to

<field name="words" collection="arraylist" type="java.lang.String" required="true">
                <bind-xml name="word" node="element"></bind-xml>
        </field>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文