Reputation: 13162
I have a server (SoapUI) answering requests for a WSDL.
When sending test requests, my server code is receiving a list of arguments, but I'm trying to achieve is a single argument, of complex type, eg:
{
ingredient_id => INT
something => STRING
...
}
My types are as follow:
<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>
Can somebody help me to understand why WSDL is making SoapUI send the arguments as a list of simple arguments, instead of a single complex argument?
EDIT: It might be some problem with sequence tag, but I can't find the issue in that, just need some light. Thanks in advance!
Sure, I have it right here:
<?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>
Still have no hints on it :(
Upvotes: 2
Views: 23000
Reputation: 4359
You need to write your WSDL in "Document/literal wrapped"-style. These WSDL-styles are a bit confusing but here is a good comparison.
In essence you will need to wrap your complexType
into an 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>
and specify this element
to be send as message
<message name="getIngredientInfoRequest">
<part name="parameters" element="IngredientInfo"/>
</message>
Thus the resulting SOAP message contains this the IngredientInfo-element
as the only child of the SOAP body:
<soap:envelope>
<soap:body>
<IngredientInfo>
<ingredient_id>42</ingredient_id>
<something>"What is..."</something>
</IngredientInfo>
</soap:body>
</soap:envelope>
Upvotes: 11
Reputation: 11
My understanding is that you currently have something like the following (I'm doing a web service call in Java, so I'll example in it):
SOAPCaller.getIngredientInformation(3, "something");
However, what you'd really like is the following:
IngredientRequest ingredientRequest = new IngredientRequest(3, "something");
SOAPCaller.getIngredientInformation(ingredientRequest);
Trying something like what Wierob suggested caused the first case to be what was generated for me. Unfortunately, the only way that I found to achieve the second is to do extra encapsulation which is messy (extra classes are generated). Yet, it allows a single object to be sent and a single object to be returned, rather than a number of objects. Here's an example:
<!-- 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>
Upvotes: 0
Reputation: 610
Ok after using your WSDL for generating a sample request using my SOAP UI here is what I see
<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>
So as seen its creating a single getIngredientInfo request object no arrays. Please confirm, try using latest version of SOAP UI if required!
Upvotes: 0
Reputation: 610
I don't think WSDL Type (IngredientRequest) is the issue, can you show the complete WSDL, especially the operation which you are testing if that's accepting a array of IngredientRequest type then that is the answer, why SOAP UI is sending a list of arguments.
Upvotes: 1