In order to create a Web service, you will need some tools. At a minimum, you will need some type of SOAP processing engine to parse the messages that are received and to call the functions or methods that the message indicates.
Many products are on the market that provide this processing. In addition, many of them provide other tools to help the developer write the code needed to do this work. In this hour, we will look at one such product—Apache Software Foundation’s Axis product. We will cover its architectural approach. Following that, we will work an example to illustrate the process that you use to create Web services with this tool.
In this hour, you will learn
What Apache Axis is
The architecture of Axis
How to create a Web service with Axis
How to create clients that use Axis
Apache Axis is an open-source project of the Apache Software Foundation. Axis stands for Apache Extensible Interaction System, which could mean anything. You can think of Axis as Apache’s latest version of its legacy SOAP processor, Apache SOAP V2.
Apache Software Foundation was created to manage open-source software projects. Open-source projects are staffed by volunteers who contribute code to collaborative, consensus-based development projects. There are many reasons that developers cite for their interest in working on open-source projects. Some engineers are graduate students and professors of computer science who work on these projects as part of their academic tasks. Other programmers are employees of companies who value open-source tools and want to have a say in their direction. Still others are just programmers who are interested in one of the projects that is being developed. All open-source projects are free for the public to download and use. The most successful open-source software projects to date have been the Apache HTTP server and the Tomcat servlet engine.
The primary attraction of open-source projects is the fact that they can be freely downloaded. They are also valuable to the self-taught developer who needs software to learn with. This is also important for anyone who wants to experiment with Web services without making a big investment.
On the other hand, established companies realize that the lowest life-cycle cost is not always associated with the lowest-cost product. In the world of software development, the cost of hiring a staff can far outweigh the cost of acquiring a piece of software. For this reason, it is important to select tools that best fit the mission and budget of your organization.
Toolsets range from bare-boned implementations that expect you to code almost everything by hand, to wizard-laden development environments that can generate many different types of software modules for you.
Axis is closer to the bare-boned model, but that doesn’t mean that it is lacking in functionality. The engineers on the Axis team just spend their energy on creating tools for programmers like themselves.
The goal of every Web services development tool is to build a bridge between the SOAP processor and the business logic that is running on the server. Normally, this business logic is kept separate from the SOAP processing logic. Figure 13.1 shows this arrangement.
The Apache Axis architecture is built on the foundation of a SOAP engine. This engine accepts SOAP messages, parses them, and calls the appropriate methods and functions in the Web service. At this level of detail, Axis is just like every other Web services engine. The uniqueness of this product, and every other product, lies in how a developer would go about organizing the processing so that the message can be responded to properly.
Apache Axis is organized in a fairly unique way. The following sections introduce you to the most important features of this organization.
Axis is built upon the concept of handlers. A handler is a piece of code that performs a specific function. One handler may log the message, another may decrypt it, another may make the calls to the legacy system, and so on. These handlers must be written in Java currently, but a C++ version of Axis is in development and might be available by the time you read this. You can think of handlers as method calls, and you would be mostly on target. Be aware, though, that handlers are not called by a main()
method. They are called by Axis directly.
Axis chains are a special type of handler that can contain other handlers. The handlers that they contain can also be chains, so the concept is very powerful. The execution of these contained chains is ordered, so chains represent a type of Axis control language, but without parameter passing.
A targeted chain is a special type of chain that contains more than one entry point. Transport handlers are handlers that have both a request side and a response side, which enables a single HTTP handler to both receive and send messages.
A targeted chain can act in both roles, however. Figure 13.2 shows how handlers can be used to subdivide the tasks associated with consuming SOAP messages.
Thus, we could define the Web service as the sum of all the handlers defined to process the incoming messages, combined with the legacy system that does the heavy lifting.
A transport is the communications mechanism that brings messages to and from the Axis engine. Originally, HTTP was the only transport supported by any Web services engine, but support for SMTP, FTP, and JMS has recently begun to appear. Because a SOAP message can be thought of as a stream of characters, it is easy to see how any transport can be used. If you want to send a picture of the new baby to your mother, you could put it on a Web site that travels over HTTP. Alternately, you could put it in a file and ask her to run FTP to retrieve it. Or, you could attach it to an email with SMTP. All these transports have a way to transfer data from one computer to another, but with varying degrees of reliability and speed.
The main entry point into a Web service is the Axis engine. This engine parses the messages and calls the appropriate handlers and chains according to instructions provided by the deployment engineer.
A dispatcher is a special type of handler that is used to separate business logic from handler logic. A special dispatcher, the RPCDispatcher converts SOAP messages to Java objects, and then makes calls to the Web service. This removes all business logic from the handlers, which is a nice design approach. Figure 13.3 shows the relationship between a dispatcher and a Web service.
A transport listener is a servlet that waits for a SOAP message. It is responsible for creating an instance of Axis (or finding an existing instance) and passing the SOAP message to it. It also tells the Axis engine what transport this message came in over. It is used to return the response to the client. A system that supports three transports would have three transport listeners as shown in Figure 13.4.
After the transport listener processes the message, it becomes a generic SOAP message. This allows the processing to proceed in the same way for all messages regardless of the transport mechanism employed to send them.
When Axis is acting like a client, it needs a way to send the requested SOAP message to a SOAP server. The Axis handlers for doing this are called transport senders. If you have a SOAP message that you want to send to a Web service via HTTP, you would use the HTTP transport sender that ships with Axis. This sender opens an HTTP connection to the Web server on the computer that hosts the Web service. It then formats the message with the appropriate HTTP headers, sends it, and waits for a response. Figure 13.5 shows this arrangement.
Other handlers are also allowed to be invoked when sending a message using Axis.
Now that you are familiar with the basic architecture of Axis, you are ready to learn how to use it. It is beyond the scope of this book to teach you how to program with Axis, but a few simple examples can be worth the proverbial thousand words. Our first example illustrates how to create a Web service automatically by taking advantage of a special Axis facility. Listing 13.1 shows a Java class for doing math.
Example 13.1. The ArithmeticProcessor.java File
public class ArithmeticProcessor { public int add(int input1, int input2) { return input1 + input2; } public int subtract(int input1, int input2) { return input1 - input2; } public int multiply(int input1, int input2) { return input1 * input2; } public int divide(int input1, int input2) { if (input2 != 0) { return input1/input2; }else { return -1000; } } }
Our sample class is called ArithmeticProcessor
.
public class ArithmeticProcessor
The first Web service method is called add
. It returns an integer value when it completes. In this case, the add()
method will need two integer parameters. It will add them together and return them as an int
value:
public int add(int input1, int input2) { return input1 + input2; }
The subtract()
and multiply()
methods are similar to the add()
method; except the math operations are different:
public int subtract(int input1, int input2) { return input1 - input2; } public int multiply(int input1, int input2) { return input1 * input2; }
The divide()
method is also different in that it checks for a divide-by-zero situation before proceeding:
public int divide(int input1, int input2) { if (input2 != 0) { return input1/input2; }else { return -1000; } }
Now that we have a class, let’s turn it into a Web service. The easiest way to do that is by renaming it and storing it in a special directory under Axis.
You might want to run these programs for yourself. If so, you will need to install Apache Tomcat and Apache Axis on your computer before you can run them. Appendix A, “Installing Apache Tomcat and Axis,” provides step-by-step instructions on how to download and install this software.
Axis provides a really simple way to turn this class into a Web service by changing its name and storing it in a special directory. The following procedure does this:
Rename the file ArithmeticProcessor.java to ArithmeticProcessor.jws; jws stands for Java Web service.
Move the file into <axis-installation-directory>. (On our test machine running Windows XP, this directory is C:Program FilesApache Tomcat 4.0webappsaxis.)
That’s it! For simple Web services, this is all you have to do to make your Web service available to the world.
Now that we have a server, we need a client to test it. Unfortunately, there is no two-step method for creating clients in Axis. If you are a programmer, however, the Axis approach only requires that you learn a few new classes and methods. Listing 13.2 shows a client that can access our ArithmeticProcessor
Web service.
Example 13.2. The ArithmeticClient.java File
//Use the import statement to tell what packages these classes //can be found in import org.apache.axis.client.Call; import org.apache.axis.client.Service; import org.apache.axis.encoding.XMLType; import org.apache.axis.utils.Options; import javax.xml.rpc.ParameterMode; import java.net.URL; public class ArithmeticClient { //A main method is the entry point for this program public static void main(String[] args) throws Exception { //The Options class is a container for the // inputs on the command line Options options = new Options(args); //An endpoint is the URL of the web service String endpointString = "http://localhost:" + options.getPort() + "/axis/ArithmeticProcessor.jws"; //The args are the command line arguments args = options.getRemainingArgs(); //check to see if the right number of args were passed in if (args == null || args.length != 3 ) { System.err.println("Wrong number of args"); return; } //The first arg is the name of the method to call String methodName = args[0]; //The other two args are the values to be combined Integer i1 = new Integer(args[1]); Integer i2 = new Integer(args[2]); //The Service object will contain a handle //to the web service Service service1 = new Service(); //The Call object will contain a handle to one call // to the web service Call callOne = (Call)service1.createCall(); //The endpoint is really a URL URL endpoint = new URL(endpointString); //tell the Call object what endpoint to access callOne.setTargetEndpointAddress(endpoint); //tell the Call object what method to call callOne.setOperationName(methodName); //Set up the parameter types and the return type callOne.addParameter("op1", XMLType.XSD_INT, ParameterMode.IN); callOne.addParameter("op2", XMLType.XSD_INT, ParameterMode.IN); callOne.setReturnType( XMLType.XSD_INT ); //make the call with the invoke() method Integer ret = (Integer)callOne.invoke( new Object[] { i1, i2 }); //Print the result on the screen System.out.println("The result is : " + ret); } }
In Java, import statements clear up any possible name conflicts by stating clearly what packages each imported class comes from:
import org.apache.axis.client.Call; import org.apache.axis.client.Service; import org.apache.axis.encoding.XMLType; import org.apache.axis.utils.Options; import javax.xml.rpc.ParameterMode; import java.net.URL;
The main()
method is the entry point into a Java program:
public static void main(String[] args) throws Exception
The Options
class is a container for the inputs on the command line:
Options options = new Options(args);
The endpointString
is a string version of the Internet address of the Web service:
String endpointString = "http://localhost:" + options.getPort() + "/axis/ArithmeticProcessor.jws";
The first argument is the name of the method to call:
String methodName = args[0];
The other two arguments are the values to be combined:
Integer i1 = new Integer(args[1]); Integer i2 = new Integer(args[2]);
The Service
object will contain a handle to the Web service. The Service
and Call
objects are always present:
Service service1 = new Service();
The Call
object represents one call to the Web service:
Call callOne = (Call)service1.createCall();
The endpoint
is really a URL object that points to the Web service:
URL endpoint = new URL(endpointString);
We have to tell the Call
object what endpoint
to access:
callOne.setTargetEndpointAddress(endpoint);
Next, we tell the Call
object what method to call:
callOne.setOperationName(methodName);
We have to set the parameter types and the return type so that our program will not be confused as to what types they are intended to be:
callOne.addParameter("op1", XMLType.XSD_INT, ParameterMode.IN); callOne.addParameter("op2", XMLType.XSD_INT, ParameterMode.IN); callOne.setReturnType( XMLType.XSD_INT );
Next, we make the call with the invoke()
method:
Integer ret = (Integer)callOne.invoke(new Object[] { i1, i2 });
Finally, we print the result on the screen:
System.out.println("The result is : " + ret);
To run this program, you must first compile it by issuing the following command:
javac ArithmeticClient.java
To run the program, you type in the following:
java ArithmeticClient -p8080 add 2 5
The java
command means to run the program. ArithmeticClient
is the name of the class containing the main()
method. -p1880
is the port number of your Tomcat server. (The default is 8080
.) add
is the name of the method to run. 2
and 5
are the two numbers that you want added.
The result of running this command with Tomcat listening on port 1880
is shown here:
java ArithmeticClient -p1880 add 2 5
A session that runs all these methods is shown here:
C:projects>java ArithmeticClient -p1880 add 2 5 The result is : 7 C:projects>java ArithmeticClient -p1880 subtract 6 3 The result is : 3 C:projects>java ArithmeticClient -p1880 multiply 7 4 The result is : 28 C:projects>java ArithmeticClient -p1880 divide 8 4 The result is : 2
Notice that the same service is run each time, but with a different method called.
This hour has introduced you to the architecture of one popular Web services engine, Apache Axis. You learned the basic concepts of how Axis handles Web service requests. Following that, you learned how to create a simple Web service and deploy it in Axis.
Finally, you learned how to create a client in Java that can call the methods in the service and receive a response.
This section is designed to help you anticipate possible questions, review what you’ve learned, and begin learning how to put your knowledge into practice.
1. | Download and install Apache Tomcat and Axis according to the instructions that you find in Appendix A. |
2. | Type in the |
3. | Type in the |
4. | Run the |