Using SOAP with Java | The Client

The client

Now we have our service deployed over the web server and try to write our first SOAP client using the Apache SOAP API. In order to talk to the SOAP handler, the SOAP client will need to know the URL of the SOAP handler. In our client example, we decide not to hard code this parameter and accept it as a command line argument. We also decide that we will accept the name variable as command line argument.

	String urlString = args[0];
	String name = args[1];

Now we need to build up a Call object, which will represent our SOAP Remote Procedure Call or RPC. In this case when we invoke the remote GreetingService and invoke the sayGreeting(String name) method on it, this becomes a Remote Procedure Call and all the information about the name of the remote service, the method name we are invoking and the parameters we are passing to it and the encoding style of the message, have to be embedded within the Call object as shown below:

       //build a Call object
       Call call = new Call();
       //creating a parameter list
       Vector params = new Vector();
       params.addElement(new Parameter("name", String.class, name,null));

//adding the parameter(s) to the Call object

Now once we have prepared the Call object, we can execute the RPC by the invoke() method of the Call object. Here inside this method we have to pass the URL of the SOAP handler. The second argument represents the SOAPACtion header information. This bit of information represents the intent of the SOAP request and often can be used by the Firewall to determine if the requested service and the intent to deal with the service can be authorized. For our simple example, we ignore this header information.

//invoke the soap method
  Response res = call.invoke(new URL(urlString), "");

As we see, the invoke() method returns a SOAP Response object which encapsulates all the information related to the SOAP Response. This Response object might contain the requested information or the return value of the Remote Procedure invoked or conditionally the Fault code and description generated because of the Remote Procedure Call. In either case, we will be able to use the Response object and retrieve the required information. To design, a good fault tolerant system, we must always handle the SOAP exceptions and the SOAP Fault messages. In order to encapsulate the fault messages, the API provides a Fault object. The following piece of code is an example of how we handle the Response and the Fault objects.

          //if there is no fault in the method invocation, get the result
          if( res.generatedFault() ==false)
              Parameter retValue = res.getReturnValue();
              Object value = retValue.getValue();
              System.out.println("The fault is: "+res.getFault().getFaultString());
        }catch(SOAPException soe)
System.out.println("The SOAP Exception is : "+soe.toString());

Once a Fault is generated, apparently that is the end of this Remote Procedure Call sequence. But depending on the situation and the types of Remote Services, we can do something constructive by examining the Fault string and the reason of the fault. For example, if it is because of the unavailability of the SOAP handler, then we might decide to try a separate handler.

Running the client

As we have the SOAP service deployed, now we can run the client to obtain the result.

java  clientclass http://localhost:8080/soap/servlet/rpcrouter yourname

Note: the client class has to be fully qualified in case you are using a package structure. Here the first command line argument indicates the URL of the SOAP handler, the second one is the name, which we want to say Hello to. Once executed without errors or exceptions, the service will generate a command line output "Hello name".

How did it work

This looks all too simple but the big question is how did it all fit together. The Apache SOAP implementation does the trick. There are two significant aspects of the SOAP implementation form Apache, one the SOAP handler that is the rpcrouter and second, the Call object. Once we execute the invoke() method of the Call object, it converts the Call object to an XML SOAP message and passes it to the rpcrouter. The rpcrouter then locates the specified service provider articraft based on the id of the specified service and invokes the necessary methods on it. The rpcrouter in turn constructs an appropriate XML SOAP response message, which the Call object returns to the caller as a Response object. The rpcrouter is essentially a Servlet which carries out multiple tasks such as locating a specified service, invoking the specified method(s) on it and also it performs the Serialization and De-Serialization of the XML data to and from the Java data types called the marshalling and un-marshalling. The Apache SOAP implementation defines the Serializers/De-serializers for the primitive data types. Once we require some custom Serialization, we can implement our own Serializers and Deserializers, which we will inspect in our next article.

Next month

If all this looks too simple for you, stay tuned for next month when I will develop a Java bean based SOAP application where we may have to deal with some excitement of Java beans and XML serialization. Happy coding.