Web Services RedBook
Web Services RedBook
Introduction to
WebSphere Studio
Ueli Wahli
Mark Tomlinson
Olaf Zimmermann
Wouter Deruyck
Denise Hendriks
ibm.com/redbooks
International Technical Support Organization
April 2002
SG24-6292-00
Take Note! Before using this information and the product it supports, be sure to read the
general information in “Special notices” on page 583.
This edition applies to WebSphere Studio Application Developer Version 4.0.2 and WebSphere
Application Server Version 4.0.1 for use with the Windows 2000 and Windows NT operating
system.
When you send information to IBM, you grant IBM a non-exclusive right to use or distribute the
information in any way it believes appropriate without incurring any obligation to you.
Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvii
The team that wrote this redbook . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xviii
Special notice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xx
IBM trademarks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xx
Comments welcome . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xx
Part 1. Introduction. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Contents v
Defining getter methods as read-only . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
Binding the EJBs to a JDBC data source . . . . . . . . . . . . . . . . . . . . . . . . . 149
Validating the project. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150
Generating the deployed code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
Testing the entity EJBs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152
Associating the EAR project with a server configuration. . . . . . . . . . . . . . 152
Executing the EJB test client. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
Developing the session EJB facade . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158
Creating the session EJB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158
Completing the session entity facade . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160
Promoting the new methods to the EJB remote interface . . . . . . . . . . . . . 164
Defining the EJB references . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165
Validating the project. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166
Generating the deployed code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166
Testing the session EJB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168
Contents vii
Implementing security . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236
Build scripts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236
Managing class paths . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237
Using CVS macros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238
Watching a file for changes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238
Other CVS commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238
Contents ix
Selecting JavaBean methods and encoding styles . . . . . . . . . . . . . . . . . . 338
XML /Java mappings. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 340
Defining Java to XML mappings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 341
Proxy generation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 342
Defining the XML to Java mappings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 343
Verifying the SOAP bindings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344
Web service test client . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344
Generating a sample client . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344
Publishing the Web service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 345
Investigating the generated files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 345
Working with the previously created XML schema . . . . . . . . . . . . . . . . . . 346
Web service WSDL files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 347
Changing the service implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 347
Changing the service interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 348
Generating SOAP deployment descriptors . . . . . . . . . . . . . . . . . . . . . . . . 350
SOAP router servlets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 351
Viewing the deployed Web services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 352
Web service client proxy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354
Web service sample client . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 356
Using the TCP/IP Monitoring Server to view message contents. . . . . . . . 358
Creating the Almaden Autos Web service client . . . . . . . . . . . . . . . . . . . 363
Copying the WSDL service implementation . . . . . . . . . . . . . . . . . . . . . . . 364
Creating the Web service client . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364
Examining the generated client files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 365
Testing the Web service requestor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 365
Building the client application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 366
Creating the XSL style sheet. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 366
Creating the new servlet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 368
Completing the servlet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 368
Linking the new servlet into the Web application . . . . . . . . . . . . . . . . . . . 370
Testing the Web service client . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 373
Considerations when enhancing this sample . . . . . . . . . . . . . . . . . . . . . . 374
Creating a Web service from a session EJB . . . . . . . . . . . . . . . . . . . . . . 374
Create the session EJB Web service using the wizard . . . . . . . . . . . . . . . 375
Testing the session EJB Web service . . . . . . . . . . . . . . . . . . . . . . . . . . . . 375
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 377
Contents xi
Export EAR files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 435
Add the SOAP admin client. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 435
Deployment to WebSphere AEs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 438
Uninstall the previous enterprise applications . . . . . . . . . . . . . . . . . . . . . . 438
Install the enterprise applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 439
Define port 8080 for AEs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 439
Regenerate the plug-in and save the configuration . . . . . . . . . . . . . . . . . 441
Add the necessary JAR files to the AEs class path . . . . . . . . . . . . . . . . . 441
Test the applications with AEs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 441
Deployment to WebSphere AE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 443
Uninstall the previous enterprise applications . . . . . . . . . . . . . . . . . . . . . . 443
Install the enterprise applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 443
Define port 8080 for AE. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 444
Add the necessary JAR files to the AE class path . . . . . . . . . . . . . . . . . . 445
Test the applications with AE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 445
SOAPEAREnabler tool . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 445
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 446
Contents xiii
Sample data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 542
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 587
Contents xv
xvi Web Services Wizardry with WebSphere Studio Application Developer
Preface
This IBM Redbook explores the new WebSphere Studio Application Developer
for J2EE application development and Web services. The WebSphere Studio
Application Developer basic tooling and team environment is presented along
with the development and deployment of Web Applications (JSPs and servlets),
XML, data, EJBs, and Web services.
WebSphere Studio Application Developer is the new IBM tool for Java
development for client and server applications. It provides a Java integrated
development environment (IDE) that is designed to provide rapid development
for J2EE-based applications. It is well integrated with WebSphere Application
Server Version 4, and provides a built-in single server that can be used for testing
of J2EE applications.
Web services are a new breed of Web applications. Web services are
self-contained, self-describing, modular applications that can be published,
located, and invoked across the Web. Web services perform callable functions
that can be anything from a simple request to complicated business processes.
Once a Web service is deployed and registered, other applications can discover
and invoke the deployed service. The foundation for Web services are the simple
object access protocol (SOAP), the Web services description language (WSDL),
and the Universal Description, Discovery, and Integration (UDDI) registry.
This redbook consists of three parts: An introduction of the sample auto parts
application that is used throughout the book; J2EE development and deployment
with WebSphere Studio Application Developer; and Web services technology,
along with the development and deployment of Web services in WebSphere
Studio Application Developer.
Denise Mark
Olaf
Ueli
Wouter
Ueli Wahli is a consultant IT specialist at the IBM International Technical Support
Organization in San Jose, California. Before joining the ITSO eighteen years ago,
Ueli worked in technical support at IBM Switzerland. He writes extensively and
teaches IBM classes worldwide on application development, object technology,
VisualAge for Java, WebSphere Studio, and WebSphere Application Server
products. Ueli holds a degree in Mathematics from the Swiss Federal Institute of
Technology.
Tom Bellwood
UDDI Development Lead, Emerging Internet Technologies, Austin, TX
Peter Brittenham
Web Services Toolkit Architect, Emerging Technologies, Raleigh, NC
Barbara McKee
AIM Architecture, Software Group, Austin, TX
Frank Mueller
IBM Global Services, J2EE Architect, e-business Integration, Heidelberg,
Germany
Dan Gisolfi
Engagement Manager/Architect, jStart Emerging Technologies, Somers, NY
Deborah Cottingham
International Technical Support Organization, San Jose Center
Preface xix
Special notice
This publication is intended to help Java developers create client and server
applications on the WebSphere platform, including the creation and usage of
Web services. The information in this publication is not intended as the
specification of any programming interfaces that are provided by WebSphere
Studio Application Developer. See the PUBLICATIONS section of the IBM
Programming Announcement for WebSphere Studio Application Developer for
more information about what publications are considered to be product
documentation.
IBM trademarks
The following terms are trademarks of the International Business Machines
Corporation in the United States and/or other countries:
e (logo)® IBM® Redbooks™
Redbooks Logo AIX® AlphaWorks®
CICS® DB2® IBM Global Network®
IBM Registry™ IMS™ MQSeries®
NetRexx™ NetView® OS/390®
Planet Tivoli® S/390® Tivoli®
Tivoli Enterprise™ TME® VisualAge®
WebSphere® z/OS™ Lotus®
Notes®
Comments welcome
Your comments are important to us!
Part 1 Introduction
In part one we introduce the sample application that is used throughout the
redbook.
The auto parts sample application starts with parts management from a dealer
point-of-view, then evolves to include the manufacturer and other parts providers.
Web services are used to connect the dealer information system to the
manufacturer information system in a static predetermined way. When other
parts providers are added, the application becomes more dynamic in nature. In
the last stage, the dealer itself provides a Web service to other dealerships.
For the time being, we introduce the business functionality aspects of the stages
only. We will discuss the technical aspects in a subsequent section of this
chapter.
Figure 1-3 Use case: Dealership dynamically determines the inventory systems
Figure 1-4 Use case: Dealerships provide their inventory services to each other
System design
The sample application described in the previous section will be implemented
using IBM WebSphere Studio Application Developer. Emphasis is on these
Application Developer tools:
Java, Web, XML, and EJB development for the implementations of the
original dealer and manufacturer applications
Web services development:
– WSDL generation from an existing JavaBean
(WSDL = Web services description language)
– Generation of a Java stub implementation from a WSDL document
– Deployment of Web service into the Application Developer WebSphere
test environment
Web services client development:
– Generation of a client side SOAP proxy from a WSDL document
(SOAP = simple object access protocol)
– Generation of a test client for a Web Service (from WSDL)
UDDI browser (UDDI = universal description, discovery, and integration):
– Export operation (publish)
– Import operation (find)
Using the Database Web pages wizard we develop a Web application with the
following characteristics:
Servlets, JSPs, HTML to structure presentation and control layer
– MVC pattern
– no EJBs (EJB development is shown on the vehicle manufacturer system)
DB2 database
– JDBC 2.0 access
Figure 1-5 shows the operational model for Stage 1 of the auto parts system.
Servlets
JSPs
Mechanic
(Browser)
WebSphere AE 4.0 DB2 UDB 7.2
The dealership takes the role of the service requestor; the manufacturer is the
service provider. There is a fixed, pre-configured relationship between the two of
them; hence, the upper layers of the Web services protocol stack (UDDI for
example) are not yet involved.
Figure 1-6 shows the operational model for Stage 2 of the auto parts system.
The UDDI operations (publish and find) required in this stage are performed
using the UDDI browser that is part of Application Developer. The find operations
also need to be executed programmatically by the Web application.
Figure 1-7 shows the operational model for Stage 3 of the auto parts system.
JSPs
Mechanic
UDDI Registry
(Browser) UDDI
SOAP Client
SOAP DB
2 Server
3 3 1
1
Parts
Manufacturer
Parts Manufacturer Manufacturer Parts
Manufacturer National Depot & Inventory DB
App. Server
JDBC
EJBs
SOAP Server SOAP Server
Figure 1-7 Stage 3: Dynamic lookup of Web services in the UDDI registry
Figure 1-8 shows the operational model for stage 4 of the auto parts system.
Dealership Web DB
Applicat. Server Other
Servlets Dealership
Mechanic JSPs
(Browser)
2 UDDI
SOAP SOAP SOAP
Client Server 3 Client Registry
optional
SOAP
4 1 Server
Parts
Manufacturer
Parts Manufacturer Manufacturer
Manufacturer National Depot Parts & Inventory
App. Server DB
JDBC
EJBs
SOAP Server SOAP Server
Web Services
Registry
register
register
1 n Inventory
Manufacturer n search
n
1 1
Part
n Dealership
1 1
VehicleManuf. 1
n
PartsManuf. n Mechanic
implemented
There are two kind of manufacturers, the vehicle manufacturer and independent
parts manufacturers. Vehicle manufacturers have many dealerships that sell
their cars, and a dealership does business with many parts manufacturers. A
dealership employs many mechanics.
Our sample system implements a database with parts and inventory tables and
we use the UDDI registry for Web service registration and search.
Each participant in the application, Almaden Autos, Mighty Motors, Plenty Parts,
and Santa Cruz Sports Cars has a set of two tables, a parts table and an
inventory table. The inventory table points to the parts table though a foreign key.
FK
The prefixes stand for Almaden Autos (AA), Mighty Motors (MM), Plenty Parts
(PP), and Santa Cruz Sports Cars (SS).
A number of different data types were used in the tables for an illustration of
functionality in the products. Our choices may not be appropriate for a real
production application.
Summary
In this chapter we introduced the auto parts scenario that is used throughout the
book.
Quiz: To test your knowledge of the auto parts scenario, try to answer the
following five questions. The answers are provided in Appendix C, “Quiz
answers” on page 559.
1. What is stored in WSDL?
2. What is SOAP used for?
3. What is stored in a UDDI registry?
4. What brand of cars does Almaden Autos sell?
5. What is the name of the manufacturer of the cars?
New features
+
Vendor Plug-in
File-based IDE
XML Tooling
Web Services Tooling
Pluggable JDK Support
Flexible Open Team Development Environment
......
The Workbench is not meant for customers, but for tool builders who want to
plug-in their tools into the WebSphere Studio Workbench. This open source
project (http://www.eclipse.org) enables other tool vendors to develop plug-ins
for the WebSphere Studio Workbench. The tool providers write their tool as a
plug-in for the Workbench, which operates on files in the workspace.
Meta
Object
Framework
Graphics
Editing
Framework
Here are some explanations about the acronyms used in Figure 2-2.
Meta Object Framework (MOF)
MOF is an architecture for describing and defining meta-data. More
information about MOF can be found at http://www.omg.org. MOF is
used to share information in memory by plug-ins.
Workbench window
We will refer to the interface of Application Developer as the Workbench. It’s an
integrated development environment that promotes role-based development. For
each role in the development of your e-business application, it has a different and
customizable perspective. A perspective is the initial set and layout of the views
in the Workbench. Each perspective is related to a different kind of project. For
example, if you want to develop Java applications, you first create a Java project.
When you work in a Java project, you probably use the Java perspective
because that is the most useful perspective to do Java developing. We give an
overview of the different perspectives and project in the next sections.
Perspectives
Perspectives are a way to look through different glasses to a project. Depending
on the role you are in (Web developer, Java developer, EJB developer) and/or
the task you have to do (developing, debugging, deploying) you open a different
perspective. The Workbench window can have several perspectives opened, but
only one of them is visible at one point in time.
Note: The screen shots shown in this chapter were taken after most of the
applications in this redbook were developed.
Page designer
Perspective toolbar
Tags
You can open a new perspective by clicking on the top icon of the
perspective toolbar.
Each perspective has its own views and editors that are arranged for
presentation on the screen (some may be hidden at any given moment).
Several different types of views and editors can be open at the same time
within a perspective.
There are several perspectives predefined (resource, Java, Web, J2EE, Data,
XML, server, help, debug, team) in the Workbench. You can customize them
easily by adding, deleting, or moving the different views.
You can also compose your own perspective by defining the views it should
contain.
Navigator view
The small navigator panel shows you how your different resources are structured
into different folders. There are three kinds of resources:
Files Files correspond to files in the files system.
Folders Folders are like directories in the file system. They can contain
files as well as other folders.
Projects You use projects to organize all your resources and for version
management. When you create a new project, you will have to
assign a physical location for it on the file system.
Editors
By double-clicking on a resource the associated editor opens and allows you to
modify it. In Figure 2-3 the active editor is the page designer, associated with
JSP and HTML files. If no editor is currently associated with a particular file
extension, the Workbench checks if there is one associated in the operating
system and uses that editor to edit the file. You can also open OLE document
editors such as Word, which is associated with the .doc extension.
When you double-click another resource, a different editor shows up. You can
easily switch between the different opened resources by selecting them on the
top bar above the editor area. If the tab of your editor contains an asterisk (*), it
means that it contains unsaved changes.
Properties view
When you click on a resource in the Navigator view and then click on the
properties tab at the bottom of the screen you can view the different properties of
that resource. The Properties view contains general things such as the full path
on the file system, the date when it was last modified, and the size, as shown in
Figure 2-4.
Tasks view
The Tasks view is shown in Figure 2-3 on page 21. The Tasks view contains a list
of two types of elements:
Problems Problems are tool determined issues that have to be resolved.
Example problems are Java compile errors, or broken links for
HTML/JSP files. They are automatically added to the Task view
when working with the tool. When you double-click on a problem,
the editor for the file containing the problem opens and the cursor
is pointed at the location of the problem.
Tasks You can manually add tasks yourself. For example, you can add
a task that reminds you that you have to implement a Java
method. Place the cursor in the method’s implementation,
right-click and select Add -> Task. When you double-click, the file
opens and the cursor is located in the method. You can also add
general tasks that do not refer to a specific file.
Customizing perspectives
You can highly customize the different perspectives by:
Closing or opening views.
Maximizing the view by double-click on the title bar. You do this when you
need a large window for code editing. Double-click again to restore the layout.
Moving views to other panes or stack them behind other views. To move a
view:
– Select in the view's title bar and start dragging the view.
– While you drag the view, the mouse cursor changes into a drop cursor.
The drop cursor indicates what will happen when you release the view you
are dragging:
The floating view appears below the view underneath the cursor.
The floating view appears to the left of the view underneath the
cursor.
The floating view appears to the right of the view underneath the
cursor.
The floating view appears above the view underneath the cursor.
The floating view appears as a tab in the same pane as the view
underneath the cursor.
You cannot dock the floating view at this point.
When you want to reset a perspective to its original state, select Perspective ->
Reset from the main menu.
On top of the perspective, you see the Workbench toolbar. The contents of the
toolbar change based on the active editor for a particular resource. The current
editor is the page designer for editing our JSP page. The toolbar now reflects
JSP development and contains icons to add JSP tags and a JSP menu item.
The Outline view shows the outline of a JSP page. It contains all the tags from
which the JSP page is constructed. When you switch to the source tab of the
page designer and you select a tag in the Outline view, the matching line in the
Source view is highlighted.
We use the Web perspective in the chapters that follow, where we develop the
sample Web application and the Web services.
Java perspective
When you want to develop Java applications you use the Java perspective. The
Java perspective is shown in Figure 2-5. It contains a lot of useful editors and
views which help you in your Java development.
packages
fields
methods
error
You navigate in the Java perspective through the Packages view. The Packages
view allows you to define and manage Java packages and the Java classes
defined in the packages.
When you right-click a Java class in the Packages view and you select Open
Type Hierarchy, the hierarchy view for that Java class opens. The Hierarchy view
allows you to see the full hierarchy of a Java class. In Figure 2-5, the Hierarchy
view is currently hidden by the Packages view.
When you double-click on a Java file the Java editor opens. You can open
multiple Java files at the same time. The Java editor features syntax highlighting
and a code assistant by pressing Ctrl-space.
The Outline view in the Java perspective gives an overview of all the methods
and fields for the Java file that is currently opened. When you click on a method
in the Outline view, the cursor is positioned in the method signature in the Java
editor. The toolbar at the top contains filters to include or exclude static methods
or fields, and to sort the Outline view.
Clicking the search icon invokes the search dialog as shown in Figure 2-6.
Now you can either do a full text search, or a more intelligent Java search, to
look, for example, for a particular method declaration or references to it.
J2EE perspective
The J2EE perspective provides useful views for the J2EE or EJB developer. The
J2EE view on Figure 2-7 shows you a list of all the different modules such as
Web modules, EJB modules or server instances and configurations that make up
your enterprise application. You can expand the module you want to explore and
can edit the associated deployment descriptors for that module by
double-clicking.
The Navigator view, hidden by the J2EE view in Figure 2-7, shows a hierarchical
view of all the resources in the workspace. When you double-click a resource,
the registered editor for that file extension opens and the Outline view shows the
outline for the file you are editing.
Data perspective
You use the data perspective (Figure 2-8) for relational database design for your
application. You can either create a relational database schema yourself, or
import it from an existing database. Afterwards, you can browse, query or modify
it. The data perspective provides the views to manage and work with database
definitions. You can find more information on using the data perspective in
“Building the entity EJBs” on page 138.
In the DB Explorer view, you can create a connection to an existing database and
browse its schema. When you want to modify or extend the schema, you have to
import it into the Data view.
The Data view allows you to define new tables, or to modify existing tables. If you
double-click on a table in the Data view, the table editor opens and you can add
or change columns and primary or foreign keys.
The Navigator view shows all the resources in the folder structure.
tables Table
Tableeditor
editor
SQL stat.
XML perspective
The XML perspective is the perspective for XML development. The XML
perspective contains several editors and views that help you in building XML,
XML schemas, XSD, DTD and integration between relational data and XML.
In Figure 2-9, the XML editor is opened. You can switch between the design and
source panel of the editor to develop your XML file. The Outline view contains all
the XML tags that make up the XML document that is currently opened in the
XML editor.
More information about the XML support in Application Developer can be found
in “XML support in Application Developer” on page 91.
Server perspective
When you want to test a Web application or EJB module you need the server
perspective (Figure 2-10). The server perspective contains views and editors that
enable you to define, configure, and manage server instances and
configurations.
The Server Configuration view (left bottom) enables you to define or modify
server instances and configurations, and bind them to a project. When you
right-click on the server configuration file in the Server Configuration view, and
select Edit, the Server Configuration editor opens. More info about this topic can
be find in “Creating a server instance and configuration” on page 82.
The Servers view (right bottom) lists all the currently defined server instances.
Here you can start or stop their execution, or assign another server configuration
to a server instance.
The Console view (currently hidden by the Servers view) shows all the output
listed by a running server instance.
The Processes view shows all the processes that are started.
The Variables view allows you to inspect the values of variables when debugging.
Servers
Projects
Tabs to other views
Debug perspective
Use the debug perspective (Figure 2-11) when you want to debug your code. The
debug perspective automatically opens when you click the Debug icon in the
Java perspective to run an application in debug mode. It allows you to step
through your code, inspect the values of variables, modify your code and resume
execution.
Source
Breakpoint
Standard output
Help perspective
The help perspective contains a lot of useful information about Application
Developer. It provides information about the different concepts used by
Application Developer, the different Tasks you can do within Application
Developer and some useful samples. The search tab allows you to do a search
in the help. You can open the help perspective just as any other perspective.
Tips:
Close perspectives that you do not need.
Do not open multiple perspectives of the same type (it is allowed).
Close editors before switching perspectives (unless you know you come
back quickly).
Projects
A project is the top level construct for organizing the different resources. It
contains files as well as folders. In Application Developer you can create different
kind of projects, and they will have a different structure. A Web project, for
example, has a different nature than a Java project, therefore it will have a
different folder structure.
We will now briefly discuss the types of projects we use in the sample
application:
Java project
EAR project
Web project
EJB project
Server project
Java project
When you want to create a Java application, you first have to create a Java
project to contain the Java files. Each Java project has a Java builder and builder
path associated with it, which are used to compile the Java source files.
Source In the Source tab you specify where the source files should be
stored; either within the normal project folders or in folders
designated by you.
Projects In the Projects tab you specify whether other projects are required
in the build path. For example, a Web project requires an EJB
project.
Libraries In the Libraries tab you can add internal and external JAR files to
the build path:
An internal JAR is contained in the Workbench. The advantage
of an internal JAR is that it can be treated like a normal
Tip: Use the predefined variables instead of adding external JARs with
absolute paths to your build path whenever possible. Application Developer
contains various predefined variables such as the DB2JAVA variable which
defines the db2java.zip file.
You can add variables for other JAR files through the Windows -> Preferences
dialog.
You can modify the Java build path after you have created a project through the
Properties context menu of the project.
When you are finished creating the Java project, the Workbench switches
automatically to the Java perspective.
To create a class in the new package select the package and select File -> New
-> Java Class or press the New Class icon in the toolbar. In the SmartGuide,
check the package name and enter the desired class name and superclass. If
you want a main method in your class, select the main method under Which
method stubs would you like to create. Click Finish. The class appears under the
package and a Java editor opens and you can start coding.
Java editing
The following useful features are available when you edit Java code:
Double-clicking in the title bar of the Java editor maximizes the editor so that it
occupies the whole perspective. Double-click again to restore its original size.
Use Ctrl-space to launch the code assist in the Java editor when coding.
Refactoring code
Refactoring your code means reorganizing it so that the behavior of the
application stays the same. There is refactoring support available from the
context menu to rename packages, classes, and methods. When you rename an
element, Application Developer automatically fixes all dependencies for the
renamed element. For example, if you change the name of a package, all import
statements referencing that package will be updated.
All refactoring actions display a dialog with all the changes that will occur, and
you can decide which of the changes should actually be performed.
For example, suppose that you want to use the SAXParser class to parse an XML
document. To use this class, you have to add the xalan.jar that contains that
class to the build path. We could add the file to the project itself, but it is better to
refer to the file:
In the Java perspective select the project. From the context menu select
Properties. Select the Java Build Path property, then the Libraries page.
We could now add the file by clicking on Add External JARs as discussed in
“Creating a Java project” on page 34, but it is better to see if Application
Developer defined a variable to refer to that jar file.
Click on Add Variable, click Browse, select WAS_XALAN and click OK. The
variable is now added to the build path and we are able to use the SAXParser.
Once you have added a JRE, you can assign a particular JRE to a project to be
launched. Open the Properties menu of the context menu of the Java project and
select JRE.
Note that specifying another JRE for a project to be launched does not affect the
compilation. Compilation is still determined by the Java build path.
EAR project
To develop a J2EE enterprise application you have to create an Enterprise
Application project (EAR project). An EAR project usually consists of one or more
EJB modules, one or more Web applications, and an application client.
IBM also provides extensions to the standard deployment descriptor for facilities
that are not defined in the J2EE specification (http://java.sun.com/j2ee), such
as Web application reloading. The ibm-application-ext.xmi contains the IBM
extensions. To open the extensions:
Open the J2EE perspective and in the J2EE view expand Enterprise
Applications.
Right-click the EAR project and select Open With -> Application Extension
Editor.
J2EE packaging
An EAR project can be packaged as an enterprise archive file (EAR file). An
enterprise application consists of the following modules:
Web applications, which are packaged in .WAR files. The WAR file contains
the resources that compose the Web application and a deployment descriptor
(web.xml). A Web application is contained in a Web project, which we discuss
in “Web project” on page 40.
EJB modules, which are packaged in .JAR files. The EJB JAR file contains all
the EJBs and a deployment descriptor (ejb-jar.xml). EJBs are contained in
an EJB project, which we discuss in “EJB project” on page 44.
Optionally we can have a stand-alone client application that uses EJBs, for
example. An application client is also packaged in a JAR file. The application
client JAR contains all the Java classes of the application client and a
deployment descriptor.
J2EE
application.xml EAR Application
.EAR file
project Developer
HTML,GIF,..
Web project
You use a Web project when you want to create and maintain resources that
compose a Web application. A Web project contains the structure of folders to
contain all files that are needed to build a Web application. Typically, a Web
application consists of HTML pages, images, XML, servlets, JSPs and
JavaBeans. How to build a Web application is described in Chapter 3, “Web
development with Application Developer” on page 55.
When you create a new Web project a default directory structure is created that
reflects the J2EE view of a Web application. A Web deployment descriptor
web.xml is generated in the /webApplication/WEB-INF folder. You can find a
detailed description about the generated folders and files in “Viewing the default
Web project files” on page 60.
The use of EJB projects and the use of the EJB wizard is illustrated in Chapter 5,
“EJB development with Application Developer” on page 133.
Attention: Please note that the bin folder also contains the META-INF folder
with the ejb-jar.xml deployment descriptor. You should never open ejb-jar.xml
from this folder, because the bin folder is the build output folder. The build
output folder can be modified by selecting Properties from the EJB project
context menu.
Server project
To test an EJB or Web project, you have to define a server instance and a server
configuration to publish and run the code. Server instances and server
configurations are defined in server projects.
After creating a project the server perspective opens and you can now add a
server configuration and a server instance. This is demonstrated in “Creating a
server instance and configuration” on page 82.
Server instance
A server instance identifies the server used to test your application. Unlike
VisualAge for Java, Application Developer has the option to deploy to and test
with both local and remote instance of the WebSphere application server, and
additionally Apache Tomcat. Here is a brief explanation of each of the server
instances:
Because Tomcat does not have EJB support, you cannot deploy EAR files to it,
only WAR files containing servlets and JSPs.
Attention: Before you can do a remote unit test you have to install and run the
IBM Agent Controller, which comes with Application Developer, on the remote
machine. IBM Agent Controller is a process that runs on the remote machine
and which enables client applications to start new host processes.
The Secure Socket Layer (SSL) and the secure HTTP (HTTPS) features that
are offered by WebSphere Application Server are not enabled in the
WebSphere test environment.
Should your application require access to this feature, use the WebSphere 4.0
Remote Server with a local instance of a WebSphere Application Server.
These are beta code limitations; in the product only the first limitation will
remain.
Server configuration
A server configuration contains the information about the server. It defines:
Port numbers for the different processes such as the naming service
Mime types
JDBC drivers
Data sources
Security enablement
All the information is stored in the server-cfg.xml, which is created when you
add a server configuration. The properties can be set by opening (double-click)
the configuration in an editor.
Server
instance 1 Project 1
Server
Configuration 1
Server
instance 2 Project 2
Server
Configuration 2
Server
Project 3
instance 3
On the next page you can set the port (default is 8080) and click Finish.
The new server appears in the server perspective and you can assign EAR
projects to the server. Those projects will be loaded when the server is started.
Later, when you define your own server instance and configuration, you can
change the project preferred server instance by selecting Properties in the
projects context menu and then selecting Server Preference (Figure 2-20).
Publishing
Publishing means copying all the resources that are required to test a project to
the right place so that the server can find them. In cases when you are testing
within the Workbench, the resources might already be at the right place.
However, when you are testing with WebSphere Application Server on a local or
remote machine, or with Tomcat on a local machine, publishing means to copy
the resources outside of the Workbench.
By default the Automatically publish before starting server option is turned on.
This option can be found in the Window -> Preferences -> Server item. When this
option is turned on, all files and folders on the server are synchronized with the
Workbench whenever starting or restarting that server.
You can manually publish by selecting the server instance in the server control
panel of the server perspective and selecting publish from the context menu as
shown in Figure 2-21.
The application at this stage is intentionally very simple, allowing basic read
access to a DB2 database in order for a mechanic to browse the parts inventory
at the Almaden Autos car dealership, as illustrated in Figure 3-1.
Servlets
JSPs
Mechanic
(Browser)
WebSphere AE 4.0 DB2 UDB 7.2
The intention of this chapter is not to provide an overview of the servlet and JSP
programming models, but to give the reader an opportunity to understand how
such components can be developed using Application Developer.
Database
PartsMasterViewBean PartsDetailsViewBean
<HttpServlet>
PartsController
Browser
Figure 3-2 Class diagram for Stage 1 of the auto parts sample
Connect
Part Number?
Result Set
Table of matching Items
Which Item?
Row
Item details
Figure 3-3 Sequence diagram for Stage 1 of the auto parts sample
This section assumes that Application Developer and DB2 7.2 have already been
installed by the user using the steps outlined in Appendix A, “Product installation
and configuration” on page 537.
Where x:/wsad is the drive and directory used to install Application Developer,
and y: is the drive used to create the workspace. It may be worth creating a
shortcut on your Windows desktop (or in the IBM WebSphere Studio Application
Developer folder) for launching the command in future, because the default
parameters to launch Application Developer used by the current start menu icon
revert your settings back to the default workspace in the installation directory.
Project configuration
First we must build a Web project to contain the application code. To do this,
launch Application Developer if it is not already running, and select the File ->
New -> Project menu from the workbench.
In the New Project dialog, select the Web category, then Web Project. Click on
the Next button.
Enter ITSOAlmaWeb in the Project name field and ITSOAlmaEAR as the
Enterprise Application project name.
The naming convention we will be using throughout the samples for our
Application Developer projects is as follows:
Web Projects: ITSOApplicationNameWeb
EJB Projects: ITSOApplicationNameEJB
EAR Projects: ITSOApplicationNameEAR
This allows us to see related projects grouped together in the main Navigator
view. While some project types (for example, Java projects) allow spaces in
their names, this is not currently supported for Web or EJB projects.
Deployment descriptor
For Web application development, the key files managed in a Web project are:
web.xml Deployment descriptor for the Web module, as defined in
J2EE 1.2. This file contains general information about the
Web application, including servlet mappings, security
information, and the welcome page. Application Developer
provides a special web.xml editor for modifying this file
which is launched by default when the file is opened it the
workbench.
ibm-web-bnd.xml WebSphere bindings for the Web application. This file
contains bindings to references used at the Web module
level as defined by IBM. J2EE provides a mechanism to
use local names for external resource objects (for example
EJBs and JMS), however, the J2EE specification does not
define how these objects are referenced at runtime. This
implementation is left to the vendor to implement in their
own way, and this file is IBM’s implementation.
ibm-web-ext.xml IBM-specific extensions to the Web module. This file is
used by WebSphere to support additional options beyond
If you have not created the ITSOWSAD database as described in “Define and
load the ITSOWSAD database” on page 542, open a DB2 command window,
navigate to the directory where the sample setup files have been downloaded
and extracted (..\sampcode\setup\ddl), and execute the following command:
db2 -tf ITSOWSAD.ddl
This DDL script creates a local database called ITSOWSAD, which has a
number of tables, two of which we are interested in at this time: AAPARTS and
AAINVENTORY. Each table is populated with some sample data.
This overwrites the JDBC driver file, db2java.zip with a new version
containing JDBC 2.0 drivers.
To verify that the database has been created successfully, open a DB2 command
window and execute these commands:
db2 connect to itsowsad
db2 select * from itso.aaparts
db2 select * from itso.aainventory
db2 connect reset
The sample project configuration is now complete and we are ready to start
developing the application itself.
We use the View Bean model to create our Web application. The Web
application generated by the Database Web Pages wizard using the View Bean
model is shown in Figure 3-6.
Client
Input Form
(HTML)
submit action
Controller
(Servlet)
dispatch dispatch
submit action
SQL SQL
Database
Once the environment has been successfully configured, we can execute the
Database Web Pages wizard.
From the Web perspective, first select the ITSOAlmaWeb project in the Navigator
view, then from the Open The New Wizard button on the Workbench toolbar
and select Database Web Pages from the Web category. (There is also a toolbar
icon Create Web Pages that access and display database fields.)
We will not be using a predefined SQL statement so skip the Choose an existing
SQL Statement panel.
Click Next.
Click on the Connect to Database button. This takes you to the Construct an SQL
Statement panel (Figure 3-10).
On the Tables tab, select the AAINVENTORY and AAPARTS tables from the
ITSO schema and click on the > button.
Switch to the Columns tab:
– Expand the AAINVENTORY table, select all the columns except
PARTNUMBER and click on the > button to add all columns from the
AAINVENTORY table to the query.
– Expand the AAParts table and add all the columns in the table to the
query.
In the Joins tab (Figure 3-10), draw a connection between the two
PARTNUMBER columns to indicate the join you wish to use in the result set
(click on PARTNUMBER and drag it to the other table on top of the matching
PARTNUMBER column).
Finally, we need to define a parameter in the SQL query that allows us to search
by a part number passed into the query from a browser:
Select the Conditions tab and click on the first column of the first row in the
table. A drop-down list appears, containing column names. Select
ITSO.AAPARTS.PARTNUMBER.
In the Operator column, select the = option from the drop-down list.
In the Value field type :partNo as a host variable.
Alternatively select the Build Expression option from the drop down list. This
opens the Expression builder dialog, which provides a number of options on
how to define the WHERE clause in the SQL query. To pass a parameter:
– Select the Constant - numeric, string or host variable option, click Next.
– We select String Constant in the following panel because PARTNUMBER
is stored as a CHARACTER(10) field in our database. Click Next again.
– First select Host variable name as the string constant type. In the field at
the top of the dialog, which should now be preceded by a colon, type a
variable name of partNo. Click Finish.
We are now returned to the Construct an SQL Statement panel. Click Next.
We can test the query by clicking on the Execute button. This displays the
Execute SQL statement dialog. Complete the following:
Click Execute and you are prompted for a value for the partNo parameter.
In the Value column of the table type 'M100000001' (with quotes) and click
Finish. (If the Finish button is not enabled, click elsewhere in the dialog first to
confirm the changes to the table cell.)
A single record should appear in the Query results table. Close this window.
Back in the SQL statement panel, click Next to specify the runtime database
connection information. For this example we will be using a JDBC 2.0 data
source and connection pool to connect at runtime instead of a direct DB2 JDBC
connection:
Select the Use datasource connection radio button and in the JNDI name field
type jdbc/ITSOWSAD.
Enter the User ID and Password of db2admin (or what was used when DB2
was installed, or leave empty). Click Next.
Important: Note the ID of this field. This is the ID that will be used to place the
part number in the request and the session data. This value can be changed,
however, the rest of the code examples assume it is partNo. Code generated
prior to WSAD v 4.0.2 may have the ID as partNo suffixed with a number, for
example partNo1. For information on modifying this in the generated code to
match the rest of the code in the book, see “Modifications required if using
code prior to Version 4.0.2” on page 80.
To change the page title, select the Page tab in the property sheet and edit
the Page Title field to Parts Inventory Inquiry.
To change the background color, select the Page tab in the property sheet
and change the Background Color field to white (255,255,255). Note that the
color does not change in the dialog.
Click Next.
Results table
The submit link on the input form passes the part number to a controller servlet
generated by the wizard. The controller servlet then invokes the Master View
JSP. This result table Master View JSP is the next page we have to tailor.
The default format for the result table contains all of the columns returned by the
query. In order to make this more attractive, we want to reduce the amount of
detail in the table, as it will be available in the details page. Suitable columns to
include on this page could include PARTNUMBER, NAME, QUANTITY and
COST.
Ensure only the following fields are selected and their column labels match
Table 3-1.
AAPARTS.NAME Name
AAINVENTORY.QUANTITY Quantity
AAINVENTORY.COST Cost
Clicking the up and down arrows to the right of the column list allows you to
sort the change the order in which they are displayed.
When changing the label, ensure you either press Enter on your keyboard or
click elsewhere in the property sheet before selecting another column,
because the changes are not committed if focus is immediately lost from the
property sheet. You can verify these changes in the preview pane.
In the Page tab of the property sheet, change the value of the Page Title
property to Inventory Inquiry Results.
To change the background color, select the Page tab in the property sheet
and change the Background Color field to white (255,255,255).
Click Next.
Details page
When the SQL query returns multiple records, the user has the option to select
an instance and look at the record in further detail. By clicking on the Details link
generated on the Master View page, the controller servlet is invoked again. The
controller servlet invokes a second JSP, the Detail View JSP, to display the
details of the record.
We now tailor the details page. Edit and sequence the properties of the fields as
shown in Table 3-2.
Table 3-2 Details form properties
Field name Label
AAPARTS.NAME Name
AAPARTS.DESCRIPTION Description
AAINVENTORY.QUANTITY Quantity
AAINVENTORY.COST Cost
AAPARTS.WEIGHT Weight
AAINVENTORY.LOCATION Location
AAINVENTORY.SHELF Shelf
AAPARTS.IMAGE_URL Image
For now we leave the AAPARTS.IMAGE_URL field in the details view, but we will
use this column later to display the actual image.
Also change the page title to Inventory Item Details.
Change the background color, to white (255,255,255).
Finally, click Next.
Controller page
The Specify Front Controller and View Bean Choices page presents the options
for generating the controller servlet and the view beans. In order to adhere as
closely as possible to a model-view-controller architecture, take the defaults.
Select Create new Front Controller to generate a new controller servlet.
Select Create view bean(s) to wrapper your data object(s) to generate view
bean wrappers for the data objects.
Click Next.
Prefix page
The Specify Prefix page displays the prefix used in generating the database Web
page files.
Change the prefix for the application to Parts.
Click Finish.
Select the Servlets tab to see the deployment information for the generated
servlets and the JSPs. A typical panel is shown in Figure 3-12.
The generated servlet and each of the generated JSPs has an entry in this file.
The entry provides a number of important pieces of information for the Web
application server:
The most obvious is the URL mappings field, which defines the URL that the
Web application can use to invoke the servlet or JSP.
The three parameters used by controller servlet define the command values that
control navigation from the controller servlet.
Also note that the initialization parameters for the JSPs contain the database
user ID and password parameters along with the data source name that we
specified in the Database Web Pages wizard.
BODY
{
BACKGROUND-COLOR: white;
COLOR: black;
FONT-FAMILY: 'Times New Roman'
}
....
A number of images are provided as part of the sample code of this redbook.
Here are the steps to import the GIF images into a new folder of the Web
application:
Select the webApplication folder in the ITSOAlmaWeb project.
Select New -> Folder item from its context menu.
In the new folder dialog, enter a folder name of images. Click Finish.
The image files should now appear under the webApplication/images folder of
the Web project.
The next step is to modify the PartsDetailsView.jsp file. Open the page
designer from the navigator by double-clicking on the JSP file. The appearance
of the page in the Design tab of the Page Designer view should be similar to
Figure 3-16.
A number of icons appear in the page, relating to embedded JSP and JavaScript
code:
The icon represents an HTML comment.
The icon represents a JavaBean, which has been inserted into the page
through the JSP <jsp:useBean> tag.
refers to a JSP expression, which is surrounded by <% and %> tags in the
source. Most of these expressions extract or set a property value from the
JavaBean (for example the part number).
<jsp:setProperty ...>
<jsp:useBean ...>
<%@ page ... >
double-click to edit
Modifications
First we add the Almaden Autos image logo to the top of the page:
Drag the almadenautos.gif file from the images folder in the Navigator view
to the page designer view, just after the HTML comment icon , or
On the Design tab, place the cursor after the HTML comment icon and click
on Insert -> Image File -> From File menu. Browse to the images folder of the
Web application and select the almadenautos.gif file.
Image URL
The field of interest at this time is the code to retrieve the image from the result
set. Double-click on the JSP expression icon next to the Image label. This opens
the script editor (Figure 3-17).
It would be better if we could move the image display to the left of the information
retrieved:
Close the script expression editor and select one of the labels on the table.
Select the Table -> Add Column -> Add to Left menu.
To make one large cell that spans the entire column, select all of the cells and
select the Table -> Join Selected Cells menu.
The next step is to add the new dynamic image into the page:
– Select the new column, and click on the Insert -> Dynamic Elements ->
Dynamic Image menu.
– The Attributes window appears. In the SRC attribute field of the Dynamic
page, enter the following:
"images/" + detailsViewDBBean.getITSO_AAPARTS_IMAGE_URL()
– Switch to the Image tab and enter a Horizontal spacing of 50 to separate
the image from the text descriptions. Click OK.
Finally remove the image row from the table. Select the Image label in the
table, then select Table -> Delete Row.
The completed page as it appears in the Design tab of the page designer is
shown in Figure 3-18.
image
Final thought
We have now completed developing our simple application. Although the
Database Web Pages wizard is very convenient for a prototype-style application
such as the sample, the number of changes required to make the pages behave
in the required manner significantly reduces its value.
We expect most developers will prefer to build their servlet and JSP applications
by hand rather than selecting the wizard, potentially using a servlet and JSP
framework such as Apache Struts (http://jakarta.apache.org/struts/).
The selected part number is stored in the HTTP session and is used by all
servlets as the key for database retrieval. Throughout the rest of the book we will
be modifying this application and will access the part number stored in the
session data through the attribute name generated by the wizard.
All sample code provided with the book uses the attribute name partNo to access
the part number in the session data. We have to verify the name of the attribute
the wizard generated for us (see “Input form” on page 69). Open the
PartsInputForm.html file and look for the lines generated for the part number
(Figure 3-19).
<TH>
Part Number:
</TH>
<TD>
<INPUT NAME="partNo8" TYPE="text" SIZE="20" MAXLENGTH="40" VALUE="">
</TD>
If the generated attribute name is not partno, you have two options:
Modify the generated code
Use the value generated here throughout the rest of the book
We recommend that you modify the value generated by the wizard. To do this,
use the Search facility to search all JSP, HTML and Java files for the field name
(Figure 3-20).
The search will find many matches in five files (Figure 3-21).
Open the files and change all hard-coded references of the value partNoX to
partNo.
The following sections describe how to configure and run the WebSphere
Application Server inside Application Developer:
Creating a server project
In the Create a new server project dialog, enter ITSOWSADServer as the project
name, and click Finish.
Select the ITSOWSADServer item in the Navigator view then use the File -> New
-> Server Instance and Configuration menu (or click the icon). The wizard
shown in Figure 3-22 opens.
Unlike VisualAge for Java, Application Developer has the option to deploy to and
test with both local and remote instance of the WebSphere application server,
and additionally, Apache Tomcat. For more explanation about the different
options, see “Server project” on page 47.
The project should now appear under the server configuration in the view. We will
be using this approach again later to associate other Web applications with the
same server configuration and instance. This allows us to test multiple J2EE
applications simultaneously on a single instance of the application server.
There are new two JDBC 2.0 drivers supplied with the latest release of DB2.
The first is COM.ibm.db2.jdbc.DB2ConnectionPoolDataSource, which we will
be using here, and is suitable for most applications. A second driver is also
supplied which supports distributed transactions across both JDBC and JMS
using JTA - COM.ibm.db2.jdbc.DB2XADataSource. Unfortunately, a detailed
discussion of this support is outside the scope of this redbook.
To add a new DB2 JDBC data source, select the Db2JdbcDriver item from the
list, click Add next to the data source list, and complete the dialog box
(Figure 3-25).
Note: This action starts the server in debug mode and enables breakpoints
in servlets and JSPs. To start the server in normal mode, select the
ITSOWSADWebSphere server in the Servers view and select Start. Then
select an HTML file and Run on Server. The application executes slower in
debug mode.
When WebSphere is launching, the Console view should appear and display
messages relating to its execution.
After the start-up has completed, the embedded browser should be open at
http://localhost:8080/ITSOAlma/PartsInputForm.html.
Figure 3-26 shows the input form for our parts inventory inquiry application as
it appears in the embedded browser.
Note: You can also use an external browser with the same URL to connect to
the internal server.
Figure 3-26 Parts inventory inquiry application in the internal WebSphere server
To test if our query works, enter a part number of M100000001 and click the
Submit link.
The PartsControllerServlet servlet gets control and calls the PartsMasterView
JSP, which uses the PartsMasterViewBean to execute the SQL query. The
JSP displays the result table. If the database query is correct, the results
should be displayed, as shown in Figure 3-27.
Congratulations! You have just completed developing and deploying your first
Web application to the WebSphere V4.0 test environment.
Summary
During this chapter we focused on building a simple application to retrieve
information from DB2 with JDBC, using both servlets and JSPs. We also
demonstrated how to publish the application to the WebSphere test environment.
Background
XML stands for eXtensible Markup Language. XML is developed through the
World Wide Web Consortium W3C. It is a meta language, meaning a language
for defining other languages. XML by itself does not define any tags; it provides a
facility to define custom tags and the structural relationships between them.
XML is derived from SGML, the Standard Generalized Markup Language, whose
predecessor GML was invented by IBM in the 1960s for describing documents in
a device-independent fashion. XML is a subset of SGML and compatible with it.
Initial focus is on serving structured documents over the Web.
W3C issued XML 1.0 on February 10th, 1998. The second edition of it was
published on October 9th, 2000.
Relationship to HTML
Actually, HTML and XML cannot be compared. While XML is a meta language,
HTML is a well-defined language. HTML has a fixed set of tags. The meaning of
the HTML tags is defined in the W3C standards specifications (or the
implementation of a particular browser, whichever came first).
We will explain the elements in this XML file in detail in the next sections. The file
spawns the following content structure (Figure 4-2):
message book-info
book-title
date day
month
year
date day
month
year
email
filename
There are six kinds of markups that can occur in an XML document:
Elements Elements are the most common form of markup. Elements
identify the content they surround:
<Date>22.11.2000</Date>
Elements begin with a start tag <Date> and end with an
end tag </Date>.
Non-empty elements contain child elements or character
data. Empty elements have no content and can be written
in one of two forms: <empty-element></empty-element> or
<empty-element/>.
Attributes Attributes are name-value pairs that occur inside element
tags after the element name, such as the Price element
has a currency attribute:
<Price currency="DEM">24.95</Price>
All attribute values must be quoted with " " or ' '. They
specify the characteristics of an element.
Entity references Entity references insert reserved characters or arbitrary
unicode, refer to repeated or varying text, or include the
content of external files:
' <!-- Apostroph -->
℞ <!-- German umlaut -->
Entity references begin with the ampersand and end with a
semicolon.
The XML specification predefines five reserved entity
references < > & " and '
representing the characters <, >, &, “, and ‘. Custom
entities can be declared.
Comments Comments are not part of the textual content of an XML
document. They begin with <!-- and end with -->:
<!-- This is a comment. -->
An XML processor is not required to pass comments along
to an application.
Note: Similar rules exist for HTML; the XHTML specification defines them.
However, HTML browsers also accept HTML documents that are not well
formed.
A DTD identifies the root element of the document and may contain additional
declarations. It must be the first item in the document after PIs and comments. A
mix of external and internal DTD elements is possible.
Here is an excerpt of the DTD of our example from Figure 4-1 on page 93:
<!ELEMENT welcome (message,book-info*)>
<!ELEMENT message (#PCDATA)>
<!ELEMENT book-info (...)>
Because DTDs are superseded by XML schemas, we do not go into more detail
here.
Validation
A well-formed document is valid only if it contains a proper document type
declaration and if the document obeys the constraints of that declaration.
All valid documents are well-formed; not all well-formed documents are valid.
Tag names should be globally unique, but for performance reasons they also
should be short; in order to resolve this conflict, the W3C namespace
recommendation defines an attribute xmlns which can amend any XML element.
If it is present in an element, it identifies the namespace for this element.
The globally unique name uses URI syntax, but it is not a real URI that can be
accessed with a browser through HTTP. Predefined global names exist, for
example for the data types defined in XML schema (see below), and in the SOAP
standard. (See Part 3 of this book.)
The namespace definition in the first line assigns the global name
http://www.my.com/acct-REV10 to the local qualifier acct. This qualifier is used
on the element names such as name in order to attach them to the namespace.
In this example, all tags in the customer record are qualified to reside in the
namespace http://www.my.com/acct-REV10. No explicit prefix is needed
because the default namespace is used. Note that the default namespace
applies to any attributes definitions.
XML schema
So far, we have only introduced DTDs as a notation for meta information about
XML documents. DTDs have drawbacks; for example, they use a different syntax
than the other definitions in an XML file. They also lack data typing capabilities as
well.
XML schemas (XSDs) bring to XML the rich data descriptions that are common
to other business systems. A schema allows to precisely define cardinality
constraints and enforce data type compliance. XSDs are defined by a W3C
recommendation dating May 2, 2001.
XSDs are XML documents themselves: they may be managed by XML authoring
tools, or through any XML processor (and can be validated as well). In other
words, there is an XML schema for XML schema.
Its worth noting that XSDs can be imported into XML files. At processing time,
the imported schemas must be accessible (for example using HTTP).
As a first example, we use the simpleType element to define and name a new
simple type:
<?xml version="1.0"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.ibm.com"
xmlns:TestSchema="http://www.ibm.com">
<simpleType name="ZipCodeType">
<restriction base="integer">
<minInclusive value="10000"/>
<maxInclusive value="99999"/>
</restriction>
</simpleType>
The restriction element indicates the existing base type and specifies two facets
minInclusive and maxInclusive. These facets constrain the permitted value
range of the new type.
Note that we have defined the default namespace for our schema as the
standard XML schema namespace http://www.w3.org/2001/XMLSchema; we
have also defined our own, schema specific namespace http://www.ibm.com.
The second part of our example shows several element declarations and two
complex type definitions. The resulting schema is suited to represent a list of
address records:
<element name="address">
<complexType>
<sequence minOccurs="1" maxOccurs="1">
<element ref="TestSchema:street"/>
<element ref="TestSchema:zipCode"/>
<element ref="TestSchema:city"/>
</sequence>
</complexType>
</element>
<element name="street" type="string"/>
<element name="zipCode" type="TestSchema:ZipCodeType"/>
<element name="city" type="string"/>
The type attribute is optional; it contains a reference to the type definition, which
is either defined in an XSD file such as ours (example: TestSchema:ZipCodeType)
or a predefined standard data type (example: string in the default XSD
namespace).
Note that the XSD file has to be accessible through HTTP. In the example,
file:///C:/temp/TestSchema.xsd is a true URL pointing to a location.
Namespaces such as http://www.ibm.com on the other hand just use the URI
notation to be globally unique. Assuming that noProtocol://www.ibm.com is
globally unique, it would be a valid namespace name as well.
The syntax of the schema location attribute defined by XML standards is:
xsi:schemaLocation="targetnamespaceURI locationURI">
This is a quite tricky notation because it is not obvious that two different entities
with a similar syntax, but different semantics appear in the same attribute. Even
worse, the locationURI often is not a full network address, but a simple local file
name.
The target namespace serves to identify the namespace within which the
association between the element and its name exists. In the case of declarations,
this association determines the namespace of the elements in XML files
conforming to the schema. An XML file importing a schema must reference its
target namespace in the schemaLocation attribute. Any mismatches between the
target and the actual namespace of an element are reported as schema
validation errors.
In this section, we only introduced the most important XML schema concepts;
there are many more features. The XSD specification consists of three parts:
primer, structures, and data types. There are numerous tutorials available on the
Internet. A good starting point is http://www.w3.org/XML/Schema.
Processing XML
XML is a way to store and describe data. We also want programs to act on such
data. There are two ways to do so:
An XML parser can produce a representation of the XML data that can be
accessed through language APIs (for example, Java).
An XML processor can apply an XSL style sheet and transform the source
XML document to any text format (another XMl file or an HTML, for example).
CDDescription CDDescription
Title
SelectedTracks Track
Track
XML parser
Two parser APIs are available: the document object model (DOM) and the simple
API for XML (SAX).
DOM
DOM is based on an object model: After parsing, the memory contains a tree of
DOM objects offering information about both the structure and contents of the
XML document. DOM provides a lot of in-memory data manipulation commands
operating on the DOM tree.
A drawback of DOM is its huge memory consumption for large XML documents.
It can stress the JVM memory management system because it creates many
small short-lived objects.
DOM is best suited for in-memory navigation and manipulation on the structure
and contents of XML documents.
SAX
SAX on the other hand is event driven. The parser passes once through the
document and generates events that correspond to different features found in the
parsed XML document.
By responding to this stream of SAX events in Java code, you can write
programs driven by XML-based data. SAX allows to map XML data into an
application specific object model in just one pass.
JDOM
JDOM provides a means of accessing an XML document within Java through a
tree structure, just as DOM. Unlike DOM, however, JDOM was specifically
designed for Java, and promises to provide a more intuitive, easier to use API
than DOM.
JDOM is an open source project initiated by Brett McLaughlin and Jason Hunter.
It has just become a JSR (JSR-102); its implementation currently is at beta level.
For more information, refer to http://www.jdom.org/index.html.
Parser implementations
There are various parser implementations. For example, Xerces is an Apache
open source project based on an early IBM parser implementation that was
called XML4J.
Summary
XML represents information and not just format. It makes data portable.
XML schemas and DTDs already exists for most business communities. More
such domain specific language catalogs are currently being defined by various
industry consortium and standards bodies.
XML standards are expanding and gaining rapid support. The use of XML is still
growing rapidly. For example, XML is one of the technical foundations for the
Web services.
In this section, we have presented a high level overview of the XML and related
technologies. For further study in XML, see “Related publications” on page 577.
Other XML utilities are also available, but not used in this book. These include:
XML generation tools There are several tools that allow you to
generate various artifacts either from an XSD or
a DTD:
JavaBeans
Table definitions for relational databases
Sample XML files
Refer to the help perspective for additional information about these tools.
Original Modified
SQL
DB XSD XSD
As a second step, we launch the XML editor in order to browse and validate the
generated XML file containing the XML representation of the query results. Using
the XML schema editor, we then inspect and modify the XSD file containing the
XML schema referenced in the XML file.
We finally show how to process an XML file adhering to the generated XML
schema. We do this by using the XML to XML mapping tool to create XSL that
represents the mapping, and then apply the generated XSL to the original XML.
We map the original XSD to the modified XSD to create the XSL (Figure 4-5).
Modify XSL
Map
Apply
Modified Modified
Modified
XML
XSD
Note that at development time we are not really interested in the data. What we
want to achieve is to reverse engineer an already existing data model and
transform it into an XSD. The XML file merely serves as an intermediate step and
as a sample.
In the second half of the book (Chapter 10, “Static Web services” on page 321, in
particular), we will use this schema to return inquiry results from the service
provider to the service requestor.
Class diagram
A high-level UML class diagram is contained in Figure 4-6. It should be read from
the bottom to the top. For example, the XSD and XML file are created by the RDB
to XML mapping editor, which executes the SQL statement.
Note: The diagram only shows the first phase, RDB to XML conversion, including
XML to HTML conversion. It does not include all the XSDs that are used to
create the XSL file for XML to XML conversion.
Sequence diagram
Figure 4-7 shows the interaction diagram for the sample scenario of mapping
SQL output to XML and to HTML.
Before we can start to work with the XML tools, we have to create a new project,
a database connection, and an SQL statement in the data perspective of
Application Developer. Then we execute this statement and let the XML from
SQL Query wizard convert its results into XML.
Now we create the SQL statement using the SQL Statement wizard. This wizard
is the same used by the Database Web Pages wizard in “Generating the basic
Web application” on page 63.
Note: Make sure to directly connect to the database from the SQL
statement creation dialog; do not use an existing data base model. This
would require creating a connection instance and importing the
connection elements into the local project. We will explore this when we
create EJBs in Chapter 5, “EJB development with Application
Developer” on page 133.
Click Finish to generated the underlying files. In the Navigator view you should
be able to see an SQL statement entry ITSOWSAD_InquireParts.sqx in the
SQLXML folder.
Note that even more files have been generated that end with xmi. They contain
meta information about the connection, database, and tables we have used. Do
not modify any of these files.
This panel allows you to: configure the XML representation of the table columns
(which can be useful for complex queries); know how the meta information about
the file should be stored (XSD or DTD); and whether a query template should be
stored for later use.
Make sure that the output folder is /ITSOMightyXML/SQLXML
Click Finish to generate the files, then close the SQL statement editor.
Five additional files of name InquireParts.xxx are generated, with .xxx being
one of the following filename extensions:
.xml The InquireParts.xml file contains the query results in XML format.
.xsd The InquireParts.xsd file holds the XML schema used by the query
result file.
.xsl An XSL style sheet that describes a simple XML to HTML conversion
for the contents of the .xml file.
.xst This file contains a template with meta information about the executed
database query.
Will will now explore the .xml and .xsd files in the base /ITSOMightyXML folder.
The original files will be used later in transforming the XML files.
As you can see, the XML file imports the XSD schema. Note that in this case
http://www.ibm.com/MMINVENTORY_MMPARTS is the target namespace, and
InquireParts.xsd is the location of the XSD file (refer to “XML schema” on
page 98 for a discussion on the syntax of the schema location attribute).
Edit the /ITSOMightyXML/InquireParts.xsd file from the Navigator and select the
Source view (Figure 4-11).
As you can see, the query results are presented as a sequence of record-like
complex type elements. These elements contain simple types representing the
attributes.
After having changed the element names, it is necessary to change the key
definition in the XSD:
Expand InquirePartsResult
Select the key MMPARTS_MMINVENTORYPRIMKEY
Remove the two fields
– MMINVENTORY_MMPARTS:ITEMNUMBER
– MMINVENTORY_MMPARTS:PARTNUMBER
Add the correct two fields
– InquireResults:ItemNumber
– InquireResults:PartNumber
Change the Selector from
– MMINVENTORY_MMPARTS:MMINVENTORY_MMPARTS to
– InquireResults:Part
Save the XSD
Make sure you click on a field other than the Selector. If the Selector field still
has the focus the change will not be saved.
Switch to the Source view and compare your changes with the file shown in
Figure 4-15. Note you can edit the XSD in the source view an you may make
changes there.
Validation
Try to verify the InquirePartsOrg.xml file again; it is no longer valid because the
schema has changed, and plenty of errors are reported in the Tasks view:
To validate the original XML file against the original XSD, change the schema
pointer in the XML file from InquireParts.xsd to SQLXML/InquireParts.xsd:
<SQLResult xmlns="http://www.ibm.com/MMINVENTORY_MMPARTS"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.ibm.com/MMINVENTORY_MMPARTS
SQLXML/InquireParts.xsd">
As soon as you save the change, the validation runs and the errors disappear.
In the XML perspective, select the XML to XML mapping icon to invoke the
XML to XML mapping tool (Figure 4-16).
Now we have to select the source and target XSDs (Figure 4-17).
Click Finish.
SQLResult InquirePartsResult
MMINVENTORY_MMPARTS Part
ITEMNUMBER ItemNumber
QUANTITY Quantity
COST Cost
SHELF Shelf
LOCATION Location
PARTNUMBER PartNumber
NAME Name
DESCRIPTION Description
WEIGHT Weight
IMAGE_URL Image_URL
As the mappings are created the source and target icons change from to
and . The mapping is also displayed in the Outline panel.
Save the mapping.
Generate the XSLT script for the mapping by selecting the Generate XSLT
script for Mapping icon (Figure 4-20).
Save the file (File -> Save XSL Trace Editor As) as InquireParts.xml in the
/ISTOMightyXML folder.
The XSL transformation appears to remove the namespace definitions for the
XSI and schema location, therefore we have to add those back in order to
make the newly generated XML validate properly.
Change the root element to look as follows by adding the underlined portion:
<InquireResults:InquirePartsResult
xmlns:InquireResults="http://www.redbooks.ibm.com/ITSOWSAD/schemas/InquireResults"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-Instance"
xsi:schemaLocation="http://www.redbooks.ibm.com/ITSOWSAD/schemas/InquireResults
InquireParts.xsd" >
If you validate the InquireParts.xml file after you have made these changes, the
validation returns Document is valid because the data file now conforms to the
updated schema.
In “Static Web services” on page 321 we will show how to programatically invoke
an XSL transformation.
We have to add the Xerces JAR file to the build path of the ITSOMightyXML
project:
Select the project and Properties (context), then Java Build Path -> Libraries
-> Add Variable -> Browse and select the WAS_XERCES variable. Click OK
to close the dialog and the Properties.
Create a package called itso.wsad.mighty.xml under the source folder and
import the file XMLParserTest.java from the sampcode\wsadxml directory (see
“Using the Web material” on page 570).
Figure 4-25 shows how to invoke the parser from a Java program.
package itso.wsad.mighty.xml;
import org.w3c.dom.*;
import javax.xml.parsers.*;
try {
String filename = "InquireParts.xml";
DocumentBuilderFactory bf = DocumentBuilderFactory.newInstance();
bf.setNamespaceAware(true);
DocumentBuilder xmlParser = bf.newDocumentBuilder();
Document xmlDoc = xmlParser.parse(filename);
String result = domWriter(xmlDoc.getDocumentElement(),
new StringBuffer());
System.out.println("Content of XML file is: " + result);
}
catch(Exception e) {
System.err.println("XML exception has occured:");
e.printStackTrace(System.err);
}
}
// domWriter method definition skipped
}
In earlier version of the Java XML APIs, parser instances were created
directly. The constructors that allow this are now deprecated and should not
be used anymore; instead the DocumentBuilderFactory is now used.
The domWriter method simply prints the XML elements and their values to
standard output. For example, the code for Element nodes starts the
recursion by invoking domWriter for all child nodes; the value of Text nodes is
printed to the result buffer.
XML file
Creating an XML file from with a Java program is no different than writing any
other text file, hence, you can use any of the Java I/O and/or string APIs. You can
also directly construct the DOM tree using the constructors, and create methods
of the Java XML API.
Here are some hints that can help you to simplify XML output development
activities:
Manually create and validate a sample file before starting to code.
Match the (potentially recursive) tree structure of the XML document by
organizing your code into multiple methods:
– You might consider implementing a public toXML method returning an
org.w3c.dom.Element for all your Java classes with data members that
need to be serialized using XML.
– The conversion of Java artifacts from and to XML is often implemented as
a general purpose utility.
Validate the output of your program with the XML tools such as XML editor,
XML schema editor, and DTD editor.
Outlook
In Chapter 5, “EJB development with Application Developer” on page 133, we
develop a session bean that returns part inventory data in JavaBeans, and in
Chapter 10, “Static Web services” on page 321 we convert those results to an
XML DOM tree using the DOM API and the XSD schema we defined in this
chapter.
The first phase in the development of this J2EE application is to create the data
access layer and some simple business logic to enable queries. As the client to
this application will eventually be a Web service, we will not focus on the client
and presentation layer of the application at this time. An outline of the application
is shown in Figure 5-1.
JavaBean Session
Client Facade EJB
Entity CMP
EJBs
In Chapter 10, “Static Web services” on page 321, we will develop the EJB client
(JavaBean) and create a Web service wrapper using Application Developer.
Figure 5-2 Class diagram fragment for the inventory item entity EJB
The class diagram for the part entity EJB is shown in Figure 5-3.
Figure 5-3 Class diagram fragment for the part entity EJB
JavaBean
EJB client, will be
implemented in
Chapter 10, “Static
Web services”
Figure 5-4 Class diagram fragment for the session entity facade EJB
Sequence diagram
Figure 5-5 Sequence diagram for Stage 2a of the auto parts example
Project configuration
Create an EJB project called ITSOMightyEJB as described in Chapter 2,
“Application Developer overview” on page 17, and associate it with a new EAR
project called ITSOMightyEAR.
Switching to the J2EE perspective, the Mighty Motors and Almaden Autos
projects should appear as shown in Figure 5-6.
Figure 5-6 J2EE view after EJB and EAR project creation
For simplicity, we are using a schema similar to the Almaden Autos parts
inventory system in the ITSOWSAD database, but with table names MMPARTS and
MMINVENTORY. This schema was created and populated when executing the DDL
during setup. We will use the schema for a bottom-up approach.
The mapping wizard opens (Figure 5-7). Because we have no EJBs currently
defined in our project, Top Down and Meet In The Middle are disabled at this
time.
Select Bottom Up, and deselect the Open mapping editor after completion
checkbox. We will look at the generated mapping later.
Click Next.
Next we select the Mighty Motors tables our EJBs will be accessing. On the
Selective Database Import panel:
Select the tables prefixed with MM (for Mighty Motors) as seen in Figure 5-9.
Click Next.
On the next panel of the wizard we have the option to add a prefix the names
of any generated EJBs. By leaving this field blank, the wizard will use the
table names defined in the schema.
Enter a package name of itso.wsad.mighty.ejb.
Click Finish (be patient, the generation and validation takes some time).
Table definitions
By expanding the ITSOWSAD database entry under Databases in the J2EE view
we can see the imported table definitions (Figure 5-10).
We now have a local copy of the database definition and we can view the table
definitions off-line by double-clicking on them and launching the table editor.
XMI files
It is also interesting at this time to open the Navigator view on our project. This
allows us to view how Application Developer has stored the metadata that
represents our schema (Figure 5-11).
It is not recommended to edit these files, however their XMI format enables us to
store the definitions in our configuration management tool later, as detailed in
Chapter 7, “Working in a team” on page 207. XMI is also described in detail in
Chapter 2, “Application Developer overview” on page 17.
Application Developer creates a separate XMI file for each table in the schema,
with the file extension .tblxmi, together with one for the schema itself, with a
.schxmi extension, and one for the database (Schema.dbxmi). Each of these files
has its own dedicated editor. These files are also copied into the bin directory
structure for inclusion in the EJB JAR file, although they should not be modified
directly from that location.
By default, the bottom-up EJB mapping technique creates a CMP entity EJB for
each table in the imported schema metadata. Note that because we only
selected the Mighty Motors tables (MM prefix), those are the only ones that
appear in the J2EE and Navigator views.
EJB definitions
By expanding the EJB module we can see from the J2EE and Navigator views
that the wizard has created two entity beans: Mmparts and Mminventory
(Figure 5-12).
Application Developer capitalizes only the first letter of the table name—this is
not ideal, but we would have to dedicate an entire chapter to refactoring this
code if we wanted to change them.
For each entity, the key, container managed fields, relationships, and
important classes are displayed. Note that the data types used to represent
the data are the complex types, such as java.lang.Long, instead of the
simple alternatives (long). This will give us more flexibility when performing
data type conversions later.
Each of these classes appear in the Navigator view as .java files in the package
folder defined in the mapping wizard. Two additional classes represent the
relationship between parts and inventory EJBs.
This behavior is very different to that of VisualAge for Java Enterprise, where this
metadata was stored internally inside the repository, which prevented developers
from easily building EJBs in a team environment with an external configuration
management tool.
Generated mapping
Open the generated mapping by double-clicking the Map.mapxmi file in the
Navigator view, or by selecting Open With -> Mapping Editor on the EJB module
in the J2EE view (Figure 5-13).
This editor opens automatically when you select Open mapping editor after
completion in the wizard (Figure 5-7 on page 139).
The top half of the editor shows the EJB and table definitions, and the bottom
half shows how the contained fields and columns are mapped to each other. Also
note the Outline view and the Properties view when selecting items.
The icons on each pane of the editor provide useful functions. Those used in the
EJBs and Tables panes are shown in Figure 5-14, while Figure 5-15 explains the
icons in the mapping pane. It is worth spending some time familiarizing yourself
with the features of these icons, because they are useful when navigating around
the mappings in the future.
Pop Up Menu
Figure 5-14 Icons used in EJB and Tables panes of EJB to RDB mapping editor
Pop up menu
Figure 5-15 Icons used in mapping pane of EJB to RDB mapping editor
In the lower panel, select one of the columns in a table on the right hand side, as
shown in Figure 5-16. Note that a drop-down list appears that allows you to
select which column is mapped to the corresponding field in the EJB.
Figure 5-16 Mapping a field to a specific column using the mapping editor
Close the mapping editor, but do not save any changes made to the map.
There are two ways the add the getters for the key field:
Have Application Developer generate the getter and setter for the field for the
implementation class (select the key field in the Outline view and Generate
Getter and Setter), then delete the setter method.
Manually add the getters to the implementation class.
Add the getter methods to the remote interface by selecting a getter method
(getItemnumber or getPartnumber) in the Outline view and Enterprise Bean ->
Promote to Remote Interface from the context menu (Figure 5-17).
Figure 5-19 Defining the JDBC data source for the EJBs
There are five validators specified: DTD Validator, EJB Validator, Map Validator,
XML Schema Validator, and XML Validator. These are provided by Application
Developer, although this is a defined WebSphere Studio Workbench extension
point, which can be used to add further alternatives.
When the validation has completed, no entries should appear in the task list.
Figure 5-21 Generating the deployed code for the EJB module
We have now completed developing the two entity EJBs using bottom up
mapping and generated the deployed code. The next step is to test them in the
local WebSphere instance.
Note: The EJB test client is also called the universal test client (UTC) because
it can be used to test Web services and other applications as well.
Wait until the server has completed starting (indicated either by the “Server
open for e-business” message in the Console view or a Started status in the
Server Control Panel view).
Alternatively, you can click on the Open Web Browser icon in the toolbar and
enter the following URL in the location field:
http://localhost:8080/UTC
The browser opens with the EJB test client home page (Figure 5-24).
Our first test should be to see if our EJBs have been added to the JNDI
namespace:
Click on the JNDI Explorer link. Expand the folders to see the JNDI names
(Figure 5-25).
Figure 5-25 JNDI explorer in the EJB test client to browse the JNDI namespace
If you fail to see the entries for the sample EJBs, return to the EJB extension
editor and ensure that the datasource has been defined correctly for the EJB
module.
This link invokes a page which prompts for the key constructor parameter.
Enter a valid part number of M100000003 and click on Invoke and Return
(Figure 5-27).
Back in the Parameters panel, click on the Invoke button to complete the call
to the findByPrimaryKey method.
In the results panel you should see an instance of Mmparts returned from the
server. Click on the Work with Object button.
This action adds the remote Mmparts object matching our part number to the
EJB references tree. Expanding the tree for this element displays the
methods available on the EJBs remote interface (Figure 5-28).
Click on the String getDescription link and on the Parameters pane, click on
the Invoke button. The results panel displays the description for the part
(Figure 5-29).
Figure 5-29 Results from the getDescription method call on the remote interface
Repeat the test for the MminventoryHome entry in the JNDI namespace with an
inventory number of 21000003. Invoking the returned remote interface method
getLocation should return a location of MM - San Francisco.
We have now tested our entity EJBs using the EJB container in the WebSphere
test environment. Being able to perform this level of unit testing is very beneficial
because it reduces the amount of debugging we might have to perform at a later
stage. Next, we must develop the business logic in our application.
The following section will describe how to build a session entity facade to the two
entity EJBs created earlier in this chapter. The session bean will contain only two
methods to find all the matching inventory item instances for a given part number.
One method returns the inventory items in a vector, the other in an array, to
enabling us to explore Web services later.
Click Next and take the defaults specified in the Enterprise Bean Details
dialog (Figure 5-31).
Click Finish.
When we return to the J2EE view, we see a PartsFacade entry under the
ITSOMightyEJB module containing entries for the home, remote interface, and
implementation class of the new session bean.
The EJB 1.1 specification requires that EJBs return serializable results.
Therefore, we return the part inventory as a Vector of serializable JavaBeans. So
first, we will create the serializable JavaBean class called PartInventory. The
code is available in sampcode\wsadejb\PartInvetory.java.
Now we must add the business logic to get the parts in the inventory based on a
part number and return a vector of PartInventory beans.
Figure 5-34 shows the inquireParts method and Figure 5-35 shows the
inquirePartsArray method.
The majority of the coding for this class is complete. Save all changes, but leave
the editor open.
There will now be a compiler errors in the PartsFacade remote class because
PartInventory and Vector cannot be resolved. To correct this, add these import
statements:
import itso.wsad.mighty.bean.PartInventory;
import java.util.Vector;
This may be unfamiliar to developers who have previously worked with version
3.5 of WebSphere and VisualAge for Java. The notation java:comp/env defines
that the lookup is to a local reference of ejb/Mmparts instead of an entry in the
global JNDI namespace.
Each of the EJBs therefore has two names, which are mapped using a reference
definition in the deployment descriptor, ejb-jar.xml.
new entry
Figure 5-36 EJB references defined for the application
We must also edit the binding details in the EJB extension editor:
Select the ITSOMightyEJB EJB module and Open With- > EJB Extension
Editor from the context menu.
Select each EJB and each reference and set the JNDI name as shown in
Table 5-1 (do not touch the Datasource JNDI name).
Table 5-1 EJB bindings defined for Mighty Motors
Element JNDI name
Mmparts itso/wsad/Mmparts
Mminventory itso/wsad/Mminventory
PartsFacade itso/wsad/PartsFacade
Save the changes to the EJB extensions and close the editor
We have now correctly defined EJB references and full JNDI names for each EJB
in the Mighty Motors system.
In the Navigator view we can see the deployed code for the EJBs in the
itso.wsad.mighty.ejb package in the ejbModule folder.
We have now completed developing the session EJB and generated the
deployed code. The next step is to test the session bean in the local WebSphere
instance.
Summary
The EJB application for Mighty Motors is now complete and ready for us to
implement as a Web service. We have explored the EJB to RDBMS mapping
capabilities, generated a session facade containing the business logic and tested
the application with the local test environment.
The next chapter discusses how we can now take this application and deploy it
from Application Developer into a stand-alone WebSphere environment.
It is also important to note that because there is only one application server in
WebSphere AEs, the administration server is contained in the WebSphere AEs
application server—that is, there is no separate administration server.
Administration of the single application server in WebSphere AEs is done
through a specified port of the application server itself.
Now we have EAR files of the two projects, we can install in WebSphere
Application Server 4.0:
ITSOAlma.ear
ITSOMighty.ear
or
Open a Command Prompt and type startserver. Startserver.bat is located in
WAS_ROOT\bin where WAS_ROOT is the directory where you installed
WebSphere, such as d:\WebSphere\AppServer. The Console output is shown
in Figure 6-2.
During the start up process the server will often pause on the line:
Waiting for applications to be started.
The server is completely started when you see the following lines displayed:
WSPL0057I: The server Default Server is open for e-business.
Please review the server log files for additional information.
Standard output: D:\WebSphere\AppServer/logs/default_server_stdout.log
Standard error: D:\WebSphere\AppServer/logs/default_server_stderr.log
or
Open a browser and enter http://localhost:9090/admin/
You are prompted for a user ID. Enter any user ID and click Submit. After you are
logged in, your browser displays the Welcome panel (Figure 6-4).
On the next panel of the wizard, leave the Virtual Host Name as default_host
and the Precompile JSPs option as Yes and click Next (Figure 6-8).
On the next panel (Confirm the following) click on Finish to deploy the
application.
The next page of the wizard is the Mapping EJB references to Enterprise
beans page (Figure 6-11).
These references were defined and explained in “Defining the EJB
references” on page 165. Leave the values as they are and click Next.
Figure 6-11 AEs application installation: mapping EJB references to JNDI names
In the next panel of the wizard we can specify the Database and Data Source
settings. Set the Schema Name(qualifier) field to ITSO and leave the other
values as they are and click Next (Figure 6-12).
The CMP data sources are left blank because we use the default data source
defined for the EJB container (jdbc/ITSOWSAD).
On the next panel of the wizard, uncheck the Re-Deploy option (Figure 6-13).
This option generates the deployable EJB code, but we already generated the
code in Application Developer (see “Generating the deployed code” on
page 151).
The list of enterprise applications should now contains both the Almaden Autos
and the Mighty Motors enterprise applications.
Important: If you specify another file than the default server-cfg.xml, you
have to specify the -configFile YourConfigFile.xml option with the
startserver and stopserver commands.
After saving the configuration, we can log out of the current session by clicking
on Exit in the black menu bar, and we can close the browser window.
To stop the Application Server open a command window and enter stopserver.
The Console output when stopping AEs is shown Figure 6-16.
To illustrate the command line tool, we deploy the EJB test client included in
Application Developer to WebSphere AEs. Installing the EJB test client enables
us to test deployed EJBs in AEs using the same GUI as in Application Developer.
Note that we could have used SEAppInstall for our sample applications because
we predefined all EJB bindings in Application Developer and we did not have to
change any of the deployment options.
We used the EJB test client when developing the EJBs in “Executing the EJB test
client” on page 153.
We will use the SEAppInstall command line tool provided with WebSphere AEs
to deploy the EJB Test Client. This is a tool for installing an application into a
server configuration file and preparing it to run within an application server. You
can also use it to uninstall an application from a server, and to export an installed
application containing configuration information.
SEAppInstall command
SEAppInstall has the following options:
-install
-uninstall
-export
-list
-extract DDL
-validate
To view the full syntax of these options, run SEAppInstall without any
parameters (SEAppInstall.bat is in the WAS_ROOT/BIN directory.
This plug-in enables the Web server to talk with the WebSphere Application
Server. In order to enable the HTTP transport between the plug-in and the
application server, every WebSphere Application Server Web container has a
built-in HTTP server—by default, the built-in HTTP server uses port 9080.
Figure 6-20 shows the setup for the HTTP server and the application server.
Plugin
XML
file
Embedded HTTP Server
plugin
configuration
HTML (plugin-cfg.xmf)
Servlets JSPs
Web Container
EJBs
EJB Container
Application Server
A plug-in has a plug-in configuration which tells the HTTP server which requests
it should forward to the application server. For example, the Web server forwards
the requests it gets for servlets and JSPs.
After you have generated the plug-in configuration, you can open the
plugin-cfg.xml file located in the WAS_ROOT/config directory. It should contain the
context roots of the installed applications (Figure 6-21).
<?xml version="1.0"?>
<Config>
......
<UriGroup Name="default_host_URIs">
...
<Uri Name="/UTC"/>
<Uri Name="/ITSOMighty"/>
<Uri Name="/ITSOAlma"/>
...
</UriGroup>
......
</config>
Important: Before you can test the enterprise applications you must make
sure that you have created the ITSOWSAD database on the machine where
WebSphere AEs is running (see “Creating the ITSOWSAD sample database”
on page 61).
The Admin Server can be started from the Programs menu (Start -> Program
Files -> IBM WebSphere -> Application Server V4.0 -> Start Admin Server) or
from the Windows Services panel (start the IBM WS AdminServer 4.0 service).
You can watch the progress using the Windows Task Manager, which is the same
as what we described in “Starting the AEs server” on page 172.
If you want to launch the Administrator’s Console from a remote machine open a
command window and enter adminClient hostname, where hostname is the host
where the Admin Server is running (either the full hostname or the IP address).
Module visibility
Next we have to change the Module visibility property to Compatibility, so that the
EJB test client will be able to see the other applications:
Select Application Servers, ITSOWSAD, on the General tab of Figure 6-24,
change the Module visibility property to Compatibility.
Click Apply to enable all the changes we made.
In the Specifying the Application or Module panel of the wizard, specify the
path for ITSOAlma.ear and set the Application name property (Figure 6-28).
The application name is the name that will appear in the list of enterprise
applications in the Administrator’s Console. Do not confuse this with the
context root (ITSOAlma) which is defined in the deployment descriptor.
Click Next and then Finish in the Completing the Application Installation
Wizard panel.
The Mapping EJB References to Enterprise Beans panel maps the EJB
references we defined to the JNDI names of the Enterprise Beans. These
references were defined and explained in “Defining the EJB references” on
page 165. Leave the values as they were extracted from the EJB deployment
descriptor inside the EAR file.
Click Next until you get the Specifying the Default Datasource for EJB
Modules panel.
The default data source JNDI name (jdbc/ITSOWSAD) matches the JNDI name
we gave to the data source that we defined in “Creating the JDBC driver and
data source” on page 191. Click Next.
On the Specifying DataSources for individual CMP Beans panel no data
source is specified for the individual CMPs because they use the default data
source specified for the EJB module.
Click Next until you get the Selecting the Application Servers panel. Click on
the ITSOMightyEJB module and select the ITSOWSAD application server.
Click Next.
In the Completing the Application Installation Wizard panel click Finish.
Select No when prompted to redeploy the code.
You should now see the two enterprise applications (ITSOAlmaEAR and
ITSOMightyEAR) in the list of enterprise applications.
Click Next until you get the Selecting Virtual Hosts for Web Modules page.
Make sure default_host is selected as the Virtual Host for the UTC Web
Module. Click Next.
On Selecting the Application Servers page, click on the UTC module and
select the ITSOWSAD application server.
Click Next and in the Completing the Application Installation Wizard click
Finish.
When you start the application server, the Web server plug-in is regenerated
because we enabled the Automatic Generation of Plug-in property. To make
sure the Web server picks up the new plug-in configuration immediately, you
can stop and restart it.
Important: Before you can test the enterprise applications you must create
the ITSOWSAD database on the WebSphere machine (see “Creating the
ITSOWSAD sample database” on page 61).
If we want to use the embedded HTTP server to test the enterprise applications,
we have to use that port in the URL.
To test the Almaden Autos enterprise application open a browser and enter:
http://localhost:9081/ITSOAlma/PartsInputForm.html
Attention: You may have to activate the virtual host alias *:9081 in the
Administrative Console (select Virtual Hosts).
You must have installed WebSphere Application Server 4.0 Single Server (AEs)
locally or on a remote machine, and you have IBM Agent Controller running on
that machine.
The IBM Agent Controller comes with Application Developer. It is a process that
runs on the remote machine and which enables client applications to start new
host processes. The IBM Agent Controller will start the application server on the
same or remote machine (Figure 6-34).
Copy
WSAD WS Starts
workspace files deploy
directory
IBM Agent
WSAD Controller
Start
remote
Local machine test
Remote machine
Figure 6-34 Remote unit test
Attention: If you already have the Agent Controller installed on a remote test
machine, and you are installing WebSphere Application Server on the same
machine, you must edit the settings in the server configuration file after you
install WebSphere Application Server:
Open the serviceconfig.xml file that is located in the
x:\Agent_Controller/config directory (where x:\Agent_controller is the
installation path of the Agent Controller).
In the file, search for the Application executable=“wteRemote.exe” tag.
Change all occurrences of path=“ %WAS_HOME%” within the Application
executable tag to path=“WAS_ROOT” (where WAS_ROOT is the installation
path of WebSphere Application Server).
Save the changes and close the file.
In the next panel specify the remote file transfer name and the remote target
directory (Figure 6-38).
– The remote file transfer name is a name you assign to the remote file
transfer instance so that you can use it in another server configuration.
– The remote target directory seen by the current machine, where you want
to publish your Web application. For example, if you mapped the
WebSphere installation drive as drive k, then you would specify
k:\WebSphere\AppServer as the target directory. Click Next.
We have configured the remote server instance and the remote server appears
in the Servers view. Now we need to configure the data source for that instance.
Click on Add to add a data source with JNDI name jdbc/ITSOWSAD and
database name ITSOWSAD. (See Figure 3-25 on page 85.)
Summary
In this chapter, we have explored the many different deployment options. We
have deployed the two previously developed enterprise applications, Almaden
Autos and Mighty Motors, to WebSphere Advanced Edition Single Server (AEs)
and WebSphere Advanced Edition (AE). We tested against both servers using
the embedded HTTP server the IBM HTTP Server as an external HTTP Server.
Quiz: To test your knowledge of the Web and EJB deployment features of
Application Developer, try to answer the following five questions. The answers
are provided in Appendix C, “Quiz answers” on page 559.
1. What are the two different ways to install an enterprise application in AEs?
2. Name at least two big differences between AE and AEs.
3. What protocol is used to communicate between the Web server plug-in and
the application server?
4. On what port is the embedded Web server listening for AEs and for AE?
5. In what file is the Web server plug-in configuration stored?
Attention: The GA version of the product can be configured with either CVS
or ClearCase LT at installation time. We only cover CVS in this book.
An extensible architecture
Figure 7-1 provides a very simple illustration of how the development
environment provides the team capabilities.
Tools
Workspace
Repositories
CVS
(Concurrent Versions System)
is the only system in the
ClearCase
Beta code Version control
Parallel development
Life cycle integration
UCM out of the box
Web Browser interface
ClearCase LT Promotion Model
Version control Baseline Comparison
Parallel development Snapshot views
Life cycle integration Dynamic views
UCM out of the box Binary Sharing
CVS Web Browser interface Auto build dependency
Version control Promotion Model Distributed builds
Parallel development Baseline Comparison Distributed servers
Life cycle integration Snapshot views Support for MultiSite
Figure 7-2 Differences between CVS and the two ClearCase versions
Application Developer will be fully compatible with both versions, although there
is a limitation that there is no interoperability between the two Rational products
(a ClearCase LT server cannot access a ClearCase repository).
Because the ClearCase support is not currently available in the beta code, the
remains of this chapter will focus on working with CVS. CVS is available on a
number of platforms including Windows, Linux, AIX, HP-UX, and Solaris.
Workspace
The workspace is maintained by the IDE and contains a snapshot of all of the
files that it knows about that reside in the file system and also contains
information relating to the last time they were modified by a developer using the
tool. If you edit a file using an external editor or add a file to the file system, you
must always use the Refresh from Local menu option to reflect those changes in
the Navigator and editors in the IDE.
Important: If you have previously been developing in VisualAge for Java, one
of the most important features you will need to know is that file deletions from
the workspace are permanent as there is no local repository. Even if you are
working alone, we still recommend that you install a local CVS instance and
regularly release changes to it.
Local history
Application Developer stores a history of locally made changes to files that still
exist in the file system for a period that is specified in the Workbench preferences
(Figure 7-3), however deleted files cannot be recovered from the local history.
To view the history of a file, simply select Compare with or Replace with -> Local
History from the files context menu.
Each workspace is created as a folder in the file system where the source code
will reside. To start the IDE with a different workspace, simply execute:
wsappdev -data myworkspacedir
This technique is useful when working on two releases of a project at the same
time—such as building a new release and performing maintenance on an old
one. Each development stream can have its own workspace and copies of the
files in the file system.
Using the technique we have just discussed, this is also possible using
Application Developer. Assuming that all of the organizations applications are
installed on the p: drive, and each developer has their own source files on a
mapped directory q:, simply start the IDE using:
p:/wsad/wsappdev -data q:/myworkspacedir
Streams
A stream maintains a team’s shared configuration of one or more related projects
and their folders and files. A team of developers share a stream that reflects their
ongoing work and all their changes integrated to date. In effect, a stream is a
shared workspace that resides in a repository.
Maintaining history is important so that one can compare the current work
against previous efforts, or revert to older work that is better. Coordinating the
work is critical so that there is one definition of the current project state,
containing the integrated work of the team. This coordination is provided through
the stream model.
initial initial
development change #2
development change #2
Developer 1
Developer 1
release catch-up release
release catch-up release
Stream
Stream
catch-up release catch-up
catch-up release catch-up
Developer 2
Developer 2 change #1 time
change #1 time
Figure 7-4 Two developers doing sequential development using a stream
Branching
A repository typically may have any number of streams, which are distinguished
by name. In a CVS repository, for instance, a stream maps to the main trunk
(known as HEAD) or to a branch.
In the team environment, resources other than projects (such as files or folders)
cannot be explicitly versioned. However, they are implicitly versioned when they
are released to the stream.
A base version of a resource contains what was released on the stream at the
time of the most recent synchronization. Therefore, the base version of a
resource in the workbench denotes its corresponding state in the repository. This
remains true even after modifying the resource locally: the base version denotes
what the resource looked like before you started modifying it. A new local history
for a resource is created the first time you modify the base version.
Terminology matrix
Table 7-1 attempts to map the terminology used between Application Developer,
native CVS, and Rational ClearCase.
Table 7-1 Terminology matrix for team support
Application Developer CVS ClearCase
Perspective overview
Open the team perspective. The default views are as follows:
Navigator The standard navigator showing all files in the workspace,
except those defined by the assigned filters. The default filter
removes all .class files from the view.
Properties Shows properties of the currently selected file in the
workspace, including the time it was last modified and its
size. If an item in a repository is selected, this view shows
the artifacts author, version number, and comments.
Repositories Shows all repository connections and their contained
streams and versions
Synchronize Used to perform release and catch-up operations, and view
differences between files
Tasks Standard task list
Resource History Responsible for displaying the version history of the selected
item when requested
cvs.apache.org is a publicly run CVS server that is used around the world by
developers contributing to the open source Apache projects, such as the Apache
Web server, the Jakarta Java tools, and the XML utilities and parsers.
To be able to perform this step, you must have a live Internet connection, or be
working behind a corporate proxy, or socks server.
Select the Repositories view and click on the File -> New -> Other menu in the
Workbench. From the CVS category select Repository Location. Click Next.
Complete the repository location wizard (Figure 7-5).
Here are brief descriptions of the CVS terms on this panel of the wizard:
Connection type The protocol you want to use to connect to the CVS server.
The default selection is pserver, which represents the
password server protocol, that is used by most public
repositories. Other CVS alternatives include the secure
shell ssh, an explanation of which is outside the scope of
this document.
User name The user ID you wish to use to log on to the CVS server.
Most public servers have an anonymous user ID published
on their Web site, which has read-only access to the
server.
Host name The machine name of the server you wish to connect to.
Repository path The fully qualified path to the location of the repository on
the server.
CVS location The complete location used by Application Developer to
connect to the repository. This is dynamically built as you
complete the previous fields.
Validate on finish This tests the repository connection before returning to the
IDE, which we recommend to keep enabled as a first
connectivity test.
Once the user ID and password have been validated, we should be returned to
the Repositories view with a new entry for the Apache server.
Let us assume that we want to retrieve the very latest source code for the
Jakarta JMeter project (a load tester for Web applications), which includes a fix
that we need to get it working with our application.
Expand the HEAD stream, scroll down the list of Apache projects to the
jakarta-jmeter entry. By expanding this element in the tree, we can see all of the
elements contained inside and their corresponding version numbers.
Right-click on the file and select Show in Resource History. The history of
changes appears in the Resource History view with entries similar to those
shown in Figure 7-7.
To open a specific version of the README file to see its contents, select an entry
from the history, such as version 1.1, and select Open from the context menu for
that row in the table. An editor opens on the resource in the team perspective.
Select Open again on another version, such as 1.6. A second editor opens.
Currently, none of these files have been added to the workspace. This is very
similar to features of the Repository Explorer that was in VisualAge for Java.
Close the comparison window for the README. Note that the right hand side of
this perspective is now split into three views—one of which is empty. Do not be
tempted to move the repositories view to remove the empty space, as future
editors will not be visible.
Next, we compare two versions of a Java source file, to demonstrate that the
comparison view behaves differently for various file types.
Notice that when comparing two Java source files, a Structure Compare panel is
also included in the comparison view. This shows an outline of the changes to
the file. Select import declarations, and you will see all changes to the import
statements in the file. Select java.io.Serializable and you will see that this does
not appear in version 1.1 (this is also shown by the + icon in the comparison
structure). By clicking on the compiler element, you can see that this class
variable has changed from being declared as static to transient static.
Navigate back to the jakarta-jmeter entry under the HEAD stream in the
Repositories view and select Add to Workspace from its context menu. After a
brief delay, while the files are downloading from the Internet, the project should
now appear in the Navigator. These files have been copied into a
jakarta-jmeter folder under the current workspace folder of the Application
Developer (the default is the workspace directory in the installation directory).
Note that there is currently no option to specify the directory you would like for
importing this source into, other than the default workspace folder.
Open the properties dialogue of the new project. Switch to the Team category,
and we can see that the project is associated with the Apache CVS server and its
HEAD stream (Figure 7-10). If we wish to amend the stream or repository the
IDE uses to release any changes, we can do so here by clicking on the Change
button.
Figure 7-10 The repository and stream assigned to the imported project.
Before we look into the files copied in more detail, open the Resource History
again on the README file. Notice that the 1.6 version is now marked with an
asterisk (*). This illustrates that this is the base version currently loaded into the
workspace.
Open the file .prj file stored in the installation directory and change the contents
as shown in Figure 7-11 (the lines to add are in bold).
workspace/.metadata/.plugins/org.eclipse.core.resources/.projects/jakarta-jmeter/.prj
<?xml version="1.0"?>
<projectDescription>
<name>jakarta-jmeter</name>
<version>0.0 000</version>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
Figure 7-11 Modified project file which stores the project type
To refresh the value stored in the IDE, select the project in the navigator and
select Close Project and then Open Project from its context menu. On reopening
the project, Application Developer reads the .prj file again and changes the type
of project to Java. This is noticable by the small letter J shown in the folder icon.
Once it has detected this change, it then attempts to compile the resources
contained inside.
When the properties dialog is closed, the project is rebuilt. Although a few
remaining deprecation warnings and some optional JavaMail errors appear, the
application should now be ready for execution.
Important: The JMeter project will not be used in the redbook. Therefore
delete the project in the Packages view to clear all the error messages.
When the code has been downloaded, unzip it into a directory named CVSNT on
the local hard disk.
Where x: is the drive letter where you want to create the repository.
A CVS NT service appears in the Windows services window (Figure 7-12). Start
the CVS service. If there are problems starting the service, check the Windows
event viewer to see the details of the errors.
To properly simulate two users working simultaneously, we will use the multiple
workspace approach discussed earlier in the chapter.
There are a number of limitations on the names you can use for projects
versions. Specifically the CVS interface prevents the use of periods (.) and
suggests using either dashes (-) or underscores (_) instead. Through this
book we will be creating versions using incrementing numbers, with minor
revisions separated by underscores, such as v1_1, v1_2.
Configuration
Create two local workspace directories using the following commands from a
Windows command prompt:
md x:/ITSOWSAD/developer1_ws
md x:/ITSOWSAD/developer2_ws
Where x: is the local data drive defined in previous chapters. Then start
Application Developer using these commands:
y:/wsad/wsappdev -data x:/ITSOWSAD/developer1_ws
y:/wsad/wsappdev -data x:/ITSOWSAD/developer2_ws
Two instances of the IDE are now executing. Close the default perspective in
each instance to preserve memory and open the team perspective. Switch to the
Repositories view.
In each instance of the IDE, create a connection to the local CVS repository
installed in the previous chapter using the appropriate developers user ID and
password, as described in “Connecting to a CVS repository” on page 215.
Because we will be demonstrating the team capabilities using Java classes, also
open the Java perspective in each instance.
Both developers are working on the same development stream with a class
named TeamTest1.java in the itso.wsad.team package.
Stream
Developer 2
change #1 time
Figure 7-13 Sequential development scenario
The first step of the development has now been completed. Next, Developer 2
must connect to the repository and retrieve the latest contents of the HEAD
stream into the workspace.
Note the version numbering used here. Each time the file was released by a
developer it increments from 1.1 to 1.2 then to 1.3. An asterisk is displayed next
to the 1.3 version because this is now the base version for the class that is in the
workspace of Developer 2. From the context menu of each of these elements in
the table, the Add to workspace menu item is available.
change #3
Developer 1
catch-up v1.3 release v1.4
Stream
catch-up v1.3 merge v1.4 and
release v1.5
Developer 2
change #4 time
Figure 7-15 Parallel development in a single stream scenario
Developer 1: Change
Switch to the workspace for Developer 1 and complete these tasks:
Open the Java perspective and edit the TeamTest1 class. Add a new method:
public void change3() { }
Save the changes and close the editor.
Release the changes to the stream, adding a comment of Change 3 complete.
By opening the Resource History view, we can see this was stored as version
1.4 in the repository.
To view what has happened, select the TeamTest1.java file from the
Navigator view and launch the Resource History on the resource.
We can see from the resource history that Developer 1 has made a change to
the file since our base version.
Next, from the Structure Compare panel in the Synchronize view, double-click
on the TeamTest1.java file. This opens the Java structure comparison panel
(Figure 7-17).
copy current
ancestor
change
visibility
from left/right
copy whole
document next/previous
change
from left/right
This action opens a fifth panel in the Synchronize view. This window shows
the source of the common ancestor of the two files—in this case version 1.3,
which is the base version of the current code in the workspace (Figure 7-19).
So what would have happened if we had not merged the changes? By releasing
the file, the current top of the stream would have been replaced with a version
that does not include the change3() method, and this version would have been
used for all future development. Streams do not support development
branches—this must be done by creating a second stream.
Figure 7-20 illustrates a scenario where our two developers branch the
development of the application:
Ensure both developers currently have version 1.5 loaded into their
workspace.
First, a project version is created from the current contents of the stream.
Developer 2 then starts adding new functionality into the application while
Developer 1 supports and maintains the version in production.
Developer 2
new feature time
Figure 7-20 Parallel development using multiple streams scenario
Next, create a new stream for the local repository using the File -> New ->
Other menu and selecting Stream from the CVS category. Enter Maintenance
as the Stream name. Click Finish.
From the Repositories view, select the new stream. Currently no projects are
assigned to this stream. Select Copy version to stream from the context
menu.
Our final step is to merge the changes that were released into the Maintenance
stream into the HEAD stream, so that the bug fix is included in the next release,
which also contains the new feature.
Close both IDEs and reopen Application Developer using the normal workspace
to continue development for the next chapter.
A good practice is to only include source files in the project. For example, in the
case of EJBs, store the generated types in the repository along with the
generated metadata such as ejb-jar.xml, but do not store the JAR files or
compiled classes.
To restore from a backup, simply restore the files from the backup copy into their
previous directory structure. If there are no backup facilities available, create a
scheduled batch script that creates a timestamped zip file of the entire CVS
directory and copies it to another machine.
There is a feature in the command line tools installed with CVS, invoked by:
cvs admin -o
Implementing security
In our current installation, all valid users of the Windows server have unlimited
access to read and write files in the CVS repository. This is unlikely to be a
satisfactory scenario.
The creation of two files is all that is required to implement tighter security for an
individual repository. On the server, create two text files called readers and
writers in the root directory of the CVS repository.
These files should contain a new line-separated list of users that you want to
grant that level of permission. If no writers file is supplied, then the CVS server
implicitly assumes that all users have both read and write permission. If only the
writers file exists, CVS grants all users read permission and only the specified
users write permission.
Note that you should not include the same user in both files—only in the file with
the higher permission level you want to provide. Putting the same name in both
readers and writers assumes that you want to only give read access.
Build scripts
Because CVS has a command line interface, it is easy to develop a batch client
that retrieves the latest versions from a particular stream to a directory structure
using cvs update -q.
These topics are outside the scope of this document, but are documented in
some detail in the WebSphere Version 4 Application Development Handbook,
SG24-6134.
Once the client has been installed, and a connection established to the
repository, enter this command:
cvs watch add -a commit files
And finally, to find out who else is watching those files, use:
cvs watchers files
Next we demonstrate each of the steps you have to perform when Web service
enabling an existing application. We use the wizards and tools available in
Application Developer.
The hands-on part is structured into four chapters: static Web services, dynamic
Web services, composed Web services, and advanced topics (advanced SOAP,
advanced UDDI, WSFL, Web service support in other IBM products). We also
cover the deployment process for Web services into WebSphere Version 4.0
Advanced Edition (AE), including the Single Server (AEs).
This is a product neutral introduction; the IBM product support for Web services
will be introduced in “Product support for Web services” on page 307. We
assume that your development environment is Java based, however.
The first three sections should give you sufficient information to start
implementing the auto parts sample application. The remaining sections cover
SOAP, WSDL, and UDDI in detail.
The SOA is based on XML. We will not introduce XML here; for an introduction to
XML including schemas and namespaces, refer to “An XML primer” on page 92.
As the protocol activity charter points out, business to business (B2B) has
significantly more potential than business to consumer (B2C), as various reports
show.
However, most Web clients still are human beings browsing linked documents,
downloading files, or manually initiating transactions. More automated solutions
face technical problems such as:
Existing integration approaches lack flexibility because they follow a tight
coupling approach.
Problems occur if firewall boundaries have to be crossed because the security
administrators usually only open the HTTP port (port 80).
There are software distribution problems when protocols such as RMI/IIOP
are used. For example, the EJB client JAR file has to be made available on
the Web client.
The Web services abstraction and the service oriented architecture (SOA)
address these issues, allowing IT systems to become clients of Web
applications.
Technical foundation
Web services combine the power of two ubiquitous technologies: XML, the
universal data description language, and the HTTP transport protocol widely
supported by browser and Web servers:
Web services = XML + HTTP
Web services can be published, located, and invoked across the Web
Some additional standards are required to do so:
– SOAP, the Simple Object Access Protocol, also known as service-oriented
architecture protocol, an XML based RPC and messaging protocol
– WSDL, the Web Service Description Language, a descriptive interface
and protocol binding language
– UDDI, Universal Description, Discovery, and Integration, a registry
mechanism that can be used to lookup Web service descriptions
In this chapter, we introduce each of these technologies.
By now you are hopefully just as excited about this emerging technology as we
are. If not, please carry on reading anyway. We hope that you will be at the end of
the book. As Web services receive a lot of attention at the moment, chances are
you will have to understand and be able to position this technology soon.
Let us now introduce the overall architecture of the Web services technology
framework.
This is just a short introduction to the key concepts in the SOA. We focus on the
aspects that you as a Web services application developer will be confronted with.
For more information, refer to:
http://www-4.ibm.com/software/solutions/webservices/resources.html
This Web site provides a collection of IBM resources on the topic at hand. For
example, you can find an introduction to the SOA in a white paper titled “Web
Services Conceptual Architecture (WSCA 1.0)”.
Service roles
Let us first introduce the roles a business and its Web service enabled
applications can take in the SOA. Three roles can be identified (Figure 8-1):
The service provider creates a Web service and publishes its interface and
access information to the service registry.
The service broker (also known as service registry) is responsible for making
the Web service interface and implementation access information available to
any potential service requestor.
The service requestor locates entries in the broker registry using various find
operations and then binds to the service provider in order to invoke one of its
Web services.
Service
Broker
Pu
I
DD
b
nd
SD
,U
lis
L,
L
Fi
SD
h
UD
W
SOAP
DI
Service Service
Requestor Bind/invoke Provider
SOA stack
Figure 8-2 shows how SOAP, WSDL, and UDDI fit into the overall Web services
protocol and standards stack.
Quality of Service
Static UDDI
Stack
Management
Service Discovery
Security
Direct UDDI Service Publication
WSDL
Service Description
SOAP
XML Messaging
HTTP, FTP, email, Network
MQ, IIOP, ...
The columns on the right hand side of the diagram contain the cross layer
operational building blocks such as security, management, and quality of service.
This book mainly focusses on development aspects; we discuss some of the
operational aspects in “Architecture and design considerations” on page 513.
Here is a first glance at the relationship between the core elements of the SOA
(Figure 8-3):
All elements use XML including XML namespaces and XML schemas
Service requestor and provider communicate with each other via SOAP
UDDI access is performed through SOAP over HTTP
WSDL is one alternative to make service interfaces and implementations
available in the UDDI registry
WSDL is the base for SOAP server deployment and SOAP client generation
UDDI
(Broker)
HTTP
Runtime
transports
SOAP other
Requestor Provider
SOA Runtime
J2EE other
Implementation
In “The web of Web service standards” on page 304, we revisit the elements of
the SOA, providing more insight on the relationships between them.
First examples
Here are some examples for macro and micro-level Web services:
A news clipping service, with which library systems can contact Web portals
when researching for publications containing certain keywords (system
initiated Web crawling).
A travel agent application comparing the ticket prices of different airlines.
A CD track listing service that audio players and record companies connect
to.
An Excel/COM based insurance policy calculation sheet that is supposed to
support a Web interface.
Business information with rich content such as weather reports, news feeds,
airline schedules, and stock quotes.
Transactional Web services for B2B or B2C (airline reservations, rental car
agreements).
Business process externalization, providing business linkages at a workflow
level, allowing complete integration at a process level.
Use your imagination to come up with examples related to your business and
project domain.
Let us examine a simple micro level Web service. Assume there is an existing
Java based IT system calculating the current exchange rates between foreign
currencies. It would be nice to make this functionality available as a Web service
that any application with Web access could invoke.
Note: In fact this Web service exists on the Web today. XMethods acts both in
service provider and broker role, as we will see in “Existing registries” on
page 300. Also note that Graham Glass uses the same example for his “The
Web service (r)evolution” series of articles on developerWorks:
http://www.ibm.com/developerworks/webservices/library/ws-peer4/
The articles use an outdated version of the WSTK and Tomcat; here we will
work with the Application Developer tool and the WebSphere test
environment.
You might be surprised not to see more protocol specific code. As a matter of
fact, this is all you have to code when implementing a requestor/provider pair.
On the provider side, the only link between this service implementation and the
SOAP server hosting it is a configuration file, and the deployment descriptor,
which we will introduce in “SOAP server” on page 270.
On the requestor side, the code using the SOAP API to bind to and invoke the
service is encapsulated in the ExchangeProxy class. This client stub class is
typically generated by tools, as we will see in “Development steps” on page 254.
We will introduce the SOAP RPC client API used by the proxy in “SOAP client
API” on page 272. The client is simple. First it passes addressing information: a
SOAP server URL (http://localhost/servlet/rpcrouter) and a service ID
(urn:Exchange). Then it invokes a method very much in the same way as if it was
executing in the same address space as the server.
The information required by client proxy and deployment descriptor can formally
be specified in WSDL. Figure 8-5 contains a snippet of the description of the
Exchange service.
Note that such a description can be generated by a tool from the Java service
implementation, as we will discuss in “Development steps” on page 254.
The Java class is represented as a port type, the method as an operation. The
method parameters are translated into message parts with matching data types.
A binding and a service definition contain access information, such as a service
ID and the URL of the SOAP server hosting the service. Note that all definitions
are abstract because WSDL is language independent; in the SOA, the Java
mapping is performed by the SOAP runtime.
Finally, a UDDI registration for this Web service could contain the entities shown
in Figure 8-6.
Figure 8-6 Excerpt from the UDDI registry entry for the Exchange service
A business entity, describing the company providing the Exchange service (not
displayed in the figure).
An informal description of the semantics of the Exchange service
(businessService entity).
An informal technical description of the syntax of the Exchange service
(tModel), including a URL reference to the formal specification in the WSDL
interface document.
An access locator describing how to access the service, including a URL
pointing to the SOAP server hosting the service, and a URL reference to the
WSDL implementation document (bindingTemplate).
Java solutions
There is a wide support for Web services in the Java world, both from vendors
and the open source community.
Open source
The following open source projects focus on elements of the service oriented
architecture:
The Apache XML project, with subprojects for Xalan, Xerces, and SOAP:
http://xml.apache.org/
Apache AXIS, the second generation SOAP implementation:
http://xml.apache.org/axis/
WSDL4J and UDDI4J, hosted at IBM developerWorks:
http://www.ibm.com/developerworks/projects/wsdl4j/
http://www.ibm.com/developerworks/projects/uddi4j/
IBM
See “Product support for Web services” on page 307 for an overview of the IBM
product support for Web services. All standards and development steps we have
introduced are supported.
SOAP Lite
SOAP::Lite for Perl is a collection of Perl modules, which provide a simple and
lightweight interface to the Simple Object Access Protocol (SOAP) both on client
and server side:
http://www.soaplite.com/
More information
James Snell gives an overview on the SOAP implementation alternatives in the
first part of his Web services insider series of articles on developerWorks:
http://www.ibm.com/developerworks/webservices/library/ws-ref1.html
What is next
Now that we have learned about the core technologies of the Web service SOA,
let us take a look at the development process for service providers and
requestors.
For a more comprehensive discussion of the topic, see the document “Web
Services Development Concepts 1.0" from the Web services development
toolkit. It is also available under the following URL:
http://www-4.ibm.com/software/solutions/webservices/pdf/WSDC.pdf
Development steps
During the build cycle of any project involving Web services, certain steps have
to be performed. Figure 8-7 illustrates them in a pseudo-UML collaboration
diagram.
SOAP
UDDI
SOAP Client
dds.xml Registry
Server Proxy
Even if all specifications are human readable (XML), there is a strong need for
tools supporting these development steps—a lot of documents with overlapping
content are involved. It would be cumbersome and error prone to define all these
files without tools.
“Product support for Web services” on page 307 will introduce the Application
Developer product support for these six Web service development steps.
Service provider
A service provider can choose between three different development styles when
defining the WSDL and the Java implementation for his/her Web service:
Top down When following the top down approach, both the server
and client side Java code are developed from an existing
WSDL specification.
In the near future, we expect most real world projects to follow the meet in the
middle approach, with a strong emphasis on its bottom up elements. This is MIM
variant 1, starting from and modify existing server side Java and generate WSDL
from it.
When developing the auto parts sample application throughout the following
chapters, we will start with the bottom up approach. Refer to “Static Web
services” on page 321.
We will demonstrate the top down approach later on as well. See “Composed
Web services” on page 413.
Service requestor
Web service clients (service requestor implementations, that is) have to import
the WSDL interface and implementation specification of the Web service to be
invoked into their environment.
Service broker
Since we do not expect that application developers implement UDDI registries
themselves, we do not discuss any related development issues in this document.
4: (un)
not
1 publish published
initial specified published waiting*
inactive
inactive 7: s
session
5:
8: stop 8: stop invalidation
invoke
2 2 6:
9: start 9: start terminate
3: 4: (un)
1 specified, deploy not
not publish 5: invoke
imple- published
imple- published
published running
running*
mented active 6: terminate
mented active
active
Run time
Build time Deploy time (*session only)
Figure 8-8 Service lifecycle
4 UDDI publishing the two not published the two published states
states
Note that state transition diagram and table only show the recommended sunny
day scenario. For instance, it would be possible to already publish from the
specified/implemented state; this would not make sense, however, because any
clients finding and binding to the service would be returned an error message.
For the sake of simplicity of the diagrams, the undeploy operation is not shown.
If you prefer to learn more about the SOAP, WDSL, and UDDI concepts before
starting to code, proceed with “An introduction to SOAP” on page 261, “WSDL
primer” on page 277, and “UDDI overview” on page 293. Even if you skip these
sections now, you can always come back and use them as a reference during
development.
In this section, we discuss both the W3C SOAP 1.1 specification and the SOAP
2.2 implementation from Apache. Apache SOAP 2.2 implements most of the
W3C SOAP 1.1 specification. There are other Java implementations, for example
Apache AXIS, as well as non Java ones. See “Architecture and design
considerations” on page 513 for more information.
Refer to “An XML primer” on page 92 for an introduction to the XML concepts
used within SOAP.
Overview
Historically, SOAP was meant to be a network and transport neutral protocol to
carry XML messages around. SOAP over HTTP became the premier way of
implementing this protocol, to the point that the latest SOAP specification
mandates HTTP support.
However, conceptually there is no limitation for the network protocol that can be
utilized. For example, because HTTP is a transport that does not guarantee
delivery and is non-transactional, SOAP messages can also be transferred by a
messaging software such as MQSeries.
The SOAP standard specifies three aspects of XML based message exchange:
Encoding rules
Encoding rules define a serialization mechanism that can be used to
exchange instances of application-defined data types.
SOAP defines a programming language independent data type scheme
based on XSD, plus encoding rules for all data types defined according to this
model.
RPC representation
The RPC representation is a convention suited to represent remote procedure
calls and the related response messages.
The usage of this convention is optional. If the RPC convention is not used,
the communication style is purely message oriented. When working with the
message oriented style, also called document oriented communication,
almost any XML document can be exchanged.
Namespaces
SOAP defines the XML namespaces shown in Table 8-2.
Table 8-2 SOAP namespaces
Prefix Namespace URI Explanation
URN
A unified resource name (URN) uniquely identifies the service to clients. It must
be unique among all services deployed in a single SOAP server, which is
identified by a certain network address. A URN is encoded as a universal
resource identifier (URI). We commonly use the format: urn:UniqueServiceID.
urn:Exchange is the URN of our Exchange Web service.
This namespace URI identifying the method name in SOAP is very similar to the
interface ID scoping a method name in distributed computing environments such
as DCOM or CORBA or the name and the associated remote interface of an
EJB.
Envelope
The envelope has the following structure:
<SOAP-ENV:Envelope .... >
<SOAP-ENV:Header name="nmtoken"> *
<SOAP-ENV:HeaderEntry.... />0..*
</SOAP-ENV:Header>
<SOAP-ENV:Body name="nmtoken">
[message payload]
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
We use an XML element oriented pseudo XSD syntax here, with 0 and *
indicating cardinalities. In general, a SOAP message is a set of headers plus one
body. Note that the message in Figure 8-10 on page 270 does not contain a
SOAP header.
The SOAP envelope defines the namespace for structuring messages. The
entire SOAP message (headers and body), is wrapped in this envelope; its main
payload (the message content) appears in the body contained in this envelope.
Note that the message body uses a service specific namespace, urn:Exchange in
our example (Figure 8-9 on page 263). This namespace is different from
SOAP-ENV, the namespace used by the envelope, which is defined by the SOAP
specification. Therefore, the application can use its own, domain specific
vocabulary when creating message bodies.
Headers are optional elements in the envelope; they allow to pass control
information to the receiving SOAP server and provide extensibility for message
structures as well. Moreover, headers serve as hooks for protocol evolution.
In the example, the header element specifies that a service invocation must fail if
the service provider does not support the quality of service (qos) level 3
(whatever qos=3 stands for in the actual invocation context). The second header
attribute is SOAP-ENV:actor, identifying the recipient of the header information.
Another example are multi-hop messages. Headers can be used to address the
intermediate actors forwarding multi-hop messages to their target destination.
Headers can also carry authentication data, digital signatures, and encryption
information, or transactional settings.
Body
In the most simple case, the body of a basic SOAP message comprises:
A message name
A reference to a service instance. In Apache SOAP, a service instance is
identified by its unified resource name (URN). This reference travels as the
namespace attribute.
One or more parameters carrying values and optional type references
Error handling
SOAP itself predefines one body element, which is the fault element used for
reporting errors. The fields of the fault element are defined as follows:
Faultcode is a code that indicates the type of the fault. The valid values are:
– SOAP-ENV:Client, indicating incorrectly formatted messages
– SOAP-ENV:Server, for delivery problems
– SOAP-ENV:VersionMismatch, which can report any invalid namespaces for
envelope element
– SOAP-ENV:MustUnderstand for errors regarding the processing of header
content
Faultstring is a human readable description of the fault.
Faultactor is an optional field that indicates the URI of the source of the fault.
Detail is an application specific field that contains detailed information about
the fault.
Advanced concepts
In this section, we discuss some more advanced SOAP concepts, such as the
different message styles as well as the SOAP data model, the available
encodings and the corresponding type mappings.
When beginning to work with SOAP, you will probably not immediately touch
these concepts. Most of the Web service samples available on the Web do not
feature them, either. When you are planning to implement a nontrivial Web
service, however, you have to be familiar with them.
Therefore, feel free to skip this section when this is your first contact with Web
services, and come back when the design issues in your project require you to
change the default settings of the Application Developer wizards, which is quite
likely to happen.
The main focus of this redbook is on the RPC style. Unless explicitly stated
otherwise, all explanations refer to the RPC style; the example given above and
the auto parts sample application used throughout the book, use it as well.
See “Web services advanced topics” on page 447 and the “Apache SOAP User’s
Guide” for more information on the document-oriented style.
Data model
The purpose of the SOAP data model is to provide a language independent
abstraction for common programming language types. It consists of:
Simple XSD types Basic data types found in most programming languages
such as int, String, date, and so forth.
Compound types There are two kinds of compound types, structs and
arrays.
Structs Named aggregated types. Each element has a unique
name, its accessor. An accessor is an XML tag. Structs are
conceptually similar to records or methodless classes with
public data members in object-based programming
languages.
Arrays Elements in an array are identified by position, not by
name. This the same concept as found in languages such
as C and Java.
The accessors in this example are country1 and country2. The accessor names
correspond to the names of the parameters, the message types to the
programming language data types ( xsd:string and java.lang.String). The
parameters must appear in the same order as in the method signature.
SOAP provides a preferred encoding for all data types defined according to this
model (see next section on Encodings).
Encodings
In distributed computing environments, encodings define how data values
defined in the application can be translated to and from protocol format. We refer
to these translation steps as serialization and deseralization, or, synonymously,
marshalling and unmarshalling (even Apache SOAP uses both pairs of terms).
The protocol format for Web services is XML, and we assume that service
requestor and provider are developed in Java. Thus, SOAP encodings tell the
SOAP runtime environment how to translate from data structures constructed in
Java into SOAP XML and vice versa.
The encoding to be used by the SOAP runtime can be specified at deploy time or
runtime. If it is specified at deploy time, it appears in the WSDL specification of
the Web service (see “WSDL primer” on page 277). Tools can then analyze this
specification and configure the SOAP runtime to use the desired encoding.
At runtime, the SOAP client API (see “SOAP client API” on page 272) allows the
specification of the encoding for the entire message and for each of its
parameters. On the server side, the encoding style is specified in the deployment
descriptor of the Web service (see “Server deployment” on page 271). The
settings on the client and the server side have to match.
At runtime, it must be possible to encode and decode values of all the data types
that are being used under a certain encoding scheme. Mappings address this
requirement.
Mappings
A mapping defines an ternary association between a qualified XML element
name, a Java class name, and one of the encodings as introduced above (note
that this is the first time that we have to discuss Java specific aspects).
A mapping specifies how, under the given encoding, an incoming XML element
with a fully qualified name is to be converted to a Java class and vice versa. We
refer to the two mapping directions as XML to Java and Java to XML, respectively.
Any SOAP runtime environment holds a table of such mapping entries, the
SOAPMappingRegistry.
SOAP server
Apache SOAP 2.2, which comes with Application Developer, provides an
implementation for a SOAP server, allowing to deploy Web services and invoke
methods on them.
Web Service
Deployment
Descriptor
DeployedServices.ds
For now, the important elements in this architecture are the rpcrouter and
messagerouter servlets, the deployment descriptor (explained below), and the
type mapping registry. These components implement the SOAP concepts
introduced so far.
The pluggable providers link a Web service and its implementation. The service
implementation is your Java code actually executing the invoked Web service.
We do not go into details about the configuration manager, and the admin GUI
here; refer to the Apache SOAP user documentation for more information.
A service implementation implementing the first step for the Exchange Web
service is:
public class Exchange {
public float getRate(String country1, String country2) {
System.out.println("getRate(" + country1 + ", " + country2 + ")");
return 1.45F; // fixed value for now
}
}
This deployment descriptor defines the URN, urn:Exchange, and the name of the
Java implementation class, Exchange. There is one accessible method, getRate.
The Web service scope is Request. This scope attribute can be set to application,
request, or session:
If the scope is application, a singleton instance of the service is created at
server startup time (like a servlet).
A service with request scope is instantiated whenever a message for it is
received.
If the scope is session, the lifetime of the service instance is bound to the
duration of the underlying transport session (for example, the HttpSession in
case HTTP is the transport protocol).
As a SOAP developer you might have to use the following classes as well:
QName Qualified name: combination of an XML namespace
and a local name. QName instances are used to identify
XML data types and other elements in an XML
document.
SOAPMappingRegistry Maps types and encoding styles to the available
serializer and deserializer classes.
SOAPHttpTransport Provides access to the HTTP transport layer. For
example, this class can be used to modify proxy and
authentication settings.
Let us take a look at an example (Figure 8-11). The message that travels if this
code is executed is the same message we inspected in “Anatomy of a SOAP
message” on page 262.
You have to perform the following steps when developing a SOAP client:
Obtain the interface description of the SOAP service, so that you know what
the signatures of the methods that you want to invoke are. Either contact the
service provider directly, or use UDDI to do so (note that this step is not
shown in the example).
Make sure that there are serializers registered for all parameters that you will
be sending, and deserializers for all information that you will be receiving (this
holds true for the example). Otherwise, develop and register the custom
mapping.
call.setParams(params);
Response resp = null;
URL url = new URL ("http://localhost/soap/servlet/rpcrouter");
resp = call.invoke (url, "urn:Exchange"); // url, soapActionURI
// soapActionURI is URN for Apache, "" for most other servers
if (resp.generatedFault()) {
Fault fault=resp.getFault();
System.out.println(" Fault code: " + fault.getFaultCode());
System.out.println(" Fault string: " + fault.getFaultString());
} else {
Parameter result=resp.getReturnValue();
Object o = result.getValue();
System.out.println("Result: " + o);
}
}
}
The SOAP client API is a string-oriented, weakly typed interface. This is due to
the fact that it is a fixed API that is unaware of the signatures of the messages
that are exchanged over it.
Usually programmers do not have to work with this rather cumbersome API
directly because there are tools wrapping it. For example, code generated from
WSDL aware tools can provide a more type oriented, easier to code interface.
We will cover the SOAP API and the code Application Developer generates on
top of it, shown in detail in “Static Web services” on page 321.
SOAP summary
Figure 8-12 contains a high level component model showing the conceptual
architecture of both the service provider (SOAP server) and the service
requestor (SOAP client).
SOAP Message
Layer RPC Message
Router Router
SOAP Transport Servlet Servlet
Layer
Transport Layer
(HTTP, SMTP, MQ, other)
On the provider side, RPC and message router servlets receive the incoming
requests. Providers route them to the Java service implementation. The server is
configured through deployment descriptor files.
Both on the requestor and on the provider side, there are mapping registries
providing access to serializer/deserializer classes implementing an encoding
scheme.
Figure 8-13 shows the interactions between client and server as well as the
server side processing of a service invocation.
Call 2
ServiceManager
- target object
- encoding style 5
- method name
- parameters RPC Router Servlet
- transport SOAP
Message
- invoke() 1
3
PluggableProvider
4 SOAP Service
1. Send SOAP RPC Request
Java Class
2. Lookup deployment descriptor
Script
3. Pass request to provider
EJB
4. Invoke service
COM Application
5. Return response
other
Figure 8-13 SOAP client and server interactions
Some recent decisions made by W3C XML Protocol Working Group are:
SOAP no longer is an acronym, but stands for itself.
The use of SOAPActionURI in the HTTP header is likely to become
discouraged or deprecated.
More information
The SOAP 1.1 specification can be downloaded from:
http://www.w3.org/TR/SOAP
For information on Apache SOAP, check out the user and API documentation as
well as the FAQ list:
http://www.apache.org/soap
In the near future, there will be a book on SOAP: “Programming Web Services
with SOAP”, by James Sell, Ken Mulched, and Paul Kulchenko, O'Reilly &
Associates, ISBN 0596000952.
What is next
SOAP enables the publication and invocation of Web services, but SOAP alone
is not enough to build a Web services infrastructure.
Without WSDL, a client has no information about the interface of a service the
server URL, the URN, the methods, the types and type mappings. Without UDDI,
a client has no information about the existence and characteristics of services.
The WSDL specification is a joint effort by Ariba, IBM, and Microsoft. It is not yet
an official standard; its current status is submission acknowledged by the W3C.
Overview
WSDL allows a service provider to specify the following characteristics of a Web
service:
Name of the Web service and addressing information
Protocol and encoding style to be used when accessing the public operations
of the Web service
Type information: operations, parameters, and data types comprising the
interface of the Web service, plus a name for this interface
A WSDL specification uses XML syntax, therefore, there is an XML schema for it.
For an introduction to XML refer to “An XML primer” on page 92 in part one of
this book.
Note that WSDL does not introduce a new type definition language. WSDL
recognizes the need for rich type systems for describing message formats, and
supports the XML schema specification (XSD).
It is worth noting that WSDL does not define any mapping to programming
languages such as Java, rather the bindings deal with transport protocols. This is
a major difference to interface description languages, such as CORBA IDL,
which have language bindings.
The containment relationship shown in the diagram directly map to the XML
schema for WSDL.
Figure 8-15 contains the service interface file for the Exchange Web service
whose SOAP representation we saw in the previous section.
This service interface file defines a single port type Exchange with only one
operation getRate. The operation makes use of two abstract messages
getRateRequest and getRateResponse. There are no type definitions because the
messages only use simple directly referenced, XSD types.
Note that the names of port type, messages, and parts are local to the WSDL
specification; the mapping to the actual transport protocol names (such as SOAP
XML elements) is performed in the binding, the next part of the service interface
file (Figure 8-16).
There is a SOAP binding ExchangeBinding for the port type. The binding
describes which runtime protocol (rpc) is supported by the service provider and
contains transport protocol configuration information
(http://schemas.xmlsoap.org/soap/http).
Here, the identifying URN urn:Exchange and the SOAP encoding are specified
per operation and message (http://schemas.xmlsoap.org/soap/encoding/).
The port references the binding in the interface file. Note that a qualified name
binding:ExchangeBinding is used in this case because the interface file uses a
different namespace than the implementation file.
Our Exchange Web service conforms to the XML schema defined in the WSDL
specification; it is possible to validate it with an XML validator. Note that in order
to verify the semantic correctness of a WSDL specification, you would require an
additional WSDL validation tool.
Namespaces
WSDL uses the XML namespaces listed in Table 8-3.
Table 8-3 WSDL namespaces
Prefix Namespace URI Explanation
The next two sections on service implementation document and service interface
document explain each of the WSDL specification elements in more detail and
discuss advanced modelling issues. Feel free to skip them at this point, or to
merely use them as a reference later on.
Service definition
A service definition merely bundles a set of ports under a name, as the following
pseudo XSD definition of the service element shows. This pseudo XSD notation
is introduced by the WSDL specification:
<wsdl:definitions .... >
<wsdl:service name="nmtoken"> *
<wsdl:port .... />*
</wsdl:service>
</wsdl:definitions>
Port definition
A port definition describes an individual endpoint by specifying a single address
for a binding:
<wsdl:definitions .... >
<wsdl:service .... > *
<wsdl:port name="nmtoken" binding="qname"> *
<-- extensibility element (1) -->
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
The binding attribute is of type QName, which is a qualified name (equivalent to the
one used in SOAP). It refers to a binding. A port contains exactly one network
address; all other protocol specific information is contained in the binding.
Any port in the implementation part must reference exactly one binding in the
interface part.
Our Exchange Web service provides such a SOAP address (see Figure 8-17 on
page 281).
Port type
A port type is a named set of abstract operations and the abstract messages
involved:
<wsdl:definitions .... >
<wsdl:portType name="nmtoken">
<wsdl:operation name="nmtoken" .... /> *
</wsdl:portType>
</wsdl:definitions>
Operations
WSDL defines four types of operations that a port can support:
One-way The port receives a message There is an input message
only.
Request-response The port receives a message, and sends a correlated
message. There is an input message followed by an output
message.
Solicit-response The port sends a message, and receives a correlated
message. There is an output message followed by an input
message.
Notification The port sends a message. There is an output message
only. This type of operation could be used in a
publish/subscribe scenario.
Each of these operation types can be supported with variations of the following
syntax. Presence and order of the input, output, and fault messages
determine the type of message:
Messages
A message represents one interaction between service requestor and service
provider. If an operation is bidirectional (an RPC call returning a result, for
example), two messages are used in order to specify the transmitted on the way
to and from the service provider:
<definitions .... >
<message name="nmtoken"> *
<part name="nmtoken" element="qname"? type="qname"?/> *
</message>
</definitions>
The abstract message definitions are used by the operation element. Multiple
operations can refer to the same message definition.
Types
The types element encloses data type definitions used by the exchanged
messages. WSDL uses XML schema definitions (XSDs) as its canonical and
built in type system:
<definitions .... >
<types>
<xsd:schema .... />*
</types>
</definitions>
Bindings
The bindings are the last set of elements in the WSDL interface document. A
binding contains:
Protocol specific general binding data such as the underlying transport
protocol and the communication style for SOAP, for example.
Protocol extensions for operations and their messages include the URN and
encoding information for SOAP, for example.
Each binding references one port type; one port type can be used in multiple
bindings. All operations defined within the port type must be bound in the
binding. The pseudo XSD for the binding looks like this:
<wsdl:definitions .... >
<wsdl:binding name="nmtoken" type="qname"> *
<-- extensibility element (1) --> *
<wsdl:operation name="nmtoken"> *
<-- extensibility element (2) --> *
<wsdl:input name="nmtoken"? > ?
<-- extensibility element (3) -->
</wsdl:input>
<wsdl:output name="nmtoken"? > ?
<-- extensibility element (4) --> *
</wsdl:output>
<wsdl:fault name="nmtoken"> *
<-- extensibility element (5) --> *
</wsdl:fault>
</wsdl:operation>
</wsdl:binding>
</wsdl:definitions>
As we have already seen, a port references a binding. Port and binding are
modelled as separate entities in order to support flexibility and location
transparency. Two ports that merely differ in their network address can share the
same protocol binding.
On the other hand, the service provider implementation looks different for each
binding, because the encoding information is part of it. A requestor following the
provider-dynamic binding development approach (see “Service requestor” on
page 256) needs the binding information at build time.
Therefore, the cut between interface and the implementation file is usually made
between the binding and the port element. There are no drawbacks because it is
possible to define a different binding in case different ports might wish to use
different URNs.
Transport bindings
As a last step, we now investigate the WSDL extensibility elements supporting
SOAP, HTTP, and MIME transport bindings.
SOAP binding
WSDL includes a binding for SOAP 1.1 endpoints, which supports the
specification of the following protocol specific information:
An indication that a binding is bound to the SOAP 1.1 protocol
A way of specifying an address for a SOAP endpoint
The URI for the SOAPAction HTTP header for the HTTP binding of SOAP
A list of definitions for headers that are transmitted as part of the SOAP
envelope
soapAction="uri"? URN
<soap:fault ... > extends operation definition, contents of fault details element
Note that the WSDL specification deals with encoding only. The mappings to be
used for a specific type under a certain encoding are out of scope; they are part
of the SOAP client and server runtime configuration (client API and deployment
descriptor, respectively). See “Mappings” on page 269.
More detailed information on the WSDL SOAP binding exceeds the scope of this
introduction. Please refer to the WSDL 1.1 specification.
Further information on the WSDL HTTP binding is out of the scope of this
introduction. Please refer to the WSDL 1.1 specification for a more complete
introduction, as well as examples.
MIME binding
The response message of a Web service might be formatted according to the
MIME format multiparts/related, returning mixed content, such as images and
text documents. WSDL provides support for describing such messages.
Further information on the WSDL MIME binding is out of the scope of this
introduction. Please refer to the WSDL 1.1 specification for a more complete
introduction as well as examples.
WSDL API
There is a WSDL Java API called WSDL4J, exposing the WSDL object model. Its
capabilities include the parsing of the contents of a WSDL document and
programmatic creation of new WSDL documents.
Note that it is always possible to use XML parsers or XSL transformations. The
two XML processing techniques are introduced in “An XML primer” on page 92.
Figure 8-18 gives an example, first reading in a WSDL specification from a file
and then extracting the service and all contained port elements.
WSDL summary
This WSDL primer has shown the power of WSDL. WSDL provides both an
abstract, language and protocol independent part as well as bindings for the
runtime protocols used in the service oriented architecture (SOA).
WSDL covers two very different aspects of a Web service specification: type and
protocol binding information appears in the interface file, and implementation
access information in the implementation file (Figure 8-19).
However, the primer has also shown that even a simple Web service definition
has to cover many interrelated aspects yielding a rather complex specification
file. Writing WSDL documents from scratch is an error prone task; therefore,
there is a strong need for tool support (see “Product support for Web services”
on page 307).
Outlook
The WSDL is currently in the process of being standardized by the W3C. We are
not aware of any plans for a WSDL Version 1.2 at the time of writing.
Basic tool support for WSDL is already available, as we will see in Chapter 9,
“Product support for Web services” on page 307. We expect several additional
WSDL tools, such as schema validators and consistency checker, to become
available in the near future. An example of a recent innovation in this area is the
Web services invocation framework (WSIF), providing a WSDL centric service
requestor API. WSIF is transport agnostic, thus a single WSIF client can support
multiple runtime protocols simultaneously, such as SOAP, a direct HTTP
connection, and a local Java call. Two articles on developerWorks provide an
introduction to WSIF:
http://www-106.ibm.com/developerworks/webservices/library/ws-wsif.html
The best sources for more information are the IBM Web services toolkit (WSTK)
and the WSDL 1.1 specification. WSDL 1.1 is contained in the IBM WSTK and
can also be found at http://www.w3.org/TR/wsdl.
What is next
Once a Web service has been specified in WSDL, it can be made publicly
available. In the SOA, UDDI is the preferred approach to do so. Therefore, the
next section introduces UDDI.
UDDI is a search engine for application clients rather than human beings;
however, there is a browser interface for human users as well.
Figure 8-20 displays this data model with the entities introduced above. It also
shows their relationships and the link to the WSDL level.
1 Business
Entity
UDDI n
Business
Service
1 m tModel
contains n find
(ServiceType)
points to Binding n n
1
Template
1
0..1 0..1
Implementation n 1 Interface
WSDL
Document import Document
The business entity tops the containment hierarchy, containing one or more
business service entities and in turn binding template entities. The tModel
instances (service types) are not contained by the business entity, but referenced
by the binding template entities.
The UDDI data model is designed to be flexible. Hence, there can be more than
one technical description for one service (a formal specification and a supporting
tutorial, for example). Vice versa, one tModel can be used to describe several
similar business services.
The possibility for the requestor to dynamically bind to a provided service through
a given tModel is a real benefit of the Web service oriented architecture.
Example
Let us take a closer look at an example, the UDDI entry for the Exchange service.
<businessService serviceKey="81FFBE10-9CE6-11D5-BA0D-0004AC49CC1E"
businessKey="4C4ABBB0-91B2-11D5-B9C3-0004AC49CC1E">
<name>ExchangeService</name>
<description xml:lang="en">Exchange Rate Service</description>
<bindingTemplates>
<bindingTemplate bindingKey="82031970-9CE6-11D5-BA0D-0004AC49CC1E"
serviceKey="81FFBE10-9CE6-11D5-BA0D-0004AC49CC1E">
<description xml:lang="en" />
<accessPoint URLType="http">http://localhost/servlet/rpcrouter</accessPoint>
<!-- tModelInstance reference skipped -->
</bindingTemplate>
</bindingTemplates>
<categoryBag>
<keyedReference tModelKey="UUID:C0B9FE13-179F-413D-8A5B-5004DB8E5BB2"
keyName="Finance and Insurance" keyValue="52" />
<keyedReference tModelKey="UUID:C1ACF26D-9672-4404-9D70-39B756E62AB4"
keyName="types" keyValue="wsdlSpec" />
</categoryBag>
</businessService>
<tModelInstanceDetails>
<tModelInstanceInfo tModelKey="UUID:7CEF0CF0-9CE6-11D5-BA0D-0004AC49CC1E">
<instanceDetails>
<overviewDoc>
<overviewURL>http://localhost/wsdl/Exchange-service.wsdl</overviewURL>
</overviewDoc>
<instanceParms><port name="ExchangePort" binding="ExchangeBinding"/>
</instanceParms>
</instanceDetails>
</tModelInstanceInfo>
</tModelInstanceDetails>
The overviewURL element contains the pointer to the WSDL implementation file.
The tModel, which contains the pointer to the WSDL interface file is not shown in
the example. It looks similar to the tModel instance shown above.
UUID
The universal unique identifier (UUID) serves as data type for all key attributes of
entities in the UDDI data model. In UDDI version 1, a UUID is a string of length
255.
For example, as you can see in Figure 8-21 on page 295, the UUID of the
business entity is 4C4ABBB0-91B2-11D5-B9C3-0004AC49CC1E.
The identifier bag explained next is a different concept; there is one and only one
UUID per entity. It is guaranteed to be unique if you are using the UDDI cloud as
described in “Advanced UDDI topics” on page 489.
Identifier bags
Business, services, and types can be known under more than one name. Hence,
an optional identifier bag can amend a business entity or a tModel.
Categorization
In order to allow potential service requestors to search for services meeting
certain criteria (other than names), UDDI introduces a categorization concept.
This concept defines taxonomies on the entries of a registry.
Our example uses the NAICS taxonomy, assigning the value 52 to the key
Exchange Key (see Figure 8-21 on page 295).
There is a need for tool support in order to simplify category assignment and
browsing.
There are find_xxx and get_xxx methods for business, service, binding
template, and service type (tModel).
There are save_xxx and delete_xxx methods for the elements of the UDDI object
model (business, service, binding, tModel).
Figure 8-24 gives an example, inquiring the IBM Test Registry for a given
business entity.
package itso.wsad.wsdynamic;
import java.util.*;
import com.ibm.uddi.client.UDDIProxy;
import com.ibm.uddi.response.*;
Requester Browser
Provider SOAP
UDDI4J HTTP(S) HTTP(S)
HTTP Server
Programmatic
access to UDDI Login Management
Registry using
SOAP
included in SOAP Server Web Application UDDI
WAS 4 and
WSAD
server
Business Logic
find, (un)publish, update
UDDI
UDDI Registry
businessEntities, businessServices, database
bindingTemplates, tModels
UDDI consists of the client side API,UDDI4J, and the registry server
implementation. The server provides HTTP and SOAP access to the registry that
is structured according to the object model described above. Basic HTTP
authentication (user ID, password) is required for all write operations such as
publish, update, and unpublish.
Existing registries
The following UDDI registries exist as of today:
UDDI Business Registry A replicated registry maintained by Microsoft, IBM,
and Ariba (soon to be replaced by HP).
Conceptually, this is just one registry. It is physically
distributed, however.
IBM Test Registry A registry for developers to experiment with the
technology and test their services.
Private registries IBM ships a private UDDI registry implementation.
Refer to “Advanced UDDI topics” on page 489 for
more information.
It is worth noting that the browser GUIs for the IBM business and test registries
as well as the one that comes with the private UDDI implementation use a
slightly different terminology than the UDDI object model exposed to API
programmers:
Business service instances are called businesses
Business services are called services
Binding templates are called access locators
tModel instances are called service types
UDDI summary
As we have seen, UDDI provides a structured means of describing and locating
meta information about service providers, service implementations, and service
interfaces.
In this introduction, we have described UDDI Version 1. Most existing UDDI sites
implement UDDI Version 1 at the time of writing, but the first implementations of
UDDI Version 2 are now appearing (UDDI Business Registry V2 Beta at the IBM
site http://www.ibm.com/services/uddi).
Pages
All known information about a business
Pages Key, name, contacts, identifierBag, categoryBag
contains businessServiceEntities
Yellow
Pages BusinessService
Family of services (busines process, for example)
Key, name, categoryBag
Contains bindingTemplates
Green
Pages BindingTemplate
Technical description of Web service
Key, name, access point (URL, for example)
Points to tModelInstance entities
Outlook
There is a road map for UDDI Version 2 and 3. UDDI version 2 provides support
for more taxonomies (categorization schemes) and for layered services. The
Version 2 specification is already available; beta level version 2 implementations
are available in January 2002.
The Version 3 specification is targeted for 2002. It will add workflow support and
allow to define custom taxonomies.
IBM and Microsoft have recently defined an additional specification for Web
service discovery: the Web services inspection language (WSIL). As opposed to
UDDI, WSIL defines a decentralized discovery mechanism, providing an XML
format for assisting in the inspection of a Web site for available services. WSIL
complements and provides bindings for WSDL and UDDI. The following
developerWorks article provides an overview:
http://www-106.ibm.com/developerworks/webservices/library/ws-wsilover/
“Dynamic Web services” on page 379 has an example for a provider dynamic
service requestor; additional information about types of registries and IBM’s
private UDDI implementation can be found in “Advanced UDDI topics” on
page 489.
Implementation
XSD XML WSDL
Interface
Metadata/vocabulary
Binding
Service description
UDDI
(Broker) HTTP MIME other
SMTP
MQ
SOAP
other Runtime
transports
WSDL
API
Requestor Provider
SOA Runtime
For example, a tModel provides supporting meta information about a service type
interface and points to the formal specification, which can be a WSDL port type in
a binding file.
Sources of information
Taking into account that Web services are an emerging technology, the amount
of information available on the Web is massive.
For more information on Web sites with information on Web services, see
“Referenced Web sites” on page 580.
Next
Now, let us take a look into the IBM tool support for Web services, before we
begin developing our auto parts sample application.
(*) Explain the difference between a UDDI tModel and a WSDL interface file.
SOAP
UDDI
SOAP Client
dds.xml Registry
Server Proxy
Figure 9-2 shows the input and output of the Web service wizard.
Web Service
Wizard Existing
application
for testing
Client Server
implementation
TestClient rpcrouter
S
interface
O
A Java
P start
Client-App Bean
Proxy
.wsdl dds.xml
UDDI Explorer DB Tx
publish deployment
descriptor
The Java proxy class encapsulates the code to make a SOAP request and to call
the Web service. In fact, the Web service client wizard is part of the Web service
wizard discussed above. It also contains the ability to generate, deploy and run a
sample Web application to test your Web service. A demonstration of the Web
service client wizard is described in “Web service client proxy” on page 354.
Figure 9-3 shows the input and output of the Web service client wizard.
implementation
TestClient rpcrouter
S
O
A Java
P
Client-App Bean
Proxy
find dds.xml
UDDI Explorer .wsdl
DB Tx
start deployment
descriptor
The main output is the client proxy (JavaBean). The sample test client can help
you in implementing the real client application.
In this wizard you start from an existing WSDL document and generate a
JavaBean. The generated JavaBean contains method definitions that conform to
the operations described in your WSDL document. After running this wizard you
have to implement the various methods in your skeleton bean to complete your
Web service implementation.
As in the Web service wizard, this wizard also allows you to generate a Java
proxy class and a sample Web application to test your Web service after you
have implemented the skeleton JavaBean. This wizard is demonstrated in
“Creating the JavaBean skeleton” on page 419.
Figure 9-3 shows the input and output of the Web service skeleton JavaBean
wizard.
implementation
TestClient rpcrouter
S
interface
O
A Java
P
Client-App Bean
Proxy
find dds.xml
UDDI Explorer .wsdl
DB Tx
publish start deployment
descriptor
The Web services DADX group configuration wizard enables you to create a
DADX group. The DADX group created with this wizard is used to store DADX
documents. A DADX group contains connection (JDBC and JNDI) and other
information that is shared between DADX files.
Once you have created a DADX group, you can import DADX files and then start
the Web service wizard to create a Web service from a DADX file. You can create
a DADX file by using the XML from SQL query wizard.
For all these operations, you have to create an account in the registry as
explained in “Preparing for development” on page 383.
WSTK architecture
The WSTK architecture (Figure 9-5) is split into:
Design-time Web services components
Runtime components, that are either
– Client components, called the Web services toolkit client runtime
– Server components
UDDI
registry
Customer
Web services
Design-time components
The design-time components of the WSTK include these tools:
To start the WSDL generator tool run the wsdlgen command located in the
WSTK_HOME/bin directory.
To start the service proxy generator tool run the proxygen -outputdir dir
wsdl-document command located in the WSTK_HOME/bin directory, where
outputdir specifies the output directory and wsdl -document is the WSDL input
document.
To run the service implementation template generator tool run the servicegen
wsdl-document -ouputdir dir command located in the WSTK_HOME/bin directory,
where outputdir specifies the output directory and wsdl-document is the WSDL
input document.
WSDL4J APIs
These APIs are a set of Java classes used to work with WSDL documents
programmatically.
Runtime components
The runtime components of the WSTK include these tools:
The client runtime also contains an Apache SOAP pluggable provider feature to
access non-Java Web services such as Microsoft COM objects.
DB2
DB2 access through Web services is supported by DADX files.The DAD exten-
sion (DADX) is an extension of the DB2 XML Extender document access defini-
tion (DAD) file. A DADX document specifies how to create a Web service using a
set of operations. The following operations are supported:
XML document based (retrieve and store XML). The operations are described
in DAD files that describe the mapping between XML documents elements
and DB2 database columns. They are used by the DB2 XML Extender, which
supports XML-based operations that store or retrieve XML documents to and
from a DB2 database.
SQL based (query, insert, delete, and update). This is demonstrated in
“Creating a Web service from a DADX file” on page 479.
DB2 stored procedure invocations
Versata
The Versata Logic Suite exploits the power of business logic automation to
deliver highly dynamic and scalable business systems. It is powered by the
Versata Logic Server (VLS), a container hosting an automation engine and
execution services within IBM WebSphere. For more information, visit the Web
site at: http://www.versata.com.
The Versata Transaction Logic Engine, at the core of the VLS, enables business
rules execution for transactional business logic and provides a J2EE framework
for necessary, reusable service, such as cross-object navigation, transaction
sequencing, event-action synchronization, and more.
Working with Web services and Versata together is an obvious match. The
automation engine provides a great mechanism for quickly building the
transactional aspects of the Web service provider implementation, both for
bottom up and top down scenarios. This integration can be already be achieved
today by using a combination of the IBM WSTK and the new Versata XML, and a
Web services toolkit, which we will describe in the next section.
As it is unlikely that the calling application wants to use VXML directly. The
adapter also provides the capability of invoking an XSL transformation on both
the inbound and outbound messages, and mapping it into a more appropriate
format for the client. This is illustrated in Figure 9-6. Such transformations can be
built using the XML tooling of Application Developer.
XSLT Handler
Message
VXML Handler
Listener
VXML
XML response Response
XSLT Handler
Client
Application XML & Web Services
Toolkit
Figure 9-6 Runtime topology of the Versata XML and Web services toolkit
Service WebSphere
Requestor Application
Versata Logic Server
Server
(Service Provider)
The Web service implementation contains one operation, process, which accepts
an XML element as an input parameter and returns the result of the rules
execution as a second XML element. Service requesters can use the WSDL
interface and implementation files supplied with the generic service processor to
create client proxies for integration into their applications.
Application Developer can assist the Versata developer in creating a client proxy
from the WSDL for the service. This client proxy, along with its accompanying
class libraries can then be imported into Versata, added to the class browser and
incorporated into business rules defined in the rules designer.
Almaden Autos decides to get involved in the Mighty Motors Web services
initiative, and is sent some WSDL describing the new Web service. Using the
interface and implementation information provided, it modifies its current
dealership inventory system to include an additional link for the mechanic that
enables searching the national system if no parts are available locally.
Figure 10-1 Basic design for the Web service provider and requester
The benefits of this approach is that neither Almaden Autos or Mighty Motors
require any details on how their Web service has been implemented, or which
type of technology has been used.
If you have not completed the steps described in the first part of this book, an
intermediate solution is available in the downloadable files that accompany it.
In order to create a clean layered architecture and a portable solution that returns
an XML document, we will create a JavaBean to interface with our session EJB.
This JavaBean will interrogate the session bean for the required information and
then convert the results into an XML document. We will then generate the Web
service from this JavaBean.
See “Creating a Web service from a session EJB” on page 374 for an example of
creating a Web service directly from a session EJB.
/**
* getDocumentBuilder - share XML document builder
*/
private DocumentBuilder getDocumentBuilder() throws Exception {
if (builder == null) {
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
builder = factory.newDocumentBuilder();
} catch (ParserConfigurationException ex) {
ex.printStackTrace();
throw new Exception("Error creating document builder: "+ex.getMessage());
}
}
return builder;
}
/**
* getPartsFacadeHome - share HOME of session bean
*/
private PartsFacadeHome getPartsFacadeHome() throws Exception {
if (partsFacadeHome == null) {
try {
InitialContext ic = new InitialContext();
Object objref = ic.lookup("itso/wsad/PartsFacade");
//Object objref = ic.lookup("java:comp/env/ejb/PartsFacade");
partsFacadeHome = (PartsFacadeHome)PortableRemoteObject.narrow
(objref,PartsFacadeHome.class);
} catch (NamingException ex) {
ex.printStackTrace();
throw new Exception("Error looking up PartsFacadeHome: "+ex.getMessage());
}
}
return partsFacadeHome;
}
/**
* newElement - create XML name/value pair
*/
private Element newElement(Document doc, String name, String value) {
Element element = doc.createElement(name);
element.appendChild( doc.createTextNode(value) );
return element;
}
Next, define a populatePart method that generates an XML element for the
XML document, containing a part and inventory item (Figure 10-8).
/**
* populatePart - create XML for a part
*/
private Element populatePart(Document doc, PartInventory bean)
throws org.w3c.dom.DOMException {
Element elPart = doc.createElement("Part");
elPart.appendChild( newElement(doc, "ItemNumber", bean.getItemNumber().toString())
);
elPart.appendChild( newElement(doc, "Quantity",
(new Integer(bean.getQuantity())).toString()) );
elPart.appendChild( newElement(doc, "Cost", bean.getCost().toString()) );
elPart.appendChild( newElement(doc, "Shelf", bean.getShelf()) );
elPart.appendChild( newElement(doc, "Location", bean.getLocation()) );
elPart.appendChild( newElement(doc, "PartNumber", bean.getPartNumber()) );
elPart.appendChild( newElement(doc, "Name", bean.getName()) );
elPart.appendChild( newElement(doc, "Description", bean.getDescription()) );
elPart.appendChild( newElement(doc, "Weight",
(new Double(bean.getWeight())).toString()) );
elPart.appendChild( newElement(doc, "ImageURL", bean.getImageUrl()) );
return elPart;
}
/**
* inquireParts - find matching parts and return as XML
*/
public org.w3c.dom.Element inquireParts(String partNumber) throws Exception {
Element result = null;
Document doc = null;
DocumentBuilder builder;
PartsFacade partsFacade;
doc = getDocumentBuilder().newDocument();
result = doc.createElement("InquirePartsResult");
result.setAttribute("xmlns",
"http://www.redbooks.ibm.com/ITSOWSAD/schemas/InquireResults");
result.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
result.setAttribute("xsi:schemaLocation",
"http://www.redbooks.ibm.com/ITSOWSAD/schemas/InquireResults
wsdl/InquireParts.xsd");
try {
partsFacade = getPartsFacadeHome().create();
Vector resultbeans = partsFacade.inquireParts(partNumber);
for (int i=0; i<resultbeans.size(); i++) {
result.appendChild( populatePart(doc,
(PartInventory)resultbeans.elementAt(i)) );
}
} catch (CreateException ex) {
System.out.println("Cannot find part: "+partNumber);
ex.printStackTrace();
throw new Exception("Error finding part: "+ex.getMessage());
} catch (java.rmi.RemoteException ex) {
ex.printStackTrace();
throw new Exception("Error with session EJB: "+ex.getMessage());
}
return result;
}
Note the XML schema location attribute is defined using a very confusing
notation that separates the target name space from the location of the schema
using a space. For more information on name space and location refer to
Chapter 4, “XML support in Application Developer” on page 91.
Click Work with Object and the InquireParts class appears under the Class
References in the References pane.
Expand the InquireParts class and select the InquireParts() constructor.
If you want to explore the tree structure of the returned XML element:
Click on Method Visibility (under InquirePartsResult).
Select both org.w3c.dom.Element and org.w3c.dom.Node and click Set. This
action adds additional methods (from Node) to the InquirePartsResult
object.
You can now execute methods such as getChildNodes or getFirstChild to
explore the XML tree structure.
Figure 10-12 Assets generated from Web service wizard during this section
The Web service will have a similar interface to the InquireParts class—a single
method inquireParts that accepts the part number as its input parameter and
returns a XML element containing the results of the query.
The XML result shown in Figure 10-13 conforms to the XML schema
(InquireParts.xsd) that we developed in “Generating an XML file and an XML
schema from SQL” on page 111.
Figure 10-13 Sample returned XML element data for InquireParts Web service
Once completed, we will have developed the first Web service and be able to
investigate its content.
This information will be part of the deployment descriptor for the Web service.
If the Use static methods option is selected, the class method that is made
available is a static method, and therefore, no object will be instantiated.
Because one instance of the SOAP router exists for each Web application (WAR
file), this option can only be edited when creating the first Web service for the
project. When creating further Web services with the Web service wizard, this
option will be disabled, showing the status of the first selection.
The wizard shows that one public method in our JavaBean is available to
include. Make sure the inquireParts method is selected.
This panel also enables us to select the encoding style for the input and output
data of each method. The encoding style defines how the Java types in the client
and server are mapped to the XML types in the SOAP message. There are two
encoding styles available:
Literal XML encoding This must be selected if the element to encode is of
type org.w3c.dom.Element. The XML element is then
inserted directly into the SOAP message.
SOAP encoding Use this option for all other datatypes, including simple
Java types, standard Java classes and non-complex
custom classes.
This illustrates the mappings between Java and XML for the Web service to
operate, assuming both a Java client and a Java server.
There are four steps in the process, indicated by the numbers in the illustration:
1. Client input mapping
This takes the parameter from the Java client and maps it using the input
encoding style. In our example, this input parameter is the part number,
defined using a Java String class and using the SOAP encoding style. This is
serialized to an XML type name of xsd:string.
2. Server input mapping
The inbound part number is now deserialized from the SOAP encoding style
in the message to a Java type of String, which is then used to invoke the
method in the JavaBean.
Figure 10-18 Java to XML mappings for input parameter and output result
Proxy generation
The client proxy provides an RPC call interface to the Web service. While this
proxy is not necessary for the implementation of the Mighty Motors application, it
provides a very useful mechanism for testing the Web service before we make it
available to third parties. Its usage was illustrated in Figure 10-12 on page 334.
We will go into more detail about this later when we integrate the Almaden Autos
Web application with the Mighty Motors Web service.
The Web Service Binding Proxy Generation panel of the wizard is shown in
Figure 10-19.
The String entry defines the mechanism to map the input XML data type to
the Java type expected by our JavaBean, as shown in phase (2) in
Figure 10-17. Leave the default mapping (string) for the input parameter.
The InquirePartsRemoteInterface entry defines the mechanism to map the
output from our JavaBean to the XML element in the reply message, shown
as phase (4) in Figure 10-17. Leave the default mapping (DOM Element) for
the result XML.
Click Next.
Application Developer now generates the Web service and associated files. The
Web service is then published to the associated server and the server is started if
it is not already running.
In this section we made a single pass through the Web service wizard and
explained some of the terminology and options available. Upon completion, a
number of files have been created. The next part of the chapter focuses on
looking at these files in more detail.
Client proxy
Deployment descriptor
Required JAR files
We want to use the XSD we created previously in “Generating an XML file and an
XML schema from SQL” on page 111. We have to replace the wizard generated
XSD file with the one we previously developed. To do this copy the XSD file we
created from the ITSOMightyXML project to the ITSOMightyWeb project:
Select the InquireParts.xsd from the ITSOMightyXML folder.
Select Copy from the context menu.
Select the ITSOMightyWEB/webApplication/wsdl folder and click OK.
Click Yes on the overwrite warning.
The XML schema file (InquireParts.xsd) is generated if you do not overwrite the
default mapping (Figure 10-18 on page 341).
The elements shown in bold define the location of the service interface file and
the URL of the SOAP router servlet required to invoke the service.
Note that there are two references (underlined) to a generated XML namespace
(in addition to the two standards defined in http://schemas.xmlsoap.org), which
we could not modify in the Web service wizard.
Operation Method
There are four items in this file that we have to change, all of which are
underlined:
We must change the XML namespaces in the interface file to match the
namespace used in the implementation file. Change both targetnamespace
and xmlns:tns entries (first two underlined):
from: http://www.inquireparts.com/definitions/InquirePartsRemoteInterface
to: http://www.redbooks.ibm.com/XXXXXXXX/definitions/InquirePartsRemoteInterface
XXXXXXXX = your last name or initials
We must change the XML namespaces for our XML in the interface file to
match the namespace used in the XSD we previously built. Change both
xmlns:xsd1 and the <import> namespace attribute (second two underlined) :
from: http://www.inquireparts.com/schemas/InquirePartsRemoteInterface
to: http://www.redbooks.ibm.com/ITSOWSAD/schemas/InquireResults
Save the changes in both WSDL files and close the editors.
Replace XXXXXXXX with a name of your own (for example your last name or
initials). This avoids duplicate names when we publish the Web service to the
IBM UDDI Test Registry.
However, do not change the namespace that refers to the XSD schema:
http://www.redbooks.ibm.com/ITSOWSAD/schemas/InquireResults
The loading hierarchy of the application and how it relates to the various
deployment descriptors is shown in Figure 10-25.
built
from
application.xml web.xml soap.xml dds.xml *.isd
dds.xml
Open the dds.xml file (Figure 10-26). As you can see, this file defines the name
of the class that implements the Web service and the method to invoke. The
scope="Application" attribute is directly related to the Web service scope that
we selected in Figure 10-15 on page 337.
rpcrouter This is the SOAP router servlet invoked for all RPC style
calls to the Web service. This will be used by our application.
messagerouter This router is used for all message style calls to the Web
service.
This allows us to view all of the important information about the Web service we
have developed, including the provider class, its exposed methods, and the
provider type—in this case, a Java class.
Note that the deployment process is not an explicit step—the Web service wizard
generates an entry in dds.xml, which is picked up by the router servlet when it is
initialized.
It is also possible to start and stop specific services from this administration
console using the other links on the left hand side (Figure 10-28).
This can be performed while an application that uses the Web service is
executing. This scenario may be useful when testing how a client application
handles the scenario that the Web service is unavailable.
This class can be completely regenerated with access only to the generated
interface and implementation WSDL files. It is worth investigating this class in
more detail because it demonstrates how to programmatically invoke the Web
service from a client.
The Call class (from the org.apache.soap.rpc package) is the main component
responsible for completing the SOAP call between the client and the server. Note
that the API shields you from the implementation details of the SOAP message
contents and significantly simplifies the calling mechanism.
The proxy class sets up the URL of the SOAP router servlet in the declaration of
the stringURL variable. This is then used in the getURL method to determine the
URL to be invoked from the Web service.
private String stringURL = "http://localhost:8080/ITSOMighty/servlet/rpcrouter";
The proxy has a single method to invoke the service, inquireParts, which has
the same method signature as the method included in the Web service
implementation JavaBean on the server side.
if(getURL() == null)
{
throw new SOAPException(Constants.FAULT_CODE_CLIENT,
"A URL must be specified via InquirePartsProxy.setEndPoint(URL).");
}
call.setMethodName("inquireParts");
call.setEncodingStyleURI(Constants.NS_URI_LITERAL_XML);
call.setTargetObjectURI(targetObjectURI);
Vector params = new Vector();
Parameter partNumberParam = new Parameter("partNumber", java.lang.String.class,
partNumber, Constants.NS_URI_SOAP_ENC);
params.addElement(partNumberParam);
call.setParams(params);
Response resp = call.invoke(getURL(), SOAPActionURI);
This code defines the URN required to invoke the Web service, the default
encoding style for the proxy (SOAP encoding), and the URL of the target SOAP
router. Again, these values can be obtained from the generated WSDL files.
The important aspects of the method are shown in bold type. The method name
to invoke on the service is defined using setMethodName.
Call Object
Call return Parameter
encoding style encoding
(Element) (partNumber)
The parameters for the Web service are constructed into a Vector of types
org.apache.soap.rpc.Parameter.
To invoke the service, the proxy calls the invoke method, which returns an object
of type org.apache.soap.rpc.Response. Finally, the getReturnValue method is
called on the response to obtain the wrapped XML element that contains the
results of the parts inquiry.
The results pane should display the XML document returned from the Web
service (Figure 10-32).
Your Web service implementation is now complete and tested. Well done!
In the server perspective, select the ITSOWSADServer server project and select
the File -> New -> Server Instance and Configuration menu and complete the
dialog (Figure 10-33), then click Finish.
In the server perspective, a new entry should appear in the Server Configuration
and Servers views. Note that unlike other server instance types, you cannot add
or remove projects from the server configuration.
Next, add the TCP/IP Monitor view to the server perspective by selecting
Perspective -> Show View -> TCP/IP Monitor.
A new view appears (Figure 10-34). It consists of three panes, showing a list of
requests, and the contents of each request and response. You can move the
view over the Console/Servers view.
The monitor can be used for two purposes. First, we will use it to view the
requests sent between the browser and the sample Web service client, as
illustrated in Figure 10-35.
String
Port Port JSP Test SOAP
8081 TCP/IP 8080
Browser Client Client
Monitoring
Element
Server
Service Proxy WSDL
Service Requestor
Figure 10-35 Using the TCP/IP monitoring server to view the HTTP requests
Select Launch “Open Web Browser” using TCP/IP monitoring server. Click
Finish.
Execute the application as before, invoking the inquireParts method with a
part number of M100000003, then return to the TCP/IP Monitor view.
Expand the host entry and select a request to see the responses
(Figure 10-37).
The second, and more interesting option, is to use the monitor to view only the
communication between the Web service client proxy and the SOAP router
servlet, as illustrated in Figure 10-38.
Port Port
String 8080 String
SOAP 8081
TCP/IP SOAP
Client Server
Monitoring
Element Element
Server
Service Proxy WSDL DD Access Bean
Service Requestor Service Providor
Figure 10-38 Using the TCP/IP monitoring server to view the SOAP requests
To configure this, we must change the binding URL defined in the client proxy
class:
While leaving both the WebSphere and TCP/IP monitoring servers executing,
open the InquirePartsProxy.java file in the Java editor.
Change the URL line:
from: private String stringURL = "http://localhost:8080/ITSOMighty/servlet/rpcrouter";
to: private String stringURL = "http://localhost:8081/ITSOMighty/servlet/rpcrouter";
Output XML
To execute the test client in future without the TCP/IP monitor, ensure that you
change the port defined in the client proxy back from 8081 to 8080.
Stop the TCP/IP monitoring server, but leave WebSphere test environment
instance running before progressing onto the next section.
The Web service has now been successfully developed. After running through
the Web service wizard, we amended the generated WSDL files to support our
schema namespace conventions and then executed the service in WebSphere
using the generated client proxy and test client.
For the first phase of this implementation, we assume that Mighty Motors sends
the WSDL files to Almaden Autos, and that they integrate the Web service into
their application at development time using static bindings. This is a more
realistic scenario than directly copying the client proxy between projects. The
more advanced topic of dynamic binding to a Web service and searching for
implementations in a UDDI registry is covered in the next chapter.
Figure 10-40 Basic design outline for Almaden Autos Web service requester
To do this:
Start the ITSOWSADWebSphere server (if it is not running).
Select the InquireParts-service.wsdl file in the ITSOAlmaWeb project and
New -> Other -> Web Services -> Web Service client. Click Next.
ITSOAlmaWeb should be preselected as Web project. Select the Generate a
sample option and click Next.
On the next panel, the WSDL file is preselected:
ITSOAlmaWeb/webApplication/wsdl/static/InquireParts-service.wsdl
Click Next.
At this stage, the Web service client wizard connects to the ITSOWSADWebSphere
server instance to retrieve the rest of the required Web service files, specifically
the service interface file InquireParts-binding.wsdl and the XML schema file
InquireParts.xsd.
If this is successful, the wizard displays the WSDL bindings and prompts for
the proxy class. Enter a proxy qualified class name of:
itso.wsad.alma.wsstatic.proxy.InquirePartsProxy
Select the Show mappings option and click Next.
View the XML to Java mappings. This should reflect the settings we defined
earlier in the Web service wizard when we initially created the service
(Figure 10-20 on page 343). The settings are default JavaBean mapping for
the parameter and DOM Element mapping for the result. Click Next.
The resulting frame should again display the contents of our XML element.
We will be using the Apache Xalan XSL parser during this exercise, so add the
class path variable WAS_XALAN into the ITSOAlmaWeb project’s Java build path.
Figure 10-41 XSL style sheet to display Mighty Motors Web service results
This style sheet creates a results table containing the part number, name,
quantity and cost and then creates a row in the table for each part in the XML
document.
Close the XSL editor and save all changes.
Accept the default values to add the servlet to web.xml and click Finish.
import javax.servlet.http.HttpServlet;
transformer.transform(xmlSource,
new javax.xml.transform.stream.StreamResult(out));
} catch (Throwable e) {
e.printStackTrace();
}
}
Figure 10-43 Source code for the servlet to invoke the Web service client proxy
if Scriptlet
else Scriptlet
new message
end Scriptlet
Add the else scriptlet the same way by placing the cursor after our message
and inserting a scriptlet with the following code:
} else {
To complete that code we need to place and end scriptlet immediately after
the table. Place the cursor immediately preceding the existing scriptlet that
follows the table and insert a scriptlet with the code:
}
Save the changes and test the Almaden Autos Web application as you did in
Section , “Executing the Web application” on page 86 using part numbers
M100000001 (result table) and M100000003 (no data returned message).
Note, we could have used the existing submit form Java script by entering a
URL of javascript:submitForm('MightyMotorsInquire'). However, this
invokes the ProcessController servlet with the MightyMotorsInquire value,
and we would have needed to modify the initialization parameters of the
controller servlet to include our new servlet, MightyMotorsInqiure.
new
code
Figure 10-47 Inventory inquiry results page with Web service results
It would be nice to enhance the client so that you can select an item from the
returned table, and be able to see the details on that part. There are a number of
alternatives to doing this:
Create another servlet that calls the existing Web service again, returning all
of the parts, and pass the selected item number into a new style sheet
designed to display the details of one item. This has the disadvantage of
retrieving all of the matching data from the database through the entity EJBs,
and is quite a large overhead.
Add the entire returned XML element, or a Java object representation of the
entire result set, into the HTTP session and retrieve the selected item from
the session for display on a new XSL style sheet. However, it is not good
practice to put large amounts of data in the HTTP session.
Create a second Web service that retrieves a single instance of a part, given
a specific item number as parameter, and perhaps returning a custom Java
type instead of an XML element.
The third option is the most attractive, but does require a significant amount of
development at this stage. Creating Web services that use custom types is
discussed in more detail in Chapter 14, “Web services advanced topics” on
page 447.
A Web service can also be created directly from the session EJB, and return the
result as a vector or array to the client. The client can then extract the results as
Java classes and format the data in any desired way. This formatting can be done
in a servlet or JSP, however, without having the nice XSL style sheet facility at
hand.
Here are short instructions on how to create a Web service from the PartsFacade
session bean. Note that this section is optional and has no effect to future
enhancements of the sample application.
Note: SOAP provides encoding for JavaBeans, vector and array results. See
“Implementing a Web service with a JavaBean as parameter” on page 451.
Generated files
The generated files include:
The proxy class (itso.wsad.mighty.sessionejb.PartsFacadeProxy)
WSDL and schema files in the wsdl folder
A sample test application in the sample\PartsFacade folder
A PartsFacade.isd file in the WEB-INF\isd folder (it is worth opening this file
and comparing it to the InquireParts.isd file)
An updated dds.xml file that includes the content of both ISD files
Using the generated test clients and the TCP/IP Monitoring Server, we explored
the runtime behavior of the service, along with investigating the components that
were generated.
In the next chapter, we will take this example a stage further by changing the
client from being a static service binding to a dynamic binding, and then we will
examine working with a UDDI registry.
Quiz: To test your knowledge of building static Web services, try to answer the
following five questions. The answers are provided in Appendix C, “Quiz
answers” on page 559.
1. What are the three types of Web service scope, and where are they
defined?
2. What is the difference between Literal XML encoding and SOAP
encoding?
3. Which of the following is the service implementation file, and which is the
service interface file?
– InquireParts-service.wsdl
– InquireParts-binding.wsdl
4. What are the ISD files used for?
5. Which of the two WSDL files are used as the basis of the client proxy
generation?
We will develop a provider dynamic service requestor. This chapter features the
UDDI explorer as well as the APIs for programmatic access to the UDDI registry,
where we will:
Publish a business entity, business service, binding and service type
Develop a client side proxy and use the UDDI4J APIs to dynamically locate
and invoke the published implemented services
The mechanics of Almaden Autos are still not satisfied with the parts inquiry
service that searches the inventory systems of both the dealership and the
vehicle manufacturer Mighty Motors.
To simplify the example, we add another actor, the Auto Parts Association. This
business entity takes ownership of the WSDL interface document from Mighty
Motors. All services are registered under this business entity; the manufacturers
themselves do not appear in the UDDI registry.
JSPs
Mechanic
UDDI Registry
(Browser) UDDI
SOAP Client
SOAP DB
2 Server
3 3 1
1
Parts
Manufacturer
Parts Manufacturer Manufacturer Parts
Manufacturer National Depot & Inventory DB
App. Server
JDBC
EJBs
SOAP Server SOAP Server
At runtime, the Almaden Autos application queries the UDDI registry to find
implementations of the InquireParts Web service by the Auto Parts association
business entity. There can be multiple implementations, for example, by Mighty
Motors and Plenty Parts.
The SOAP addressing information is extracted from the UDDI registry, and each
Web service is then dynamically invoked by the Almaden Autos application. The
inquiry results are displayed, and the mechanic can choose from which parts
manufacturer to order the part.
We mainly work in the Java and the Web perspective in this stage. As a UDDI
registry, we use the public IBM Test Registry, but the code has also been tested
using the IBM WebSphere UDDI Registry Preview (a private registry).
Class diagram
The component model for auto parts Stage 3 is displayed in Figure 11-2. We will
explain the classes, attributes, and methods when we implement them.
Sequence diagram
The component interactions for the discovery part of auto parts Stage 3 are
displayed in Figure 11-3. Use it as a reference in the subsequent discussions.
The interactions for the service invocation are very similar to those in auto parts
Stage 2. They are therefore not displayed in the figure. See “Static Web services”
on page 321 for further information.
InquireParts-binding.wsdl
Figure 11-4 Service interface and implementation WSDL files
To distinguish between the Web services of Plenty Parts and Mighty Motors, we
want to assign more meaningful service names in the implementation files
(webApplication/wsdl/InquireParts-service.wsdl):
For Plenty Parts we specified the service name as InquirePlentyParts, instead
of InquirePartsService:
<service name="InquirePlentyParts">
For Might Motors, edit the InquireParts-service.wsdl file and change the
service name:
From: <service name="InquirePartsService">
To: <service name="InquireMightyMotors">
Note: Changing the name of the service in the implementation file does not
affect the runtime environment:
The service name is not stored in the deployment descriptor.
Each Web application has its own deployment descriptor and SOAP
administration application.
The service is accessed through its URI (urn:InquireParts ).
Our Web services have the same URI but run in different Web applications.
In the steps that follow, we use the UDDI explorer and its built in categorization
helper utility to:
Publish a business entity (the service provider)
Publish a service interface and implementation
Find and import a service interface and implementation
1 Business
Entity
n
Business
UDDI Service
1
http://www.redbooks.ibm.com/XXXXXXXX/
contains definitions/InquirePartsRemoteInterface
points to m tModel
n find
(ServiceType)
Binding n n
WSDL
1
Template
1
0..1 0..1
Implementation n 1 Interface
Document import Document
ITSOMighty/InquireParts-service.wsdl ITSOMighty/InquireParts-binding.wsdl
ITSOPlenty/InquireParts-service.wsdl ITSOPlenty/InquireParts-binding.wsdl
Restriction: The IBM Test Registry allows you to publish only one business
entity per registered user, up to four services per business entity, two binding
templates per business service, and ten tModels per registered user. Similar
restrictions apply to the IBM Business Registry, which we do not use.
Figure 11-6 shows the UDDI browser GUI after selecting the IBM Test Registry.
(XXXXXXXX)
XXXXXXXX
Attention: Replace XXXXXXXX with your last name or initials to distinguish from
other users that go through this exercise.
(XXXXXXXX)
Mighty Motors
We start with the publishing of Mighty Motors’ InquireMightyMotors Web service
by taking these steps:
Ensure that the WSDL file is accessible from your workstation, for example:
http://localhost:8080/ITSOMighty/wsdl/InquireParts-service.wsdl
Start the ITSOWSADWebSphere server if it is not running. You will receive an
HTTP error 500 or a NullPointerException otherwise because the explorer
gets the WSDL file from that URL. In order to verify that the URL can be
served, open a new Internet Explorer and direct it to the URL. The XML
representation of the WSDL specification should be displayed.
In the UDDI Navigator pane, select the business entity we have created in the
previous step.
In the Actions pane, click the Publish Business Service icon and the
actions panel for a business service opens (Figure 11-10).
Click Browse and locate the ITSOMighyWeb project and select the
InquireParts-service.wsdl file. Click GO.
Note: If you select the WSDL file before opening the UDDI explorer, then it is
already filled in this panel.
In the Actions pane, enter a meaningful explanation of the service in the
Description text box.
Click Add to add category types, key names, and key values for your Web
service. Click Browse and navigate through the NAICS category hierarchy to
select the same Key name as in the previous step. The Key value defaults
when a key name is selected.
Click Go in the Actions panel.
The UDDI explorer is automatically updated with the published Web service. The
explorer automatically publishes the WSDL binding document
InquireParts-Service-binding.wsdl as well.
Three entities are created in the UDDI registry: a business service, a binding
template, and a tModel (service type).
Attention: The.wsdl files must contain valid URLs that are accessible from
your workstation; if both the service provider and the service requester run on
the same machine, the generated code does not have to be modified. If they
do not, replace all occurrences of localhost with the hostname for the
development environment of the service provider. Use the correct hostname in
the URL for WSDL Implementation file input field of the UDDI browser as well.
In our example, localhost is fine because all processes run on one machine.
Note that in the UDDI browser, two services with the same interface are
displayed (Figure 11-11). They only differ in the URLs pointing to the WSDL files
on their respective Web sites.
Business entity
Business service
tModel
(service type)
Tip: You can run multiple instances of the Web service on the same machine.
In this case, you either have to register and lookup the Web service under
multiple URNs (not recommended). Alternatively, you can deploy the different
instances of the Web service into different Web applications. Because each of
these Web applications has its own URL prefix and RPC router servlet, the
SOAP server address (the URLs of the router servlet, that is), is guaranteed to
be unique.
Please note that the IBM Test Registry is not a production site; on the other hand,
the IBM Business Registry should not be used for development and test
purposes.
Verification
With the two publish operations we have just performed, we have created a
complete UDDI tree structure conforming to the data model presented in the
UDDI overview in “Web services overview and architecture” on page 241.
There is a business entity, two business services and binding templates, as well
as a tModel (or service type).
Click on each of the entries to inspect the respective attribute details. For
example, if you click on ITSO - Auto Parts Association and then the link under
Discovery URL, you can download an XML file containing a registry dump of the
business entity and all contained entities.
Note: Although the WSDL file was used to publish the Web service to the
UDDI registry, the WSDL file itself is not stored in the UDDI registry.
Click on InquireMightyMotors as well. Note that the details of the service do not
display any service type information. In order to see it, you have to go into the
edit mode. Go back to the first page and click on the Edit link in the
InquireMightyMotors row.
From the Edit Service page, click on the Edit link of the only row in the Access
Point(s) table. The Edit Access Point page lists the pointer to the tModel as the
only entry under Service Type Details. Click on the Edit link of this entry. On the
Edit Service Type Information page, the Implementation Details Overview
contains the link to our WSDL implementation file.
Note that we do not directly exchange code between the Application Developer
projects that implement the provider and the requestor (ITSOMightyWeb and
ITSOAlmaWeb, respectively). We rather use UDDI as the only interface between
the two projects.
Also, note that we only import the InquireParts-binding.wsdl service type file,
because we implement a provider dynamic requester. The UDDI browser would
have allowed us to import one of the two service implementation files as well.
As an optional step, you can go to the Navigator view and double-click on the
imported WSDL file to launch the XML editor. Take a look at its message, port
type, and binding elements.
Restriction: You might want to validate the WSDL file. However, Application
Developer can only check for well-formedness because the WSDL XSD is not
accessible.
Simply locate the entity you want to delete and select the Unpublish icon from the
upper right corner of the window. Make sure that you are logged in with an
appropriate user ID and password combination.
Do not delete the entries now; otherwise, our provider dynamic service requester
will not find any business services in the UDDI registry. You might want to
perform this step after having completed this redbook to cleanup the registry.
To update business entities, service types, and (business) services, locate the
entry and click the Update icon to change the data.
Note that we could have generated the client proxy on a different machine than
the server implementation. The only link between the two systems is the WSDL
file.
UDDI Registry
Business Entity white pages Service Type
Business Service (tModel)
Categorization Specification
yellow pages
Description Categorization
Description
URL
Access Point (Binding Template)
green pages
UDDIAccessor class
To create the UDDIAccessor class:
First add two variables, DDI4JJAR and MAILJAR, to the ITSOAlmaWeb project
Java build path. Define them as:
UDDI4JJAR <WSAD_INSTALL_DIR>plugins/com.ibm.etools.
websphere.runtime/lib/uddi4j.jar
MAILJAR <WSAD_INSTALL_DIR>plugins/com.ibm.etools.
servletengine/lib/mail.jar
UDDIAccessor processing
Let us take a closer look at the UDDIAccessor class. The UDDI lookup is done in
the findServiceImplementors method. The goal of this method is to collect all
the access points defined for a given provider and service type and return the list
as a Java vector.
To understand how the access points are located for the specified service and
provider, let us examine the relationship between the UDDI entities available
through the UDDI4J APIs.
2
provider
service type 1
Business Service
(serviceInfo) tModelBag
3
Service ID
(serviceKey)
Binding Template
3
Access Point
Figure 11-15 Locating the access points from the service type and business entity
Collect tModels
Using the service type parameter, we find all the tModels and collect their keys in
a tModelBag:
// find tmodel for the service name and fill tModelBag with keys
TModelBag tmb = new TModelBag();
Vector tmbv = new Vector();
tmb.setTModelKeyVector(tmbv);
TModelList tml = proxy.find_tModel(servicename, null, 0);
TModelInfos tmis = tml.getTModelInfos();
Vector v1 = tmis.getTModelInfoVector();
for (int i1=0; i1 < v1.size(); i1++) {
TModelInfo tmi = (TModelInfo)v1.elementAt(i1);
String tmk = tmi.getTModelKey();
System.out.println("TModel="+tmi.getNameString()+" "+tmk);
TModelKey tmKey = new TModelKey(tmk);
tmbv.addElement(tmKey);
if (i1==14) { System.out.println("Too many tModels-stop");
break; }
}
The access points can then be used to invoke the service dynamically, which we
describe when we implement the servlet that uses the UDDIAccessor class (see
“UDDI lookup servlet” on page 405).
UDDIAccessor testing
In the spirit of iterative development, we will now test the UDDIAccessor class
before integrating it into our application.
package itso.wsad.alma.wsdynamic.uddi;
import java.util.Vector;
Running this class with our service type and provider parameters produces the
output shown in Figure 11-17. (The .... in the listing indicate the UUIDs in the
registry.)
To run the program, change the XXXXXXXX to your specifications, and start the
program in the Java perspective.
Processing
The UDDILookupServlet first places some initial HTML into the output stream.
The key portion of the servlet comes next and is highlight in bold. The servlet
uses the UDDIAccessor we implemented in “UDDIAccessor class” on page 399 to
get a list of all the access points (endpointURLs) defined in the registry for our
provider and service type.
For each Web service exercised successfully, the returned data is transformed
into HTML using an XSL style sheet and added to the output stream.
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:res="http://www.redbooks.ibm.com/ITSOWSAD/schemas/InquireResults">
<xsl:output method="html"/>
<xsl:template match="res:InquirePartsResult">
<table border = "1">
<tr><bold>
<TH BGCOLOR="#00ffff">Part Number</TH>
<TH BGCOLOR="#00ffff">Name</TH>
<TH BGCOLOR="#00ffff">Quantity</TH>
<TH BGCOLOR="#00ffff">Cost</TH>
<TH BGCOLOR="#00ffff">Location</TH>
</bold></tr>
<xsl:apply-templates/>
</table>
</xsl:template>
<xsl:template match="res:Part" >
<tr>
<td><xsl:value-of select="res:PartNumber"/></td>
<td><xsl:value-of select="res:Name"/></td>
<td><xsl:value-of select="res:Quantity"/></td>
<td><xsl:value-of select="res:Cost"/></td>
<td><xsl:value-of select="res:Location"/></td>
</tr>
</xsl:template>
</xsl:stylesheet>
Figure 11-19 Style sheet implementation for the dynamic Web service
This style sheet creates a results table containing part number, name, quantity,
and cost columns, and then creates a row in the table for each part in the XML
document. The rest of the HTML is generated in the servlet.
This is a link to the UDDILookupServlet we just developed. Make sure to use the
name specified when registering the servlet into the web.xml file with the servlet
creation wizard in “UDDI lookup servlet” on page 405.
This completes the implementation of the dynamic Web service example. We are
now ready to test the implementation.
Unit testing
As in the previous steps, the unit testing is performed in the WebSphere Test
environment included in Application Developer. Use the TCP/IP Monitoring
Server introduced in “Static Web services” on page 321, to intercept and trace
the communication between the service requester and the two service providers.
Now you can start the server instance and load the Almaden Autos homepage
(PartsInputForm.html) into the browser in the same way as shown in “Static
Web services” on page 321 (Figure 11-20).
Select a part that is not locally available, M100000003. and click Submit. No parts
are found, and the updated HTML with the new link is displayed (Figure 11-21).
Click on the new link that allows you to discover part manufacturers in the UDDI
registry. The search results are shown in Figure 11-22.
Make sure that your class path settings include the JAR files mentioned in “Unit
testing” on page 408.
Quiz: To test your knowledge about dynamic Web services, try to answer the
following five questions. The answers are provided in Appendix C, “Quiz
answers” on page 559.
1. Name the two different types of dynamic Web service clients, and explain
the difference between them. Which type is likely to be implemented more
often?
2. List at least three different ways in which you can inspect the content of a
UDDI registry.
3. Which two HTTP operations must a service provider support, after
publishing a service to the UDDI registry?
4. Name at least three artifacts in the UDDI object model.
5. Which WSDL file is the implementation file and which file, is the interface
file?
To be able to do this chapter you must have completed Chapter 10, “Static Web
services” on page 321. It is not necessary to have finished Chapter 11, “Dynamic
Web services” on page 379.
Dealership Web DB
Applicat. Server Other
Servlets Dealership
Mechanic JSPs
(Browser)
2 UDDI
SOAP SOAP SOAP
Client Server 3 Client Registry
optional
SOAP
4 1 Server
Parts
Manufacturer
Parts Manufacturer Manufacturer
Manufacturer National Depot Parts & Inventory
App. Server DB
JDBC
EJBs
SOAP Server SOAP Server
We introduce another car dealer, Santa Cruz Sports Cars, which uses the Web
service of Almaden Autos to look up parts. Using the terminology introduced in
Chapter 8, “Web services overview and architecture” on page 241 Santa Cruz
Sports Cars is the service requestor and Almaden Autos is now the service
interface provider and service implementation provider.
We do not show how Santa Cruz Sports Cars in turn can expose its inventory
system as a Web service, because this step is identical to the case of Almaden
Autos we describe in this chapter.
Moreover, a composed Web service would usually invoke Web services with a
different signature than the original one. For instance, we could have a parts
inquiry Web service that invokes in its implementation another Web service
which looks up the prices for the parts found. It then sends back all information
(parts + prices) to the requestor. For simplicity reasons, we do not introduce a
Web service with a different signature than the one created in Chapter 10,
“Static Web services” on page 321.
The interaction diagram (Figure 12-3) shows the scenario in which nothing is
found in the local database of Santa Cruz Sports Cars, and nothing is found in
the Almaden Autos database. Eventually, the part is found in the Mighty Motors
database.
To make it easy, Santa Cruz Sports Cars is (besides the name and the database
tables it uses) identical to Almaden Autos developed in Chapter 3, “Web
development with Application Developer” on page 55. Therefore, you can follow
the guidelines of that chapter in order to create the Santa Cruz Sports Cars
dealer. You can skip the section “Creating the ITSOWSAD sample database” on
page 61 because the ITSOWSAD already contains the tables necessary to
construct the Santa Cruz Sports Cars dealer. You should use the
SSINVENTORY and SSPARTS tables instead of the AAINVENTORY and
AAPARTS tables throughout the guidelines.
If you do not want to go through all the steps of Chapter 3, “Web development
with Application Developer” on page 55, you can just import the necessary
projects into the workspace by taking the following steps:
In the Web perspective select File -> Import. Select EAR file and click Next.
Locate the sampcode\wscomposed\ITSOSanta.ear file and specify
ITSOSantaEAR as the project name. Click Finish.
After importing the EAR file, two new projects are added to the workspace:
– EAR project ITSOSantaEAR
– Web project ITSOSantaWeb
Add the ITSOSantaEAR project to the ITSOWSADWebSphere server configuration.
Make sure the Santa Cruz Web application is working before continuing. You can
test the Web application the same way as you test the Almaden Autos Web
application (use part number M100000001 as test input).
Note: In a real-life situation you cannot copy the file from the Mighty Motors
Web application as we do here. Instead you could download the file through
the URL pointer in the UDDI registry as illustrated in Chapter 11, “Dynamic
Web services” on page 379, or you could receive it through e-mail.
Note: In a real life you cannot just copy the file. Instead, you can invoke the
link for the schema in a browser, and download it to your file system;
afterwards, importing it into your workspace. Alternatively, this XML
schema can be hosted at a central location, such as the Auto Parts
Association standards body.
import org.w3c.dom.*;
Attention: Although we specified the qualified path for the skeleton JavaBean
as itso/wsad/alma/wscomposed/service/InquireParts.java, the code was
generated into a folder named itso.wsad.alma.wscomposed.service.
Now let us take a closer look at the methods in the InquireParts class:
The inquireParts method (Figure 12-7) implements the Almaden Autos Web
service. It allocates and executes the PartsMasterViewBean to retrieve local
data and converts the local data by calling the convertXml method. If no local
data is found, it invokes the Mighty Motors Web service using the proxy
generated for the static Web service.
The convertToXml method (Figure 12-8) converts a local SQL result data to a
DOM Element to match the result of the Mighty Motors Web service. First the
result is initialized and then the populatePart method is called for each result
row of the SQL view bean.
The populatePart method retrieves the column values of the SQL row to
generate the XML for one inventory item by calling the newElement method for
each column value.
The newElement method creates one name/value pair.
The getDocumentBuilder method instantiates a shared document builder.
The last three methods are identical or similar to the methods used for the static
Web service in “Implementing the InquireParts JavaBean” on page 327.
This scenario is described in the interaction diagram in Figure 12-3 on page 416.
Run the Web service with part numbers of M100000001 and M100000003. The first
test retrieves local data and the second test invokes the Mighty Motors Web
service. Both sets of XML result data are identical in format.
We assume that Almaden Web autos sends the WSDL files to Santa Cruz Sports
Cars. Santa Cruz Sports Cars then integrates the Web service into their existing
Web application using static bindings.
We have now completed the generation and testing of the proxy to call the
Almaden Autos Web service. Next we have to integrate that into the Santa Cruz
Sports Cars Web application.
Edit the XSL style sheet and change the name of the image file from
almadenautos.gif to santacruzsportscars.gif, and the heading to <H1>Almaden
Autos Inventory Inquiry Results</H1>.
Because we use the Apache Xalan XSL processor, we have to add the
xalan.jar into the ITSOSantaWeb project Java build path. You can do this by
adding the WAS_XALAN variable to the build path.
package itso.wsad.santa.web;
import javax.servlet.http.HttpServlet;
Select the PartsInputForm.html file in the ITSOSantaWeb project and select Run
on Server. The browser opens and the parts inventory inquiry input page is
displayed.
We can test three scenarios with three different input part numbers as shown in
Table 12-1.
Table 12-1 Scenarios for composed Web services
Part number Part found in Web services invoked
Part in
Almaden
Autos
tables
Part in
Mighty
Motors
tables
When running the scenario with part number M100000003 you should see two
rpcrouter servlets initialized in the console, indicating that two different SOAP
servlets have been invoked, one for the Almaden Autos Web application, and one
for the Mighty Motors Web application.
URL considerations
If we take a look at the different resources of the four sample applications, we
see that there are quite some references to localhost and port 8080:
In the ITSOAlmaWeb application, the InquireMightyMotors servlet contains a
URL reference to the XSL style sheet which is used to display the XML results
in HTML format:
http://localhost:8080/ITSOAlma/InquirePartsResultTable.xsl
All the generated WSDL files contain references to localhost:8080.
The URL for invoking the SOAP servlets in the generated proxy clients
contain references to localhost:8080. For example, InquireAlmaPartsProxy
in the ITSOAlmaWeb application contains the following line in its constructor:
new URL("http://localhost:8080/ITSOAlma/servlet/rpcrouter")
Normally, you change all these references when you deploy Web applications to
a production environment. There are two approaches:
Replace the absolute URL paths with relative URL paths. You can do this only
in certain cases such as in HTML links. You can, however, not change the
URL reference for the rpcrouter servlet in the client proxy to a relative path
In this chapter, however, we have chosen not to replace the URL references of
localhost:8080. Instead, we configure the application server in such a way that is
also listens to port 8080. Such a configuration is not suggested for a real
environment; we only want to demonstrate the deployment of Web services.
When generating the Web service from the JavaBean, described in “Using the
Web service wizard” on page 336, the SOAP admin client was added to the Web
application. However, this was not the case in the Web service JavaBean
skeleton wizard illustrated in “Creating the JavaBean skeleton” on page 419.
Attention: The final Application Developer product code does generate the
admin client into the Web application, but learning about AAT is good anyway.
Note: The application assembly tool (AAT) that ships with WebSphere is a tool
that enables you to assemble enterprise application into an EAR file. With AAT
you can:
Modify and add modules to applications
Generate deployment code for modules
Verify archives
View deployment descriptors
Specify JNDI bindings and resolve references
Convert EJB JAR files from 1.0 to 1.1 format
We have not been using the Application Assembly Tool so far, because of two
major reasons:
Unlike VisualAge for Java 4.0 or WebSphere Studio 4.0, Application
Developer is capable of exporting EAR files.
Application Developer is capable of generating deployed code for the EJB
1.1 specification.
The sample applications we install in this chapter use the same data source we
defined in “Creating the JDBC driver and data source” on page 174. You must
complete that section in order to complete this chapter.
Once you uninstalled the Almaden Autos and Mighty Motors enterprise
applications, the Administrator’s Console warns you to regenerate the plug-in
and to save the configuration. You can postpone this until you finished the
installation of the new EAR files described in the next section.
Uninstall by command
You can also uninstall enterprise application using the SEAppInstall command:
seappinstall -uninstall ITSOAlmaEAR -delete true
To install the Almaden Autos, Santa Cruz Sports Cars and Plenty Parts
enterprise applications (which contain no EJB modules) follow the guidelines
described in “Installing the Almaden Autos enterprise application” on page 176.
For the Mighty Motors enterprise application, which contains an EJB module,
follow the instruction described in “Installing the Mighty Motors enterprise
application” on page 178. Make sure you specify ITSO as the Schema Name in
the Database and Data Source settings and that you deselect the Re-Deploy
option for the EJB modules.
Using SEAppInstall
When can also install the enterprise applications with the command line tool
SEAppInstall, located in the WAS_ROOT/bin directory. To see all available options
with this tool, enter the command SEAppInstall.
We assume that the exported EAR files are in a directory called c:\temp.
To install the Almaden Autos enterprise application (and Santa Cruz Sports
Cars and Plenty Parts) enter this command:
seappinstall -install c:\temp\ITSOAlma.ear -interactive false
To install the Mighty Motors enterprise application enter:
seappinstall -install c:\temp\ITSOMighty.ear -interactive false
-ejbdeploy false -schemaName ITSO
Add an alias
An alias is the TCP/IP hostname and port number used to request a Web module
resource. For the virtual host default_host to accept requests for port 8080, we
have to add an alias:
Expand Virtual Hosts, default_host.
Click on Aliases and click New in the right panel. Specify a * for the Host
Name and 8080 for the port. Click OK.
It is necessary to add the JAR files that were added to the class path of the
ITSOWSAD WebSphere server instance in “Unit testing” on page 408, to the
WebSphere Application Server class path:
Copy the mail.jar
from: WSAD_ROOT\plugins\com.ibm.etools.servletengine\lib
to: WAS_ROOT\lib\ext
Check that soap.jar and uddi4j.jar are already in WAS_ROOT\lib.
Use the -configFile option for both commands to specify the server
configuration file, if you saved your configuration in a file other than the default
(server-cfg.xml)
M100000003 Mighty Motors tables and/or Mighty Motors or Plenty Parts tables
Plenty Parts tables (depending on the link you follow)
(depending on the link you
follow)
Enter the values in Table 13-2 for the part number to test the different scenarios:
Table 13-2 Scenarios for testing Santa Cruz Sports Cars
Part number Part found in Web services invoked
http://localhost:9080/ITSOMighty/admin/index.html
http://localhost/ITSOMighty/admin/index.html
The sample applications that we install in this chapter use the same data source
we defined in “Creating the JDBC driver and data source” on page 191. You must
complete that section in order to complete this chapter. We also use the same
ITSOWSAD application server we defined in “Creating an application server” on
page 192.
In fact, to install Almaden Autos, Santa Cruz Sports Cars, and Plenty Parts
enterprise applications (which contain no EJB modules) follow the guidelines
described in “Installing the Almaden Autos enterprise application” on page 194.
For Mighty Motors, which contains an EJB module, follow the instruction
described in “Installing the Mighty Motors enterprise application” on page 195.
Make sure not to choose to regenerate the deployed code for the EJB modules.
Add an alias
To define a virtual host alias for the default_host for port 8080:
In the Administrator’s Console select Virtual Hosts.
To have the HTTP Server pick up the new plug-in configuration, restart the IBM
HTTP Server as well.
To test the applications, follow the instructions described in “Test the applications
with AEs” on page 441. However, for testing with the embedded Web server you
have to use the port defined in Figure 13-4, instead of 9080. This port can be the
same as 9080 depending on the application servers already defined on your
node.
SOAPEAREnabler tool
In the WebSphere/AppServer/bin directory you can find a command line tool,
soapearenabler.bat, for enabling a set of SOAP services within an EAR file. We
did not have to run this tool with our deployed EAR files, because they already
contained the necessary SOAP servlets.
For example, you have to use this tool when you create a Web service with
WebSphere Studio Version 4.0. Typically, with WebSphere Studio Version 4.0,
you export the Web application in a WAR file. Then you assemble the WAR file
into an EAR file using AAT. Then you run the soapearenabler tool, which adds a
Web module containing the SOAP router servlets to the EAR file. If desired, the
tool can add the SOAP admin Web application as well.
Programmatic deployment
The code snippet of Figure 14-1 shows how Web services can be deployed to
Apache SOAP using the SOAP API.
Document doc;
DeploymentDescriptor deploymentDescriptor;
DocumentBuilder xdb = XMLParserUtils.getXMLDocBuilder();
Serializer Deserializer
1 1 1
Java Type
1
n
1 n
Encoding Mapping
n
1
XML Type
SOAP Literal XML
Default Custom
Java primitive types such as int, float, and so SOAP Default, custom
forth, and their wrappers (java.lang.Integer,
java.lang.Float and so forth)
Any SOAP runtime environment holds a table of such mapping entries, the
SOAPMappingRegistry. The mappings are looked up by the SOAP runtime when
(de)serializing request and response parameters.
At startup time, this table is pre-loaded with entries for all available default
mappings. On the server side, additional entries can be configured in the
deployment descriptor:
<isd:mappings>
<isd:map encodingStyle="encoding-uri"
xmlns:x="qname-namespace" qname="x:qname-element"
javaType="java-type" java2XMLClassName="serializer"
xml2JavaClassName="deserializer"/>
...
</isd:mappings>
On the client side, it is necessary to add custom mappings through the SOAP
client API, as we will see in the next section.
As a first step, let us investigate how the standard SOAP encoding deals with
JavaBeans. As an example, we implement a new Web service GetInvItem
returning a JavaBean holding detailed information about inventory items.
Note that we do not have to implement a custom mapping. SOAP 2.2. provides a
bean serializer class. This class can marshall and unmarshall instances of any
Java class conforming to the JavaBean specification.
We implement, describe, and test the Web service in the same way as described
in “Static Web services” on page 321.
package itso.wsad.alma.custom;
import org.w3c.dom.Element;
public class GetInvItem {
package itso.wsad.alma.custom;
public class InvItemBean
{
long itemNumber;
int quantity;
float cost;
String shelf;
String location;
String partNumber;
String name;
String description;
double weight;
String imageURL;
public InvItemBean() { }
Important: The Web service wizard for generating a Web service from a
JavaBean tries to publish to the defined WebSphere instance even if you do
not choose to launch the sample. In this process it tries to start the server
instance. If the ITSOAdvancedEAR project is not associated with the running
server instance, the wizard will fail. Make sure the project is associated with
the running server instance or stop all server instances.
<isd:service id="urn:GetInvItem"
xmlns:isd="http://xml.apache.org/xml-soap/deployment">
<isd:provider type="java" scope="Application" methods="getAsBean">
<isd:java class="itso.wsad.alma.custom.GetInvItem" static="false"/>
</isd:provider>
<isd:mappings >
<isd:map encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:x="http://www.getinvitem.com/schemas/GetInvItemRemoteInterface"
qname="x:itso.wsad.alma.custom.InvItemBean"
javaType="itso.wsad.alma.custom.InvItemBean"
java2XMLClassName="org.apache.soap.encoding.soapenc.BeanSerializer"
xml2JavaClassName="org.apache.soap.encoding.soapenc.BeanSerializer"/>
</isd:mappings>
</isd:service>
......
public class GetInvItemProxy
{
................
private String stringURL =
"http://localhost:8081/ITSOAdvanced/servlet/rpcrouter";
......
{
org.apache.soap.encoding.soapenc.BeanSerializer ser_4 = new
org.apache.soap.encoding.soapenc.BeanSerializer();
org.apache.soap.encoding.soapenc.BeanSerializer deSer_4 = new
org.apache.soap.encoding.soapenc.BeanSerializer();
smr.mapTypes("http://schemas.xmlsoap.org/soap/encoding/",
new QName
("http://www.getinvitem.com/schemas/GetInvItemRemoteInterface",
"itso.wsad.alma.custom.InvItemBean"),
itso.wsad.alma.custom.InvItemBean.class, ser_4, deSer_4);
}
}
The mapping information in the client side registry matches with the server
side deployment descriptor entry in Figure 14-5. In both cases, encoding,
qualified XML type name, and Java type name are mapped to pairs of
(de)serializer classes. The serializer and deserializer class and instance can
be (but do not have to be) identical.
Make sure to update the port information to the port your TCP/IP
tunnel/monitor listens to so that we can investigate the exchanged messages.
Refer to “Using the TCP/IP Monitoring Server to view message contents” on
page 358 for instructions how to set up the monitor server instance, which
defaults to port 8081, or use the standalone version of the monitor that comes
with Apache SOAP (port 4040).
Use the TCP/IP Monitor view to inspect the exchanged SOAP messages. You
can see the XML representation of the JavaBean in the response message
(Figure 14-8).
Figure 14-8 SOAP messages from testing the GetInvItem Web service
We have to implement two interfaces, each defining one method. This is the
org.apache.soap.util.xml.Serializer interface:
public void marshall(
java.lang.String inScopeEncStyle,
java.lang.Class javaType, java.lang.Object src,
java.lang.Object context, java.io.Writer sink,
org.apache.soap.util.xml.NSStack nsStack,
org.apache.soap.util.xml.XMLJavaMappingRegistry xjmr,
org.apache.soap.rpc.SOAPContext ctx);
These functions are called by the SOAP layer both on the client and the server
side when serializing/deserializing request and response parameters.
To run the Web service wizard with a custom mapper, we have to make the
mapper available first.
Figure 14-9 contains the class definition of the StringSerializer and the
marshall method.
package itso.wsad.alma.custom.mappings;
import org.apache.soap.util.xml.Deserializer;
import org.apache.soap.util.xml.Serializer;
nsStack.pushScope();
// ** Java to XML
String tagname = context.toString();
System.out.println("Marshalling: " + tagname +": "+ src.toString());
try {
sink.write("<" + tagname + " xsi:type=\"xsd:string\">"
+ src.toString() + "</" + tagname + ">");
}
catch(java.io.IOException e) {
throw new java.lang.IllegalArgumentException("marshall:IOException");
}
finally {
nsStack.popScope();
}
}
Figure 14-10 shows the corresponding unmarshall method. It receives the XML
representation of the string as a org.w3c.dom.Node instance, extracts its only
child element, a text node containing the value for the Java string instance, and
instantiates an org.apache.soap.util.Bean object from it. Such a bean is a
wrapper for a Java object and its type, which makes is possible to send a typed
null pointer.
Figure 14-11 Server side mapping configuration in the Web service wizard
Take a look at the generated client proxy and the ISD file (Figure 14-13), which is
also added to the dds.xml file.
<isd:service id="urn:GetInvItem2"
xmlns:isd="http://xml.apache.org/xml-soap/deployment">
<isd:provider type="java" scope="Application" methods="getAsBean">
<isd:java class="itso.wsad.alma.custom.GetInvItem2" static="false"/>
</isd:provider>
<isd:mappings >
<isd:map encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:x="http://www.w3.org/2001/XMLSchema" qname="x:string"
javaType="java.lang.String"
java2XMLClassName="itso.wsad.alma.custom.mappings.StringSerializer"
xml2JavaClassName="itso.wsad.alma.custom.mappings.StringSerializer"/>
<isd:map encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:x="http://www.getinvitem2.com/schemas/GetInvItem2RemoteInterface"
qname="x:itso.wsad.alma.custom.InvItemBean"
javaType="itso.wsad.alma.custom.InvItemBean"
java2XMLClassName="org.apache.soap.encoding.soapenc.BeanSerializer"
xml2JavaClassName="org.apache.soap.encoding.soapenc.BeanSerializer"/>
</isd:mappings>
</isd:service>
It is worth noting that our string serializer is not just used for the part number
parameter; it is recursively invoked during the serialization of the InvItemBean as
well.
In cases when you are starting to write your own custom deserializers, make
sure to check the Apache SOAP source code before doing so. For debugging
purposes, compare your message bodies with the ones created by already
existing serializers.
A simple solution is to modify the generated proxy. You have to change the
encoding on the parameter level for the data type reporting the encoding
problem. Compare your settings with Table 14-2 on page 450. Usually any
org.w3c.dom.element parameters should use the literal XML and all others the
SOAP encoding.
Tip: In the SOAP 2.2 API, an encoding can optionally be specified on the call
level. If it is there, it is used to define the encoding style for the response. It
serves as a default value for the parameter level as well. On the parameter
level, an encoding parameter has to be passed to the constructor; this
parameter can be set to null, however.
For more information, consult the FAQ list that comes with SOAP 2.2.
As a final design alternative, you can also follow the meet in the middle
development approach and modify the Java method signature, moving the data
carried by the non XML parameters into the XML element.
Summary
Mappings implement the deserialization functionality required to encode and
decode data values under certain encodings. Table 14-3 and Table 14-4
summarize where default and custom mappings are available.
Table 14-3 Encoding and mapping styles (default mapping)
Basic types Complex types XML element
In general, you should not to implement custom mappings unless you cannot
avoid it. This is due to the fact that the custom mapping couples the service
requestor and provider quite tightly, because two additional software components
have to be made available at the two ends of the communication channel.
Message-oriented communication
As described in “Web services overview and architecture” on page 241, SOAP
does not only offer an RPC communication style; there is a message or
document oriented interface as well. At the time of writing, most SOAP tutorials
and programming samples focus on the RPC style, just as we did up to this point
in the book.
Figure 14-15 contains the class diagram for our message client.
We will explain these classes and their interactions (Figure 14-16) as we develop
the solution.
A Web service enabled Web application has to be available. In the last step, we
generated such a Web application. Now, run the Web service wizard and create
a dummy RPC Web service in case you skipped that step.
The only API we use is Apache SOAP 2.2, which was already added to build
path by the wizard. Also required is mail.jar. Add the MAILJAR variable for this
library to the build path.
package itso.wsad.alma.message;
import java.util.*;
import org.w3c.dom.*;
import org.apache.soap.*;
import org.apache.soap.rpc.*;
import org.apache.soap.messaging.*;
In this case, the service implementation does not do much with the received
body element(s). It merely prints them to the standard output. To do so, it uses a
helper class XMLUtils, which we will implement later.
Deployment
In Application Developer, message-oriented services are deployed directly by
editing the deployment descriptor file; there is no wizard support.
The easiest way for us to manually configure our service is to copy and paste an
existing entry, and then change the URN to urn:Message, the method name to
sendDocument, and the class name to itso.wsad.alma.message.MessageService.
<root>
<isd:service ........
.... existing entries
</isd:service>
<isd:service xmlns:isd="http://xml.apache.org/xml-soap/deployment"
id="urn:Message" type="message" checkMustUnderstands="false">
<isd:provider type="java" scope="Request" methods="sendDocument">
<isd:java class="itso.wsad.alma.message.MessageService" static="false"/>
</isd:provider>
</isd:service>
</root>
The basic steps for creating a client that interacts with a SOAP message-oriented
service are as follows:
package itso.wsad.alma.message;
import java.io.*;
import java.net.*;
import java.util.*;
import org.w3c.dom.*;
import org.apache.soap.*;
import org.apache.soap.messaging.*;
import org.apache.soap.transport.*;
import org.apache.soap.util.*;
// ** send message
System.out.println("Proxy: sending message ...");
msg.send(this.url, soapActionURI, env);
System.out.println("Proxy: done.");
// ** receive response
System.out.println("Proxy: receiving response ...");
SOAPTransport t = msg.getSOAPTransport();
BufferedReader br = t.receive();
System.out.println("Proxy: done.");
return result.toString();
}
All elements in the message body have to implement the Serializer interface,
because they are responsible for the marshalling of the contained data. We,
therefore, need the new class MessageSerializer. The message proxy creates
an instance of this class, wrapped in a SOAP bean instance, and adds it to the
message body (Figure 14-21).
package itso.wsad.alma.message;
import java.io.*;
import org.apache.soap.rpc.*;
import org.apache.soap.util.xml.*;
package itso.wsad.alma.message;
import java.net.*;
Note that we could use the TCP/IP Monitor port (8081) to inspect the exchanged
messages (try that with a binary protocol such as IIOP). Use port 8080 if you are
not interested in the trace messages.
The XMLUtils helper class that the message service uses to display the incoming
XML element is shown in Figure 14-23. Note that the helper does not support
XML entity references and processing instructions.
import org.w3c.dom.*;
A lower-level client API, which is slightly more complex than the RPC API, has to
be used. The SOAP RPC layer itself is actually implemented against this API. On
the server side, a different router servlet called messagerouter is used; the
method signature for any service implementation is fixed. Both service requestor
and provider have full control over the SOAP envelope (headers, body). The
response can be anything, or nothing at all.
We expect additional tools and convenience APIs to come out soon. For
example, the Web services toolkit (WSTK) 2.4 contains such an API defining a
ServiceProxy, a ServiceRequest, and a ServiceResponse class as well as a
message demo. These classes are similar in function to our MessageProxy.
Check the Apache SOAP 2.2 User’s Guide and API documentation for more
information. If you prefer do read the API source code, feel free to do so (Apache
SOAP is open source, and available at http://www.apache.org/soap).
Prepare a project
Create a ITSODadxWeb Web project related to a new EAR project called
ITSODadxEAR. Set the context root to ITSODadx. Add the ITSODadxEAR project to
the ITSOWSADWebSphere server configuration.
Click the Browse button next to Connect to a database and import a new
database model. Select the ITSOWSADDB folder in the ITSODadxWeb project as
the target folder, click OK.
Click Next.
Complete the Database Connection panel (Figure 14-25):
– Specify ITSODadxDB for the Connection Name, ITSOWSAD for the Database
and make sure to specify a valid User ID and Password for DB2 (or leave
the fields empty).
– Click Filters, enter AAPARTS (the only table we will use), and set the
Predicate to LIKE. Click OK.
</wsdl:documentation>
<dadx:query>
<dadx:SQL_query>
<![CDATA[
SELECT ITSO.AAPARTS.PARTNUMBER, ITSO.AAPARTS.NAME FROM ITSO.AAPARTS
]]>
</dadx:SQL_query>
</dadx:query>
</dadx:operation>
</dadx:DADX>
This file defines one operation, selectParts, which refers to the SQL statement
we defined. The SQL statement itself, shown in bold, is also contained within the
DADX file.
Notes:
We could not overwrite the URI of the Web service in the wizard:
http://tempuri.org/ITSOGroup/ITSOSelectPartsDadx.dadx
This value is in the ISD file (and therefore in dds.xml) and in the client proxy.
The target URL points to /ITSOGroup, which is mapped to the DxxInvoker
servlet defined in the Web application:
http://localhost:8080/ITSODadx/ITSOGroup/ITSOSelectPartsDadx.dadx/SOAP
To test the Web service using WORF, paste this URL into the internal or an
external Web browser:
http://localhost:8080/ITSODadx/ITSOGroup/ITSOSelectPartsDadx.dadx/TEST
This is almost the same URL as used in the client proxy (Figure 14-30 on
page 486), but with TEST as suffix.
We did not experiment with this feature for this redbook, because it was not
available in the beta code.
Summary
In this section we demonstrated how to create a Web service from a DADX group
based on an SQL statement.
This section outlines the six identifiable types of UDDI business registries and
provides recommendations as to which is the most appropriate for different
business scenarios. These variants are as follows:
UDDI operator cloud
e-marketplace UDDI
Portal UDDI
Partner catalog UDDI
Internal enterprise application integration UDDI
Test bed UDDI
We also investigate how to use the IBM WebSphere UDDI Registry product
provided on the WebSphere Developer Domain:
http://www7b.boulder.ibm.com/wsdd/downloads/UDDIregistry.html
The UDDI specification was designed to address the requirements of finding and
searching for business entities and services that were published in the global
UDDI business registry currently operated by IBM, Microsoft, and Ariba (which
will be replaced by HP).
When most people discuss UDDI, this is the registry they refer to. However, other
types of UDDI nodes are supported by the specification and are actually of more
practical use when developing Web services today. These are critical to the
emergence of a dynamic style of service-oriented architectures, and are
described in more detail in the following sections.
Changes made in each node are replicated on a regular basis to the other nodes.
The runtime topology for this architecture is shown in Figure 14-33.
Protocol Firewall
Domain Firewall
Protocol Firewall
Partner
Existing Web Server Infrastructure
applications Web App
Plug-in
Internet and
Server
and data Applications
Domain Name
Database Server
Server
UDDI
Operator
Cloud
Figure 14-33 Runtime topology for using the UDDI operator cloud
The UDDI operator cloud contains Web services data for many different kinds of
businesses in various geographies and industries. Some of this data represents
legitimate businesses and information, and the business process exposed as
Web services. Some of this data represents organizations posing on the
transactional Web, but do not provide Web services. Finally, some of this data
can represent fraudulent or misleading information on business intent. In order to
use this registry successfully for dynamic e-business, we must be able to
distinguish between meaningful entries and entries that are a waste of time.
If Web services discovery relies only on the operator cloud, all discovery
operations must be performed at design time. As the tModel field contains
text-prose information, it must be examined in detail and invoked using hand
crafted code based on the description.
e-marketplace UDDI
This is a form of private UDDI registry that can be hosted by an e-marketplace, a
standards body or a consortium of organizations that participate and complete in
the industry. In this scenario, the publish and find UDDI APIs are deployed for
access over the Internet by any of the member organizations. This uses a similar
runtime topology to that shown in Figure 14-33.
Currently, very few of these e-marketplace UDDI nodes exist, and this presents a
huge business opportunity for new players in the industry or existing
e-marketplace operators, who want to ensure they are not made redundant by
the UDDI operator cloud.
Such e-marketplace registries can limit the entries to a subset of the existing
Web service taxonomies (such a small number of the NAICS categories) as well
as providing standard tModels for common business processes in the industry. In
some circumstances, it may be necessary to provide completely custom
taxonomies if no appropriate standards exist.
The real benefits of such a registry are that as a developer, you have a
reasonable guarantee that using the find and bind operations against the registry
for dynamic binding at runtime using a single service proxy, will be successful.
Portal UDDI
Just as a company can have a presence of the traditional document-based Web
(http://www.acme.com), it can also have a presence on the transactional Web
(http://www.acme.com/uddi).
The portal UDDI sits inside the organizations demilitarized zone as shown in
Figure 14-34.
This portal UDDI server contains only metadata related to the company’s Web
services that it wishes to provide to external partners. The publish APIs will be
removed for users accessing the registry from the Internet, restricting publishing
rights to internal applications only. This gives the organization complete control
over how their Web services metadata can be used and retrieves information
about who the interested parties are. It could also potentially restrict find access
to a specific list of trusted partners.
This topology can be used in conjunction with the UDDI operator cloud or
e-marketplace UDDI registries, although a replication mechanism must be put in
place to ensure that the entries are synchronized. This is discussed in the later
section, “Managing the relationships between UDDI nodes” on page 494. The
URL for the UDDI portal server can be used as the discoveryURL in the
businessEntity record for the company in the UDDI operator cloud.
Protocol Firewall
Domain Firewall
Protocol Firewall
Partner
Existing Web Server Infrastructure
applications Web App
Plug-in
Internet and
Server
and data Applications
Domain Name
Database Server
Server
UDDI
Portal Operator
UDDI Cloud or
e-market
Server
place
This setup is especially useful when the nature of the business requires
extensive legal contracts to be agreed to before the two organizations can
integrate their applications. It provides all of the benefits of dynamic binding at
runtime, but against a controlled and validated set of partners.
This topology again raises the question of how these entries are continually
synchronized with the parent UDDI node, which is discussed later.
Protocol Firewall
Domain Firewall
Protocol
ProtocolFirewall
Partner
Existing Web Server Infrastructure
applications Web App
Plug-in
Internet and
Server
and data
Firewall
Applications
Domain Name
Database Server
Server
UDDI
Partner Operator
Cloud or
Catalog e-market
UDDI place
Server
Figure 14-35 Runtime topology for using a partner catalog UDDI server
This runtime topology is very similar to the partner catalogue variety, except that
the entries are for Web services provided by other departments or groups within
an organization. The administrators of the registry have the power to define the
Web services standards that will be used in the organization by limiting the
tModels available.
This may potentially be a very attractive approach for organizations who have
selected a multi-vendor approach to application development, and require
interoperability between loosely-coupled applications. However, this should not
be confused with a scalable EAI architecture solution, such as MQSeries or
MQSeries Integrator, which provides a higher quality of service, and a greater
number of integration platforms.
Directory and
Security
Services
Requesting
Existing Infrastructure
applications Web App
Server and
and data Applications
Database
Server
Internal
EAI UDDI
server
Figure 14-36 Runtime topology for using a internal EAI UDDI server
A test node provides an environment where developers can test that the UDDI
entries for their Web service are accurate, and that applications can use the
metadata to generate proxies from the UDDI entry to access the service.
Firewall
Firewall
Test bed UDDI UDDI operator
cloud
Portal UDDI
Internal EAI
UDDI
The implications of these limitations is that while it is likely that the previously
described scenarios are attractive application topologies, caution should be used
during implementation, and steps taken to ensure that developed functions are
isolated from future changes to the specification.
Attention:
When we wrote the redbook we used the WebSphere UDDI Registry
preview code on Windows. This code is not available any more. The
version 1.1 code on Windows does not work in the same way as the
preview code and not all functions of the Application Developer UDDI
Explorer are supported.
We suggest that you use the IBM Business Test Registry for UDDI tests
with the Application Developer.
Integration of the Application Developer with the WebSphere UDDI
Registry should be possible again in the future when a newer level of the
WebSphere UDDI Registry or the Application Developer is available.
Traditionally, business process modeling starts with a picture of what the process
looks like as a whole, broken down in terms of the specific activities that must be
completed, the order in which they must be completed, the dependencies
between those activities, and a definition of who is responsible for making sure
those activities are completed.
Each activity can either represent a new piece of business logic or an interface to
an existing system using some middleware. Web services are an ideal
technology to use for creating such activities, as they provide the flexibility of
easily interchanging the implementation without impacting the defined business
process.
WSFL fits naturally into the Web services computing stack. It is layered on top of
WSDL, which it uses for the description of services interfaces and their protocol
bindings. WSFL also relies on an envisioned endpoint description language to
describe the non-operational characteristics of service endpoints, such as
quality-of-service properties. This has provisionally been referred to as the Web
services endpoint language (WSEL), although even the first draft of this
specification is not yet complete at the time of writing.
One final aspect to note is that WSFL provides support for what is known as
“recursive composition”. This means that a flow defined in WSFL can itself be
exposed as a Web service and used in a different WSFL flow. This provides
scalability to the language and support for progressive refinement of the design,
with increasing granularity, as well as aggregation.
These proposals are all far from complimentary. As to what will be the most
successful in the future is anyone’s guess, although the number of vendors who
see this as an important aspect of Web services technology is reassuring.
Each process defined in the flow is referred to as an activity. There are four types
of activities that are available: local operations, static Web service bindings,
UDDI lookups, or dynamic bindings based on a given criteria.
WSFL also supports activities that fork when they have more than one outgoing
control link defined. Each activity defined following the fork is then executed in
parallel. Similarly, once a flow has been forked it must be synchronized at a later
time. This is done through a join activity that has more than one incoming control
link. By default, activities defined after the join are only executed when all parallel
activities are complete.
Activities that have no incoming control link are by definition start activities, and
those without an outgoing control link are end activities. When the last end
activity completes, the output of the overall flow is determined and returned to its
invoker.
Each data link is weighted by a map specification. This prescribes how fields in
the target’s input message are constructed from fields in the output message.
Data links are also used to describe the input and output of the flow itself. Any
links which target activities in the flow from outside are known as flow sources,
and links from activities inside the flow that target activities outside the flow are
known as flow sinks.
Every activity in the flow can be performed by a different business partner. This is
defined by specifying a service provider, who is responsible for providing the
appropriate Web service for the activity.
Send shipping
order
Figure 14-39 Sample flow model for ordering a part from a supplier
Each of the shaded boxes illustrates an activity in our business process, and the
arrows show the control flow. The corresponding WSFL for a fragment of the
example is shown in Figure 14-40.
This WSFL code shows the flow model entries that describe the control flow
between the Send shipping order and Receive shipping order activities. The text
highlighted in bold shows the links between the service providers, their activities,
and the corresponding control and data links.
Figure 14-40 WSFL fragment showing the control flow between two activities
A service provider type defines the interface of a Web service with a set of port
types that declare the operations supported. Each service provider fulfilling a role
within the process must implement these port types and define them in the
WSDL describing their Web service interface. The service provider types are
defined using the grammar shown in Figure 14-41. Again note how the names
underlined match those in Figure 14-40.
The interaction between a set of service providers in the global model are
declared using plug links.
When interacting with Web services that are external to the flow, the activities
must be exposed using an export definition through to the public interface, and
defined as plug links to provide the flow engine with the information necessary to
perform the operation, and tie that back into the business process being
executed.
Finally, a WSFL implementation engine could take the global model, run it
through a WSDL generation process, and create the Web service interface
(WSDL port type) definition containing the public interface. This can then be used
to generate a Web service client as described in Chapter 10, “Static Web
services” on page 321.
The most recent release at the time of writing, MQSeries Workflow Version 3.3,
does not provide these capabilities out of the box. However, a download is now
available from the IBM alphaWorks site called the IBM Web services process
management toolkit (WSPMTK), which provides these features. It is available at
the following URL:
http://www.alphaworks.ibm.com/tech/wspmt
WSPMTK and WSFL: It is important to note at this point that the current
release of the WSPMTK does not generate WSFL, but instead uses its
non-XML-based Flow definition language (FDL) as the basis for generating
the WSDL interfaces.
Client Deployment
1
Proxy Descriptor
WebSphere
MQWF
Generic Execution
SOAP
Service 4 Server
Client
Provider
The service provider models a process using the MQWF process modeler,
deploys it to the workflow engine, and generates a FDL representation of this
process from the runtime representation using the MQWF fmcibie utility (1).
The service provider executes the fdl2wsdl translator (provided by the
WSPMTK) against the FDL and generates the following artifacts:
– Serializers and deserializers for all structures used within the process
– A deployment descriptor, which is used by the generic server provider to
binds specific URIs to various workflows
– A single WSDL file, which provides the Web service interface description
for service requests to the workflow (2)
The WSDL file is published to an appropriate UDDI registry (3).
The generic Web service provider shipped (4) with the WSPMTK is added to
the Web application, and is required for routing the SOAP messages to
MQWF, along with the generated proxy and serializer classes. When the Web
application is deployed to an application server instance, the service is ready
for execution.
Clients of the Web service import the WSDL definition into Application
Developer, and use it to create client proxies for the service (5). These can be
integrated into the client application as described elsewhere in this book.
2 1
FDL WSDL UDDI
3
WebSphere
MQWF
Client
Execution SOAP
Proxy
Server Router
5
4
SOAP SOAP
UPES Client Service
Implementation
Service Requestor
Service Provider
Figure 14-43 Consuming a Web service as an MQWF activity
One of the primary roles MQSI can play in the context of Web services is that of
the service mediator (a new role in the Web services terminology). For example,
on receiving a Web service request, a flow may:
Transform this request message into an alternate Web service request
Route the request to a different system
Even capture data from the request for in-flight logging in a warehouse or
audit system
MQSI WSSoapNode
Additionally, MQSI Version 2 now provides a custom WSSoapNode, which
implements a Web services requestor that can invoke a Web service and use it
to augment or transform the document in the message flow. This is available in
the latest MQSeries Integrator Java Plug-in support pac (IA76), downloadable
from:
http://www-4.ibm.com/software/ts/mqseries/txppacs/ia76.html
WSDL
Other
Client Deployment
Format
Proxy Descriptor
Message Flow 1
WebSphere
MQSI Broker App
SOAP
Service in MQ
SOAP Proxy
Client "Bridge"
Message Flow 2
In general, you can expect to develop a pair of flows (or a complex flow with two
execution paths) to implement a Web service, as shown in Figure 14-45.
One flow mediates the inbound request, and the other flow mediates the
outbound response. Additionally, a single flow could be used to perform a
synchronous set of operations and reply immediately to the initiator of the flow.
SOAP
Router
WSSoapNode
Client
Proxy
SOAP Service
Client Implementation
MQSI does not currently provide support for inbound or outbound SOAP
requests over HTTP. The simplest approach to invoke a message flow is to
develop a Web service proxy that acts as a bridge to the MQSI runtime by
sending and receiving MQSeries messages, presumably using the Java
Message Service (JMS). The simple implementation passes the entire body of
the SOAP request directly into the body of the message, and sends it to the
MQSI input queue to invoke the message flow. In general, this then requires
additional transformations at the start and end of the flow to transform it between
SOAP, and the form required by the particular implementation. This can be
performed using the standard MQSI tools.
The publish and subscribe features of the product also provide an opportunity to
try a different Web services model using push technology. This involves Web
service requesters registering themselves for events in the Web service, and
information pushed to them using the matching engine. Again, a proxy service
still has to be developed to broker between SOAP over HTTP messages, and the
MQSeries transport mechanism used by MQSI.
Figure 14-46 Configuration of the MQSI Java node to use the SOAP service
Ensure that the element tree for the input message contains the expected
SOAP element tree structure.
Quiz: To test your knowledge on the topics we covered in this chapter, try to
answer the following five questions. The answers are provided in Appendix C,
“Quiz answers” on page 559.
1. Name the two encodings supported by the Application Developer Web
service wizard. Do they support java.lang.boolean?
2. Assign the following class names to the two styles (SAP RPC vs SOAP
message-oriented): Message, Envelope, Body vs. Call, Parameter,
SOAPMappingRegistry.
3. Decide which SOAP communication style to use for the following two
scenarios that a news portal provider is confronted with:
– When processing incoming HTTP requests, the news portal wants to
translate the HTTP request parameters into a Web service invocation to
one of its content providers. The request parameters are fixed and
known at build time.
– The interface between the content management system and the news
portal is supposed to be reimplemented; each night, a set of XML files
needs to be transferred from the content management system to the
portal.
4. Name at least three possible scenarios for UDDI registries.
5. What does WSFL stand for and what is it used for?
Tier-1
Browser End User Client
B2C/B2B Client Application IT System
Clients
Tier-2
Tier-2a httpd, View
Common
Presentation servlet engine (JSPs)
Interaction Services
and Control Controller
Layer Facade XSL Security
Objects Processor
XML
Tools
Tier-2b Model
Logging
Model XML
Business (plain
(EJB based) Repository
Java)
Logic Layer Transactions
Persistence
Tier-2c
Persistence and Connectors Database
Networking
Connectivity Layer
Tier-3 Backend
Backend System
Tier-2
Tier-2a httpd, rpcrouter, View
Common
Presentation servlet engine messagerouter (JSPs)
Interaction Services
and Control Controller
Layer service Facade XSL Security
implementation Objects Processor
XML
Tools
Tier-2b Model
Logging
Model XML
Business (plain
(EJB based) Repository
Java)
Logic Layer Transactions
Persistence
Tier-2c
SOAP
Persistence and Connectors
Client/Proxy
Database
Networking
Connectivity Layer
This topic currently receives a lot of attention in the industry. Here are two
examples:
The SOAP message communication style is suited for document oriented
message exchange. For instance, self-describing queries become possible;
the client does not have to be changed when server upgrades.
Peer-to-peer computing and decentralized networking over the Internet
Check the developerWorks Web services zone for articles on this topic.
Firewall considerations
The server side RPC router is just another servlet that is accessed through
HTTP; an additional HTTPs connection to an external system, the UDDI
registry, might be required in order to be able to publish a service.
A service requestor is just another HTTP client (assuming that HTTP is used
as transport protocol).
Let us have a word on the port 80 discussion. If we simply say with SOAP client
systems can access Web applications through the same port as browser s we are
missing the point. The SOA concept is not about sneaking through an already
open port—firewalls are there for a reason, and your security administrator will
probably not approve such an approach.
As a first step, a separate port such (81, for instance) can be used to distinguish
from user-oriented HTML communication. The key difference is that the protocol
the SOA uses is text based. The firewall can therefore inspect the messages (if
they are not encrypted). A new type of application level gateways performing
such checks could evolve.
But this step does not solve the problem; as a matter of fact, the security
requirements have to be addressed on every layer of the SOA protocol stack.
Web service security is a partially open issue; standard and products
implementing them are expected to be available in the near future.
From a deployment point of view, the SOAP server components and the Web
service implementation are bundled as a .war file, which in turn is part of a .ear
file. Therefore, configuration management tasks such as installing new versions
of .jar files should be carried out on the application server level as well.
Technical logging for a service implementation can be handled in the same way
as for any other Java Web application. It is worth noting, however, that the
internal tracing and logging capabilities of the Apache SOAP implementation are
very limited. It is always possible, however, to use a non-GUI version of a TCP/IP
tunnel to intercept the message flow in order to record the client/server
interactions. The UDDI and WSDL APIs offer some more support; for example,
there is a debug flag in the wstkProperties.xml configuration file.
Business logging of Web services translates into accounting and billing of Web
service invocation. A first proposal is described in the following article on
developerWorks:
http://www.ibm.com/developerworks/webservices/library/ws-maws/
On the requestor side, the SOAP API and the proxy on top of it are just another
communication component. We expect them to fit nicely into any client side
management policy.
On the other hand, a text based protocol such as SOAP is not necessarily slower
than binary ones, taking into account that client stubs supporting binary protocols
such as IIOP or DCOM might have to be downloaded and initialized before the
message exchange can start.
It should be noted that all server side Java and servlet performance optimization
and load balancing techniques are available.
Regarding Apache SOAP 2.2 and Microsoft’s NET SOAP, the two protocol
implementations are generally interoperable. One known problem is that the
Microsoft implementation does not always send all type information Apache
expects. A patch from James Snell is available. Consult the Apache SOAP FAQ
list for more information.
Apache SOAP is an open source project, which makes it easier to apply patches
to the SOAP runtime, in case unexpected problems occur anyway.
In regard to WSDL support, a few minor differences between the IBM and the
Microsoft toolkits exist as of today.
IBM's jStart team (see Chapter 16, “IBM’s jStart program” on page 531) has
successfully demonstrated interoperability between the IBM and the Microsoft
toolkits in several customer projects. For more information about interoperability
issues, refer to:
Apache: http://xml.apache.org/soap/index.html
Yahoo discussion group: http://groups.yahoo.com/groups/soapbuilders
IBM developer site:
http://www-106.ibm.com/developerworks/library/ws-ref3/?n-ws-5241
MSDN on SOAP interoperability:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnsoap/htm
l/soapinteropbkgnd.asp
Reliable messaging
Take a look at the following paper presenting a preview of how a reliable HTTP
protocol could look like:
http://www.ibm.com/developerworks/webservices/library/ws-phtt/
The XMA specification, an XML version of the X/Open XA interface for resource
managers, promises to standardize how distributed transactions involving
multiple Web service invocation should be handled. The SOAP header can be
used to pass transactional context information from the requestor to the provider
The IBM jStart team is available to support you during your first steps (see
Chapter 16, “IBM’s jStart program” on page 531):
http://www.ibm.com/software/jStart
For example, a Web service client might be a client, rather than an EJB or a
database connection, in order to access its business data?
This design issue is essentially the same as for any other backend
connection. You should define two methods in your Web service, and get only
the minimal data set you need for the list display in the first place. When the
user clicks on a list entry, the second Web service method then retrieves the
full data set needed for the details view.
Under some circumstances, it can make sense to use session scope and hold
the connection handle in there (a pointer to a stateful session bean, for
example). Be careful with this approach, though (as with stateful session
beans in general): there is no failover support, and the load balancing
capabilities are limited.
Keep method names, parameter names, XML tag names, and namespace
prefixes short
These identifiers travel with the message payload at runtime.
Be as stateless as possible
Use the application style whenever possible. Switch to request if you have to
allocate certain resources each time a Web service is invoked. Use session
only if you use case has stateful conversation semantics.
Have you heard of Web services, UDDI, SOAP, or WSDL? If so, we are ready to
jump-Start your companies adoption of dynamic e-business utilizing these key
technologies. How about Java, XML, and/or PvC? These technologies have
been in our portfolio over the past one to four years, and provide a strong
foundation for our current emerging technology focus.
Put the industries most advanced software tools and techniques, the most
sophisticated e-business technology, and one of the most capable development
teams to work for you. Start today by choosing jStart for your business.
The jStart team partners with you to help you use software technologies to
deliver the high-quality business-critical solutions you need now. We will help you
add the power of XML, SOAP, WSDL, pervasive technologies and UDDI - plus
IBM’s powerful arsenal of software tools such as WebSphere Application Server,
the Web services toolkit, MQ Series, and UDDI4J to your existing IT assets.
We deliver complete solutions as we mentor you and your staff in the use of
sophisticated tools and technologies. By partnering with jStart to develop and
deploy a dynamic e-business project, you and your staff will realize the benefits
of our world class program and skills.
Who we are
We are a highly experienced and uniquely capable team of special purpose
experts in emerging technologies. jStart engagement managers are ready to
help any organization—from the biggest multi-national to the five-person start-up
in any industry ranging from finance and insurance to manufacturing and
distribution—gain an edge in today’s market, as we help you develop the
strategic applications you need now.
How we work
You will notice a big difference when you work with the IBM jStart team. Unlike
many other application solutions providers, with jStart there are no ponderous
steering committees to deal with. We do not put a lot of layers between the
strategic work that needs to get done. We are hands-on professionals who are
driven to help you quickly achieve your e-business objectives.
What we do
We focus on helping you create flexible and scalable solutions using emerging
software technologies. Tell us your requirements and objectives—then let us help
you address your tactical and strategic challenges, as we deploy new
applications that meet your real world business needs.
Hours of planning sessions do not make a difference in your project until the
solutions you envision are designed, developed, and working for you in the
marketplace. You have to move quickly from merely talking about e-business to
actually doing e-business.
By engaging with jStart to move quickly, you will realize the benefits from a
time-to-market standpoint, as we work with you to rapidly deploy e-business
applications. You benefit because your engaged early in the technology cycle
and you pave the way for future projects and technology adoption. The jStart
engagement model is a proven approach for quickly moving from talking about
e-business to doing e-business.
Explore our site to learn more about the range of capabilities we offer, the
solutions that we can provide, our experience, and customer examples—then be
sure to contact us in order to take the next step. To contact the jStart team
directly, send an E-mail to:
mailto:[email protected]
Part 4 Appendixes
Alternatively, you can install DB2 7.1 FixPack 3 with the same options.
JDBC Version 2
You have to enable JDBC 2.0 because access to DB2 using DataSources only
works with JDBC 2.0. To enable JDBC 2.0, do the following:
Stop all DB2 processes from the Services list.
Change to JDBC 2.0 by running d:\SQLLIB\java12\usejdbc2.bat
Restart DB2 processes.
Verification
Check that the lines listed here are added at the end of the IBM HTTP Server
configuration file (d:\IBM HTTP Server\conf\http.conf):
LoadModule ibm_app_server_http_module
D:/WebSphere/AppServer/bin/mod_ibm_app_server_http.dll
Alias /IBMWebAS/ "D:/WebSphere/AppServer/web/"
Alias /WSsamples "D:/WebSphere/AppServer/WSsamples/"
WebSpherePluginConfig D:\WebSphere\AppServer\config\plugin-cfg.xml
WebSphere AE and AEs cannot share the same HTTP configuration file
(httpd.conf), so you have to keep a separate copy for AE and AEs (such as
httpdae.conf and httpdaes.conf. You then have to start the HTTP Server on
the command line, specifying the right configuration file:
apache -file httpdae.conf
Attention: You have to select if you want to use CVS or ClearCase LT (or
nothing) as the team repository.
The IBM WebSphere UDDI Registry can be used instead of the IBM Test
Registry for Web services publishing. This is especially useful for testing on a
machine that is not connected to the Internet.
The IBM WebSphere UDDI Registry is not a complete product at the time of the
writing of this book:
Originally we used the IBM WebSphere UDDI Registry Preview code on
Windows, which worked reasonably well with the Application Developer.
When we updated the book in February 2002, the preview code was not
available any more for Windows, and the beta code for Windows did not work
good enough with the Application Developer.
In March 2002, IBM WebSphere Registry Version 1.1 became available. It
supports UDDI Version 2, whereas Application Developer is based on UDDI
Version 1, and not all interfaces are working.
You can try to download whatever code is available for the Windows platform
and try it out with the Application Developer.
– Follow the installation instructions that come with the downloaded code.
– Connect to the registry from the UDDI Explorer and try out find and publish
functions.
See also the comments in “IBM WebSphere UDDI Registry” on page 496.
Open a DB2 command window and run this command to load the database:
db2 -tf itsowsad.ddl
Sample data
The ITSOWSAD database has four sets of two tables, PARTS and INVENTORY:
The Almaden Autos tables are AAPARTS and AAINVENTORY
The Mighty Motors tables are MMPARTS and MMINVENTORY
The Plenty Parts tables are PPPARTS and PPINVENTORY
The Santa Cruz Sports Cars tables are SSPART ad SSINVENTORY
MMINVENTORY table
ITEMNUMBER PARTNUMBER QUANTITY COST SHELF LOCATION
---------- ---------- ----------- ------------ ----- --------------------
21000003 M100000003 10 59.99 L8 MM - San Francisco
21000004 M100000003 12 57.99 B7 MM - New York
31000005 W111111111 2 12.34 H8 MM - Los Angeles
900 T0 1 99.00 M0 MM - San Jose
901 T1 1 11.00 M1 MM - Heidelberg
902 T2 1 22.00 M2 MM - Brussels
903 T3 1 33.00 M3 MM - Raleigh
904 T4 1 44.00 M4 MM - London
905 T5 1 55.00 M5 MM - Zurich
PPINVENTORY table
ITEMNUMBER PARTNUMBER QUANTITY COST SHELF LOCATION
---------- ---------- ----------- ------------ ----- --------------------
21000001 M100000001 99 99.99 X1 PP - Heidelberg
21000003 M100000003 42 49.99 01 PP - Heidelberg
31000006 B222222222 13 123.45 E5 PP - Frankfurt
SSINVENTORY table
ITEMNUMBER PARTNUMBER QUANTITY COST SHELF LOCATION
---------- ---------- ----------- ------------ ----- --------------------
21000001 M100000001 99 89.99 2A SS - Santa Cruz
21000002 X333333333 7 12.34 2D SS - Santa Cruz
1 HEAD stream
Not existing 3
2
Branch stream
Assigned in
workspace 3
2
8 4
Unassigned In repository
10 in workspace stream
7
9 6 5
1
These transitions are listed below and described in the subsequent sections:
1. Not existing -> Unassigned in workspace
2. Unassigned in workspace -> Assigned in workspace
3. Assigned in workspace -> In repository stream
4. In repository stream -> Assigned in workspace
5. In repository stream -> Repository version
6. Repository version -> In repository stream
7. Repository version -> Assigned in workspace
8. Unassigned in workspace -> In repository stream
9. Unassigned in workspace -> Not existing
10.Assigned in workspace -> Not existing
11.Repository version -> Not existing
5
7 4 3
6
In project Modified
2 Top of stream
version in workspace
1 11
9
10
These transitions are listed below and described in the subsequent sections:
1. Not existing -> Modified in workspace
2. Modified in workspace -> Top of stream
3. Top of stream -> Below top of stream
4. Top of stream -> Base version in workspace
5. In project version -> Base version in workspace
6. Base version in workspace -> Modified in workspace
7. Modified in workspace -> Base version in workspace
8. Below top of stream -> Base version in workspace
9. Modified in workspace -> Not existing
To import an existing file from the file system, simply select the
File -> Import menu from the IDE and select a suitable source
type.
Working in a team
1. Are file deletions from the workspace permanent?
Yes, unless you are working with either a local or shared repository.
2. What is a stream?
A stream maintains a teams shared configuration of one or more related
projects and their folders and files.
3. What are the two possible operations when synchronizing with a stream?
Release and catch-up
Select the Additional materials and open the directory that corresponds with
the redbook form number, SG24-6292.
Setup
DDL (ITSOWSAD.ddl—DDL to create the ITSOWSAD database)
ITSOWSAD (ITSOWSADServer.zip—server definition)
images (*.gif—auto parts base images for each of the Web applications)
The solution subdirectory in each chapter directory contains the ZIP, JAR, or
EAR files for the completed chapter.
Once you have completed the setup instructions and the configuration of the
WebSphere instance, you can import these EAR files for a complete working
solution.
The ZIP, JAR, or EAR files are cumulative and contain the complete solution
to the specified chapter in the book.
The instructions following the EAR file import instructions for each chapter are
cumulative. They assume that the previous instructions have been
completed. This mostly affects the definition of the Java build path for the
Web projects and the addition of EAR files to the server instance.
For more detailed instructions on building the chapter solution, see the
referring chapter.
Important: The Application Developer does not allow you to import an EAR
file into an existing EAR project. Therefore:
Delete the existing EAR project.
Import the EAR file into the specified EAR project. This will create the EAR
project and import the WAR files into the existing Web projects. This
overwrites the existing files in the Web project but leaves the Web project
definitions in place. This is important because deleting the Web projects
along with the EAR project and allowing the EAR import to create the
contained Web projects will reset your Web project definitions back to the
default... most importantly resetting the Java build path for the project.
However, EJB projects must be deleted before importing the EAR file.
Setup directory
From a DB2 command window, from the sampcode\Setup\DDL directory
containing the DDL run:
db2 -tf ITSOWSAD.ddl
See “Define and load the ITSOWSAD database” on page 542 for more
information.
For testing of Web and EJB applications in the Application Developer we use an
internal WebSphere server:
Create a server project called ITSOWSADServer
Import the zip file into the ITSOWSADServer project.
Update the paths for the server configuration.
– Open the server-cfg.xml file.
– Click Yes when presented with the message in Figure 16-5.
– Save the configuration file.
Define the following Java build variables in Application Developer. Select Window
-> Preferences -> Java -> Classpath variables, and click on New :
UDDI4JJAR <WSAD_INSTALL_DIR>plugins/com.ibm.etools.
websphere.runtime/runtime/uddi4j.jar
MAILJAR <WSAD_INSTALL_DIR>plugins/com.ibm.etools.
servletengine/lib/mail.jar
WSADXML directory
These instructions refer to Chapter 4, “XML support in Application Developer”:
Create a Java project called ITSOMightyXML.
Import the zip file from the solution directory into the ITSOMightyXML project,
overwriting existing files.
Place the InquireParts.xml file from the solution directory in the root install
directory (d:\WSAD, for example).
WSADEJB directory
These instructions refer to Chapter 5, “EJB development with Application
Developer”:
Delete the ITSOMightyEAR and the ITSOMightyEJB projects.
Import the ITSOMighty.ear file from the solution directory into the
ITSOMightyEAR project.
Rebuild the ITSOMightyEJB project.
Add the ITSOMightyEAR project to the ITSOWSADWebSphere server
configuration.
WSADDeploy directory
These instructions refer to Chapter 6, “Deployment of Web and EJB applications
to WebSphere”:
Import the ITSOWSADRemoteServer.zip file from the solution directory into the
ITSOWSADServer project, overwriting files.
Edit the ITSOWSADRemote server instance:
– Change the hostname to the name of the machine running your remote
WAS instance.
– Make sure the installation directory and deployment directory exist on your
machine or change them to directories that exist on your machine.
WSStatic directory
These instructions refer to Chapter 10, “Static Web services”:
Delete the ITSOAlmaEAR project.
Import the ITSOAlma.ear file from the solution directory into the ITSOAlmaEAR
project.
Add the variables WAS_XALAN and SOAPJAR to the ITSOAlmaWeb project Java
build path.
Delete the ITSOMightyEAR and the ITSOMightyEJB projects.
Import the ITSOMighty.ear file from the solution directory into the
ITSOMightyEAR project.
Add the variables WAS_XALAN, and SOAPJAR to the ITSOMightyWeb project Java
build path.
Add project ITSOMightyEJB to the ITSOMightyWeb project Java build path.
WSDynamic directory
These instructions refer to Chapter 11, “Dynamic Web services”:
Import the ITSOPlenty.ear file into the ITSOPlentyEAR project.
– Add the ITSOPlentyEAR project to the ITSOWSADWebSphere server instance.
– Add the variables WAS_XERCES and SOAPJAR to the ITSOPlentyWeb Java
build path.
Delete the ITSOAlmaEAR project.
Import the ITSOAlma.ear file from the solution directory into the ITSOAlmaEAR
project.
– Add the variables WAS_XERCES, WAS_XALAN, SOAPJAR, UDDI4JJAR and
MAILJAR to the ITSOAlmaWeb project Java build path
Delete the ITSOMightyEAR and ITSOMightyEJB projects.
WSComposed directory
These instructions refer to Chapter 12, “Composed Web services”:
Delete the ITSOAlmaEAR project.
Import the ITSOAlma.ear file from the solution directory into the ITSOAlmaEAR
project.
– Add JAR soapcfg.jar to the ITSOAlmaWeb project Java build path from
/ITSOAlmaWeb/webApplication/WEB-INF/lib
– Rebuild the ITSOAlmaWeb project.
Import the ITSOSanta.ear file from the solution directory into the
ITSOSantaEAR project.
– Add JAR dbbeans.jar, ibmSerializers.jar and xsdbeans.jar to the
ITSOSantaWeb project Java build path from
/ITSOSantaWeb/webApplication/WEB-INF/lib
– Add the variables WAS_XALAN, WAS_XERCES and SOAPJAR to the ITSOSantaWeb
project Java build path.
– Rebuild the ITSOSantaWeb project.
– Add the ITSOSantaEAR project to the ITSOWSADWebSphere server instance.
WSDeploy directory
These instructions refer to Chapter 13, “Deployment of Web services to
WebSphere”:
Use the supplied EAR files to follow the instructions for deploying the
ITSOAlma, ITSOMighty, ITSOPlenty, and ITSOSanta enterprise applications to
WebSphere AEs and WebSphere AE.
The publications listed in this section are considered particularly suitable for a
more detailed discussion of the topics covered in this redbook.
IBM Redbooks
For information on ordering these publications, see “How to get IBM Redbooks”
on page 581.
Self-Study Guide: WebSphere Studio Application Developer and Web
Services, SG24-6407
WebSphere Version 4 Application Development Handbook, SG24-6134
WebSphere V4.0 Advanced Edition Handbook, SG24-6176
Programming J2EE APIs with WebSphere Advanced, SG24-6124
Enterprise JavaBeans for z/OS and OS/390 CICS Transaction Server V2.1,
SG24-6284
EJB Development with VisualAge for Java for WebSphere Application Server,
SG24-6144
Design and Implement Servlets, JSPs, and EJBs for IBM WebSphere
Application Server, SG24-5754
Programming with VisualAge for Java Version 3.5, SG24-5264
WebSphere V3.5 Handbook, SG24-6161
Version 3.5 Self Study Guide: VisualAge for Java and WebSphere Studio,
SG24-6136
How about Version 3.5? VisualAge for Java and WebSphere Studio Provide
Great New Function, SG24-6131
Servlet and JSP Programming with IBM WebSphere Studio and VisualAge for
Java, SG24-5755
Revealed! Architecting Web Access to CICS, SG24-5466
IMS Version 7 and Java Application Programming, SG24-6123
Migrating WebLogic Applications to WebSphere Advanced Edition,
SG24-5956
WebSphere Personalization Solutions Guide, SG24-6214
Other resources
These publications are also relevant as further information sources:
Sections on Web services in IBM WebSphere Application Developer beta,
Help perspective, August 2001 (contained in Application Developer beta
code)
Web Services Conceptual Architecture, Version 1.0, Web Services
Architecture Team, June 2001, contained in IBM WSTK 2.3 (currently no
ISDN number or URL available)
Redpieces are Redbooks in progress; not all Redbooks become Redpieces and
sometimes just a few chapters will be published this way. The intent is to get the
information out much quicker than the formal publishing process allows.
Information in this book was developed in conjunction with use of the equipment
specified, and is limited in application to those specific hardware and software
products and levels.
IBM may have patents or pending patent applications covering subject matter in
this document. The furnishing of this document does not give you any license to
these patents. You can send license inquiries, in writing, to the IBM Director of
Licensing, IBM Corporation, North Castle Drive, Armonk, NY 10504-1785.
Licensees of this program who wish to have information about it for the purpose
of enabling: (i) the exchange of information between independently created
programs and other programs (including this one) and (ii) the mutual use of the
information which has been exchanged, should contact IBM Corporation, Dept.
600A, Mail Drop 1329, Somers, NY 10589 USA.
The information contained in this document has not been submitted to any formal
IBM test and is distributed AS IS. The use of this information or the
implementation of any of these techniques is a customer responsibility and
depends on the customer's ability to evaluate and integrate them into the
customer's operational environment. While each item may have been reviewed
by IBM for accuracy in a specific situation, there is no guarantee that the same or
similar results will be obtained elsewhere. Customers attempting to adapt these
techniques to their own environments do so at their own risk.
Any pointers in this publication to external Web sites are provided for
convenience only and do not in any manner serve as an endorsement of these
Web sites.
Java and all Java-based trademarks and logos are trademarks or registered
trademarks of Sun Microsystems, Inc. in the United States and/or other
countries.
Microsoft, Windows, Windows NT, and the Windows logo are trademarks of
Microsoft Corporation in the United States and/or other countries.
UNIX is a registered trademark in the United States and other countries licensed
exclusively through The Open Group.
SET, SET Secure Electronic Transaction, and the SET Logo are trademarks
owned by SET Secure Electronic Transaction LLC.
SAX Simple API for XML WSTK Web Service Development Kit
Index 589
archive file binding 289
see EAR port 242
Enterprise JavaBeans server 189, 199
see EJB transport 440, 444
entity HTTPR 316
EJB 138
create 138
reference 93
I
IBM Agent Controller
envelope 262, 264
see Agent Controller
error handling 266
ibm-application-ext.xmi 237
export
ibm-application-ext.xml 61
EAR file 171
ibm-ejb-jar-bnd.xmi 44, 145
WSDL 390
ibm-ejb-jar-ext.xmi 44, 145
eXtensible style sheet language
ibm-web-bnd.xml 60
see XSL
ibm-web-ext.xml 60
extension point 19
ignore 235
external JAR 35
image
display 75
F import 76
file URL 77
life cycle 553 implementation
firewall 518 WSDL 277
FTP 42 import
EAR 571
images 76
G WAR file 42
generated types
Web site 41
Web application 71
WSDL 394
getter method 147
initialization parameters 74
global JNDI name 162
inspector view 32
graphics editing framework 20
install
enterprise application 176
H installation
head stream 213, 546 Agent Controller 540
header 265 Application Developer 540
help CVS 222
hover 36 DB2 538
perspective 32 WebSphere
hierarchy view 26 AE 539
history of changes 210 AEs 539
home interface 144, 162 UDDI Registry 541
host variable 67 integrated development environment 19
hover help 36 interface 277
HTML WSDL 277
input page 72 interoperability 244, 523
markup 92 inventory
style sheet 41 EJB 135
HTTP table 12
Index 591
method debug 31
promote 148, 164 help 32
read-only 148 J2EE 27
Mighty Motors 8, 106, 134 Java 25
mime type 49 server 30
model-view-controller 71 team 215
modular toolbar 21
Web services 243 views 21
module Web 21, 25
dependencies 41 XML 29
visibility 193 Plenty Parts 8
monitor server 48 Web service 384
MQSeries 261, 493 plug-in 19
Integrator 493, 507 Web server 186, 193
Workflow 503 WebSphere AEs 441
MQSI 507 port 49
type 284
WSDL 283
N portal UDDI 491
NAICS 298, 389
precompile JSP 177
namespaces
preferences 22, 35
UDDI 297
server 50
WSDL 282
problem 23
XML 97
processes view 30
naming convention 59
processing
CVS 223
instructions 95
navigator view 22
XML 101
project 33
O configuration 58
open source 18, 215, 523 EAR 38
optimistic concurrency 212 EJB 44
outline view 23 Java 33
lifecycle 548
naming convention 59
P server 47, 82
package
Java 35 type 221
packages view 26 version 550
page designer 55, 78, 370 Web 40
parallel development 227 promote 164
parser 101, 102, 128 method 148
part EJB 135 properties view 23
partner catalog 492 protocol 246
parts table 12 proxy
peer-to-peer computing 517 testing 427
performance 33, 522 Web service 342
perspective 20 publishing 51
customize 24
data 28
Index 593
UDDI 405 DADX 483
wizard 368 wizard 110
session state transitions 545
EJB static service 256
create 158 stream 212, 545
Web service 374 branch 546
facade 135, 158 head 546
SGML 92 merge 233
simple API for XML multiple 231
see SAX style sheet 407
simple object access protocol HTML 59
see SOAP synchronize 212
simple type 99 syntax highlighting 26
SOAP 6, 246 system files 52
1.1 specification 276
admin client 352, 435
administration 422
T
table
binding 281, 287, 344
editor 28
body 265
tag library 43, 63
Call object 273
tasks view 23
client
taxonomy
API 272
UDDI 298
proxy 397, 455
TCP/IP
communication style 267
Monitor view 359, 456
data model 266, 267
Monitoring Server 48, 358, 408, 456
deployment 422
team
descriptor 255, 271, 350
development 224
encoding 262, 268, 339
perspective 215
envelope 262
terminology 212
error handling 266
template 51
header 265
terminology
introduction 261
matrix 214
Lite 253
team support 212
mapping 269
test
message 262, 456
client
communication 517
EJB 153
service 471
registry 300
programming 448
Web service 332
remote procedure call 262
tips
router servlet 347, 351
performance 33
RPC client 249
variables 35
security 338
tModel 251, 293, 404
server 250
Tomcat 48, 83
implementation 270
toolbar 21
soap.xml 350
transformation
SOAPEAREnabler tool 445
XML 125
SQL
troubleshooting 530
query 67
type
statement 66, 110, 480
Index 595
server configuration 30 testing 332, 425
servers 30 type 325
tasks 23 URI 337
TCP/IP Monitor 359 wizard 308, 336, 420
variables 31 WSDL files 347
virtual host 195, 200, 440 services
visibility 184, 193 architecture 514
VisualAge for Java 18 conversation language 498
description language
see WSDL
W endpoint language 498
WAR file 40, 41
flow language
Web
see WSFL
application 40
inspection language 302
archive 41
invocation framework 292
deployment 81
object runtime framework 487
development 55
overview 241
execution 86
process management toolkit 504
deployment descriptor 41, 42
protocol stack 246
module 27, 60
terminology 305
perspective 21, 25
toolkit
project 40
see WSTK
configuration 58
tools 307
files 60
site
service
import 41
client 364, 373, 426
web.xml 41, 42, 60, 73
client wizard 310
WebSphere
composed 413
Administration Server 190
consumption wizard 317
AE 170, 443
creation 334
installation 539
creation wizard 316
AEs 170, 438
DADX 479
installation 539
DADX group configuration wizard 312,
remote server 47
482
Studio (classic) 316
deployment 433
Studio Application Developer
design 525
see Application Developer
development 254
Studio Workbench
dynamic 379
see Workbench
generated files 345
test environment 47, 82
Mighty Motors 334
UDDI Registry 496
proxy 342, 354
installation 541
publishing 345
well-formed XML document 95
sample client 356
wizard
scope 271, 421
Application Installation 178
session EJB 374
Database Web Pages 62
skeleton JavaBean wizard 311
EJB to RDB Mapping 138
standards 304
servlet 368
static 321
Web service 308, 336
test client 344
XML from SQL Query 109
Index 597
598 Web Services Wizardry with WebSphere Studio Application Developer
Web Services Wizardry with
WebSphere Studio Application Developer
(1.0” spine)
0.875”<->1.498”
460 <-> 788 pages
Back cover ®