Did some more work on this, I though it might be related to me exposing the
service via JSR 181 instead of through services.xml but thats not the case
(never made sense anyways).  

Even if I have the following very simple operation exposed, the client fails
to bind the returning collection into the ArrayOfString object.  The SOAP
response is correct but when I try to access the list using the API
generated using the wsgen task, the list is always empty.  

Has anybody actually got a Collection to return using a web service?  I've
posted my complete configuration.

Here's the service class:

public Collection<String> getStrings() {
    Collection<String> list = new ArrayList<String>();
    list.add("elem 1");
    list.add("elem 2");
    return list;
}

Here's the services.xml:

<beans xmlns="http://xfire.codehaus.org/config/1.0";>
  <service>
    <name>StringService</name>
    <serviceClass>StringService</serviceClass>
  </service>
</beans>


Here's the sample client code:

Service serviceModel = new
ObjectServiceFactory().create(StringServicePortType.class);
StringServicePortType service = (StringServicePortType) new
XFireProxyFactory().create(serviceModel, SERVICE_URL);
ArrayOfString strings = service.getStrings();
System.out.println("strings = " + strings.getString().size()); // always
zero

Here's the response I captured using TCPMON:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/";
xmlns:xsd="http://www.w3.org/2001/XMLSchema";
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";>
   <soap:Body>
      <getStringsResponse xmlns="http://xfire.codehaus.org/BookService";>
         <out xmlns="http://xfire.codehaus.org/BookService";>
            <string>elem 1</string>
            <string>elem 2</string>
         </out>
      </getStringsResponse>
   </soap:Body>
</soap:Envelope>


Here's the complete WSDL:


<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="http://DefaultNamespace";
xmlns:tns="http://DefaultNamespace";
xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/";
xmlns:soap12="http://www.w3.org/2003/05/soap-envelope";
xmlns:xsd="http://www.w3.org/2001/XMLSchema";
xmlns:soapenc11="http://schemas.xmlsoap.org/soap/encoding/";
xmlns:soapenc12="http://www.w3.org/2003/05/soap-encoding";
xmlns:soap11="http://schemas.xmlsoap.org/soap/envelope/";
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/";>
  <wsdl:types>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema";
attributeFormDefault="qualified" elementFormDefault="qualified"
targetNamespace="http://DefaultNamespace";>
<xsd:element name="getStrings">
<xsd:complexType/>
</xsd:element>
<xsd:complexType name="ArrayOfString">
<xsd:sequence>
<xsd:element maxOccurs="unbounded" minOccurs="0" name="string"
nillable="true" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="getStringsResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element maxOccurs="1" minOccurs="1" name="out" nillable="true"
type="tns:ArrayOfString"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
  </wsdl:types>
  <wsdl:message name="getStringsResponse">
    <wsdl:part name="parameters" element="tns:getStringsResponse">
    </wsdl:part>
  </wsdl:message>
  <wsdl:message name="getStringsRequest">
    <wsdl:part name="parameters" element="tns:getStrings">
    </wsdl:part>
  </wsdl:message>
  <wsdl:portType name="StringServicePortType">
    <wsdl:operation name="getStrings">
      <wsdl:input name="getStringsRequest" message="tns:getStringsRequest">
    </wsdl:input>
      <wsdl:output name="getStringsResponse"
message="tns:getStringsResponse">
    </wsdl:output>
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="StringServiceHttpBinding"
type="tns:StringServicePortType">
    <wsdlsoap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="getStrings">
      <wsdlsoap:operation soapAction=""/>
      <wsdl:input name="getStringsRequest">
        <wsdlsoap:body use="literal"/>
      </wsdl:input>
      <wsdl:output name="getStringsResponse">
        <wsdlsoap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="StringService">
    <wsdl:port name="StringServiceHttpPort"
binding="tns:StringServiceHttpBinding">
      <wsdlsoap:address
location="http://localhost:8080/xfirespring/services/StringService"/>
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>















Zarar Siddiqi wrote:
> 
> The XFire client generated using wsgen (default jaxb binding) has trouble
> binding the returned SOAP message to Java objects when using a Collection
> as a return type.  It works for all other cases but as soon as I try to
> return a Collection or an array, the binding fails.  The correct soap
> message is returned from the server but when I use the API to print the
> values the list size is always zero even though the soap message contained
> multiple items corresponding to the collection:
> 
> ArrayOfUser users = service.getUsers(..);
> System.out.println(users.getUser().size()); // always prints 0
> 
> I've annotated one of my domain objects (User) with an Aegis annotation to
> prevent the properties being wrapped around the JAXBElement type, aside
> from that nothing "weird" is going on.
> 
> The docs say that I don't need to specify a .aegis.xml file if I'm using
> Java5 Generics and that the binding should happen normally.
> http://xfire.codehaus.org/Mapping+collections
> 
> I'm not making any changes to the generated code.  Any help is
> appreciated.
> 
> I'm running XFire 1.2.4 with JDK 1.5.0_11 and have the following service
> exposed using JSR 181 annotations.  
> 
> @WebService
> public interface UserService {
> 
>     public Collection<User> getUsers(String authority)
>             throws WebServiceException;
> }
> 
> 
> @WebService(serviceName="UserSoapService", endpointInterface =
> "com.arsenalist.UserService")
> @InHandlers  (handlers={ // my in-handlers  })
> @OutHandlers (handlers={ // my out-handlers })
> public class UserSoapService implements UserService {
> 
>     public Collection<User> getUsers(String authority)
>             throws WebServiceException {
>             
>             // return a list of users
>       }
> }
> 
> public class User {
>       private String username;
>       
>       @XmlElement(minOccurs="1")
>       public String getUsername() {
>               return username;
>       }
>       
>       public void setUsername(String username) {
>               this.username = username;
>       }
> }
> 
> 
> My spring configuration is as follows:
> 
> <bean id="webAnnotations"
>       class="org.codehaus.xfire.annotations.jsr181.Jsr181WebAnnotations"/>
> <bean id="handlerMapping"
>       class="org.codehaus.xfire.spring.remoting.Jsr181HandlerMapping">
>     <property name="typeMappingRegistry">
>         <ref bean="xfire.typeMappingRegistry"/>
>     </property>
>     <property name="xfire">
>         <ref bean="xfire"/>
>     </property>
>     <property name="webAnnotations">
>         <ref bean="webAnnotations"/>
>     </property>
> </bean>
> 
> <bean
> class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
>     <property name="urlMap">
>         <map>
>             <entry key="/">
>                 <ref bean="handlerMapping"/>
>             </entry>
>         </map>
>     </property>
> </bean>
> 
> <bean id="userSoapService" class="com.arsenalist.UserSoapService"/>
> 
> 
> 

-- 
View this message in context: 
http://www.nabble.com/Problem-returning-a-Collection-or-an-array-using-generics-tf3364015.html#a9374205
Sent from the XFire - User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe from this list please visit:

    http://xircles.codehaus.org/manage_email

Reply via email to