 | Level: Introductory Graham Glass (graham-glass@mindspring.com), CEO/Chief Architect, The Mind Electric
01 Dec 2000 This article provides a step by step explanation of how to develop a Web service, including what tools you will need, how to install them, how to write the code, and how to deploy the service. It goes on to explain how to invoke other Web services from across the Internet.
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.
Tools and installation
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.
Starting the Web server
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 a Web service
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.
Deploying a Web service
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!
Invoking a Web service
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.
Resources
About the author  | |  |
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. |
Rate this page
|  |