Welcome to the second installment of my column that focuses on the evolutionary and revolutionary aspects of Web services technology. In the first installment, I presented an overview of Web services and the problems that must be addressed in order for this technology to become mainstream. In this installment, I'll teach you everything you need to know in order to build and deploy your first Web service. I'll also show you how to invoke Web services that are already deployed on the Internet.
The first step in building your first Web service is to select a tool set. The tools that you'll use are:
- Apache SOAP 2.0 - This open source Java implementation of SOAP includes support for a useful subset of the SOAP 1.1 specification, and integrates nicely with existing Web servers. See the Resources section to download this software.
- Apache Jakarta Tomcat 3.2.1 - This open source Java Web server also implements the Java servlets 2.2 API specification, which is necessary to host Apache SOAP 2.0. See the Resources section to download this software.
- Apache Xerces XML Parser 1.2.3 - This open source XML parser implements most of the latest XML specifications, and is used by Apache SOAP 2.0. See the Resources section to download this software.
I hope you have a fast download link, as the total size of these downloads is over 6 megabytes. I downloaded the software from my home over a 28K link, and had enough time to drink several cups of coffee and go for a run!
If you unzip each package into your root directory, you should have the directory structure in Listing 1.
Listing 1: The Apache package directory listing
\
\jakarta-tomcat-3.2
\lib - contains webserver.jar, servlet.jar, jasper.jar,
parser.jar, jaxp.jar
\soap-2_0
\lib - contains soap.jar
\xerces-1_2_3 - contains xerces.jar
|
The next thing to do is to add the Xerces and Apache SOAP .jar files into your class path, making sure that xerces.jar goes in front. If you don't do this, there's a chance that Apache SOAP will find the wrong XML .jar file and things won't work properly. On my system, I added the following two entries into my class path:
C:\xerces-1_2_3\xerces.jar C:\soap-2_0\lib\soap.jar |
Then add the tomcat bin subdirectory to your PATH setting and set the
environment variable TOMCAT_HOME to the tomcat home directory. If you
installed tomcat into your root directory, you would add
C:\jakarta-tomcat-3.2\bin to PATH and set TOMCAT_HOME to
C:\jakarta-tomcat-3.2.
The next part is a little annoying. Apparently the main Tomcat script
makes the mistake of inserting its own classes in front of the existing
class path, leading to the out-of-order xerces.jar problem I mentioned
earlier, so you have to edit \jakarta-tomcat-3.2\bin\tomcat.bat (or
.sh if you're using UNIX) and replace the line:
set CP=%CP%;%CLASSPATH%
with the line:
set CP=%CLASSPATH%;%CP%
or its UNIX equivalent. By swapping the order, the xerces.jar file is
now in the correct search position again.
Finally, you must configure Tomcat so that it automatically detects
the Apache SOAP subsystem by editing \jakarta-tomcat-3.2\conf\server.xml
and appending the <Context> entry in Listing 2
after the entries that are already in the file:
Listing 2: The <Content> entry into server.xml
<Context path="/soap" docBase="C:/soap-2_0/webapps/soap" reloadable="true"> </Context> |
Set the docBase attribute to the full path leading to the Apache
SOAP webapps/soap subdirectory. If you're using Windows, you must
include the drive letter or things won't work (I found this out the hard
way).
You're now ready to start building your first Web service application.
Before I show you how to write your own Web service, let's start Tomcat
and activate the SOAP welcome page. Create a directory called \demo1
to hold the example application, move into this directory, and then type:
tomcat run
This starts the Tomcat Web server running on your local host on port 8080. You should see the screen in Figure 1.
Figure 1: Booting the Tomcat Web server

Then fire up your Web browser and type in the URL, http://localhost:8080/soap.
This activates the Apache SOAP system which was installed into /soap when
you edited the Tomcat server.xml file. If all is right, you should
see the opening page in Figure 2.
Figure 2: Welcome page of the Apache SOAP system

At this point, close the browser and stop Tomcat. You'll restart them again after the Web service is written and ready to be deployed.
Writing the Web service is the easy part. I'll write a simple Web service that calculates the exchange rate between two countries. The Java interface for this service is shown in Listing 3.
Listing 3: A Java interface for a simple Web service
public interface IExchange
{
float getRate( String country1, String country2 );
}
|
Apache SOAP doesn't require you to actually declare an interface -- you can publish methods directly from the implementation class -- but I prefer this approach as part of good programming practice. Listing 4 shows the simple implementation of the interface that you'll use.
public class Exchange implements IExchange
{
public float getRate( String country1, String country2 )
{
System.out.println( "getRate( " + country1 +
", " + country2 + " )" );
return 144.52F; // always return the same value
for now
}
} |
Add \demo1 to your class path then compile the code to create \demo1\Exchange.class. Once this
is done, you can publish the Java class as a Web service into Tomcat.
To deploy the Exchange service, launch Tomcat again from the \demo1
directory by typing tomcat run. Then type the URL http://localhost:8080/soap
into your browser and click on Run the admin client when you see the welcome
screen. You should see the screen in Figure 3.
Figure 3: The SOAP Admin page

This screen presents choices that allow you to deploy, un-deploy, and list services that hosted in the Tomcat/SOAP system. If you click on the list option, you'll see that there are no services to begin with. To deploy the Exchange service, click on the deploy option and fill in the fields as shown in Figure 4.
Figure 4: Deploying the Exchange service

Here is an explanation of each field in the Deploy screen:
- ID: The Web service identifier. In this example, I set the ID of
the service to be
urn:demo1:exchange, which follows the uniform resource Naming convention recommended by http://www.ietf.org/rfc/rfc2141.txt where demo is a namespace and exchange is the service string. - Scope: The activation mode for the service. Request means that a new instance of the service is created with every individual request. The other available modes are Session and Application.
- Methods: A white-space delimited list of the methods to expose in the Web service. Note that this seems to imply that a Web service cannot expose two methods with the same name, but there is nothing in the SOAP specification that prevents this.
- Provider: The type of the Web service. Apache/SOAP currently only supports Java classes and Bean scripts, but future versions will undoubtedly support EJBs and other popular component types.
- Provider Class/Static: The name of the Java class. This class must be available via your class path setting. If Static is true, the methods are assumed to be static on the Java class, otherwise they are processed as instance methods.
The other fields are related to proprietary add-ons to the Apache/SOAP platform and are beyond the scope of this article.
Once you've entered the fields, scroll down and click the deploy button at the bottom of the window. You should see a screen that indicates that the service has been deployed. If you click on the List button, you'll see the URN of your Web service is listed. Click on its link and you should see the information in Figure 5.
Figure. 5: Listing the URN of your Web service

As you can see, the deployment process is very easy and straightforward.
All of the information about the currently deployed services is stored
by Tomcat/SOAP into a file called DeployedServices.ds in the current
directory. Don't bother to try and read it -- it contains a serialized Java
Hashtable!
To invoke a Web service from a Java client, import the various packages
required by Apache/SOAP and then prepare your remote SOAP invocation by
constructing a Call object and initializing its fields. The encoding style
is usually set to Constants.NS_URI_SOAP_ENC -- alternative encoding
styles are beyond the scope of this article.
Each parameter is represented by a Parameter object with the name of the argument, the type of the argument , the value of the argument(with primitives wrapped in their Object equivalent) , and the encoding style for the argument (null selects the default).
To send the method call, execute the invoke() method with the URL of the SOAP endpoint and the SOAPAction value (usually an empty string, and discussed in the next column). If all goes well, the result is returned, with primitives wrapped in their object equivalents. Listing 5 shows the source code for the Java client.
Listing 5: The Java client code
import java.net.*;
import java.util.*;
import org.apache.soap.*; // Body, Envelope, Fault, Header
import org.apache.soap.rpc.*; // Call, Parameter, Response
public class Client
{
public static void main( String[] args ) throws Exception
{
URL url = new URL( "http://localhost:8080/soap/servlet/rpcrouter" );
String urn = "urn:demo1:exchange";
Call call = new Call(); // prepare the service invocation
call.setTargetObjectURI( urn );
call.setMethodName( "getRate" );
call.setEncodingStyleURI( Constants.NS_URI_SOAP_ENC );
Vector params = new Vector();
params.addElement( new Parameter( "country1", String.class, "USA", null ) );
params.addElement( new Parameter( "country2", String.class, "japan", null ) );
call.setParams( params );
try
{
System.out.println( "invoke service\n" + " URL= " + url + "\n URN =" +
urn );
Response response = call.invoke( url, "" ); // invoke the service
if( !response.generatedFault() )
{
Parameter result = response.getReturnValue(); // response was OK
System.out.println( "Result= " + result.getValue() );
}
else
{
Fault f = response.getFault(); // an error occurred
System.err.println( "Fault= " + f.getFaultCode() + ", " +
f.getFaultString() );
}
}
catch( SOAPException e ) // call could not be sent properly
{
System.err.println( "SOAPException= " + e.getFaultCode() + ", " +
e.getMessage() );
}
}
}
|
When you run the program by typing java Client, you should see the result
in Figure 6.
Figure 6: Running the Java client

Finally, the output from the Web service should appear in the Tomcat screen as in Figure 7.
Figure 7: The Web service output on Tomcat

Congratulations! You've just built and run your first Web service application. Now the fun really starts!
Invoking Web services across the Internet
Since Web services use a standard XML format over HTTP for their messaging, it's fairly straightforward to invoke Web services across the Internet. To demonstrate this, visit the XMethods site (see Resources). This site hosts a selection of Web services that are perfect for experimenting with this new technology. Their home page displays a list of the available Web services as shown in Figure 8.
Figure 8: XMethods' listing of Web services

Click on the Web service called "Currency Exchange Rate" from this index. This displays a screen (see Fig. 9) that describes all the details of this Web service, including the URN, the router endpoint URL and a description of each method available to the developer.
Figure 9: Information about the Currency Exchange Rate Web service on Xmethods

We'll examine Web services in more detail in the next installment of
this column. For now, accept that the Web service published at XMethods
provides exactly the same methods as the one you just built. To invoke
the XMethods service, modify the URL and URN settings in your Java client
to be http://services.xmethods.net:80/soap,
and urn:xmethods-CurrencyExchange, respectively, and then run the
client again. You should see something like Figure 10.
Figure 10: Running the Currency Exchange Rate Web service

I remember the first time that I ran this kind of code -- it was a magic feeling seeing a method call reach across the Internet and invoke a service thousands of miles away!
In the next installment of this column, I'll explain the inner workings of SOAP, including XML's on-the-wire format, encoding schemes and how it integrates with Web servers.
- In his first installment, Graham examines the benefits and challenges of building Web service applications to enable peer-to-peer distributed networks.
-
To download Apache SOAP 2.0, visit http://xml.apache.org/soap/index.html,
click on the download link, and then select
soap-bin-2.0.zip(for Windows) or the appropriate packaging for your platform. -
Apache Jakarta Tomcat 3.2.1 is no longer available. To download Apache Jakarta Tomcat 3.3, visit http://jakarta.apache.org/site/binindex.html or http://jakarta.apache.org,
click on Tomcat 3.3 to get to
http://jakarta.apache.org/builds/jakarta-tomcat/release/v3.3/,
.
-
To download Apache Xerces XML Parser 1.2.3, visit http://xml.apache.org/xerces-j/,
then click on the download link and select
Xerces-J-bin-1.2.3.zip. - XMethods provides a listing of Web
services that developers can access.
-
I used XMethods' Currency
Exchange Rate Web service as an example.
Graham Glass is founder, CEO, and Chief Architect of The Mind Electric, which designs, builds and licenses forward-thinking distributed computing infrastructure. He believes that the evolution of the Internet will mirror that of a biological mind, and that architectures for helping people and businesses to network effectively will provide insight into those that wire together the human brain. He can be reached at graham-glass@mindspring.com.
Comments (Undergoing maintenance)





