Skip to main content

Support for J2EE Web Services in WebSphere Studio Application Developer V5.1 -- Part 2: The Client Environment

Greg Flurry (flurry@us.ibm.com), Senior Technical Staff Member, IBM Austin, Texas
Greg Flurry is a Senior Technical Staff Member in IBM's Emerging Technologies group in Austin, Texas. His responsibilities include advancing IBM's e-business technologies. You can contact Greg at flurry@us.ibm.com.

Summary:  The latest versions of WebSphere Studio and WebSphere Application Server support J2EE Web services as defined by JSR-101 and JSR-109. This two-part article examines this support through several examples, covering server-side support in Part 1 and client-side support in Part 2.

Date:  15 Oct 2003
Level:  Introductory
Activity:  317 views

Introduction

The latest version of IBM ® WebSphere® Application Server -- Version 5.0.2 -- supports Web services in the JavaTM 2 Enterprise Edition (J2EE) environment as defined by Java Community Process specifications JSR-109 and JSR-101. The latest version of WebSphere Studio Application Developer -- Version 5.1 -- supports WebSphere Application Server V5.0.2 and development of Web services for J2EE. This series of articles examines the support for J2EE Web services available in Application Developer V5.1 through a number of examples, with emphasis on the new level of support. Part 1 examined support for the server environment, while this article, Part 2, examines support for the client environment.


Web services in Application Developer V5.1

Part 1 offered a brief introduction to JSR-109 and its requirements for Web services in the J2EE environment. Part 1 also examined in detail the server-side support for JSR-109 and the WS-I Basic Profile in Application Developer V5.1, which also supports the client-side requirements of JSR-109. Improved tools in Application Developer V5.1 automatically generate the required client-side artifacts and support easy manipulation of those artifacts.


The client side

Now we examine Application Developer's support for the client side of J2EE Web services. First create a new Web project named " StockClient" and put it in the same EAR as the Services project created in part 1. In the Project Navigator view of any perspective, right click StockClient and select New => Other => Web Services => Web Service Client => Next. The Web Services Client Wizard starts and displays the Web Services panel. Make sure the options on this panel are set for the creation of a Java " proxy" and to test the generated proxy, then click Next. All the defaults in the next panel, Client Environment Configuration are acceptable, so click Next. On the Web Service Selection panel, click Browse to bring up the Resource Browser, shown in Figure 1, and navigate to the WSDL document for the StockFullQuote service. Select StockFullQuote.wsdl and click OK, then in the Web Service Selection panel, click Next. In the resulting Web Service Proxy panel, all the defaults are correct, so click Finish. The wizard implements the "WSDL-to-Java" tool functions that build the necessary client side artifacts as described in JSR-109. You may see an error regarding the WSDL file not being available; simply rebuild the StockClient project to fix the error. In addition, as requested in the Web Services panel, the wizard creates a JSP-based Web client to test the artifacts as in previous versions of Application Developer.


Figure 1. Resource Browser for selecting Web service.
ALT TEXT

Figure 2 shows the artifacts created for the client by the Web Services Client Wizard. The wizard creates the following Java classes for compliance with JSR-109:

StockFullQuote
This class defines the service endpoint interface (SEI) for the Web service client. It is identical in implementation to the StockFullQuote_SEI generated for the server side in part 1, and reflects the interface of the original StockFullQuote JavaBean as well as the remote nature of the Web service, per JSR-109.
FullQuote
This data bean can be used by the client to examine responses from the Web service, and is analogous to the FullQuote bean we created on the server side.
FullQuote_Deser, FullQuote_Ser, FullQuote_Helper
These classes serve the same purpose as on the server side, to allow Web service engines deserialize and serialize, respectively, the FullQuote JavaBean.
StockFullQuoteService
This class defines a factory interface for getting the SEI for the Web service, per JSR-109.
StockFullQuoteServiceLocator
This class is the implementation of the factory the client uses to get the SEI for the Web service. This is used for J2SE applications as defined in JSR-101.
StockFullQuoteSoapBindingStub
A client actually uses this stub to invoke the Web service. The stub implements the SEI to allow the client to invoke the Web service without any knowledge of SOAP, HTTP, or Web service implementation specifics, greatly enhancing interoperability.

Figure 2. StockClient project after Web service client creation.
ALT TEXT

In addition, per JSR-109, the wizard copied the WSDL file into the WEB-INF directory of the project, created a mapping deployment descriptor analogous to that created for the server, and finally created the Web services deployment descriptor for the client, webservicesclient.xml. Double-click on the file to open it with the Web Services Client Editor, new in this version of Application Developer. You will see the file opened with the Service References view shown in Figure 3; you can click the editor tabs to view other aspects of the deployment descriptor. In the Service References view, you can see the details of the service reference on the right, including the service reference name used in JNDI lookups (more on this later), the class for the factory (service interface name) the WSDL file, the mapping deployment descriptor, and the class name of the SEI. For this simple example, that is all the information needed to define the service reference and to allow a client to access the StockFullQuote service.


Figure 3. Web Services Editor for the StockClient project - Service Referenced view.
ALT TEXT

Testing the client artifacts

In addition to creating the JSP-based Web client to test the client artifacts, the wizard can deploy the client to the server and start a browser instance to run the client; if you find this did not happen, deploy the StockClient project to the server and start the server, then run the test client. The test client, shown in Figure 4, is virtually identical in appearance to that supported by previous versions of Application Developer. The implementation is different of course in that it uses the JSR-109 artifacts generated by the wizard.


Figure 4. Automatically Generated Test Client for StockFullQuote.
ALT TEXT

In the test client, select the getQuote method in the Methods pane. The Inputs pane will change to accept input; type any string into the symbol text entry field and click Invoke. The Result pane will contain the response; you should see something similar to Figure 5. The output of the client is similar to that of the WSDL Explorer used to test the Web service itself in part 1.


Figure 5. Test Client after invoking StockFullQuote.getQuote.
ALT TEXT

We shall examine how the test client uses the Java classes generated by the wizard. The following code snippets comes from Result.jsp which is generated by the wizard. The first statement creates an instance of StockFullQuoteServiceLocator factory. The second statement gets an instance of the stub from the factory. The third statement invokes the Web service via the stub.

... 
<jsp:useBean id="StockFullQuoteidLocator" scope="session" 
        class="wstest.StockFullQuoteServiceLocator" /> 
<%... 
wstest.StockFullQuote StockFullQuoteid = StockFullQuoteidLocator.getStockFullQuote(); 
...%> 
<%... 
wstest.FullQuote getQuote2mtemp = StockFullQuoteid.getQuote(symbol0idTemp); 
...%>

To prove one of the primary aspects of interoperability, we will now invoke the StockFullQuoteEJB Web service using the JSP test client that was just constructed to test the StockFullQuote Web service. This is possible because both Web service implement the same SEI, or in WSDL terms, the same PortType. In the Methods pane of the test client shown in Figures 4 and 5, you will see getEndpoint and setEndpoint methods. Click getEndpoint in the Methods pane and then click Invoke in the Inputs pane, and you will see the URL for the StockFullQuote Web service in the Results pane -- http://localhost:9080/Services/services/StockFullQuote. Now open the WSDL file for the StockFullQuoteEJB Web service and find the URL for the StockFullQuoteEJB port -- http://localhost:9080/MoreServices/services/StockFullQuoteEJB. Copy the URL. Now click setEndpoint in the Methods pane; paste the URL for the StockFullQuoteEJB port into the text entry field labeled URLString and click Invoke. Now invoke the getQuote method again, as described above. You should see results similar to those shown in Figure 5, but the response is coming from the EJB Web service.


A J2SE test client

We will now create a simple stand-alone J2SE client that accesses the Web service and examines more details of the use of the client artifacts. In the StockClient project, create a new class called SEClient and give it a main method. The following code snippet shows the implementation to invoke the StockFullQuote Web service.

import java.rmi.RemoteException; 
import javax.xml.rpc.ServiceException; 
import wstest.FullQuote; 
import wstest.StockFullQuote; 
import wstest.StockFullQuoteServiceLocator; 
 
public class SEClient { 
        public static void main(String[] args) { 
                StockFullQuoteServiceLocator factory = new StockFullQuoteServiceLocator(); 
                try { 
                        StockFullQuote sfq = factory.getStockFullQuote(); 
                        try { 
                                FullQuote fq = sfq.getQuote("xyz"); 
                                System.out.println( 
                                        "Quote for " + fq.getSymbol() 
                                                + "\n\tCurrent:\t" + fq.getCurrent() 
                                                + "\n\tHigh:\t\t"  + fq.getHigh() 
                                                + "\n\tLow:\t\t"   + fq.getLow()); 
                        } catch (RemoteException e1) { 
                                e1.printStackTrace(); 
                        } 
                } catch (ServiceException e) { 
                        e.printStackTrace(); 
                } 
        } 
}

This client follows the pattern established by the JSP examined above. In the first statement of the main method, we create an instance of the factory for the Web service stub. Next, use the factory to get a stub for the Web service; according to JSR-109, we must catch a ServiceExeption if the factory fails. In this case, the getStockFullQuote method on the factory returns the SEI StockQuoteFull, but StockQuoteFullSoapBindingStub is the actual implementation of the interface. When we call the getQuote method on the SEI, we are really calling the stub to invoke the Web service using SOAP/HTTP. If the Web service or the stub fails, then we must catch a RemoteException. When you run SEClient, you should see something like the output in the console shown in Figure 6.


Figure 6. Console output for SEClient.
ALT TEXT

A J2EE test client

The simple client above is not J2EE compliant. JSR-109 is really about J2EE and Web services, so we will now examine a J2EE compliant application. You can create different types of J2EE applications using Application Developer. The most obvious is a Web application. To be consistent with the previous example, however, we will create a J2EE Application Client. To do so, in the J2EE Hierarchy view of the J2EE perspective right-click on Application Client Modules and select New => Application Client Project. The default for the initial J2EE Specification version panel is correct, so click Next. In the following Application Client project panel, enter the name "EEClient" in the Project name text entry field. In the EAR project area, click the New button to bring up the Enterprise Application project dialog; you can simply click Finish in that dialog, as the default name assigned is acceptable.Finally, in the Application Client project panel, click Finish.

Now go to the Java perspective. We will create the "Main class" for the application client. Expand the EEClient project and right click on appClientModule. Add a Java class named EEClient and give it a main method. Now we need to define the "Main class" to the application client environment. Return to the J2EE perspective and expand Application Client Modules. Double- click on the EEClient project to start the Client Deployment Descriptor Editor. On the right, find the Main class section and click Edit . This brings up the Jar Dependency Editor; at the bottom, in the Main class section, click Browse; in the Type Selection Dialog type "EEClient" and click OK. You can now close the Jar Dependency Editor and the Client Deployment Descriptor Editor.

Return to the Java perspective. Add qname.jar, webservices.jar and wsdl4j.jar to the Java Build Path for the EEClient project. We must now copy some client artifacts generated in the StockClient project to the EEClient project because Application Developer V5.1 cannot create the client artifacts in an application client project. First copy the entire wstest package from the StockClient project to the appClientModule folder in the EEClient project. Now copy webservicesclient.xml from the StockClient project to the META-INF folder in the EEClient project; you will see two errors that complain about the WSDL file and the mapping deployment descriptor; you can fix these errors copying them as well, or by opening webservicesclient.xmland deleting the references to these files in the Service reference implementation details section as they are not needed for our example

Finally open the EEClient class.The following code snippet shows the complete implementation.

import java.rmi.RemoteException; 
import javax.naming.NamingException; 
import javax.xml.rpc.ServiceException; 
import wstest.FullQuote; 
import wstest.StockFullQuote; 
import wstest.StockFullQuoteService; 
 
public class EEClient { 
 
        public static void main(String[] args) { 
                javax.naming.InitialContext ic = null; 
                StockFullQuoteService factory = null; 
                try { 
                        ic = new javax.naming.InitialContext(); 
                        factory = (StockFullQuoteService) ic.lookup( 
                                        "java:comp/env/service/StockFullQuoteService"); 
                } catch (NamingException e) { 
                        e.printStackTrace(); 
                } 
                try { 
                        StockFullQuote sfq = factory.getStockFullQuote(); 
                        try { 
                                FullQuote fq = sfq.getQuote("xyz"); 
                                System.out.println( 
                                        "Quote for " + fq.getSymbol() 
                                                + "\n\tCurrent:\t" + fq.getCurrent() 
                                                + "\n\tHigh:\t\t"  + fq.getHigh() 
                                                + "\n\tLow:\t\t"   + fq.getLow()); 
                        } catch (RemoteException e1) { 
                                e1.printStackTrace(); 
                        } 
                } catch (ServiceException e1) { 
                        e1.printStackTrace(); 
                } 
        } 
}

For the J2EE environment, use a JNDI lookup to find the service factory. This is the only real difference between the J2EE and J2SE clients. The rest of the implementation is identical. Notice the value that is used in the lookup, in this case java:comp/env/service/StockFullQuoteService. For Web services, the standard client environment context java:comp/env/is always used. The rest of the value is defined by Service reference name field in Service reference implementation details section of webservicesclient.xml. For the StockFullQuote Web service, the Web Services Wizard uses an unofficial convention hinted by JSR-109 that results in the logical service name of service/StockFullQuoteService.

Now run EEClient as a WebSphere V5 Application Client. It takes a bit longer to start than a J2SE client. You will see some environmental information in the console, but eventually you will see that the Web service gets invoked with results similar to the J2SE client. Figure 7 shows part of the console when the J2EE application client EEClient is run:


Figure 7. Console output for EEClient.
ALT TEXT

Interoperability

Now we will again demonstrate the interoperability by invoking the StockFullQuoteEJB using both the J2SE and J2EE clients described above. This requires a small modification to the clients. Replace the single statement that gets the factory with the following statements in both clients.

URL squrl = null; 
try { 
    squrl = new URL("http://localhost:9080/MoreServices/services/StockFullQuoteEJB"); 
} catch (MalformedURLException e2) { 
    e2.printStackTrace(); 
} 
StockFullQuote sfq = factory.getStockFullQuote(squrl);

In this code segment, you can consider that the factory gets a stub for the StockFullQuote PortType with the actual endpoint implementation identified by the URL parameter. In this example, the code simply retrieves a stub that uses the address for the StockFullQuoteEJB Web service rather than the default address for the StockQuoteFull Web service. Once again, this works because the StockFullQuote Web service in the Web container and the StockFullQuoteEJB Web service in the EJB container implement the same PortType, or the same SEI. When you run the clients you will see results similar to those shown in Figures 6 and 7. This technique is useful for any client that wants to implement late binding of the actual implementation of a PortType.


Conclusion

As you can see, Application Developer V5.1 makes it very easy to create, and test interoperable Web service clients in a JSR-109 compliant environment like WebSphere V5.0.2. Application Developer can create virtually all of the necessary client side artifacts. If changes in those artifacts are needed, Application Developer provides specialized editors to greatly simplify the task. Application Developer V5.1 can really accelerate your Web services development for the J2EE environment, for both the server and client environments!

Top of page

Back to Part 1


Resources

About the author

Greg Flurry is a Senior Technical Staff Member in IBM's Emerging Technologies group in Austin, Texas. His responsibilities include advancing IBM's e-business technologies. You can contact Greg at flurry@us.ibm.com.

Comments (Undergoing maintenance)



Trademarks  |  My developerWorks terms and conditions

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=WebSphere
ArticleID=14376
ArticleTitle=Support for J2EE Web Services in WebSphere Studio Application Developer V5.1 -- Part 2: The Client Environment
publish-date=10152003
author1-email=flurry@us.ibm.com
author1-email-cc=

My developerWorks community

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere).

My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Rate a product. Write a review.

Special offers