Introduction
The following provides an example of writing a SOAP client and a SOAP web service using the Apache Axis framework. The documentation for Axis is available at Axis website.
The web service is an echo web service, it returns the string sent to it as an argument of the invocation of the web service. The example is based upon a tutorial (
Axis: The next generation of Apache SOAP).
The files mentioned below can be found at /vol/projects/dsrg/tutorials/webservice.
Before starting you must set your environment variables so that java can find the Axis libraries and an XML parser. This is done by adding the files to the environment variable AXISCLASSPATH. Assuming that you are using tcsh or csh you need to either execute the following or add the following lines to your .cshrc file:
set AXIS_HOME=/vol/courses/comp417/axis-1_2_1
set AXIS_LIB=$AXIS_HOME/lib
set AXISCLASSPATH=$AXIS_LIB/samples.jar:$AXIS_LIB/axis.jar:$AXIS_LIB/commons-discovery-0.2.jar:$AXIS_LIB/commons-logging-1.0.4.jar:$AXIS_LIB/jaxrpc.jar:$AXIS_LIB/saaj.jar:$AXIS_LIB/log4j-1.2.8.jar:$AXIS_LIB/log4j.properties:$AXIS_LIB/wsdl4j-1.5.1.jar:$AXIS_LIB/activation.jar:$AXIS_LIB
You can get these lines from setup.env.
Note that if you are working home, just copy all of the files in $AXIS_LIB and you should be able to still use the same classpath as shown above.
In the future you may want to put the properties file somewhere central and reference it by adding its directory into your classpath.
The Server
The first task is to write the web service. The web service that we create here is an echo service. It is implemented as the EchoServer that has one method, echo, which takes a message as its only parameter and returns the same message. Note that the class does not contain any Axis-specific code:
public class EchoServer {
public String echo(String message) {
return message;
}
}
Compile the server with:
javac EchoServer.java
The next task is to write an Axis Web Service Deployment Descriptor (WSDD) for the web service. A deployment descriptor contains a bunch of things that you want to "deploy" into Axis. The most common thing is to deploy a web service. The EchoServer.wsdd deployment descriptor for EchoServer looks like this:
<deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<service name="EchoService" provider="java:RPC">
<parameter name="className" value="EchoServer"/>
<parameter name="allowedMethods" value="*"/>
</service>
</deployment>
The outermost element states that this is a WSDD deployment and defines the "java:" namespace. Next the service element actually defines the service. The service in this case is "java:RPC", which is built into Axis. RPC services follow the SOAP RPC and encoding rules. Each SOAP RPC invocation and result are encoded using XML. Axis will deserialise the XML into Java objects, invoke the appropriate method and serialise the returned Java object(s) from your service back into XML.
The RPC service must be told which class to instantiate and call (e.g., EchoService). This is done by including
tags. The first parameter gives the class name, and the second indicates that any public method of that class may be called via SOAP.
The Client
The next step is to write a client, in this example the client implementation is the EchoClient class. Note that this example assumes that the Axis server is running on port 8080, if it is running on a different port then you will need to change the port specified in the endpoint URL.
public class EchoClient {
public static void main(String [] args) throws Exception {
Options options = new Options(args);
String endpoint = "http://localhost:8080/axis/services/EchoService";
args = options.getRemainingArgs();
if (args == null or args.length != 1) {
System.err.println("Usage: EchoClient message");
return;
}
String message = args[0];
Service service = new Service();
Call call = (Call) service.createCall();
call.setTargetEndpointAddress( new java.net.URL(endpoint) );
call.setOperationName("echo");
call.addParameter("message", org.apache.axis.Constants.XSD_STRING, ParameterMode.IN );
call.setReturnType(org.apache.axis.Constants.XSD_STRING);
String ret = (String) call.invoke(new Object[] {message});
System.out.println("Echo : " + ret);
}
}
As you can see Axis hides many of the complexities of SOAP from the programmer. A client that wants to invoke a service sets up an org.apache.soap.rpc.Call object with the URL of the target web service, the name of the method to be invoked and the parameters (if any) for that method. You will notice that the parameter type and return type are explicitly specified. Once the Call object is set up, the clients calls its invoke() method. This is actually handled by an Axis rpcrouter servlet. When the servlet returns a response, the invoke() method parses and returns the result.
You can find out the mappings between the org.apache.axis.Constants and Java types in the Axis documentation.
Now compile the client.
javac -classpath $AXISCLASSPATH EchoClient.java
Execution
To deploy the service with a configuration file follow these steps:
- Start the minimal web server provided with the Axis distribution in the same directory as EchoServer.class. Note that you specify the port to use with the -p option.
java -Djava.net.preferIPv4Stack=true -classpath .:$AXISCLASSPATH org.apache.axis.transport.http.SimpleAxisServer -p 8080 &
- Next deploy the descriptor, again the port is specified using the -p option.
java -Djava.net.preferIPv4Stack=true -classpath $AXISCLASSPATH org.apache.axis.client.AdminClient -p 8080 EchoServer.wsdd
You should see the messages:
Processing file EchoServer.wsdd
Done processing
Now run the client using the following:
java -Djava.net.preferIPv4Stack=true -classpath .:$AXISCLASSPATH EchoClient hello
You can observe the actual SOAP messages by using the Axis utility tcpmon.
This allows you to setup a proxy between your client and the Axis server that displays the raw SOAP. Simply change the client to use another port, for example 8081 (you will need to change the endpoint in the client program), and setup tcpmon to intercept traffic to 8081 and pass it onto 8080. See the Axis documentation for more information.
Cleaning Up
This is very important
Shutdown the Axis webserver before logging off.
Use
ps
to find your processes.
To find your processes and use:
kill -9 process_id
or
killall -9 java
To kill the running server.
Alternative Ways to Build a Service
This tutorial uses the Axis dynamic invocation interface to make invocations. You can also make use of stubs to make your invocations, which be faster but less flexible.