You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by Libor Svehlak <li...@seznam.cz> on 2008/10/09 13:12:49 UTC

Passing array parameters when using document/literal/bare SOAP binding

I need to use document/literal/bare SOAP binding I'm little bit surprised
about difference of passing array parameters when using this SOAP binding in
oposite to document/literal/wrapped style.

I have following simple interface:

@WebService
@SOAPBinding(style=Style.DOCUMENT, use=Use.LITERAL, parameterStyle =
ParameterStyle.BARE) 
public interface ITestWebService {	
	public void testPassingArray(@WebParam(name = "arrayOfLongs") Long[]
arrayOfLongs);
}

Auto-generated WSDL (by CXF version 2.1.2) looks like following:

<?xml version="1.0" ?><wsdl:definitions name="TestBareWebServiceImplService"
targetNamespace="http://testbare.webservice.com/"
xmlns:ns1="http://cxf.apache.org/bindings/xformat"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://testbare.webservice.com/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <wsdl:types>
<xs:schema attributeFormDefault="unqualified"
elementFormDefault="unqualified"
targetNamespace="http://jaxb.dev.java.net/array"
xmlns="http://jaxb.dev.java.net/array"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:complexType final="#all" name="longArray">
        <xs:sequence>
            <xs:element maxOccurs="unbounded" minOccurs="0" name="item"
nillable="true" type="xs:long"></xs:element>
        </xs:sequence>
    </xs:complexType>
</xs:schema>
<xsd:schema attributeFormDefault="unqualified"
elementFormDefault="qualified"
targetNamespace="http://testbare.webservice.com/"
xmlns:ns0="http://jaxb.dev.java.net/array"
xmlns:tns="http://testbare.webservice.com/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <xsd:import namespace="http://jaxb.dev.java.net/array"></xsd:import>
    <xsd:element name="arrayOfLongs" nillable="true"
type="ns0:longArray"></xsd:element>
</xsd:schema>
  </wsdl:types>
  <wsdl:message name="testPassingArray">
    <wsdl:part element="tns:arrayOfLongs" name="arrayOfLongs">
    </wsdl:part>
  </wsdl:message>
  <wsdl:message name="testPassingArrayResponse">
  </wsdl:message>
  <wsdl:portType name="ITestWebService">
    <wsdl:operation name="testPassingArray">
      <wsdl:input message="tns:testPassingArray" name="testPassingArray">
    </wsdl:input>
      <wsdl:output message="tns:testPassingArrayResponse"
name="testPassingArrayResponse">
    </wsdl:output>
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="TestBareWebServiceImplServiceSoapBinding"
type="tns:ITestWebService">
    <soap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http"></soap:binding>
    <wsdl:operation name="testPassingArray">
      <soap:operation soapAction="" style="document"></soap:operation>
      <wsdl:input name="testPassingArray">
        <soap:body use="literal"></soap:body>
      </wsdl:input>
      <wsdl:output name="testPassingArrayResponse">
        <soap:body use="literal"></soap:body>
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="TestBareWebServiceImplService">
    <wsdl:port binding="tns:TestBareWebServiceImplServiceSoapBinding"
name="TestBareWebServiceImplPort">
      <soap:address
location="http://localhost:8080/ProwebWebServices/services/TestBareWebService"></soap:address>
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>

When I generate Java client stubs from this WSDL generated interface looks
like following:

@WebService(targetNamespace = "http://testbare.webservice.com/", name =
"ITestWebService")
@XmlSeeAlso({ObjectFactory.class})
@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
public interface ITestWebService {

    @WebMethod
    public void testPassingArray(
        @WebParam(partName = "arrayOfLongs", name = "arrayOfLongs",
targetNamespace = "http://testbare.webservice.com/")
        LongArray arrayOfLongs
    );
}

I'm surprised that array parameter is "wrapped" in generated class LongArray
through which I need to access internal list of items. I have expected that
generated method on the client side is something like following:

    @WebMethod
    public void testPassingArray(
        @WebParam(partName = "arrayOfLongs", name = "arrayOfLongs",
targetNamespace = "http://testbare.webservice.com/")
        java.util.List<java.lang.Long> arrayOfLongs
    );

When I'm using document/literal/wrapped SOAP binding then generated client
stub interface is "more friendly and logical":

@WebService(targetNamespace = "http://testbare.webservice.com/", name =
"ITestWebService")
@XmlSeeAlso({ObjectFactory.class})
public interface ITestWebService {

    @RequestWrapper(localName = "testPassingArray", targetNamespace =
"http://testbare.webservice.com/", className =
"com.webservices.test.TestPassingArray")
    @ResponseWrapper(localName = "testPassingArrayResponse", targetNamespace
= "http://testbare.webservice.com/", className =
"com.webservices.test.TestPassingArrayResponse")
    @WebMethod
    public void testPassingArray(
        @WebParam(name = "arrayOfLongs", targetNamespace = "")
        java.util.List<java.lang.Long> arrayOfLongs
    );
}

Is this expected behavior when using document/literal/bare SOAP binding?
Originally I thought that when I switch from wrapped to bare client will
compile without any changes. But it seems that client stubs are different
and I need to adapt my client to the little bit different generated
interfaces.

Can someone explain me if described behovior is correct or is it a bug?
Shouldn't be generated interfaces on the client side still the same
independent of which SOAP binding is currently used?

-- 
View this message in context: http://www.nabble.com/Passing-array-parameters-when-using-document-literal-bare-SOAP-binding-tp19896773p19896773.html
Sent from the cxf-user mailing list archive at Nabble.com.


Re: Passing array parameters when using document/literal/bare SOAP binding

Posted by Libor Svehlak <li...@seznam.cz>.
Thank you for fast answer. Originally I thought that generated proxy stubs
should be the same independent on binding. Seems I need to learn more in
this area. Thanks again.


dkulp wrote:
> 
> 
> This is all correct.  Arrays/collections in "bare" mode really don't work 
> well.     Global elements in schema aren't allowed to have a "maxOccurs"
> on 
> them.  Since doc/lit has to point at an element, we have to generate a
> pseudo 
> element that points to a sequence with an element with the maxOccurs.  
> Kind 
> of a wrapped thing.  
> 
> Code generated from that would then generate a type for that wrapper type 
> thing and point at it.
> 
> Anyway, a bit strange, but is working properly.    For the most part
> though, 
> I'd recommend sticking to wrapped doc/lit for code first type things.
> 
> Dan
> 
> 
> 
> On Thursday 09 October 2008 7:12:49 am Libor Svehlak wrote:
>> I need to use document/literal/bare SOAP binding I'm little bit surprised
>> about difference of passing array parameters when using this SOAP binding
>> in oposite to document/literal/wrapped style.
>>
>> I have following simple interface:
>>
>> @WebService
>> @SOAPBinding(style=Style.DOCUMENT, use=Use.LITERAL, parameterStyle =
>> ParameterStyle.BARE)
>> public interface ITestWebService {
>> 	public void testPassingArray(@WebParam(name = "arrayOfLongs") Long[]
>> arrayOfLongs);
>> }
>>
>> Auto-generated WSDL (by CXF version 2.1.2) looks like following:
>>
>> <?xml version="1.0" ?><wsdl:definitions
>> name="TestBareWebServiceImplService"
>> targetNamespace="http://testbare.webservice.com/"
>> xmlns:ns1="http://cxf.apache.org/bindings/xformat"
>> xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
>> xmlns:tns="http://testbare.webservice.com/"
>> xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
>> xmlns:xsd="http://www.w3.org/2001/XMLSchema">
>>   <wsdl:types>
>> <xs:schema attributeFormDefault="unqualified"
>> elementFormDefault="unqualified"
>> targetNamespace="http://jaxb.dev.java.net/array"
>> xmlns="http://jaxb.dev.java.net/array"
>> xmlns:xs="http://www.w3.org/2001/XMLSchema">
>>     <xs:complexType final="#all" name="longArray">
>>         <xs:sequence>
>>             <xs:element maxOccurs="unbounded" minOccurs="0" name="item"
>> nillable="true" type="xs:long"></xs:element>
>>         </xs:sequence>
>>     </xs:complexType>
>> </xs:schema>
>> <xsd:schema attributeFormDefault="unqualified"
>> elementFormDefault="qualified"
>> targetNamespace="http://testbare.webservice.com/"
>> xmlns:ns0="http://jaxb.dev.java.net/array"
>> xmlns:tns="http://testbare.webservice.com/"
>> xmlns:xsd="http://www.w3.org/2001/XMLSchema">
>>     <xsd:import namespace="http://jaxb.dev.java.net/array"></xsd:import>
>>     <xsd:element name="arrayOfLongs" nillable="true"
>> type="ns0:longArray"></xsd:element>
>> </xsd:schema>
>>   </wsdl:types>
>>   <wsdl:message name="testPassingArray">
>>     <wsdl:part element="tns:arrayOfLongs" name="arrayOfLongs">
>>     </wsdl:part>
>>   </wsdl:message>
>>   <wsdl:message name="testPassingArrayResponse">
>>   </wsdl:message>
>>   <wsdl:portType name="ITestWebService">
>>     <wsdl:operation name="testPassingArray">
>>       <wsdl:input message="tns:testPassingArray" name="testPassingArray">
>>     </wsdl:input>
>>       <wsdl:output message="tns:testPassingArrayResponse"
>> name="testPassingArrayResponse">
>>     </wsdl:output>
>>     </wsdl:operation>
>>   </wsdl:portType>
>>   <wsdl:binding name="TestBareWebServiceImplServiceSoapBinding"
>> type="tns:ITestWebService">
>>     <soap:binding style="document"
>> transport="http://schemas.xmlsoap.org/soap/http"></soap:binding>
>>     <wsdl:operation name="testPassingArray">
>>       <soap:operation soapAction="" style="document"></soap:operation>
>>       <wsdl:input name="testPassingArray">
>>         <soap:body use="literal"></soap:body>
>>       </wsdl:input>
>>       <wsdl:output name="testPassingArrayResponse">
>>         <soap:body use="literal"></soap:body>
>>       </wsdl:output>
>>     </wsdl:operation>
>>   </wsdl:binding>
>>   <wsdl:service name="TestBareWebServiceImplService">
>>     <wsdl:port binding="tns:TestBareWebServiceImplServiceSoapBinding"
>> name="TestBareWebServiceImplPort">
>>       <soap:address
>> location="http://localhost:8080/ProwebWebServices/services/TestBareWebServi
>>ce"></soap:address> </wsdl:port>
>>   </wsdl:service>
>> </wsdl:definitions>
>>
>> When I generate Java client stubs from this WSDL generated interface
>> looks
>> like following:
>>
>> @WebService(targetNamespace = "http://testbare.webservice.com/", name =
>> "ITestWebService")
>> @XmlSeeAlso({ObjectFactory.class})
>> @SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
>> public interface ITestWebService {
>>
>>     @WebMethod
>>     public void testPassingArray(
>>         @WebParam(partName = "arrayOfLongs", name = "arrayOfLongs",
>> targetNamespace = "http://testbare.webservice.com/")
>>         LongArray arrayOfLongs
>>     );
>> }
>>
>> I'm surprised that array parameter is "wrapped" in generated class
>> LongArray through which I need to access internal list of items. I have
>> expected that generated method on the client side is something like
>> following:
>>
>>     @WebMethod
>>     public void testPassingArray(
>>         @WebParam(partName = "arrayOfLongs", name = "arrayOfLongs",
>> targetNamespace = "http://testbare.webservice.com/")
>>         java.util.List<java.lang.Long> arrayOfLongs
>>     );
>>
>> When I'm using document/literal/wrapped SOAP binding then generated
>> client
>> stub interface is "more friendly and logical":
>>
>> @WebService(targetNamespace = "http://testbare.webservice.com/", name =
>> "ITestWebService")
>> @XmlSeeAlso({ObjectFactory.class})
>> public interface ITestWebService {
>>
>>     @RequestWrapper(localName = "testPassingArray", targetNamespace =
>> "http://testbare.webservice.com/", className =
>> "com.webservices.test.TestPassingArray")
>>     @ResponseWrapper(localName = "testPassingArrayResponse",
>> targetNamespace = "http://testbare.webservice.com/", className =
>> "com.webservices.test.TestPassingArrayResponse")
>>     @WebMethod
>>     public void testPassingArray(
>>         @WebParam(name = "arrayOfLongs", targetNamespace = "")
>>         java.util.List<java.lang.Long> arrayOfLongs
>>     );
>> }
>>
>> Is this expected behavior when using document/literal/bare SOAP binding?
>> Originally I thought that when I switch from wrapped to bare client will
>> compile without any changes. But it seems that client stubs are different
>> and I need to adapt my client to the little bit different generated
>> interfaces.
>>
>> Can someone explain me if described behovior is correct or is it a bug?
>> Shouldn't be generated interfaces on the client side still the same
>> independent of which SOAP binding is currently used?
> 
> 
> 
> -- 
> Daniel Kulp
> dkulp@apache.org
> http://dankulp.com/blog
> 
> 

-- 
View this message in context: http://www.nabble.com/Passing-array-parameters-when-using-document-literal-bare-SOAP-binding-tp19896773p19949573.html
Sent from the cxf-user mailing list archive at Nabble.com.


Re: Passing array parameters when using document/literal/bare SOAP binding

Posted by Daniel Kulp <dk...@apache.org>.
This is all correct.  Arrays/collections in "bare" mode really don't work 
well.     Global elements in schema aren't allowed to have a "maxOccurs" on 
them.  Since doc/lit has to point at an element, we have to generate a pseudo 
element that points to a sequence with an element with the maxOccurs.   Kind 
of a wrapped thing.  

Code generated from that would then generate a type for that wrapper type 
thing and point at it.

Anyway, a bit strange, but is working properly.    For the most part though, 
I'd recommend sticking to wrapped doc/lit for code first type things.

Dan



On Thursday 09 October 2008 7:12:49 am Libor Svehlak wrote:
> I need to use document/literal/bare SOAP binding I'm little bit surprised
> about difference of passing array parameters when using this SOAP binding
> in oposite to document/literal/wrapped style.
>
> I have following simple interface:
>
> @WebService
> @SOAPBinding(style=Style.DOCUMENT, use=Use.LITERAL, parameterStyle =
> ParameterStyle.BARE)
> public interface ITestWebService {
> 	public void testPassingArray(@WebParam(name = "arrayOfLongs") Long[]
> arrayOfLongs);
> }
>
> Auto-generated WSDL (by CXF version 2.1.2) looks like following:
>
> <?xml version="1.0" ?><wsdl:definitions
> name="TestBareWebServiceImplService"
> targetNamespace="http://testbare.webservice.com/"
> xmlns:ns1="http://cxf.apache.org/bindings/xformat"
> xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
> xmlns:tns="http://testbare.webservice.com/"
> xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
> xmlns:xsd="http://www.w3.org/2001/XMLSchema">
>   <wsdl:types>
> <xs:schema attributeFormDefault="unqualified"
> elementFormDefault="unqualified"
> targetNamespace="http://jaxb.dev.java.net/array"
> xmlns="http://jaxb.dev.java.net/array"
> xmlns:xs="http://www.w3.org/2001/XMLSchema">
>     <xs:complexType final="#all" name="longArray">
>         <xs:sequence>
>             <xs:element maxOccurs="unbounded" minOccurs="0" name="item"
> nillable="true" type="xs:long"></xs:element>
>         </xs:sequence>
>     </xs:complexType>
> </xs:schema>
> <xsd:schema attributeFormDefault="unqualified"
> elementFormDefault="qualified"
> targetNamespace="http://testbare.webservice.com/"
> xmlns:ns0="http://jaxb.dev.java.net/array"
> xmlns:tns="http://testbare.webservice.com/"
> xmlns:xsd="http://www.w3.org/2001/XMLSchema">
>     <xsd:import namespace="http://jaxb.dev.java.net/array"></xsd:import>
>     <xsd:element name="arrayOfLongs" nillable="true"
> type="ns0:longArray"></xsd:element>
> </xsd:schema>
>   </wsdl:types>
>   <wsdl:message name="testPassingArray">
>     <wsdl:part element="tns:arrayOfLongs" name="arrayOfLongs">
>     </wsdl:part>
>   </wsdl:message>
>   <wsdl:message name="testPassingArrayResponse">
>   </wsdl:message>
>   <wsdl:portType name="ITestWebService">
>     <wsdl:operation name="testPassingArray">
>       <wsdl:input message="tns:testPassingArray" name="testPassingArray">
>     </wsdl:input>
>       <wsdl:output message="tns:testPassingArrayResponse"
> name="testPassingArrayResponse">
>     </wsdl:output>
>     </wsdl:operation>
>   </wsdl:portType>
>   <wsdl:binding name="TestBareWebServiceImplServiceSoapBinding"
> type="tns:ITestWebService">
>     <soap:binding style="document"
> transport="http://schemas.xmlsoap.org/soap/http"></soap:binding>
>     <wsdl:operation name="testPassingArray">
>       <soap:operation soapAction="" style="document"></soap:operation>
>       <wsdl:input name="testPassingArray">
>         <soap:body use="literal"></soap:body>
>       </wsdl:input>
>       <wsdl:output name="testPassingArrayResponse">
>         <soap:body use="literal"></soap:body>
>       </wsdl:output>
>     </wsdl:operation>
>   </wsdl:binding>
>   <wsdl:service name="TestBareWebServiceImplService">
>     <wsdl:port binding="tns:TestBareWebServiceImplServiceSoapBinding"
> name="TestBareWebServiceImplPort">
>       <soap:address
> location="http://localhost:8080/ProwebWebServices/services/TestBareWebServi
>ce"></soap:address> </wsdl:port>
>   </wsdl:service>
> </wsdl:definitions>
>
> When I generate Java client stubs from this WSDL generated interface looks
> like following:
>
> @WebService(targetNamespace = "http://testbare.webservice.com/", name =
> "ITestWebService")
> @XmlSeeAlso({ObjectFactory.class})
> @SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
> public interface ITestWebService {
>
>     @WebMethod
>     public void testPassingArray(
>         @WebParam(partName = "arrayOfLongs", name = "arrayOfLongs",
> targetNamespace = "http://testbare.webservice.com/")
>         LongArray arrayOfLongs
>     );
> }
>
> I'm surprised that array parameter is "wrapped" in generated class
> LongArray through which I need to access internal list of items. I have
> expected that generated method on the client side is something like
> following:
>
>     @WebMethod
>     public void testPassingArray(
>         @WebParam(partName = "arrayOfLongs", name = "arrayOfLongs",
> targetNamespace = "http://testbare.webservice.com/")
>         java.util.List<java.lang.Long> arrayOfLongs
>     );
>
> When I'm using document/literal/wrapped SOAP binding then generated client
> stub interface is "more friendly and logical":
>
> @WebService(targetNamespace = "http://testbare.webservice.com/", name =
> "ITestWebService")
> @XmlSeeAlso({ObjectFactory.class})
> public interface ITestWebService {
>
>     @RequestWrapper(localName = "testPassingArray", targetNamespace =
> "http://testbare.webservice.com/", className =
> "com.webservices.test.TestPassingArray")
>     @ResponseWrapper(localName = "testPassingArrayResponse",
> targetNamespace = "http://testbare.webservice.com/", className =
> "com.webservices.test.TestPassingArrayResponse")
>     @WebMethod
>     public void testPassingArray(
>         @WebParam(name = "arrayOfLongs", targetNamespace = "")
>         java.util.List<java.lang.Long> arrayOfLongs
>     );
> }
>
> Is this expected behavior when using document/literal/bare SOAP binding?
> Originally I thought that when I switch from wrapped to bare client will
> compile without any changes. But it seems that client stubs are different
> and I need to adapt my client to the little bit different generated
> interfaces.
>
> Can someone explain me if described behovior is correct or is it a bug?
> Shouldn't be generated interfaces on the client side still the same
> independent of which SOAP binding is currently used?



-- 
Daniel Kulp
dkulp@apache.org
http://dankulp.com/blog