Tuesday, July 26, 2011

web service client No deserializer for error

When you encounter the error of No deserializer  in web services client:

faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.userException
faultString: org.xml.sax.SAXException: No deserializer for {http://xxxx.com}ArrayOfString
        {http://xml.apache.org/axis/}stackTrace:org.xml.sax.SAXException: No des
erializer for {http://collections.soap.yodlee.com}ArrayOfString
        at org.apache.axis.encoding.ser.BeanDeserializer.onStartChild(BeanDeseri
        at org.apache.axis.encoding.DeserializationContext.startElement(Deserial
        at org.apache.axis.message.SAX2EventRecorder.replay(SAX2EventRecorder.ja
        at org.apache.axis.message.MessageElement.publishToHandler(MessageElemen
Most likely the server has the bad web services interface design, I encountered this, web services interface is using Java Collection Framework java.util.Map, so the WSDL definition has the following element,

            <element name="mapOfAttributes" nillable="true" type="tns2:Map" minOccurs="0" />

            <complexType name="Map">
                    <element name="table" nillable="true" type="tns2:Entry" maxOccurs="unbounded" minOccurs="0" />

            <complexType name="Entry">
                    <element name="key" nillable="true" type="xsd:anyType" minOccurs="0" />
                    <element name="value" nillable="true" type="xsd:anyType" minOccurs="0" />

anyType is the type of Map’s key and value,  but there is no deserializer for anyType.

In the response SOAP XML, the value of the map which has a type of ArrayOfString which is not defined in the WSDL since WSDL define anyType for this element, so there is no deserializer for it.

                <arrayOfAttributes xmlns="">
                    <table xmlns="">
                        <key xmlns:s885="http://www.w3.org/2001/XMLSchema" xmlns="" xsi:type="s885:string">YodleeAttributes</key>
                        <value xmlns:s886="http://xxxx.com" xmlns="" xsi:type="s886:ArrayOfString">
                            <elements xmlns="" xsi:nil="1"/>

The short-term workaround is, add the following ArrayOfString definition to the WSDL. (it is a bad solution since the WSDL is automatically generated from Java interface), then regenerated the stub class.

<complexType name="ArrayOfString">
                    <element name="elements" nillable="true" type="xsd:string" maxOccurs="unbounded" minOccurs="0" />

The long-term solution is to change the web service interface design, not to use any Java Collection Framework or anyType in WSDL, but use array instead.