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);
//         }

//     }
}

Reply via email to