Level: Introductory James Snell (jasnell@us.ibm.com), Software Engineer, Emerging Technologies, IBM
01 May 2001 In this installment of the "Web services insider," James Snell shows that Apache and Microsoft can play nicely together, by demonstrating how easy it is to consume Apache SOAP-based Web services using the Microsoft SOAP Toolkit Beta 2.
The concept of Web services is finally starting to take hold. But as
you experiment with implementation, it's important not to forget that seamless
cross-platform interoperability, regardless of development platform or
programming language, is the driving force behind this technology. If you
don't get interoperability issues nailed down, the various SOAP and Web
services implementations will experience breakdowns in communication. And
Web services will become just another failed experiment.
IBM, Microsoft and Apache
Last spring, as many of you may know, IBM and Microsoft both released
the first versions of their SOAP implementations. (IBM later donated its
code to Apache to kick off what is now the Apache SOAP Project.) But while
all of the marketing literature for SOAP promised cross-platform interoperability,
the tools didn't provide it. There were too many various bugs and nuances
in the way SOAP had been implemented, and they made communication between
the two tools nearly impossible. But things are beginning to change. Thanks
to a concerted effort on the part of the members of the Apache SOAP Project
and Microsoft, interoperability has become a center-stage issue. Many of the initial
problems have disappeared, and the few remaining incompatibilities are
dying a quick and painless death.
Please note that in order to experiment with the two samples presented
here you will need to download the latest release version of Apache SOAP
(version 2.1) and the most current version of the Microsoft SOAP Toolkit
(Beta 2 or higher). See Resources.
Interoperability -- the problem of the xsi:type attribute
If you've read through the other articles on developerWorks that discuss
the Web services architecture, you're no doubt familiar with the following
diagram and what it represents. (If you haven't read these articles, I
strongly recommend that you visit the library and take a look around.)
Figure 1: The fundamental components of the Web services architecture

Figure 1 represents the three fundamental operations
performed by the three fundamental components of the Web services architecture:
-
Service providers deploy and publish services by registering them with
the Service broker;
-
Service requesters find services by searching the Service broker's registry
of published services;
-
Service requesters bind to the Service provider and consume the available
services.
In the world of Web services, each of these three operations involves three
complimentary yet distinct technologies:
-
Publishing services uses the Universal Description, Discovery and Integration
(UDDI) API;
-
Locating services uses a combination of UDDI and the Web Services Description
Language (WSDL);
-
Binding to services leverages WSDL and the Simple Object Access Protocol
(SOAP).
At the most basic level, the Binding operation stands out as the most important
of the three. It involves the actual consumption of services, where the
vast majority of interoperability problems occur. Simply put, full support
of the SOAP specification by both the Service provider and the Service
requester solves these problems and enables seamless interoperability.
Unfortunately, this simple solution sounds easier to implement than
it actually is. The flexibility built into SOAP via its many optional components,
and its inherent complex simplicity, can frustrate us when we're trying
to implement it. Take the conflict of the xsi:type attribute that
arose between the Microsoft and Apache SOAP toolkits, an annoying little
problem that caused, for a while, a halt in interoperability between the tools completely.
Remember that according to SOAP specification, the various elements
contained in an envelope may optionally use the xsi:type attribute
to identify the type of data that the element contains. If the provider
and requester have some other means of communicating this information,
then it needn't be included in the envelope. The xsi:type attribute
should only be used if these data types can not be communicated by any
other means.
To solve this problem, Microsoft built a dependency on an external service
description document, that described the data types and could be accessed
by both the requester and provider. Apache required that the xsi:type
attribute be included at all times.
Both approaches were "legal SOAP" (although the approach taken by Apache's
implementation was admittedly a bit legalistic and inflexible), but they
were incompatible with each other. Apache SOAP did not and still doesn't, I might add, understand the Service Description Language used by Microsoft, that has gone through three iterations. First it was the "Service Description
Language" or SDL, then as the "Service Contract Language" or SCL, and now
as the Web Services Description Language or WSDL.
Microsoft also did not include any mechanism to easily add the xsi:type
attribute to the SOAP envelopes generated by the tools. Luckily, things
have changed. Microsoft now has a new and very flexible SOAP implementation
which includes better support and lower-level control over the composition
of the SOAP Envelope. And Apache has removed the restriction that requires
the xsi:type attribute to be present. The result has been two tools that
can communicate freely with one another.
An extended stock quote service, version one
Our example here will create a SOAP-based interface to the free NASDAQ
InfoQuotes Service, available at http://quotes.nasdaq.com.
This simple service provides extended stock quotes in HTML or XML format
via an HTTP-GET request. All the Java and XML source files for this project
are included in the Resources section. The screen
shot in Figure 2 shows the XML-data returned by the
Quote Service.
Figure 2: A Screenshot of the XML data from NasdaqQuotes

For version one of the NasdaqQuotes Web service, we will use a simple
Java class that exposes a single getQuotes method; this returns
the XML output of the HTTP-GET request as a string, as illustrated in the
code snippet in Listing 1 in the sidefile.
Deploying the Web service
To deploy this Java class as a Web service, compile it and make sure
it's in your Java Web server's class path (assuming you already have Apache
SOAP 2.1 installed and configured). The following steps explain how to
deploy the service and invoke it from Microsoft SOAP.
Step 1. Create an Apache deployment descriptor. The
Apache SOAP Service Manager uses the deployment descriptor (a simple XML
document) to collect information about deployed services. Take a look at
the deployment descriptor for the NasdaqQuotes Version 1.0 Service in Listing
2.
<isd:service xmlns:isd="http://xml.apache.org/xml-soap/deployment"
id="urn:NasdaqQuotes">
<isd:provider type="java"
scope="Application"
methods="getQuote">
<isd:java class="NasdaqQuotes" static="false"/>
</isd:provider>
<isd:faultListener>org.apache.soap.server.DOMFaultListener</isd:faultListener>
<isd:mappings>
<isd:map encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:x="" qname="x:symbol"
xml2JavaClassName="org.apache.soap.encoding.soapenc.StringDeserializer"/>
</isd:mappings>
</isd:service>
|
For a detailed structural explanation of deployment descriptor
XML, go to the Apache SOAP documentation. But take note of the <isd:mappings>
section in our example, which removes the xsi:type restriction
from Apache SOAP. Here we've declared the XML element symbol to
map to the StringDeserializer class. This class transforms the
contents of the XML element into an instance of java.lang.String.
By using this kind of explicit mapping, Apache SOAP doesn't have to look
for xsi:type in order to provide the mapping information. Rather,
it can assume that all instances of the XML symbol element are Strings
and thus, deserialize them as such.
Step 2. Once you've created the Deployment Descriptor,
you need to use it to deploy the NasdaqQuotes service into the services
registry. Do so by executing this command line instruction.
Here http://acme.com/soap/servlet/rpcrouter corresponds
to your installation of the SOAP RPC Router Servlet.The NasdaqQuotes Service
should now be deployed and ready to use. You can test the service by invoking
the Java-based client I have provided in the zip package that accompanies
this article. Look in the readme.txt for instructions.
Step 3. The Microsoft tools require the use of a WSDL
Document that describes the interface and location of the service. Since
Apache SOAP does not include any support for WSDL, you have two options:
you can use the WSDL-Toolkit from IBM's alphaWorks to generate WSDL for
a specified Java Class, or you can write the WSDL file ourselves. I recommend
you write the WSDL out by hand (see Listing 3 in the sidefile)
-- writing things out by hand also gives you a better feel for WSDL structure
and function. If you need a good XML editor, I highly recommend the commercial
XML-Spy product, but any editor will do.
After the NasdaqQuotes.wsdl file has been edited,
it's time to use Microsoft tools. In the Zip that accompanies this article,
you will find two files in the samp1e directory called nq.vbs
and vq.bat
. The file nq.vbs (see Listing
4) contains the code for invoking the NasdaqQuotes Service using the
Microsoft SOAP Toolkit. The script contains forty-three lines of code,
but the actual SOAP invocation occurs within the first six lines (with
four of those lines consisting of basic variable initialization code).
As you can see, Microsoft has done a great job making it easy to use their
tools.
Set SC = CreateObject("MSSOAP.SoapClient")
SC.mssoapinit "D:\Services\NasdaqQuotesClient.wsdl", "", "", ""
Res = SC.getQuote(WScript.Arguments(0))
|
You can invoke the NasdaqQuotes Service by executing the nq.bat
file, passing in the symbol you would like to query as a command line parameter
(see Figure 3).
Figure 3: Running the NasdaqQuotes from the command line

Homework: NasdaqQuotes version two
The NasdaqQuotes Service Version 1.0 demonstrates very simply that
Microsoft and Apache are now capable of easily communicating with one another.
But the fact that information returned by the Quote service is returned
in the form of a string means that more work could be done to improve the
service. For example, we may want the body of the SOAP envelope to return
the results of the Query in XML form rather than returning a string. The
NasdaqQuotes2 Service sample included in the Zip download takes you one
step in the right direction. Your homework is to dissect that example
and see what's going on. As usual, if you have any problems, let me know
and I'll see if I can't help you out.
Resources
About the author  | 
|  |
James Snell is both an author and a developer and is one of the newest members of the IBM Web Services development team. He comes to IBM with an extensive background in custom enterprise application development and business-to-business integration, and a passion for the cutting edge of Web technology. You can reach him at jasnell@us.ibm.com. |
Rate this page
|