 | Level: Introductory Greg Flurry (flurry@us.ibm.com), Senior Technical Staff Member, IBM Austin, Texas
15 Oct 2003 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.
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.

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.

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.

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.

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.

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.

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.

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. |
Rate this page
|  |