Title: How to deseralize a hashtable?

Hi, All.

I have a WS in Perl via SOAP::Lite.  Via this WS, a client can call a method getAllInfo() which returns a
Hashtable.  I wrote a WS client in perl with success, but writing a WS client in Java via the Apache-Soap-2.3.1 is never successful.

Specifically, the error I got is like this:

Exception in thread "main" java.lang.IllegalArgumentException: No Deserializer found to deserialize a 'http://xml.apache.org/xml-soap:SOAPStruct' using encoding style 'http://schemas.xmlsoap.org/soap/encoding/'.

        at org.apache.soap.util.xml.XMLJavaMappingRegistry.queryDeserializer(XMLJavaMappingRegistry.java:206)
        at org.apache.soap.util.xml.XMLJavaMappingRegistry.unmarshall(XMLJavaMappingRegistry.java:302)
        at org.apache.soap.encoding.soapenc.ParameterSerializer.unmarshall(ParameterSerializer.java:206)
        at org.apache.soap.util.xml.XMLJavaMappingRegistry.unmarshall(XMLJavaMappingRegistry.java:314)
        at org.apache.soap.rpc.RPCMessage.unmarshall(RPCMessage.java:417)
        at org.apache.soap.rpc.RPCMessage.extractFromEnvelope(RPCMessage.java:197)
        at org.apache.soap.rpc.Response.extractFromEnvelope(Response.java:142)
        at GetChemDef.main(GetChemDef.java:167)


Here is the payload I got from the server:

<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope xmlns:namesp2="http://xml.apache.org/xml-soap" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><SOAP-ENV:Body><namesp17:getAllInfoResponse xmlns:namesp17="http://johnny5:8002/ChemDefServices"><s-gensym68 xsi:type="namesp2:SOAPStruct"><delimilator xsi:type="xsd:string">|</delimilator><chemistry xsi:type="xsd:string">caffeine</chemistry><a xsi:type="xsd:string">aPiece</a><smiles xsi:type="xsd:string">c1ccccc1</smiles><b xsi:type="xsd:string">bPiece</b><syntaxOk xsi:type="xsd:int">1</syntaxOk></s-gensym68></namesp17:getAllInfoResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>


This payload refects a hashtable:

%h = ( chemistry => 'caffeine',
           a             => 'aPiece',
           b             => 'bPiece',
           smiles     => 'c1ccccc1'
         );

Here are the major code lines (as you can see, I was trying to use the HashtableSerializer ):

        // build the call.
        Call call = new Call();
        call.setSOAPTransport(st);
        call.setTargetObjectURI("http://localhost:8002/ChemDefServices");
        call.setMethodName("getAllInfo");

        SOAPMappingRegistry smrr = new SOAPMappingRegistry ();
        HashtableSerializer hsd = new HashtableSerializer ();
        smrr.mapTypes(Constants.NS_URI_SOAP_ENC, new QName("", "ChemDefServices"), Hashtable.class, null, hsd);

        // create the transport and set parameters
        call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC);
        call.setSOAPMappingRegistry(smrr);
        Vector params = new Vector();
        params.addElement(new Parameter("definition", String.class, "definition", null));
        params.addElement(new Parameter("chemDefString", String.class, chemDefString, null));
        call.setParams(params);

        // invoke it
        System.err.println("Invoking chemDef service at: ");
        System.err.println("\t" + serviceURL);
        Response resp;
        try {
            SOAPMappingRegistry smr = call.getSOAPMappingRegistry();
            SOAPContext reqCtx = call.getSOAPContext();
            DocumentBuilder xdb = XMLParserUtils.getXMLDocBuilder();

            Envelope callEnv = call.buildEnvelope();
            StringWriter payloadSW = new StringWriter();
            callEnv.marshall(payloadSW, smr, reqCtx);
            reqCtx.setRootPart(payloadSW.toString(),
                               Constants.HEADERVAL_CONTENT_TYPE);

            st.send(url, "", null, null, smr, reqCtx);

            SOAPContext respCtx = st.getResponseSOAPContext();
            String payloadStr = Call.getEnvelopeString(st);

            Document respDoc =    xdb.parse(new InputSource(new StringReader(payloadStr)));
            Element payload = null;
            if (respDoc != null)            {
                payload = respDoc.getDocumentElement();
            }     else     {
                throw new SOAPException (Constants.FAULT_CODE_CLIENT,
                    "Parsing error, response was:\n" + payloadStr);
            }
            System.out.println("payloadStr = \n" + payloadStr);
           Envelope respEnv = Envelope.unmarshall(payload, respCtx);
            System.out.println("respEnv = \n" + respEnv.toString());
            System.out.println("respCtx = \n" + respCtx.toString());
            resp = Response.extractFromEnvelope(respEnv, smr, respCtx);  // I got error right here

Did I miss something to make it work?  Do I need to write my own deseralizer for the hashtable?  If yes, how to incorporate the deseralizer to the main funciton?

Thanks in advance,

Donald           

Reply via email to