This series of articles employs IBM tools and technologies to develop and deploy Web services-based applications. Specifically, the articles describe how to use the IBM WebSphere Studio Application Developer to develop and test Web services and Web applications, how to deploy the Web services on IBM WebSphere Application Server, and how to publish and find Web services in the IBM WebSphere UDDI Registry.
IBM believes Web services are a catalyst for the next generation of e-business, that of dynamic e-business. IBM has stated that the company will "enable dynamic e-business using open Internet standards so that our customers gain the highest level of business advantage" (see the Resources section below for more details). This series demonstrates how IBM is fulfilling this commitment. These articles focus on the following IBM tools and technologies:
- WebSphere Studio Application Developer Use to develop and test Web services and J2EE applications.
- WebSphere Application Server Version 4.0 Use to deploy Web services and J2EE.
The articles show how you can use these IBM tools and technologies to create Web services-based solutions for dynamic e-business.
The series covers the following:
- Part 1, this article, demonstrates how to use Application Developer to create and test a Web service.
- Part 2 demonstrates how to use Application Developer to publish the Web service in the UDDI Registry and find the Web service in the UDDI Registry, import WSDL (Web Services Description Language) files, and create a client of the published Web service.
- Part 3 demonstrates how to use Application Developer to create and test a Web application that uses the Web service.
- Part 4 demonstrates how to deploy the Web service into WebSphere Application Server 4.0 and access the deployed Web service from a Web application running in Application Developer.
WebSphere Studio Application Developer
WebSphere Studio Application Developer offers the application developer a number of capabilities, including Web application development and testing, XML development and testing, and Web services development and testing (which is the focus of this series). After you have installed Application Developer, you should spend some time going through Application Developer's online help documentation; it is extremely informative. In particular, you should read the Task topic, "Developing Web Services," and the Samples topic, "Tutorial: Creating a Web service from a Bean."
In this article, we'll create a Web service that produces weather forecasts. The Web service provides actual weather forecasts obtained in real time from the National Weather Service.
Creating a Web service using Application Developer
We'll execute the following steps to create the Web service:
1. Create a Web project.
2. Import the JavaBean and the additional resources required.
3. Generate the WSDL and deployment descriptor describing the Web service,
a proxy that assists a client in using the Web service, and a test client
for the Web service.
If you have not already started Application Developer, do so. First, create a Web Project by selecting File => New => Web Project. The Create a Web Project wizard prompts you to enter a project name. In the Project name field, enter WForecast. Here, enter the name of the Enterprise Application archive; for this example, use WForecastEAR.
Figure 1. The Create a Project Wizard

Click Next to go to the Module Dependencies pane. Click Next. You will now see the Define Java Build Settings pane.
Figure 2. The Define Java Build Settings pane of the Create a Web Project wizard

We need to add to the build path because will be working with
XML. Select the Libraries tab. On the subsequent pane, select Add
External JARs. Browse to <install_path>/plugins/com.ibm.etools.websphere.runtime/lib
and select xerces.jar, where <install_path> refers
to where you placed the source code. Then, click OK. Click Finish
to complete the creation of the Web Project.
Importing the Web service JavaBean and resources
Now we will import the Java and resource files for the Web service. To do so, you must first download and unzip the source code provided with this series of articles; see the Download section below.
Select the source folder in the WForecast project and
select File => Import. In the resulting Import wizard, select File
System and then click Next. In the File System pane of the Import
wizard, select Browse and browse to where you unzipped the source code.
Select the folder WForecast/source/and click OK. Expand
the source folder and select the checkbox next to forecast, and then
click Finish.
Figure 3. The File System pane of the Import wizard

Application Developer will import WeatherForecast.java,
a properties file and two HTML files. Your Application Developer Navigator view
now looks as follows:
Figure 4. The Application Developer Navigator view

You can double-click on WeatherForecast.java to examine
the JavaBean using Application Developer. The following figure shows key aspects
of the source code for the bean; the references offer more details. The constructor
(not shown) reads a properties file; the file contains a single property indicating
whether the Web service should actually contact the National Weather Service
(NWS) for the forecast, or used "canned" data. The method getStates()
returns a DOM Element containing a list of state abbreviations;
this information is hard-coded in the bean (as STATES). The getCities()
method returns a DOM Element containing a list of reporting cities
in the requested state; the city list is retrieved from the NWS, if online (using
the harvestResults() method), and from a file, if not online; the
method caches state and city information to improve performance. The getForecast()
method returns a DOM Element containing a forecast for a city;
the forecast is retrieved from the NWS if online and from a file if not; the
method uses the cached state and city information to improve performance.
package forecast;
public class WeatherForecast {
public Element getStates() {
DocumentImpl doc = new DocumentImpl();
try {
// formulate a response
System.out.println("in getStates");
Element response = doc.createElement("states");
doc.appendChild(response);
for (int i=0; i<STATES.length; i++) {
createElementWithContent(doc, response,
"state", STATES[i]);
}
} catch (Exception ex) {
ex.printStackTrace();
}
return doc.getDocumentElement();
}
public Element getCities(String state) {
DocumentImpl doc = new DocumentImpl();
int i;
for (i=0; i<URL_MAP.length; i++) {
if (URL_MAP[i][1].equals(state)) {
break;
}
}
String result = null;
if (!offline) {
result = harvestResults(URL_BASE + URL_MAP[i][0]);
}
...
stateCached = state;
cityCache = findCities(result);
Enumeration cities = cityCache.elements();
cityCache = new Vector();
try {
// formulate a response
Element response = doc.createElement("cities");
doc.appendChild(response);
response.setAttribute("state", state);
while (cities.hasMoreElements()) {
String [] ce = processCity((String)
cities.nextElement());
cityCache.addElement(CE);
createElementWithContent(doc, response, "city", CE[1]);
}
} catch (Exception ex) {
ex.printStackTrace();
}
return doc.getDocumentElement();
}
public Element getForecast(String state, String city) {
DocumentImpl doc = new DocumentImpl();
Vector tmpCities = null;
if (state.equals(stateCached)) { // used cached city info
//System.out.println("using cached info for "+city+",
"+state);
} else { // must get new city info
getCities(state);
}
tmpCities = (Vector) cityCache.clone();
// find the city url in the cache
String url = null;
for (int i=0; i<tmpCities.size(); i++) {
String [] info = (String []) tmpCities.elementAt(i);
if (info[1]Equals(city)) {
url = info[0];
break;
}
}
// get the forecast
String result;
if (url == null) {
throw new Exception("Invalid city");
} else {
if (!offline) {
result = harvestResults(url);
} ...
}
try {
// formulate a response
Element response = doc.createElement("forecasts");
doc.appendChild(response);
// process the forecast
int beg = result.indexOf("<PRE");
String [] content = null;
// get the header
content = extractContent(result, beg, "<B>", "\n", "</F");
createElementWithContent(doc, response, "location",
content[0]);
createElementWithContent(doc, response, "issued",
content[1]);
// get the "middle" day forecasts
beg = Integer.parseInt(content[2]) + 10;
for (int j=0; j<4; j++) {
// extract DOW forecast
content = extractContent(result, beg, "<B>",
"</FONT></B>", "<B>");
beg = Integer.parseInt(content[2]);
Element el = createElementWithContent(doc, response,
"forecast", content[1]);
el.setAttribute("period", content[0]);
}
// get the last day forecast
content = extractContent(result, beg, "<B>", "</FONT></B>",
"</PRE>");
Element El = createElementWithContent(doc, response,
"forecast", content[1]);
el.setAttribute("period", content[0]);
} catch (Exception ex) {
ex.printStackTrace();
}
return doc.getDocumentElement();
}
} |
Creating the WSDL, deployment descriptor, proxy and sample client
The WeatherForecast Web service methods all return a generic
DOM Element; this is something that you may want if you don't care
to have the Web service infrastructure do validity checking of your information.
For a description of the process of creating a Web service with simple data
types, see the Application Developer online help documentation.
To turn the JavaBean into a Web service, return to the Web Project perspective, select the WForecast project, and select File => New => Web Service. You will now see the first pane of the Web Service wizard. Verify that the WForecast Web project is identified and click Next.
Figure 5. The first pane of the Web Service wizard

You will see the Web Service Type Selection pane. It should
have WeatherForecast.java highlighted. Click Next.
Figure 6. The Web Service Type Selection pane of the Web Service wizard

On the subsequent Java Bean Selection pane, simply click Next.
The Web Service JavaBean Identity pane allows you to configure the JavaBean-based Web service. You can accept all the defaults with one exception. You must change the Scope field to Session and then select Next. The Session scope ensures a new instance for each user, allowing caching to work properly.
Figure 7. The Web Service JavaBean Identity pane of the Web Service wizard

The Web Service Java Beans Methods pane allows you to select
the methods to deploy. In this case, accept the default (all public
methods). You can also modify the encoding style used for inputs and outputs.
The default (SOAP encoding of the input strings and Literal XML encoding of
the output DOM Elements) is correct. You should simply click Next.
Figure 8. The Web Service Java Beans Methods pane of the Web Service wizard

On the subsequent Binding Proxy Generation pane, click Next. A SOAP-based proxy for the Web service will be generated.
On the subsequent Test Client pane, click Next because we don't want the Test Client to be started. The Test Client is a generic framework for testing EJBs and Web services (see the Application Developer online help documentation) and can deal with more complex data types, but it does not provide an example on using the generated proxy. We will use the Sample client instead.
You will now see the Web Service Sample Generation pane. Check Generate a sample and Launch the sample, then click Finish.
Figure 9. The Web Service Sample Generation pane of the Web Service Client wizard

Application Developer generates the WSDL files describing the Web service, generates a SOAP deployment descriptor, and deploys the Web service in the Application Developer WebSphere Test Environment.
Application Developer also generates a proxy that a client can use to access the Web service and generates the sample client (a set of JSPs) that can be used to test the proxy and the Web service.
When you created the Web service, in addition to creating the WSDL description of the service, the proxy, the sample client, etc., Application Developer automatically deployed the Web service and the client in the built-in WebSphere Test Environment and starts the environment. The run-time architecture looks as follows:
Figure 10. The run-time architecture

Notice that the Web service itself and the client of the Web service both run in the Application Developer test environment. The WeatherForecast Web service accesses the National Weather Service over the Internet.
To test the Web service, in the Application Developer Navigator
view, expand the WForecast project, expand the webApplication/sample/WeatherForecast
folder, right-click on TestClient.jsp, and select Run on Server.
When you run TestClient.jsp, Application Developer starts a browser
pointed to the JSP page. When the browser starts and the JSP finishes compiling,
you will see the Test Client, as shown in the following figure:
Figure 11. The Test Client displaying the compiled JSP

The sample client exposes all the methods offered by the Web service proxy. You will see the "business" operations for getting the states, cities and forecast, as well as methods for setting and getting the "endpoint," or URI for the Web service; the latter allows you to route requests through filters, etc.
To test the Web service using the sample client, select getForecast
in the Methods pane. The Inputs pane will change. Enter a state abbreviation
and a city name (the state and city names have to be available from the NWS,
and you can use the getCities() method to find valid cities for
a state. Click Invoke. In the Result pane, you will see the XML document
with the forecast; for this example, use TX and Austin. The results
are shown in the following figure:
Figure 12. The results displayed in the Test Client after clicking Invoke
| XML error: The image is not displayed because the width is greater than the maximum of 580 pixels. Please decrease the image width. |
If you want to run the Web service without a connection to
the Internet, you can edit the OFFLINE property in the forecast.properties
file. If you do so, you will need to restart the WebSphere Application Server
server that is running the Web service. The easiest way to do so is to select
(or open) the Server Perspective and then select the Server Control
Panel tab. Right-click on WebSphere v4.0 Test Environment and select
Restart.
This article walked through the steps necessary to use WebSphere Studio Application Developer to create and test a Web service. Application Developer automates, and therefore greatly simplifies a number of steps in the process, making the creation and testing of Web services much easier.
| Name | Size | Download method |
|---|---|---|
| workspace.zip | 10 KB | FTP |
Information about download methods
- Part
2 of the series describes how to publish and import a Web service using
Application Developer.
- Part
3 of the series describes how to create an application using the Web service.
- Part
4 of the series describes how to deploy the completed Web service to a
production WebSphere Application Server Version 4.0 and then run the application
using the production version of the Web service.
- Learn more about dynamic e-business and IBM's activities in support of dynamic
e-business at Web
services by IBM: Foundation for dynamic e-business.
- The Web Services
Zone on IBM developerWorks offers a number of articles and tutorials on
the standards and technologies underlying Web services.
Greg Flurry is an STSM currently working in IBM's Emerging Technologies group. His responsibilities include advancing IBM's e-business technologies, and specifically, IBM's Web services technologies. You can contact Greg at flurry@us.ibm.com.
