How to deseralize a hashtable?

"Chen, Donald" <[email protected]>
Newsgroups gmane.text.xml.soap.user
Message-ID <[email protected]>
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(XMLJav
aMappingRegistry.java:206)
        at
org.apache.soap.util.xml.XMLJavaMappingRegistry.unmarshall(XMLJavaMappin
gRegistry.java:302)
        at
org.apache.soap.encoding.soapenc.ParameterSerializer.unmarshall(Paramete
rSerializer.java:206)
        at
org.apache.soap.util.xml.XMLJavaMappingRegistry.unmarshall(XMLJavaMappin
gRegistry.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:ge
tAllInfoResponse
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:getAllInfoRespons
e></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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.