In this article, I will discuss the basics of web services and explore how Apache Axis, an open-source SOAP toolkit, and can be used to create, deploy, and access such services. After a quick introduction, we'll discuss downloading and installing Axis. Then, we'll build a simple web service and communicate with it. Finally, we'll discuss some of the details behind a more advanced example.
Web services technology has quickly become an important enabler of true distributed computing over the Internet. By using web services, consumers and providers of functionality can quickly connect, without the usual integration hassles, in a way that is language-independent and platform-independent. For example, if you develop remote functionality in C++ on a Microsoft Windows NT system, your friend using Java on Sun Solaris will be access it over the Internet.
To motivate the need for web services, let's consider an example. Suppose you have developed a useful Java class that you would like to distribute to others via the Internet. How would you (at Internet site x) make Java functionality accessible to your remote friend (at Internet site y)?
One option is to use something like Java IDL (i.e., CORBA). After all, doesn't CORBA and the IIOP protocol allow distributed objects (potentially written in different languages) to communicate with each other over the Internet? Well, yes and no. CORBA-IIOP solutions, while possible, can be problematic in terms of security and ease of deployment. In terms of security, ensuring that IIOP will work through firewalls is often painful, since IIOP traffic does not travel on port 80, as does normal HTTP traffic. A second major issue is the lack of simple deployment. Unless they want to really do some lower level programming, both participants in an IIOP exchange must have Object Request Brokers (ORBs), which manage objects locally and route requests to available instances. There are other issues, but we don't have the space to get into a full-blown debate. However, in all fairness, I should at least note that there do exist counter-arguments .
Well, what about skipping all of this complexity and just using servlets? For example, you could embed your functionality in a servlet and route its output back to callers. However, doing so involves a lot of ugliness:
What we really want is some way to combine the flexibility and interoperability of CORBA with the ease of deployments that Java servlets provide. So, does such as solution exist? As it turns out, it does: web services.
Web services leverage the de-facto platform indepedence of the Web and the extensibility and flexibility of XML to simplify distributed computing on the Internet. The concept is straightforward: those that want to distribute functionality publish web services, those that want to use that functionality access those services.
The conceptual web services technology stack is shown in Figure 1.
Let's start by explaining a few of the acronyms:
There are a variety of transports that one can use to communicate with a web service - RPC, email, FTP, and HTTP, for example. In this short tutorial, we will focus on HTTP, since that is the protocol most readers will likely find applicable.
So then, in a nutshell, the technology stack in Figure 1 describes how web services can be described, deployed, and accessed. In this article, we will assume that we know the web service we want and where it is deployed; thus, it only makes sense that access (SOAP) is our chief concern. And this is exactly where Apache Axis comes in.
Apache Axis is a SOAP toolkit that makes it easy to create, deploy, and consume web services. By using Axis, you will be able to quickly convert existing Java functionality into web services, deploy those services, and be able to communicate with them remotely via the Internet, usually through firewalls (if necessary).
More precisely, Axis is an implementation of SOAP. Most people like to think of it as a toolkit. From the programmer's point of view, it's like an API. It makes it easy for you to communicate - with SOAP - to a remote object, without having to worry about the details associated with the protocol. In practice, it is a lot like using RPC, CORBA, RMI, or any of the other distributed computing technologies you may have experience with. The process is largely the same: you describe the target of your communication, invoke the remote method and marshall your parameters, and then demarshall the return values. Since AXIS makes this process simpler than ever, development is a breeze.
SOAP is a simple an extensible protocol for communication between application-level objects. It is a standard that originated between a number of vendors, including Microsoft and IBM. However, its support has grown to include Sun and is now generally viewed as the best open standard for structured communication between objects on the Web.
As described above, SOAP messages are encoded with XML and the protocol can be deployed over a variety of transports. In contrast to other synchronous protocols, SOAP communication is one-way: from sender to receiver. Upon this, higher-level request-response designs can be implemented.
A SOAP message consists of an envelope that contains an optional SOAP header and a mandatory SOAP body. The header is a mechanism for extensibility; we won't worry about it much more here. The body contains the guts of the communication between parties. For example, the body could contain information on the remote method to be called, on the parameters to call it with, etc. As a detailed example of a SOAP message, consider the simple example (note that there is no header here -- remember, it is optional) shown in Figure 2.
This example illustrates a request to a SOAP node such that the method "GetCurrentTime" is invoked with the parameters "city" (Las Vegas) and "state" (of Nevada). The service containing that method is found at example.com. With this simple example, you now have a feel for what SOAP messages look like. If you are interested in a more detailed description of the SOAP protocol, check out the W3C note. For our discussion here, I summarized SOAP messaging for the purposes of underscoring that:
If you inferred that much from the above, you got the major points. Time to move on.
Although it is possible to describe how to generally use Axis, I am going to take a more "in the trenches" approach, since I want you to be able to run the examples I describe. Although the existing Apache Axis documentation does a fine job of getting you started, it does take a little while to identify some of the key configuration issues. My hope is that this document streamlines that process even more.
First, keep in mind that this article pertains to the Beta 2 of Apache Axis, released in April of 2002. Pre-production open source software often changes and it may be possible that post-beta-2 changes make some of this document invalid, so please consider that if trying to use this document with any other release of Axis.
Second, since this document goes into the details of configuring Axis, it makes some assumptions:
Third, before you get started with Axis, you also need to have a J2EE compliant subsystem that implements the Java 2.2 Servlet specification. A good candidate for that is the Apache Tomcat Java servlet container. This tutorial assumes that you are using the latest (at least at this time!) stable version: Tomcat 4.03. As you know, you can run Tomcat independent of your web server. It runs on a specified port (8080 by default) and can be started up with a simple boot script that is included with the release. You can install Tomcat anywhere on your machine. It will likely choose c:\Program Files\Apache Tomcat 4.0 by default. Whether it is this or another location of your choosing, no matter - the point of installation is referred to hereafter as $TOMCAT_HOME.
Now, just to make sure no odd problems occur during our installation of Axis, make sure that Tomcat is not running. We will start it up later.
Finally, to parse the XML, you need to have an XML parsing library available, such as Xerces or the Java API for XML Processing (JAXP). Opting for an all-Apache approach, I used Xerces 2.0.1, which comes with the following libraries (available in the top level directory of the Xerces release):
In this section, I describe how to download and configure Apache Axis as a web application for your servlet container (Tomcat). Once installed, clients will be able to access SOAP nodes on your server via an Apache Axis servlet.
The first step is to download the Axis release. This is usually a ZIP file. At the time of this writing it was located here. You can install this release anywhere on your machine; for example, I installed it under c:\Program Files\Apache Group\xml-axis-beta2.
The second step is to integrate Axis as a web application of Apache Tomcat. This step is extremely simple: just copy (recursively) the webapps/axis directory under the webapps directory of your Tomcat installation (i.e., $TOMCAT_HOME\webapps). Next, copy the XML parser libraries (such as the 3 Xerces JAR files mentioned above) to the $TOMCAT_HOME\webapps\axis\lib directory.
Next, a very important point that is sort of buried in the current Axis instructions and FAQ: relocation of the RPC library Axis uses. Specifically, you need to move (or copy) the file lib/jaxrpc.jar to common/lib directory, under your Tomcat home (i.e., $TOMCAT_HOME\common\lib).
Finally, one point about setting up your environment. Later in this article, you will need to compile some Java classes. To do so means that you need to setup your classpath to use the Axis libraries. I find it most simple to define a setup file that augments the classpath to include the following libraries (all found in $AXIS_HOME/lib):
Before moving on, it might be useful to do a sanity check and make sure that Tomcat works fine outside of Axis. That way, if you have a problem in the next section, you can potentially rule out Tomcat. So, for example, you should be able to point your web browser at http://localhost:8080/examples/servlets/index.html and be able to execute the Hello World servlet example.
Okay, you've downloaded and installed everything. You've ensured that Tomcat works. Time to start building and testing out web services with Axis. We'll start out with a very easy example - this should quickly convince you how easy it is to deploy web services with Axis.
The easiest way to get started is to simply copy any independent Java class into your Axis web application directory and access it via SOAP remotely. This is easier than you think. There are only three steps involved: (a) developing the Java class, (b) deploying it, and (c) building and running a client to access it.
The first step is to develop a Java class. Let's keep things really simple and try out a Hello World -style class. We'll develop one method, called greet() that takes someone's name as a parameter and returns a nice greeting message with that person's name.
To do this, locate the $AXIS_HOME/samples directory. Create a new subdirectory called "hello". In this subdirectory, create the file Hello.java, and include the following code:
NOTE:We're keeping Hello.java in the $AXIS_HOME/samples/hello directory to keep things consistent with the rest of the Axis built-in examples.
Now, do NOT compile Hello.java. Just copy it into $TOMCAT_HOME/webapps/axis and name it Hello.jws. Clients (such as the one we develop next) will request this service and the Axis servlet will compile and execute our Hello.java class on the fly! As you can see, developing a web service could not be more painless. We didn't have to use a single library or implement a single interface.
Time to build a client to access our service. This is where we finally see some library code. But, as you will soon notice, it's very simple and straightforward.
Again, to keep things consistent with the examples provided by the Axis release, let us develop our client code in the file HelloClient.java, which we will store at $AXIS_HOME/samples/hello. In an abstract sense, HelloClient.java needs to do the following:
Below is code for HelloClient.java that enables this:
Here, there are obviously a few more things to note. Let's take them one at a time.
Now, we can simply compile this client, specifically:
As you can see, development is pretty simple with Axis. It hides behind the scenes and makes SOAP-based connectivity quick and painless. Part of the magic behind why you were able to simply copy the Hello.java file and have it accessible to your client has to do with the $TOMCAT_HOME/webapps/axis/WEB-INF/web.xml deployment descriptor file. In that file, you will find the following section:
These instructions tell Tomcat to run the Axis servlet on all requests to files that end in .jws. You'll also notice that the compiled class is stored in $TOMCAT_HOME/webapps/axis/WEB-INFjwsClasses as Hello.class.
The Axis API does such a good job of hiding the details in example above, you're probably wondering: where is the SOAP? Actually, on the wire, XML-encoded SOAP messages are being exchanged. Axis comes with a tool called tcpmon that allows you to see this (it monitors the target TCP port). If you were to look at it, the request would look something like what you see in Figure 4 and the reply like you see in Figure 5.
As the Axis documentation suggests, there are a variety of cases where you cannot simply copy your Java source files into the web application deployment directory. You may not have the source code or you may want to use other handlers during processing, etc. Both reasons motivate us to look at a more general method for deploying and accessing services with Axis
In this example, let us focus on the development and deployment of a service that we will call "LoudService". This service takes an input string and returns the uppercase form of the string, as if the string were being spoken loudly.
The steps involved in development and deployment are:
The code for LoudService is just as simple as the code for the Hello service we developed earlier:
Developing the client is not that much different from what we did earlier. As the code below shows, the main difference is that we use the QName API to specify the name of the service (LoudService) and the method (serviceMethod) we intend to execute. Notice that the endpoint URL is obtained automatically (in this case, it is: http://localhost:8080/axis/servlet/AxisServlet -- the class and method are resolved dynamically at runtime).
We can then store this file in $AXIS_HOME/samples/loud and compile it with the Java compiler.
The Axis web services deployment descriptor (WSDD) is an XML-encoded way of specifying details about how SOAP-accessible functionality can be deployed. There are a variety of options for deployment, but we'll focus on the simple task of deployment as a web service. The type of descriptor we need is shown in Figure 6. We don't have the space to go into all of the options for how to deploy services; but, using the example below, you should be able to get an idea.
We name this descriptor deploy.wsdd and store it in $AXIS_HOME/samples/loud.
Now it is time to deploy our new service. To do that, we use the Axis administrative service and call it with the deployment descriptor above:
Of course, there are many more features and interesting details related to Apache Axis than we can cover here. However, the two examples we discussed above should hopefully clarify where Axis fits in the overall web services architecture, give you a better understanding about what Axis can do, get you started using its tools and libraries, and leave you curious about more advanced features. As you can Axis is simple, easy to use, and powerful. We can deploy web services from existing functionality in a very short time and thus rapidly move towards true Internet distributed computing.