Hi
I got an issue with casting arrays returned when calling my SOAP
service.
Interface:
public Address[] lookupAddress(...);
Implementation:
public Address[] lookupAddress(...) {
... some stuff happening ...
UKAddress address = new UKAddress[10];
... 10 UKAddress objects added to address array ...
return address;
}
Model:
public class BaseModel{}
public class Address{} extends BaseModel
public class UKAddress extends Address{}
Spring setup:
<bean id="addressLookupService"
class="com.surgex.addresslookup.service.impl.AddressLookupServiceImpl" i
nit-method="init">
<property name="addressLookupDAO" ref="addressLookupDAO" />
</bean>
<jaxws:endpoint id="soapService" implementor="#addressLookupService"
address="/AddressLookup">
<jaxws:serviceFactory>
<ref bean="jaxws-and-aegis-service-factory"/>
</jaxws:serviceFactory>
</jaxws:endpoint>
<bean id="aegisBean"
class="org.apache.cxf.aegis.databinding.AegisDatabinding"/>
<bean id="jaxws-and-aegis-service-factory"
class="org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean">
<property name="dataBinding" ref="aegisBean"/>
<property name="serviceConfigurations">
<list>
<bean
class="org.apache.cxf.jaxws.support.JaxWsServiceConfiguration"/>
<bean
class="org.apache.cxf.aegis.databinding.AegisServiceConfiguration"/>
<bean
class="org.apache.cxf.service.factory.DefaultServiceConfiguration"/>
</list>
</property>
<property name="properties">
<map>
<entry key="writeXsiType">
<value type="java.lang.Boolean">true</value>
</entry>
<entry key="overrideTypesList">
<list>
<value>com.surgex.addresslookup.model.BaseModel</
value>
<value>com.surgex.addresslookup.model.Address</value>
<value>com.surgex.addresslookup.model.UKAddress</
value>
</list>
</entry>
</map>
</property>
</bean>
Note: the client side also has the <property name="properties"> setup
as per the server above.
WSDL:
<xsd:complexType name="ArrayOfUKAddress">
<xsd:sequence>
<xsd:element maxOccurs="unbounded" minOccurs="0"
name="UKAddress" nillable="true" type="tns:UKAddress"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="ArrayOfAddress">
<xsd:sequence>
<xsd:element maxOccurs="unbounded" minOccurs="0"
name="Address" nillable="true" type="tns:Address"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType abstract="true" name="BaseModel"/>
<xsd:complexType name="Address">
<xsd:complexContent>
<xsd:extension base="tns:BaseModel">
<xsd:sequence>
<xsd:element minOccurs="0" name="country"
nillable="true" type="xsd:string"/>
<xsd:element minOccurs="0"
name="matchingAttributes" type="xsd:int"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="UKAddress">
<xsd:complexContent>
<xsd:extension base="tns:Address">
<xsd:sequence>
<xsd:element minOccurs="0" name="building"
nillable="true" type="xsd:string"/>
<xsd:element minOccurs="0"
name="dbleDependentLocality" nillable="true" type="xsd:string"/>
<xsd:element minOccurs="0" name="department"
nillable="true" type="xsd:string"/>
<xsd:element minOccurs="0"
name="dependentLocality" nillable="true" type="xsd:string"/>
<xsd:element minOccurs="0"
name="dependentThoroughfare" nillable="true" type="xsd:string"/>
<xsd:element minOccurs="0"
name="matchingAttributes" type="xsd:int"/>
<xsd:element minOccurs="0" name="organisation"
nillable="true" type="xsd:string"/>
<xsd:element minOccurs="0" name="poBox"
nillable="true" type="xsd:string"/>
<xsd:element minOccurs="0" name="postalCode"
nillable="true" type="xsd:string"/>
<xsd:element minOccurs="0" name="postalTown"
nillable="true" type="xsd:string"/>
<xsd:element minOccurs="0" name="subBuilding"
nillable="true" type="xsd:string"/>
<xsd:element minOccurs="0" name="thoroughfare"
nillable="true" type="xsd:string"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
The issue is that when using SOAP to access this service (Note that
this service is also exposed through RMI, JMX, HttpInvoker, Hessian
and Burlap and they're all fine) I cannot cast the Address[] to a
UKAddress[] eventhough all elements in the Address[] are UKAddress
objects.
I get a ClassCastException.
I have the same bunch of tests which are executed using RMI, JMX,
HttpInvoker, Burlap and Hessian and they have no issue with the cast.
Address[] addresses = service.lookupAddress(...);
UKAddress[] addr = (UKAddress[])addresses -> ClassCastException;
Code below runs ok.
Address[] addresses = service.lookupAddress(...);
assertTrue(addresses instanceof Address[]);
System.out.println(addresses.length);
for (int i=0; i<addresses.length; i++)
{
assert(addresses[i] instanceof UKAddress);
UKAddress addr = (UKAddress)addresses[i];
System.out.println(addr);
}
How can I get that cast to work with SOAP?
Thx.
--
Frederic P. Soulier
OpenPGP key available on http://pgpkeys.mit.edu/
1024D/BA6700ED 49A6 8E8E 4230 8D41 1ADE B649 3203 1DD2 BA67 00ED