Discussions

XML & Web services: Returning an ArrayList of HashMaps from web service

  1. Hi All,

    What I want to do is return an ArrayList of HashMaps from a
    web service.

    This is an EJB (stateless) that I can´t really change so I can´t change the return type to Object[] etc

    I am using:

    OS: windows 2000
    Server: weblogic 7.0 service pack 5

    The error I get is:

    java.rmi.RemoteException: web service invoke failed; nested exception is:
    javax.xml.soap.SOAPException: failed to deserialize xml:weblogic.xml.schema.binding.DeserializationException: mapping lookup failure. type=['http://www.w3.org/2001/XMLSchema']:anyType schema context=TypedSchemaContext{javaType=javax.xml.soap.SOAPElement}

    javax.xml.soap.SOAPException: failed to deserialize xml:weblogic.xml.schema.binding.DeserializationException: mapping lookup failure. type=['http://www.w3.org/2001/XMLSchema']:anyType schema context=TypedSchemaContext{javaType=javax.xml.soap.SOAPElement}

    The relevant part of the web-services.xml is:

      <web-service targetNamespace="http://www.indra.com/webservices/Callejero" uri="/Callejero" style="rpc" name="Callejero" protocol="http">
        <types>
        <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
      xmlns:stns="java:language_builtins.util"
      attributeFormDefault="qualified"
      elementFormDefault="qualified"
      targetNamespace="java:language_builtins.util">
     <xsd:import namespace="http://schemas.xmlsoap.org/soap/encoding/">
     </xsd:import>
     <xsd:complexType name="ArrayList">
      <xsd:complexContent>
       <xsd:restriction xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
         base="soapenc:Array">
        <xsd:attribute xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
          wsdl:arrayType="xsd:anyType[]"
          ref="soapenc:arrayType">
        </xsd:attribute>
       </xsd:restriction>
      </xsd:complexContent>
     </xsd:complexType>

    </xsd:schema>

    <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                xmlns:stns="java.util.HashMap"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                attributeFormDefault="qualified"
                elementFormDefault="qualified"
                targetNamespace="java.util.HashMap">
     <xsd:import namespace="http://schemas.xmlsoap.org/soap/encoding/">
     </xsd:import>

       <xsd:complexType name="HashMap">
          <xsd:sequence>
            <xsd:element name="key"
                         type="xsd:string">
            </xsd:element>
            <xsd:element name="valor"
                         type="xsd:string">
            </xsd:element>
          </xsd:sequence>
       </xsd:complexType>
    </xsd:schema>

    </types>


    My class to do the serialization/deserialization:

    public class HashMap extends AbstractCodec
    {
      public HashMap()
      {}

    public void serialize(Object obj,
                            XMLName name,
                            XMLOutputStream writer,
                            SerializationContext context)
        throws SerializationException
    {
    try {
        out("serialize");
        out("XMLNAME: " + name);

          java.util.HashMap map = (java.util.HashMap)obj;

          //outer start element
          writer.add(ElementFactory.createStartElement(name));

          Iterator itKeys = map.keySet().iterator();

          Object objKey = null;
          Object objValor = null;

          while(itKeys.hasNext())
          {
            objKey = itKeys.next();
            objValor = map.get(objKey);

            out("KEY: " + objKey);
            out("VALOR: " + objValor);

            //employee name element
            writer.add(ElementFactory.createStartElement("key"));
            writer.add(ElementFactory.createCharacterData(objKey.toString()));
            writer.add(ElementFactory.createEndElement("key"));

            //employee id element
            writer.add(ElementFactory.createStartElement("valor"));
            writer.add(ElementFactory.createCharacterData(objValor.toString()));
            writer.add(ElementFactory.createEndElement("valor"));
          }

          //outer end element
          writer.add(ElementFactory.createEndElement(name));

        } catch(XMLStreamException xse) {
          throw new SerializationException("stream error", xse);
        }
    }

    How I register my mapping in the client:

          Callejero_Impl impl = new Callejero_Impl(urlWSDL.toString());
          TypeMapping mapping = impl.getTypeMappingRegistry().getTypeMapping(SOAPConstants.URI_NS_SOAP_ENCODING);
          mapping.register(java.util.HashMap.class,new QName("java.util.HashMap"),new com.factoriaSoftware.soap.codecs.HashMap(),new com.factoriaSoftware.soap.codecs.HashMap());
          CallejeroPort port = impl.getCallejeroPort();
          port.setAplicacion("TSGF");
          //This should be a list of HashMaps but fails
          Object[] list = port.getProvinciasFromCP("0200");

    If anyone has any ideas please reply and sorry for the long message .

    Gerardo
  2. I'm not sure, but i have used wsdl2java that is a tool from axis for generating clients to invoke a webservice.
    I have used it in calling ws that returns complex objects.
    It is not a difficult tool to use.

    http://ws.apache.org/axis/java/user-guide.html and look for wsdl2java

    I hope this will help.
  3. I am getting same error.

    The client works as standalone but does not work from WebLogic War file