When a wsdl operation is defined to be doc/lit, the org.apache.client.Call
setOperation() methods seem to make unexpected assumptions about the form of
the argument parameters, both in number and type. I tested this in
axis-1_2RC1 using the client program pasted below. Clearly I must be
missing something. Is the behavior below by design?
Suppose I have a wsdl defined to have
<types>
<schema ...
<element name="op" >
<complexType>
<sequence>
<element name="s1" type="xsd:string"/>
<element name="s2" type="xsd:int"/>
...
<element name="opReturn" ...>
...
<message name="opRequest">
<part name="part" element="tns:op"/>
</message>
<message name="opResponse">
<part name="ret" element="tns:opReturn"/>
</message>
<portType>...
<operation name="op">
<input message="tns:opRequest"/>
<output message="tns:opResponse"/>
</operation>
...
and the binding specifies a doc/lit operation.
If I understand correctly, a doc/lit operation such as that above defined
suitably for compatibility with the WS-I Basic Profile should take a single
parameter which is an element or document and return an Element or Document.
I assumed, incorrectly, it seems, that a single argument should be passed in
the client.
I try to pass this argument to Call.invoke in the form of an
org.w3c.dom.Element:
<op><s1>foo</s1><s2>33</s2></op>
but these things go wrong:
1. The client program requires two objects in the parameter array passed
to invoke.
2. If I supply the first one as above, and a null second one, the soap
body contains:
<Body>
<op>
<s1><op><s1>foo</s1><s2>33</s2></op></s1>
<s2></s2>
</op>
</Body>
That is, it is assumed that the constituents of the operation's input doc
part will be provided as separate parameters, rather than as a single
document.
The example below is self-contained and should depend only on the jars in
the Axis build.
---------------------- TestClientDocLit.java -----------------
import java.io.FileReader;
import java.io.BufferedReader;
import java.io.StringReader;
import org.w3c.dom.*;
import org.xml.sax.*;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import javax.xml.namespace.QName;
import javax.xml.rpc.ParameterMode;
import javax.xml.parsers.*;
// import javax.xml.transform.*;
// import javax.xml.transform.stream.*;
// import javax.xml.transform.dom.*;
// import org.apache.axis.encoding.ser.ElementSerializerFactory;
// import org.apache.axis.encoding.ser.ElementDeserializerFactory;
// import org.apache.axis.encoding.ser.ElementDeserializer;
public class TestClientDocLit
{
// static TransformerFactory tf = TransformerFactory.newInstance();
public static void main(String [] args) {
try {
String ns = "http://www.wolfram.com/XML/SOAP/WolframSearch";
QName serviceName
= new QName(ns, "WolframSearchService");
QName operationName = new QName(ns, "WolframQuickSearch");
QName portName
= new QName(ns, "WolframSearchPort");
QName returnQName = new QName(ns, "WolframQuickSearchReturn");
String endpoint =
"http://webservices.wolfram.com/services/SearchServices/services/WolframSear
ch";
Service service
= new
Service("http://webservices.wolfram.com/services/SearchServices/WolframSearc
h.wsdl", serviceName);
Call call
= (Call) service.createCall(portName,
operationName.getLocalPart());
String testStr
= "<WolframQuickSearch xmlns='" + ns
+ "'><text>definite
integral</text><limit>30</limit></WolframQuickSearch>";
Document d = null;
try {
DocumentBuilderFactory dbf =
DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
d = db.parse(new InputSource(new StringReader(testStr)));
} catch (Exception e) {
System.err.println("Failed to parse test doc " + e);
return;
}
Element ret = (Element) call.invoke(operationName, new Object[] {
d.getDocumentElement(), null // have to add ", null" here to
get invocation
});
// System.out.println("Sent:");
// serialize(d);
// if (ret != null) {
// System.out.println("Received:");
// serialize(ret);
// } else {
// System.err.println("Null response.");
// }
} catch (Exception e) {
System.err.println(e.toString());
}
}
// static void serialize(Document d) {
// serialize(d.getDocumentElement());
// }
// static void serialize(Element e) {
// try {
// tf.newTransformer().transform(new DOMSource(e), new
StreamResult(System.out));
// } catch (Exception x) {
// System.err.println("Failed to serialize " + x);
// }
// }
}