Soap WSDL ComplexType被发布为错误的参数类型

时间:2009-09-04 03:35:40

标签: web-services soap xsd wsdl

我有一个服务器(SoapUI)来回答对WSDL的请求。

发送测试请求时,我的服务器代码正在接收参数的列表,但我正在尝试实现复杂类型的单个参数,例如:

{
 ingredient_id   => INT
 something       => STRING
 ...
}

我的类型如下:

  <wsdl:types>
    <xsd:schema targetNamespace="/ingredient">
      <xsd:element name="getIngredientInfo" type="tns:IngredientRequest"></xsd:element>
      <xsd:element name="getIngredientInfoResponse" type="tns:ingredient"></xsd:element>

      <xsd:complexType name="ingredient">
        <xsd:sequence>
            <xsd:element name="ingredient_id" type="xsd:int" minOccurs="1" maxOccurs="1"></xsd:element>
            <xsd:element name="ingredient_name" type="xsd:string" minOccurs="1" maxOccurs="1"></xsd:element>
            <xsd:element name="status_gm" type="xsd:boolean" minOccurs="1" maxOccurs="1"></xsd:element>
            <xsd:element name="status_vegan" type="xsd:boolean" minOccurs="1" maxOccurs="1"></xsd:element>
            <xsd:element name="status_vegetarian" type="xsd:boolean" minOccurs="1" maxOccurs="1"></xsd:element>
            <xsd:element name="author_id" type="xsd:int" block="#all" minOccurs="1" maxOccurs="1"></xsd:element>
        </xsd:sequence>
      </xsd:complexType>

      <xsd:complexType name="IngredientRequest">
        <xsd:sequence>
            <xsd:element name="ingredient_id" type="xsd:int"></xsd:element>
            <xsd:element name="something" type="xsd:string"></xsd:element>
        </xsd:sequence>
      </xsd:complexType>

    </xsd:schema>
  </wsdl:types>

有人可以帮助我理解为什么WSDL会使SoapUI将参数作为简单参数列表而不是单个复杂参数发送吗?

编辑:序列标签可能有些问题,但我找不到问题,只需要一些亮点。 提前谢谢!


当然,我就在这里:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<wsdl:definitions
  name="ingredient"
  targetNamespace="/ingredient"
  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
  xmlns:tns="/ingredient"
  xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <wsdl:types>
    <xsd:schema targetNamespace="/ingredient">
      <xsd:element name="getIngredientInfo" type="tns:IngredientRequest"></xsd:element>
      <xsd:element name="getIngredientInfoResponse" type="tns:ingredient"></xsd:element>

      <xsd:complexType name="ingredient">
        <xsd:sequence>
            <xsd:element name="ingredient_id" type="xsd:int" minOccurs="1" maxOccurs="1"></xsd:element>
            <xsd:element name="ingredient_name" type="xsd:string" minOccurs="1" maxOccurs="1"></xsd:element>

            <xsd:element name="status_gm" type="xsd:boolean" minOccurs="1" maxOccurs="1"></xsd:element>
            <xsd:element name="status_vegan" type="xsd:boolean" minOccurs="1" maxOccurs="1"></xsd:element>
            <xsd:element name="status_vegetarian" type="xsd:boolean" minOccurs="1" maxOccurs="1"></xsd:element>
            <xsd:element name="author_id" type="xsd:int" block="#all" minOccurs="1" maxOccurs="1"></xsd:element>
        </xsd:sequence>
      </xsd:complexType>


      <xsd:complexType name="IngredientRequest">
        <xsd:sequence>
            <xsd:element name="ingredient_id" type="xsd:int"></xsd:element>

            <xsd:element name="something" type="xsd:string"></xsd:element>
        </xsd:sequence>
      </xsd:complexType>
    </xsd:schema>
  </wsdl:types>
  <wsdl:message name="getIngredientInfoRequest">
    <wsdl:part element="tns:getIngredientInfo" name="parameters"/>
  </wsdl:message>
  <wsdl:message name="getIngredientInfoResponse">

    <wsdl:part element="tns:getIngredientInfoResponse"
        name="parameters" />
  </wsdl:message>
  <wsdl:portType name="ingredient">
    <wsdl:operation name="getIngredientInfo">
      <wsdl:input message="tns:getIngredientInfoRequest"/>
      <wsdl:output message="tns:getIngredientInfoResponse"/>
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="ingredientSOAP" type="tns:ingredient">

    <soap:binding style="document"
        transport="http://schemas.xmlsoap.org/soap/http" />
    <wsdl:operation name="getIngredientInfo">
        <soap:operation
            soapAction="http://entropy.homelinux.org/kasak/" />
        <wsdl:input>
            <soap:body use="literal" />
        </wsdl:input>
        <wsdl:output>
            <soap:body use="literal" />
        </wsdl:output>

    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="ingredient">
    <wsdl:port binding="tns:ingredientSOAP" name="ingredientSOAP">
      <soap:address location="http://entropy.homelinux.org/kasak/"/>
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>

仍然没有提示:(

4 个答案:

答案 0 :(得分:10)

您需要以“Document / literal wrapped”风格编写WSDL。这些WSDL样式有点令人困惑,但here是一个很好的比较。

实质上,您需要将complexType打包成element

<element name="IngredientInfo">
  <complexType>
    <sequence>
            <element name="ingredient_id" type="xsd:int"></xsd:element>
            <element name="something" type="xsd:string"></xsd:element>
    </sequence>
  </complexType>
</element>

并指定此element作为消息发送

<message name="getIngredientInfoRequest">
    <part name="parameters" element="IngredientInfo"/>
</message>

因此,生成的SOAP消息包含IngredientInfo-element作为SOAP主体的唯一子节点:

<soap:envelope>
    <soap:body>
        <IngredientInfo>
            <ingredient_id>42</ingredient_id>
            <something>"What is..."</something>
        </IngredientInfo>
    </soap:body>
</soap:envelope>

答案 1 :(得分:1)

我认为WSDL Type(IngredientRequest)不是问题,你能否展示完整的WSDL,尤其是你正在测试的操作,如果它接受一个I​​ngredientRequest类型的数组那么这就是答案,为什么SOAP UI正在发送参数列表。

答案 2 :(得分:0)

使用我的SOAP UI生成样本请求后,使用WSDL就可以了。

    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ing="/ingredient">
   <soapenv:Header/>
   <soapenv:Body>
      <ing:getIngredientInfo>
         <ingredient_id>?</ingredient_id>
         <something>?</something>
      </ing:getIngredientInfo>
   </soapenv:Body>
</soapenv:Envelope>

所以看到它创建一个getIngredientInfo请求对象没有数组。请确认,如果需要,请尝试使用最新版本的SOAP UI!

答案 3 :(得分:0)

我的理解是你现在有类似下面的内容(我正在用Java进行Web服务调用,所以我将在其中进行示例):

SOAPCaller.getIngredientInformation(3, "something");

但是,你真正喜欢的是:

IngredientRequest ingredientRequest = new IngredientRequest(3, "something");
SOAPCaller.getIngredientInformation(ingredientRequest);

尝试Wierob建议的东西导致第一个案例成为我的生成。不幸的是,我发现实现第二种方法的唯一方法是进行额外的封装,这种封装很麻烦(生成额外的类)。然而,它允许发送单个对象并返回单个对象,而不是许多对象。这是一个例子:

<!-- assume the including of your complex types from above -->
<xsd:element name="getIngredientInfo" >
  <xsd:complexType>
    <xsd:sequence>
      <xsd:element name="ingredient" type="tns:IngredientRequest" />
    </xsd:sequence>
  </xsd:complexType>
</xsd:element>

<xsd:element name="getIngredientInfoResponse" >
  <xsd:complexType>
    <xsd:sequence>
      <xsd:element name="ingredientResponse" type="tns:ingredient" />
    </xsd:sequence>
  </xsd:complexType>
</xsd:element>