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