Web Services

Web services is a big, fast-moving topic and really the subject for another tutorial entirely. However, since we have already covered so many of the basic networking concepts (and cover XML in detail in ), we would be shirking our duties if we didn't provide an introduction to this important direction in app development. We conclude this chapter on client-side web communications with a small example of invoking a web service. In contrast to regular web apps intended to be visited by web browsers, web services are app-level APIs intended to be invoked by other app components. The primary distinction from other types of interapp communications mechanisms is that they use web standards and XML to maximize cross-platform interoperability. We will leave the analysis of when exactly this is important and the cost versus benefits tradeoffs out of our discussion here. But the value in this idea should be evident from the explosion of web-based business apps in the past few years. Web services allow web-based apps to provide well-defined, "hardened" interfaces for other web-based apps.

XML-RPC

The term web services means different things to different people and has spawned many (probably too many) new standards in recent years. However, the original concept is simple. Web services take the ubiquitous, universally understood, and easily implemented HTTP transaction and marry it with XML to define a standard for invoking app services over the Web. The process is a type of remote procedure call in which HTTP plays its traditional role as the basic communication provider and XML adds a "business envelope" in which structured data is passed. This RPC-style web service interaction defines both the basic structure of an invocation request and also a set of XML encodings for marshaling the primitive data types, allowing data parameters and results to be exchanged in a truly cross-platform way. In contrast, another form of web services termed "document style" places more emphasis on the exchange of app-specific XML documents than on RPC-style data marshaling and unmarshaling. We will concentrate on RPC-style web services since they currently provide the tightest coupling to Java.

WSDL

A key component of web-services technology is the Web Services Description Language (WSDL). Using this standard, a structured XML document describes a web service, the individual functions (methods) it offers, and the XML data types for their respective arguments and return values. WSDL is a type of interface definition language (IDL) and plays that role for web services. However, a WSDL document can also specify the service location and other features. For the client-side web-services developer, the WSDL document describing a service contains all of the information needed to generate the client-side code used to invoke the service from Java (or any other language). As we'll see in our example, it is not even necessary to have an understanding of WSDL to use the service. One can simply generate the client-side interfaces and use them from a Java language viewpoint. We'll see in that we can generate the WSDL document for a new service directly from our own Java code as well.

The Tools

Sun's Java Web Services Developer Pack or JWSDP contains all of the tools and standard extension classes necessary to use, create, and work with web services in Java. Although most of the basic tools for working with XML are already packaged with the core Java distribution, the JWSDP adds the JAX-RPC classes necessary for remote calls as well as the development time wscompile tool. The wscompile tool reads a WSDL description file and generates the required Java interface and implementation classes to invoke it. The JWSDP can be downloaded at http://java.oracle.com/webservices/. The JWSDP is by no means the only way to build and deploy web services. Most app servers provide their own mechanisms for deploying web services and generating client-side code. The Apache Axis project is another popular Java web services alternative.

Installation and environment

Using and, as we'll see in , writing web services is very easy. The only catch is that since the classes of the JWSDP are not yet part of the core Java distribution, a lot of external JAR files need to be in your classpath in order to use the code. The wscompile tool that reads the WSDL document and generates client-side classes is easy to run, but to use those classes currently requires a dozen additional JAR files. (Quite a mess.) To make life easier for you, we're giving you two options for running the examples in this section. First, we're supplying you with a complete Ant build.xml file that can both generate the necessary classes and run the example for you. When you're working on a real project, using Ant is certainly the way to go. If you aren't yet comfortable with Ant or just prefer to play around with the examples directly, we've also provided scripts, client-env.sh and client-env.bat, that set the appropriate classpath (relative to the JWSDP) for you to run the client example. The build.xml file and scripts have been tested with JWSDP-1.5 and Java 5.0. You can find all of this and the source code for this section with the examples on the CD accompanying this tutorial or online at http://examples.oracle.com/learnjava3/CD-ROM/. In both cases, you must first set the location of your JWSDP install directory. For Ant, set the property in the build.xml file. For the shell scripts, set the environment variable JWSDP_HOME prior to running them. There's one more thing: when you install the JWSDP, it may ask for the location of a server "container" (such as Tomcat) into which it should add the server-side components for running web services. It's not necessary for this chapter, but if you want to plan ahead for , you can go ahead and download Sun's reference Tomcat web services container from http://java.oracle.com/webservices/containers/tomcat_for_JWSDP_1_5.html. If you install it first (just unzip it to your preferred location), you can allow the JWSDP install to add its components now. If you don't want to do this yet, don't worry. We'll tell you how to add the components in .

The Temperature Service

This example shows just how easy it is to use a web service from client-side code. We're going to create a client for a web-based temperature lookup service. The service accepts a U.S. zip code as an argument and returns the actual temperature for that area as a result. Please note that the server-side component of this example is hosted by a web site called xmethods.net, which is a popular site for web services definitions and examples. Because this is a third-party educational site, we cannot guarantee that it will remain active. If for any reason xmethods.net takes this service down, you'll have to wait until , where we implement a simple web service ourselves. Assuming you've installed the JWSDP classes, you can begin by downloading the WSDL file for the xmethods temperature service from http://www.xmethods.net/sd/2001/TemperatureService.wsdl or find it with the example code on the CD. This is one of the neat things about web servicesyou can usually ask the web service to give you its own WSDL description file. This means that about all you'd need to get started using someone's service is the appropriate URL. (Note that web browsers that don't display XML well may do odd things when you try to load this file. If you don't see the WSDL document, try using another browser such as FireFox or Microsoft Internet Explorer or fetch it from the CD.) We'll walk through the steps for building and running the client code on the command line first. If you prefer to use the Ant build (which takes all the hassle out of it), we'll give you instructions later in this section. Before running the wscompile command, we must create a small configuration file telling it the location of the WSDL file and the name of the Java package into which to place the generated files. (This step is not part of the web services standard, just something the JWSDP implementation requires.) Place the following in a file called client-config.xml (or grab it from the CD):

<configuration xmlns="http://java.oracle.com/xml/ns/jax-rpc/ri/config">
 <wsdl location="./TemperatureService.wsdl" package />
</configuration>


Now we can run wscompile, found in JWSDP_HOME/jaxrpc/bin, like so:

% wscompile -gen client-config.xml


When wscompile completes, you should find a new directory named temp (for temperature) containing Java classes for the temperature service interface and an implementation class. This package contains an interface called TemperatureService as well as a TemperatureService_Impl implementation class and a service interface called TemperaturePortType. The "port" is WSDL terminology for a group of functions on a web service. Our client app can now use these classes to invoke the service. The following code looks up the current temperature in the 63112 zip code:

import temp.*;
 
class TemperatureLookup {
 public static void main( String [] args ) throws Exception
 {
 TemperatureService impl = new TemperatureService_Impl( );
 TemperaturePortType port = impl.getTemperaturePort( );
 float temp = port.getTemp("63112");
 System.out.println("Temp = "+temp);
 }
}


To compile and run this example on the command line, first add the appropriate classpath using the appropriate client-env script and installation directory. On Windows, run these commands:

C:\> set JWSDP_HOME=install dir
C:\> client-env.bat


On Unix, run these commands instead:

% export JWSDP_HOME=install dir
% source client-env.sh


If you'd prefer to use the Ant build, just edit the build.xml file to set the jwsdphome property to your install directory and then run one of the targets: generate-client or run-client. The generate-client target calls wscompile in the same way that we showed earlier. The run-client target simply sets the appropriate classpath and runs the TemperatureLoookup client.

% ant run-client


Since run-client automatically calls generate-client, that's all there is to it from the client side. The generated classes do all of the work. What we've demonstrated here is deceptively simple looking, but very powerful. From the WSDL documentan XML-based, completely language-neutral service descriptionwe have generated a Java client-side API. From there, it took us just three lines of code to invoke the service. With similar tools, it should be possible to do the same from other languages as well. This is the appeal of web services. We'll return to the topic of web services and implement our own web service in the next chapter, where we hop over to the server side of things and start building web apps.

Java ScreenShot
Comments