Novell is now a part of Micro Focus

How to Build J2EE Applications Using Novell Technologies: Part 7

Articles and Tips: article

J. Jeffrey Hanson
Chief Architect
Zareus Inc.
jeff@jeffhanson.com

01 Dec 2002


This is the seventh in a series that outlines a platform and methodology for Java 2 Platform Enterprise Edition (J2EE) application development on NetWare using a service-oriented architecture.In this AppNote, we learn about how our DAO framework can also be used to simplify and unify access to Web service provider sources.


Topics

Java application development, J2EE, Java Management Extensions (JMX)

Products

Java 2 Enterprise Edition

Audience

developers

Level

intermediate

Prerequisite Skills

familiarity with Java programming

Operating System

n/a

Tools

none

Sample Code

yes

Introduction

This is the seventh in a series of AppNotes outlining a platform and methodology for Java 2 Platform Enterprise Edition (J2EE) application development on NetWare using a service-oriented architecture.

In the previous AppNote we looked at how our platform interfaces with the data tier and how we can build our data-access components to be flexible and robust.

In this AppNote, we will discuss how our DAO framework can also be used to simplify and unify access to Web service provider sources.

An Introduction to Web Services

The term Web services is used to describe concepts and technologies that integrate business processes and services over the Web using standard network protocols. Web services, as a technology, is a mechanism for delivering cross-platform, cross-language services, and business content to any Web-enabled client or device.

Web services are URL-addressable software components that are connected by a common protocol, and which allow applications and services to access them over the Internet. Web services are based on XML envelopes containing either documents or procedures and data structures. The Web services model allows applications to interacted with one another in a very loosely coupled manner over a networked environment.

The operations surrounding Web services usually fall within three major categories: publish, find, and bind. Publishing involves exposing the service in a manner that makes it easy to find and use by a service consumer. This typically involves staging the service in a public registry. When a service is listed in a registry, it can then be found or discovered, bound using SOAP and then invoked by a service consumer. The following figure illustrates the relationships between the parties involved in the lifecycle of a typical Web service:

Figure 1: Parties involved in the lifecycle of a typical Web service.

The current manner most used to describe Web services is the Web Services Description Language (WSDL). Web services are typically published in a registry using technologies such as Universal Description, Discovery, and Integration (UDDI), and invoked over HTTP using the Simple Object Access Protocol (SOAP).

Overview of SOAP

SOAP is an XML-based communication protocol and data-encoding format which is currently considered to be the primary message-payload medium for Web services interplay. SOAP was originated by Microsoft, DevelopMentor and other major software vendors and, now, under the direction of the W3C XML Protocol working group is fast becoming the most widely used mechanism for Web services communication.

The XML structure of a SOAP message consists of an envelope containing an optional header, a mandatory body and zero or more additional, optional entries. The following is a sample SOAP envelope:

<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
 <soap-env:Header/>
 <soap-env:Body>
        <pim:agenda xmlns:pim="http://www.jeffhanson.com/services/pim">
            <pim:event>
                <pim:meeting>11/12/2002</pim:meeting>
                <pim:purpose>Marketing Review</pim:purpose>
          </pim:event>
       </pim:agenda>
  </soap-env:Body>
</soap-env:Envelope>

The following is the same sample SOAP envelope with the addition of one security element in the header:

<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
 <soap-env:Header>
      <wsse:Security> 
           <wsse:BinarySecurityToken 
                ValueType="wsse:X509v3"
              EncodingType="wsse:Base64Binary"  
               Id="X509Token">
               MIIEZzTHEv7gAwWEBAgISumtJZc0rqrKh5iFUN89Yim
          </wsse:BinarySecurityToken>
        </wsse:Security>
   </soap-env:Header>
 <soap-env:Body>
        <pim:agenda xmlns:pim="http://www.jeffhanson.com/services/pim">
            <pim:event>
                <pim:meeting>11/12/2002</pim:meeting>
                <pim:purpose>Marketing Review</pim:purpose>
          </pim:event>
       </pim:agenda>
  </soap-env:Body>
</soap-env:Envelope>

The AXIS of Power for Web Services

The Apache Extensible Interaction System (AXIS) from Apache is an SOAP-based Web services producer/consumer framework. AXIS, a derivative of the Apache SOAP project, provides Java APIs and components for constructing SOAP consumers, producers, and gateways. AXIS includes:

  • A SOAP engine

  • Support for automatic deployment of Java classes as SOAP services

  • Support for all basic XML data types, and a type-mapping system for defining new data type handlers known as serializers and deserializers

  • Automatic serialization and deserialization of Java Beans

  • Provider support for RPC and message-based SOAP services

  • Automatic WSDL generation from deployed services

  • A WSDL2Java utility for generating Java stubs and skeletons from WSDL documents

  • A Java2WSDL tool for generating WSDL files from Java classes

  • Support for SOAP-with-Attachments

  • An EJB provider for exposing EJBs as Web services

  • Servlet-based producer support

  • JMS-based producer support

  • A stand-alone server

  • An embedded server

  • A utility for monitoring IP packet flow

AXIS on NetWare

Within our platform, we will be using AXIS as our SOAP engine.

  1. Our first step will be to download the latest release of AXIS as a zip file from http://xml.apache.org/axis.

  2. Once the archived release is downloaded, extract the contents by executing the following command at the system console:

    unzip ArchivedReleaseName.zip

  3. After the archive has been unzipped, you will find a folder named xml-axis-10 at the root of the volume on which the command was executed.

    Browsing around inside of the xml-axis-10 folder you will notice folders named docs, lib, samples, webapps, etc. AXIS is implemented in the Jar file axis.jar; which is located in the lib directory. The AXIS implementation and auxiliary files come prepackaged as a Web application located in the file, axis.war. The prepackaged configuration is setup to execute as a SOAP server.

  4. At this point, you need to create a subdirectory named axis in the /VOL/tomcat/33/webapps directory. Into this directory copy the contents of the webapps/axis directory from the unzipped AXIS distribution.

  5. Now, reinitialize your Web application environment by typing "java -exit" at the server console, then type "unload apache" at the console, then type "my_tomcat33.ncf" at the server console and finally type "startapache.ncf" at the server console.

Validating the Installation

After installing the Web application and dependencies, we need to make sure that the server is running the axis Web application. To do this follow the steps below:

  1. Navigate to the start page of the axis Web application by entering http://nwServerHostName/axis in a browser window, substituting your host name for nwServerHostName. As a response, you should see an Apache-AXIS start page.

  2. Click the Validate link. This will load a test JSP page that attempts to verify that needed and optional libraries are present.

  3. Now we will test a service invocation by submitting an XML request to the endpoint. An endpoint in Web services terminology refers to the final destination of a service invocation, usually a site on a networked host. We are going to invoke the getVersion method from the Version endpoint of our AXIS installation, as follows:

    http://nwServerHostName:8080/axis/services/Version?method=getVersion

    This should return a response that looks something like the following SOAP envelope:

<?xml version="1.0" encoding="UTF-8" ?> 
   <soapenv:Envelope 
        xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
       xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <soapenv:Body>
 <getVersionResponse 
      soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
        <getVersionReturn 
            xsi:type="xsd:string">
            Apache Axis version: 1.0 Built on Nov 12, 2002 (08:20:33 PST)
        </getVersionReturn> 
   </getVersionResponse>
  </soapenv:Body>
</soapenv:Envelope>

Automatic Web Service Deployment

AXIS provides the ability to automatically deploy Java classes as Web services. This is enabled by simply renaming a .java file with a .jws extension and dropping it into a Web application directory. When a request is made to a method in the .jws file, it is automatically compiled by AXIS and executed.

We will now test a JWS service, by invoking a method on a pre-built sample, EchoHeaders. To do this, enter the following into a browser:

http://nwServerHostName/axis/EchoHeaders.jws?method=list

This should return a response that resembles the following:

<?xml version="1.0" encoding="UTF-8" ?> 
<soapenv:Envelope 
   xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
   xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <soapenv:Body>
     <listResponse 
            soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
            <listReturn xsi:type="soapenc:Array" 
             soapenc:arrayType="xsd:string[6]" 
               xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
                <item>accept-language:en-us</item> 
              <item>accept-encoding:gzip, deflate</item> 
              <item>user-agent:Mozilla/4.0</item> 
             <item>host:nwServerHostName</item> 
              <item>connection:Keep-Alive</item> 
          </listReturn>
      </listResponse>
    </soapenv:Body>
</soapenv:Envelope>

Manual Web Service Deployment

AXIS allows existing Java components to be manually deployed when renaming the extension is not convenient. This is accomplished by placing the classes that contain the components you wish to deploy into the classes directory subordinate to the WEB-INF directory within your Web application. If the classes exist in a .jar file, place them into the lib directory subordinate to the WEB-INF directory.

Once the classes or .jar files are placed in the appropriate directories, we must reinitialize the servlet environment by typing "java -exit" at the server console, then type "unload apache" at the console, then type "my_tomcat33.ncf" at the server console and finally type "startapache.ncf" at the server console.

To configure AXIS with information about our Java components, we create a deployment configuration file, known as a Web Service Deployment Descriptor (WSDD). The WSDD file is an XML file that describes the service name, the service methods and other information. The following is a sample WSDD file:

<deployment xmlns="http://xml.apache.org/axis/wsdd/"
  xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
  <service name="MyService" provider="java:RPC">
     <parameter name="className" value="com.jeffhanson.samples.MyService"/>
     <parameter name="allowedMethods" value="*"/>
   </service>
</deployment>

Once a WSDD file is created, our environment needs to be setup in order to deploy the WSDD file to the AXIS server, so, we add axis.jar, commons-discovery.jar, commons-logging.jar, jaxrpc.jar, saaj.jar, log4j-1.2.4.jar, and a JAXP-compliant parser such as xerces.jar (http://xml.apache.org/xerces2-j/index.html) to our classpath.

At this point, we can traverse to the folder containing the deployment descriptor for our service and run AdminClient by typing a command at the server console following this pattern:

java org.apache.axis.client.AdminClient
-lhttp://nwServerHostName/axis/servicePath/serviceName deployFile.wsdd

The Data Access Object Pattern Revisited

Web services connect two or more entities together to exchange data. Looking at a Web service in this way points out a lot of similarity with a typical data resource such as a database, directory service or file system. Thus, we will access construct our platform to access Web services in much the same way we do for a database or other data resource.

To reiterate, the Data Access Object (DAO) pattern exposes Web services to the following advantages:

  • Separates a Web service interface from its specific implementation.

  • Adapts a specific Web service's access API to a generic interface.

  • Allows a Web service implementation to adjust independently from the code that uses the DAO.

  • Offers access to a particular Web service without coupling the service's API to the business logic.

  • Permits application developers or deployment engineers the choice of a Web service access mechanism with no changes to the program code.

This approach allows a developer access to a Web service only in terms of its DAO interface. Based on configuration data, an application uses a factory object to select the DAO implementation at runtime.

A DAO interface has at least one concrete class that implements the interface for a specific type Web service. To add a new type of Web service, an application developer simply follows the steps listed below:

  • Create a class that implements the DAO interface for the new Web service.

  • Specify the implementing class's name in a meta-data configuration source.

  • Facilitate a re-initialization by the client service, which causes the creation of an instance of the new DAO class by the factory, which the application will now use.

Figure 2 shows the implementation of the DAO design pattern for a DAO that accesses data for a Stock Web service. Notice how the factory is used to select the DAO implementation.

Figure 2: Implementation of the DAO design pattern.

The Stock DAO Interface

public interface StockDAO
{
    public float getQuote(String symbol) 
        throws StockDAOException;
    
 public void buy(String symbol, int numShares, float targetPrice)
     throws StockDAOException;
    
 public void sell(String symbol, int numShares, float targetPrice)
        throws StockDAOException;
}

The Stock DAO Implementation

public class AXISStockDAO implements StockDAO
{
    public AXISStockDAO()
    {
    }
    
 public float getQuote(String symbol) 
        throws StockDAOException
 {
    }
    
 public void buy(String symbol, int numShares, float targetPrice) 
        throws StockDAOException
 {
    }
    
 public void sell(String symbol, int numShares, float targetPrice) 
       throws StockDAOException
 {
    }
}

The Stock DAO Factory

public class StockDAOFactory
{
  /**
        * This method instantiates a particular DAO based on the
     * information obtained from a configuration file
     */
   public static StockDAO getDAO()
      throws StockDAOException
 {
        StockDAO stockDao = null;
        try {
            InitialContext ctx = new InitialContext();
           String className =
               (String)ctx.lookup(ConfigFile.STOCK_DAO_CLASS);
          stockDao =
               (StockDAO)Class.forName(className).newInstance();
        } catch (NamingException e) {
            throw new StockDAOException(StockDAOFactory.getDAO: "
                                                + ne.getMessage());
      } catch (Exception e) {
          throw new StockDAOException("StockDAOFactory.getDAO: "
                                               + se.getMessage());
      }
    
     return stockDao;
 }
}

Concrete DAO Factory Implementation for AXIS

public class AXISDAOFactory extends DAOFactory
{
   public StockDAO getStockDAO()
    {
        return new AXISStockDAO();
   }
}

A DAO Client

// create the DAO Factory
AXISDAOFactory axisFactory =   
  (AXISDAOFactory)DAOFactory.getDAOFactory(DAOFactory.DAO_AXIS_STOCK);
 
// Create the DAO
StockDAO stockDAO = axisFactory.getStockDAO();
    
// get a quote using the DAO
float quote = stockDAO.getQuote(symbol);
   
// sell a number of shares using the DAO
stockDAO.sell(symbol, 40, 8.85);
   
// buy a number of shares using the DAO
stockDAO.buy(symbol, 40, 5.53);

Conclusion

This AppNote introduced Web services and the Simple Object Access Protocol. We also discussed how a DAO framework can be used to simplify and unify access to Web service provider sources.

The next AppNote in this series, we will further explore AXIS and Web services and look at how we can integrate AXIS to become a SOAP gateway and an integral component of our platform.

For Additional Information

For more information about the technologies discussed in this AppNote, refer to the following resources:

* Originally published in Novell AppNotes


Disclaimer

The origin of this information may be internal or external to Novell. While Novell makes all reasonable efforts to verify this information, Novell does not make explicit or implied claims to its validity.

© Copyright Micro Focus or one of its affiliates