Start Writing Web Services Today (cont.)

A Complex Web Service
This next Web service that we will explore is more complicated on two accounts. In this example we will actually be building and deploying both the client-side and the server-side of the exchange. We will thus be building the Web service itself. Second, we will be exchanging Java objects between the client and the Web service, requiring some additional settings to handle the serialization of the objects into XML so they can be transported within the SOAP message body. The development and deployment of the application is far more interesting than the actual context of the example. The client application is a WidgetFactory that sends widgets of all colors shapes and sizes to the WidgetConsumer (the Web service).

We won't require any changes to the environment settings for this example, so we can dive right into building the Widget class (a JavaBean), the WidgetConsumer class (the Web Service), and finally the WidgetFactory class (the client). The Widget class is an arbitrary JavaBean consisting of the following properties:

  • a private variable of type String called color
  • a private variable of type String called shape
  • a private variable of type Double called weight
  • public getter and setter methods for each property
  • a default constructor (no parameters)—public Widget()
Next we build the Web service itself, the WidgetConsumer class. The WidgetConsumer class is even less impressive than the Widget class. It contains only two members:
  • a default constructor—public WidgetConsumer
  • a single business method—public String receiveWidget( Widget w ). This method returns a string identifying the properties of the widget sent by the factory.
That's it? Where are all the fancy classes that need to be imported, and what about the elaborate infrastructure that a Web services exchange requires? In short, what's all the hype about? The beauty of Web services is that they define a neutral, standards-based interface for software applications. These can be existing Web applications, legacy applications that need to be Web-enabled, standard Java classes, Perl scripts, or any other component that could benefit from exposing a language, platform, and vendor-neutral interface.

The reality is that there is a substantial amount of routing, marshalling/unmarshalling, parsing, formatting, etc. that must go on in order to enable an XML protocol such as SOAP to activate a Java application as though it were a native object, but fortunately, there are many excellent frameworks that handle all of those ugly details for you. Apache Axis is one such Web service framework.

Now on to the Java client. The Java client is significantly more complicated but is still very straightforward. Make sure that the following jars are in your classpath before beginning: %AXIS_DIST%/lib/axis.jar; %AXIS_DIST%/lib/jaxrpc.jar; %AXIS_DIST%/lib/commons-logging.jar; %AXIS_DIST%/lib/tt-bytecode.jar and your parsers jar file.

We begin by importing the necessary classes and packages:

import org.apache.axis.client.*;
import org.apache.axis.encoding.XMLType;
import org.apache.axis.encoding.ser.*;
import javax.xml.rpc.ParameterMode;
import javax.xml.rpc.namespace.QName;
Next, we make the class declaration and set up some variables to hold the invocation properties:
  public class WidgetFactory {
   
     private static final String    ENDPOINT_URL = "local://";
     private static final String    NAMESPACE_URI = "urn:Widget";
     private static final String    SERVICE_NAME = "WidgetConsumer";
     private static final String    OPERATION_NAME = "receiveWidget";
The endpoint URL, local://, indicates that the service will be deployed on the Axis internal test server. In a real-world scenario, you would want to integrate Axis with a J2EE application server, but for experimentation purposes, the internal test server works great. The other interesting property value is the service name variable. The service name is a logical name that is used within the SOAP message and on the SOAP server to refer to a particular service as a logical entity that can be accessed, deployed, and undeployed.

The next thing we need is the main method for the WidgetFactory. This is the only method in our client class, and it is the starting point for the entire exchange.

                   if ( args.length != 3 ) {
            System.err.println
( "Usage: java WidgetFactory [color] [shape] [weight]" );
            System.exit(0);
          }//end if

          Service     service;
          Call	           call;
          QName     qname;
          String        response = null;
          Widget      widget; 
After ensuring that the proper information has been passed in, we proceed to declare the variables that we will be using to access the WidgetConsumer service.
               try {
       // Build the call
       service = new Service();
       call = ( Call )service.createCall();
       call.setTargetEndpointAddress( new java.net.URL( ENDPOINT_URL ) );
       call.setOperationName( new QName(SERVICE_NAME, OPERATION_NAME) );
NNext we start a try/catch block and build the Call object that will be used to invoke the service. All of this so far has been almost identical to the previous client we built. The really interesting part is next:
 // Set up serialization encoding for the Widget object
           qname = new QName( NAMESPACE_URI, "WGT" );
           call.registerTypeMapping( Widget.class, qname, 
 new BeanSerializerFactory( Widget.class, qname ),
           new BeanDeserializerFactory( Widget.class, qname ) );
           call.addParameter( "arg1", qname, ParameterMode.PARAM_MODE_IN );
           call.setReturnType( XMLType.XSD_STRING );
We begin by creating a qualified name object. Then we register a serializer and a deserializer with the Call object to handle the Widget custom data type. To do this, we invoke the registerTypeMapping() method, passing in the Java class to be serialized, the fully qualified name for the XML element, and an object to actually perform the serialization and another to handle the deserialization. The BeanSerializerFactory and BeanDeserializerFactory classes are provided by the Axis API, and are capable of serializing Java objects of any class so long as the class adheres to the JavaBeans specification. Next, we set up a parameter on the Call object that will later house our serialized Widget. Next, we specify the return type expected from the service.
                      //Build the Widget Object
              widget = new Widget();
              widget.setColor( args[0] );
              widget.setShape( args[1] );
              widget.setWeight( Double.parseDouble( args[2] ) );
              response = ( String )call.invoke( new Object[]{widget} );
            } catch( Exception e ) {
                e.printStackTrace();
            }//end try/catch

            System.out.println( response );
	}//end main()
}//end class WidgetFactory
Finally, we build the Widget object, pass it as a parameter into the service call and display the response to the screen. Once you've compiled the code successfully, you're ready to embark on the deployment process.


A Simple Web Service Deploying the Service


In this Article
Introduction A Complex Web Service
Web Service Examples Deploying the Service
A Simple Web Service Download the Code
 





FEATURE SOFTWARE:
dtSearch Web
Add power searching to your web site.
Buy Now!

Encrypt It
Encrypt and Decrypt Data, Passwords and Files within your application.
Buy Now!

Standards Organizations and Web Service Coalitions

Key Platforms

Pure-Play Web Services Vendors

Web Service Technologies or Components

From Sun.com

For Further Reading

Discussion Groups
Java Web Services
.NET Web Services

Back to the Special Report

Java Zone

2001 Special Report: Judging Java

TALK BACK
How do you intend to make your entry into Web services? What kinds of applications do you think you'll select first for web services deployment? Tell us in the Java Web Services newsgroup.


Sponsored Links

Advertising Info  |   Member Services  |   Contact Us  |   Help  |   Feedback  |   Site Map
Jupiterweb networks

internet.comearthweb.comDevx.comClickZ

Search Jupiterweb:

Jupitermedia Corporation has four divisions:
JupiterWeb, JupiterResearch, JupiterEvents, and JupiterImages

Copyright 2004 Jupitermedia Corporation All Rights Reserved.
Legal Notices, Licensing, Reprints, & Permissions, Privacy Policy.

Jupitermedia Corporate Info | Newsletters | Tech Jobs | E-mail Offers

Copyright Information/Privacy Statement