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();
call.setTargetObjectURI("urn:greetingService");
call.setMethodName("sayGreeting");
call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC);
//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
call.setParams(params);
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
try
{
if( res.generatedFault() ==false)
{
Parameter retValue = res.getReturnValue();
Object value = retValue.getValue();
System.out.println(value);
}else
{
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.
New on the Java Boutique:
New Review:
Time Management Made Easy with the Quartz Enterprise Job Scheduler
Why not just use the Java timer API? This open source scheduling
API boasts simplicity, ease-of-integration, a well-rounded feature
set, and it's free!
New Applet:
Reverse Complement
Reverse Complement is a simple applet that converts DNA or RNA
sequences into three useful formats.
Elsewhere on internet.com:
WebDeveloper Java
Lots of Java information on webdeveloper.com
WDVL Java
Thorough Java resource at the Web Developer's Virtual Library.
ScriptSearch Java
Hundreds of free Java code files to download.
jGuru: Your View of the Java Universe
Customizable portal with online training, FAQs, regular news updates, and tutorials.