Contents


Build Web Services with Rational Application Developer

Part 1: Building and testing

Comments

Before you start

About this tutorial

This tutorial is the first in a two-part series about developing and deploying Web services. If you want to create Web services and are new to IBM® Rational® Application Developer Version 6.0, or who want to learn how to use this tool for building Web services quickly, this tutorial is for you.

For this tutorial, you need a basic knowledge of Java™ technology. You don't need to have a background in Web services or technologies such as Simple Object Access Protocol (SOAP), the Web Services Description Language (WSDL), or Universal Description, Discovery, and Integration (UDDI) because Rational Application Developer takes care of building all this for you. Instead, you'll understand the code generated by Rational Application Developer which, in turn, lets you see how the tool uses SOAP and WSDL in the work order management scenario discussed in this tutorial.

In this tutorial, learn how to:

  • Use Rational Application Developer to develop Web services.
  • Use existing functionality that you have already developed in Java code and expose it as a Web service.
  • Develop the Web service description and package the project as an enterprise archive.

You do all this using the set of tools packaged with Rational Application Developer; you are not required to manually build any of these components. You will also learn how to test your Web service from within Rational Application Developer using a simple client.

Most of the focus in this tutorial is on the mainstream Web services wizards. This tutorial is based on a real business scenario involving a work order management application. The Web service you will build, called createWorkOrder, allows clients to create new work orders for a company's workforce. The work manager object is responsible for accessing, creating, and modifying the work orders.

Part 2 of this tutorial takes the Web service you develop here and shows you how to:

  • Deploy it on a computer running IBM WebSphere® Application Server Version 6.0
  • Publish the service in a registry
  • Test the Web service after you deploy it

Prerequisites

To run the examples in this tutorial, you need the following software:

You will find this tutorial easier to follow if you download and install Rational Application Developer Version 6.0. However, it's not a prerequisite, and you can follow the tutorial even if you don't have a working copy of the software. As an alternative, you can download and use IBM Rational Web Developer for WebSphere Software Version 6.0: All the steps and screens are identical. Rational Application Developer includes all the functions that are in Rational Web Developer.

Manage the work order

Overview

Web services shine in business environments in which decoupled applications need to interact to complete an end-to-end business process. These systems may or may not reside on the same network segment and may not even be managed by the same organization. Before Web services, this type of environment would require complex and costly integration and private networks. Web services use the connectivity of the Internet, the simplicity of HTTP, and the wide adoption of SOAP, WSDL, and UDDI to provide the same level of integration at a fraction of the cost.

The scenario used in this tutorial is taken from a real business environment -- a work order management scenario.

Work order management scenario

Imagine a company that's in the business of satellite TV installations. To protect the innocent, let's call the company InstallCo. They have a national workforce of approximately 2500 installers who specialize in installations all over the United States. Every day, each installer has 3-5 work orders for installing a dish. In the morning, each installer gets a "to do" list and goes off to complete the day's work.

InstallCo does not get the customer order directly. They are contracted by the dish companies and retailers. The dish companies and retailers sell the service to consumers and book the appointment. These companies then forward the information to InstallCo, who creates a work order in their work management system. InstallCo is responsible for performing the installation and for updating the originator regarding the status of the work order.

InstallCo is paid based on the number of completed work orders. It's therefore in InstallCo's best interest to work with as many retailers and dish companies as possible. The most difficult aspect of getting a new retailer to work with InstallCo is the way in which new orders are transferred from the retailer to InstallCo. Most retailers capture new customers in their own, separate system. It's not feasible to perform complex integration with so many systems, and yet InstallCo doesn't want these orders to arrive as paper requests because this makes the work-handling process expensive and error-prone. So, how does InstallCo provide a simple, standards-based way to create a new installation order electronically over the Web? By using a Web service, of course.

CreateWorkOrder Web service

InstallCo's (IT) department inspected the work order management system and listed the information required to capture a new work order. This information includes the appointment times, the customer address, and the type of installation. It also includes the name of the company that initiated the installation order. After the order is created in InstallCo's work management system, the order number is returned to the client who invoked the Web service. This number can later be used to track the progress of the order.

The createWorkOrder Web service is based on the above analysis. In making a call to this service, the required work order information is sent and the order number returned. The service is the front end to InstallCo's work management system and is exposed over the Web for all retailers and dish companies to use. Because InstallCo is using a Web service to expose the interface, the order data is passed as an XML document (see Figure 1).

Figure 1. InstallCo's order data flow
order data

order data

As Figure 1 shows, when a retailer or dish provider sets an appointment with a customer, the order information is packaged as XML data and used to invoke the Web service, which in turn creates the order within the work management system.

The fact that work order creation is packaged as a Web service makes it available over the public Internet and thus accessible to all at a very low cost of ownership. Packaging this function as a Web service has one other important effect: It makes InstallCo easy to find as a service provider and makes the createWorkOrder function easy to interface with, even if a customer has never used it before. Making the function a Web service means that it's self-describing and easy to publish.

Publishing self-describing services

InstallCo works with many retailers. Some of these retailers have large IT departments, and some have very small IT departments. Because InstallCo wants to get as many work orders as possible, it's important that building an interface to InstallCo is simple. It's also important that the createWorkOrder Web service be self-describing so that a retailer wanting to use it does not have to approach InstallCo's IT department and go through a lengthy integration project. It's equally important that the service can be used regardless of the retailer's platform -- for example, WebSphere systems or Microsoft® .NET systems. All these requirements are satisfied through Web services.

In the same way that InstallCo might be listed in the yellow pages, the company also wants to use the Web Services framework to self-publish the createWorkOrder Web service on public registries. In this way, a retailer who doesn't know InstallCo can search through such registries for companies who install dishes, discover InstallCo, then quickly build an interface to InstallCo using the self-describing interface point.

The combination of a published, self-describing interface means that "electronic bonding" is easy. A new retailer who needs to commit to new customers for dish installations can search public registries looking for companies that can do such installations. At the end of this discovery process, using UDDI, they find InstallCo. The retailer then uses the WSDL file to learn how to invoke the service. A proxy is generated based on the WSDL; this proxy is used to invoke the createWorkOrder Web service. The invocation is done using SOAP (see Figure 2).

Figure 2. Proxy invoking the service through SOAP
proxy using SOAP

proxy using SOAP

All this is possible because of the technologies forming Web services: UDDI, WSDL, and SOAP.

60 seconds on SOAP, WSDL, and UDDI

This tutorial doesn't teach you about SOAP, WSDL, or UDDI. For links to material on these subjects, refer to Related topics. One of the great things about Rational Application Developer is that it takes care of all generation involved with both creating and invoking the Web service. Still, if you're not yet familiar with SOAP, WSDL, or UDDI, it's worthwhile spending 60 seconds so that you have the right reference framework.

Web services are functional elements deployed on a node on a network and accessed over the Internet. This description is quite generic and doesn't say too much; what makes such a service endpoint a Web service is the how, not the what. Web services are based on a set of standards -- specifically, SOAP, WSDL, and UDDI. SOAP is the protocol by which a remote client can invoke the functionality implemented by the Web service. Developers of Web services use WSDL to define the metadata describing the Web service, and remote clients use WSDL to learn what arguments are required for invoking the Web service (as well as other things required to make the remote call). Web services providers use UDDI to publish their Web services, and clients of Web services use UDDI to discover where these Web services (and the metadata describing them) reside.

Enough with theory. Let's move on to building the service.

Implement the Web service

Create a new Web project

The first step in implementing the service is creating a new Web project in Rational Application Developer.

  1. Select File > New > Project to launch the New Project Wizard.
  2. Expand the Web folder and select Dynamic Web Project (see Figure 3).

    Figure 3. Create a new dynamic Web project
    dynamic web project

    dynamic web project

  3. Click Next.
  4. In the Dynamic Web Project window (see Figure 4), enter WorkOrderManagerIfc as the project name, then click Finish.

    Figure 4. Name the project
    name the project

    name the project

Rational Application Developer creates all the required components for the project. If you expand the Enterprise Applications folder in the Project Explorer, you'll see that Rational Application Developer also created an enterprise application called WorkOrderManagerIfcEAR that you will use later to deploy the service on a computer running Application Server.

Create the WorkOrder class

The first class you need is the WorkOrder class. This class maintains the data required to perform a work order. To create the WorkOrder class:

  1. Within the Project Explorer, expand the WorkOrderManagerIfc and the Java Resources folders.
  2. Right-click the JavaSource folder and select New > Class.
  3. In the Java Class window, create a new Java class.
  4. Enter a package name and a class name, as shown in Figure 5.

Figure 5. Enter the package and class names
Enter the package and class names

Enter the package and class names

Now you need to write the code for the WorkOrder class (see Listing 1). The code for the WorkOrder class is very simple. Some of the get and set methods are omitted for the sake of brevity. The order number is set in the constructor when you create a new work order.

Listing 1. Code to create the WorkOrder class

package com.installco;  
import java.util.Date;  
import java.lang.String;  
public class WorkOrder {  
        
        // input data  
        private String customerName;  
        private String addressStreet;  
        private String addressCity;   
        private String addressState;  
        private String addressZip;  
        private String sourceCompany;  
        private Date   appointmentDate;  
          
        // output data  
        private int orderNumber;  
          
        // manage a sequence to assign order number  
        static int nextOrderNumber = 0;  
          
        public WorkOrder() {  
                // set the order number upon creation.  
                this.orderNumber = nextOrderNumber;  
                // increment the sequence  
                nextOrderNumber++;  
        }  
          
        public String getCustomerName() {  
                return this.customerName;  
        }  
          
        public void setCustomerName(String customerName) {  
                this.customerName = customerName;  
        }  
          
        ...  
          
        public Date getAppointmentDate() {  
                return this.appointmentDate;  
        }  
          
        public void setAppointmentDate(Date appointmentDate) {  
                this.appointmentDate = appointmentDate;  
        }  
          
        // no set method - the order number is created by the  
        // constructor and cannot be changed later  
        public int getOrderNumber() {  
                return this.orderNumber;  
        }  
       
}

Create the WorkOrderManager class

The only other class you need for the back end is the WorkOrderManager class. This class manages a vector of work orders and implements the methods used for creating a new work order. You will later wrap this method as a Web service.

To create the class, follow the same procedure shown in Create the WorkOrder class. Listing 2 shows the code for this class.

Listing 2. Code to create the WorkOrderManager class

package com.installco;  
import java.util.Vector;  
import java.util.Date;  
public class WorkOrderManager {  
          
        static Vector orders = new Vector();  
          
        // Get input data and create a new work order.  
        // Return the order number  
        public int createNewWorkOrder(  
                String customerName,  
                String addressStreet,  
                String addressCity,  
                String addressState,  
                String addressZip,  
                String sourceCompany,  
                Date   appointmentDate) {  
                          
                        WorkOrder newOne = new WorkOrder();  
                        newOne.setCustomerName(customerName);  
                        newOne.setAddressStreet(addressStreet);  
                        newOne.setAddressCity(addressCity);   
                        newOne.setAddressState(addressState);  
                        newOne.setAddressZip(addressZip);  
                        newOne.setSourceCompany(sourceCompany);  
                        newOne.setAppointmentDate(appointmentDate);  
                          
                        orders.addElement(newOne);  
                          
                        return newOne.getOrderNumber();  
                }  
       
}

Now that you've completed the back end, you're ready to build the Web service wrapper.

Create the Web service

Launch the Web Services Wizard

To launch the Web Services Wizard:

  1. Select File > New > Other.
  2. In the Select a wizard window, select Show All Wizards (see Figure 6).

    Figure 6. Launch the Web Services Wizard
    Web Services Wizard

    Web Services Wizard

  3. Open the Web Services folder and select Web Service. Click Next.

    Note: A window might appear telling you that you need to activate Web Service Development features. Select Always enable capabilities and don't ask me again, then click OK.

  4. In the Web Services window, select Generate a proxy and make sure that the Client proxy type is set to Java proxy (see Figure 7). This generates a client-side proxy through which you will test your Web service later in this tutorial.

    Figure 7. Set options for the new Web service
    default type

    default type

  5. Select Test the Web service so that the wizard also creates a small test application for you. The proxy and the test application are covered later in this tutorial.
  6. If this is not the first time you've generated a Web service, select Overwrite files without warning to ensure that if you change some of the properties of the code but have a previously saved version of the Web service files, you will replace them.
  7. Click Next.
  8. In the next window, enter com.installco.WorkOrderManager as the bean, then click Next.

The default Web service type is set to Java bean Web Service. Keep this setting because you're wrapping an existing Java class with a Web service. You will publish this Web service in Part 2 of this tutorial, so clear the Launch the Web Services Explorer to publish this Web service to a UDDI Registry option at this time.

Select the service deployment

Make sure that you've selected the WorkOrderManagerIfc Web project as the Service project. The default server -- in this case, a WebSphere Server Version 6.0 machine running on localhost -- is selected as the target deployment platform. Because you're generating both a server and a client (with the proxy), two projects come into play. The WorkOrderManagerIfcClient project is generated automatically and includes both the proxy and the test application. Leave the defaults and click Next (see Figure 8).

Figure 8. Select the service Web project
Service Web Project

Service Web Project

In the next window, click Next to allow the Web Services Wizard to generate the default service endpoint.

Configure the Web service

In the Web Service Java Bean Identity window, select the methods from the Java class that should be exposed as Web services. In this case, the createNewWorkOrder method and its signature are already selected. The Web service URI is created automatically for you (you can always change it later using the WSDL Editor), and there is only one WSDL document that includes all the required definitions. In addition, you can select whether to use Document (SOAP) or Remote Procedure Call (RPC) encoding as well as the type of security configuration to use. Leave the default selections so that the wizard window looks like Figure 9, then click Finish.

Figure 9. Configure the Java bean as a Web service
configure Java bean

configure Java bean

Use the WSDL Editor

About the WSDL Editor

Rational Application Developer Version 6.0 has enhanced tools for viewing and modifying WSDL. In addition, Rational Application Developer supports building applications that are consistent with the Web Services Interoperability Organization (WS-I) Basic Profile.

To view the WSDL file previously generated for you, double-click the WorkOrderManager.wsdl file in the WebContent\wsdl\com\installco folder. The WSDL Editor opens. The source of the file incorporates the WSDL types, messages, port types, operations, bindings, services, inputs, and outputs. Click the Graph tab at the bottom of the editor to view a graphical depiction of the Web service and all the individual components that come together to implement it (see Figure 10). You can then expand each artifact and view the relationships -- all the way to the Java method. Integration with the Rational developer-centric view of the world certainly makes Rational Application Developer Version 6.0 even more complete than previous versions of IBM WebSphere Studio Application Developer.

Figure 10. View relationships on the Graph tab
view relationships

view relationships

This visual editor is a useful and convenient tool that makes editing Web service definitions much easier and comprehensive. You no longer have to manually sift through large XML files -- you can now get a view of how the Web service is constructed and make changes quickly.

Navigating the WSDL Editor

The WSDL Editor is perhaps the most important tool in the category of Web services, so let's spend a few minutes reviewing some of its capabilities.

The WSDL Editor is divided into two panes, using the Rational Application Developer real estate as do all editors. The top pane has two tabs: the Graph tab (showing the full relationship between the services, port types, messages, and so on) and the Source tab (showing the WSDL source). The bottom pane includes the property editor, which is context sensitive to the element selected in the top pane and allows you to view and modify attributes per the selected element.

Each element has an expand icon with which you can see the details of that element. Expanding an element also shows the interrelationships between the different elements. As an example, expand the WorkOrderManagerService element to open the WorkOrderManager port (see Figure 11).

Figure 11. View elements details
element details

This figure reflects the WSDL definition shown in Listing 3.

Listing 3. WSDL definition for WorkOrderManagerService

<wsdl:service name="WorkOrderManagerService">
  <wsdl:port binding="impl:WorkOrderManagerSoapBinding" name="WorkOrderManager">
    <wsdlsoap:address location="http://localhost:9080/WorkOrderManagerIfc/
                 services/WorkOrderManager"/>
  </wsdl:port>
</wsdl:service>

Expand the WorkOrderManager port. As you can see, the port has a wsdlsoap:address attribute (see Figure 12). Click this attribute; the property editor in the bottom left pane allows you to modify the location (that is, the original URI that was provided as a default in the Web Services Wizard.) This URI specifies where clients can access the Web service and is therefore very important.

Figure 12. Modify the wsdlsoap:address attribute
modify attribute

modify attribute

Now, go back and click the WorkOrderManager port. You'll see that the port definition has a WorkOrderManagerSoapBinding binding, which has a port type of WorkOrderManager (see Figure 13).

Figure 13. The WorkOrderManager port definition
port definition

port definition

Furthermore, the property editor in the bottom left pane displays the port attributes, including the binding, and allows you to click the button marked ... to create a new binding, select an existing binding, or even import a binding from a file.

SOAP encoding vs. literal XML encoding

When selecting the input and output encoding style, the encoding style must match the way that you code your methods. Using SOAP encoding (document encoding) means that Java types are mapped to predefined SOAP types -- types defined in the XML Schema namespace, or xsd. In the example used in this tutorial, all the arguments are simple types (for example, int) or standard Java classes (for example, String and Date) and hence, SOAP encoding makes perfect sense. Using SOAP encoding saves you quite a bit of work and leaves the type mapping and XML creation up to the SOAP libraries.

Literal XML encoding means that you need to perform the data extraction and injection explicitly using XML element objects. When using literal XML encoding, you need to explicitly create an XML document object into which you build all the XML elements that you require. You need to write more code -- usually quite a bit of code. The advantage of this method is that it is completely generic. If you're using literal XML encoding for your output, you can build any XML structure you need, and it will be inserted directly into the SOAP message. For example, if you had to write the createNewWorkOrder method to use literal encoding for its output, it would look like the code shown in Listing 4.

Listing 4. Code to create the createNewWorkOrder method

// Get input data and create a new work order.  
// Return the order number within an XML document  
// which needs to be manually built  
public Element createNewWorkOrder(  
  String customerName,  
  String addressStreet,  
  String addressCity,  
  String addressState,  
  String addressZip,  
  String sourceCompany,  
  Date   appointmentDate) {  
                          
    WorkOrder newOne = new WorkOrder();  
    newOne.setCustomerName(customerName);  
    newOne.setAddressStreet(addressStreet);  
    newOne.setAddressCity(addressCity);   
    newOne.setAddressState(addressState);  
    newOne.setAddressZip(addressZip);  
    newOne.setSourceCompany(sourceCompany);  
    newOne.setAppointmentDate(appointmentDate);  
                          
    orders.addElement(newOne);  
          
    // Generate the output XML - explicitly  
    DocumentImpl doc = new DocumentImpl();  
    try {  
      Element oderNumElement = doc.createElement("OrderNumber");  
      doc.appendChild(oderNumElement);  
      oderNumElement.appendChild(  
           doc.createTextNode(new String(newOne.getOrderNumber())));  
    } catch (Exception ex) {  
      ex.printStackTrace();  
    }  
    return doc.getDocumentElement();          
}

As long as you're using standard types, SOAP encoding means that the whole Web service request/response process is completely transparent to you. Incidentally, if you are using SOAP encoding, you can see what mapping will be created and modify the mapping to custom types, if necessary. This again is done within the WSDL Editor, as shown in View type information using the WSDL Editor.

View type information using the WSDL Editor

Starting from the last view you had in the WSDL Editor:

  1. Click the WorkOrderManager port and the WorkOrderManagerSoapBinding binding, then expand the WorkOrderManager port type. Notice that createNewWorkOrder is the only operation within the port type. If you expand the createNewWorkOrder operation, you'll see that (as all operations) it has an input and an output.
  2. Click input. The WSDL Editor shows you that the input is implemented by the createNewWorkOrderRequest message, which has a createNewWorkOrder XML element as its parameter.
  3. Expand the createNewWorkOrder element to show the internal structure of this element and all the sub-elements within it. These are the primitive data structures that hold the data you send when creating a new work order. This fully expanded view gives you a good overview of how your Web service is structured (see Figure 14).

    Figure 14. Expanded createNewWorkOrder element
    expanded element

    expanded element

  4. Look at the properties editor: The createNewWorkOrder element is defined as a complex type that is a sequence as defined in the WSDL type. You can modify the type by clicking ... and selecting either the Built-in simple type (of which there are quite a few, as Figure 15 shows), the User-defined simple type, or the User-defined complex type option.

    Figure 15. Simple types
    simple types

In this case, you have a sequence -- a user-defined complex type that was not published as an explicit type but that can be viewed in the WSDL source (see Figure 16).

Figure 16. User-defined complex type
complex type

complex type

Now that you've finished building (and understanding) the server side, let's revisit the client side of the Web service.

Use the proxy and a test client

Using the proxy

Part of the beauty of Rational Application Developer Version 6.0 is that it generates not only the server-side code (the Web services wrapper) but also a client-side proxy. The client-side code uses this proxy to make a Web service invocation. In making such an invocation, you don't need to write SOAP and XML documents; the client-side code has access to the proxy Java object and can make remote invocations transparently. For example, Listing 5 shows you the method through which you can create a new work order by making an "ordinary" Java call.

Recall that when you originally created the Web service, you also asked Rational Application Developer to generate a proxy and a test application for you. The proxy is a class implementing your service by making a call to the server; it is generated from the WSDL file. You can also generate the proxy and test the application directly from the WSDL file generated earlier. While you don't need to know anything about the proxy, it's enlightening to look at what it does. You can view the source for the generated proxy by navigating to the WorkOrderManagerIfcClient dynamic Web project in the Project Explorer, then to the Java Resources\JavaSource\com.installco folder. This package contains a few files:

  • WorkOrderManager.java: An interface encapsulating the operations contained in the service
  • WorkOrderManagerService.java: An interface encapsulating lookup operations to find the work order manager
  • WorkOrderManagerProxy.java: A proxy class implementing the WorkOrderManager interface that provides a readable "implementation"; used mostly for client code
  • WorkOrderManagerSoapBindingStub.java: The "real" proxy class, implementing the WorkOrderManager interface; the stub class performs the work
  • WorkOrderManagerServiceLocator.java: The implementation class of the WorkOrderManagerService interface responsible for returning appropriate proxy instances and other service values
  • WorkOrderManagerServiceInformation.java: Responsible for type mappings and operation descriptions

All these classes are generated by Rational Application Developer's Web Services WSDL2Java emitter, which processes the WSDL and creates conforming Java code. The most interesting class is the stub class in which, in addition to various support structures, a Java method is created for each method you chose to wrap as a Web service. In the work order example, the interesting generated methods are createNewWorkOrder and _getcreateNewWorkOrderInvoke0 as shown in Listing 5.

Listing 5. The createNewWorkOrder and _getcreateNewWorkOrderInvoke0 methods

public int createNewWorkOrder(
   java.lang.String customerName, 
   java.lang.String addressStreet, 
   java.lang.String addressCity, 
   java.lang.String addressState, 
   java.lang.String addressZip, 
   java.lang.String sourceCompany, 
   java.util.Calendar appointmentDate) 
            throws java.rmi.RemoteException {
     if (super.cachedEndpoint == null) {
      throw new com.ibm.ws.webservices.engine.NoEndPointException();
     }
     java.util.Vector _resp = null;
     try {
      _resp = _getcreateNewWorkOrderInvoke0(new java.lang.Object[]
      {customerName, addressStreet, addressCity, addressState, 
      addressZip, sourceCompany, appointmentDate}).invoke();

     } catch (com.ibm.ws.webservices.engine.WebServicesFault wsf) {
      Exception e = wsf.getUserException();
      throw wsf;
     } 
     try {
      return ((java.lang.Integer)
      ((com.ibm.ws.webservices.engine.xmlsoap.ext.ParamValue) 
      _resp.get(0)).getValue()).intValue();
     } catch (java.lang.Exception _exception) {
      return ((java.lang.Integer) super.convert(
      ((com.ibm.ws.webservices.engine.xmlsoap.ext.ParamValue) 
      _resp.get(0)).getValue(), int.class)).intValue();
     }
    }
    
private synchronized com.ibm.ws.webservices.engine.client.Stub.Invoke 
    _getcreateNewWorkOrderInvoke0(Object[] parameters) 
       throws com.ibm.ws.webservices.engine.WebServicesFault  {
     com.ibm.ws.webservices.engine.MessageContext mc = 
      super.messageContexts[_createNewWorkOrderIndex0];
     if (mc == null) {
      mc = new com.ibm.ws.webservices.engine.MessageContext(super.engine);
      mc.setOperation(WorkOrderManagerSoapBindingStub._createNewWorkOrderOperation0);
      mc.setUseSOAPAction(true);
      mc.setSOAPActionURI("");
      mc.setEncodingStyle(com.ibm.ws.webservices.engine.Constants.URI_LITERAL_ENC);
      mc.setProperty(com.ibm.ws.webservices.engine.client.Call.SEND_TYPE_ATTR, 
        Boolean.FALSE);
      mc.setProperty(com.ibm.ws.webservices.engine.WebServicesEngine.PROP_DOMULTIREFS, 
       Boolean.FALSE);
      super.primeMessageContext(mc);
      super.messageContexts[_createNewWorkOrderIndex0] = mc;
     }
     try {
      mc = (com.ibm.ws.webservices.engine.MessageContext) mc.clone();
     }
     catch (CloneNotSupportedException cnse) {
      throw com.ibm.ws.webservices.engine.WebServicesFault.makeFault(cnse);
     }
     return new com.ibm.ws.webservices.engine.client.Stub.Invoke(connection, 
       mc, parameters);
    }

Launch the test client

The last artifact that Rational Application Developer generates for you is a simple test application; because Rational Application Developer already created the test application when it created the proxy, all you need to do now is launch the application. (Note that if you selected the Test the Web service option in the Web Services Wizard, the test application is already up and running.)

The test application is a simple JavaServer Pages (JSP) file that uses the proxy. It is created within the WorkOrderManagerIfcClient project under WebContent\sampleWorkOrderManagerProxy.

To launch the application:

  1. Right-click TestClient.jsp and select Run > Run on Server.
  2. Select the existing server, then click Finish.
  3. The test application has three panes. In the left pane, select which Web service method you want to invoke -- in this case, createNewWorkOrder.
  4. The top-right pane contains a form matching the input arguments to the service. Notice that because the WSDL service implementation file contains all typing information, the form knows that the last argument is a date and tells you the data format that is expected. Type in some input data, then click Invoke.
  5. The lower right pane displays the output of the service -- the order number that was created (see Figure 17).

    Figure 17. Output of the service
    Output of the service

    Output of the service

You have now finished developing the Web service and have tested it to make sure that it works. The last step within Rational Application Developer is to package your application so that you can deploy it onto the computer running Application Server and publish your service in a UDDI registry. These last two topics are covered in Part 2 of this tutorial.

Package your application for deployment

Modify the WSDL

The service interface file (WorkOrderManagerService.wsdl) includes address information about where the service resides and where the WSDL files reside. When Rational Application Developer generated these files, it pointed these locations at the local server. For example, the SOAP address element will look as follows (assuming the server is listening on port 9080):

<wsdlsoap:address location=
   "http://localhost:9080/WorkOrderManagerIfc/services/WorkOrderManager"/ >

This functionality is good for testing your code, but after you're ready to deploy your application, you should modify the address information. If you are deploying on a node called xxx.yyy.zzz on port ppp, modify every instance of localhost:9080 to xxx.yyy.zzz:ppp (or xxx.yyy.zzz if deploying on port 80).

To modify the address information:

  1. In the WorkOrderManagerIfc\WebContent\wsdl\com\installco folder, double-click the WorkOrderManager.wsdl file, then open the WSDL Editor.
  2. Expand WorkOrderManagerService from the Services section.
  3. Expand WorkOrderManager.
  4. Select wsdlsoap:address to open the appropriate property editor (see Figure 18).

    Figure 18. Open a property editor
    open a property editor

    open a property editor

  5. As an example, change the URL from http://localhost:9080/WorkOrderManagerIfc/services/WorkOrderManager to http://xxx.yyy.zzz:ppp/WorkOrderManagerIfc/services/WorkOrderManager. Save the WSDL file.

Build the EAR file

The last step is to package your application as an Enterprise Archive (EAR).

  1. Rebuild your projects one last time by selecting Project > Clean.
  2. In the Project Explorer, expand the Enterprise Applications folder, right-click WorkOrderManagerIfcEAR and select Export > EAR File.
  3. Select a directory to export the file to, then click Finish.

Rational Application Developer creates the EAR file with an embedded Web Archive (WAR) file that includes all the Web service specifics as well as the implementation code for the server (see Figure 19).

Figure 19. Create the EAR and WAR files
EAR file

EAR file

Now do the same for the client project, WorkOrderManagerClientIfcEAR.

Wrap up

Summary

In this tutorial you developed a Web service using Rational Application Developer Version 6.0. You built a simple work order manager as a Java class, then proceeded to wrap it as a Web service. You used the Web Services Wizard within Rational Application Developer to build the Web service, setting all the properties and letting Rational Application Developer generate the code for you. While this was not the focus of this tutorial, you should have a clear idea of not only how to use the Rational Application Developer wizards but also what happens behind the scenes. You saw the WSDL definitions that Rational Application Developer created for the deployment phase and also learned about the proxy that helps client applications invoke your service. Finally, you packaged your application and Web service in an enterprise archive so that you can deploy it in Part 2 on a machine running Application Server Version 6.0.

In Build Web services with Rational Application Developer Version 6.0, Part 2: Deploying and publishing, you'll continue with the work order management scenario and proceed to deploy the EAR on the computer running Application Server. You'll publish the service in a UDDI registry so that potential users of the Web service can easily find it, and you'll learn how to invoke the service.


Downloadable resources


Related topics


Comments

Sign in or register to add and subscribe to comments.

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Rational
ArticleID=135656
ArticleTitle=Build Web Services with Rational Application Developer
publish-date=04252005