You are on page 1of 314

IBML

IBM Network Computing Framework


for e-business Guide
Barry D. Nusbaum, Thomas Liu, Marco Pistoia, Giancarlo Rochester

International Technical Support Organization


http://www.redbooks.ibm.com
This book was printed at 240 dpi (dots per inch). The final production redbook with the RED cover will
be printed at 1200 dpi and will provide superior graphics resolution. Please see How to Get ITSO
Redbooks at the back of this book for ordering instructions.

SG24-5296-00

IBML

International Technical Support Organization


IBM Network Computing Framework
for e-business Guide
September 1998

SG24-5296-00

Take Note!
Before using this information and the product it supports, be sure to read the general information in
Chapter 7, Special Notices on page 289.

First Edition (September 1998)


This edition applies to Version 4.6 of Lotus Domino Go Webserver for use with the AIX and NT operating systems.
Comments may be addressed to:
IBM Corporation, International Technical Support Organization
Dept. HZ8 Building 678
P.O. Box 12195
Research Triangle Park, NC 27709-2195
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.
Copyright International Business Machines Corporation 1998. All rights reserved.
Note to U.S. Government Users Documentation related to restricted rights Use, duplication or disclosure is
subject to restrictions set forth in GSA ADP Schedule Contract with IBM Corp.

Contents
Figures

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Preface
. . . . . . . . . . . . . . . .
The Team That Wrote This Redbook
. . . . . . . .
Comments Welcome

. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .

Chapter 1. Overview
. . . . . . . . . . . . . . . . . . . . . . . . . . .
1.1 Developing Applications in the Network Computing Framework
. . . . . . . . . . . . . . . . . . . . . .
1.1.1 An Overview of NCF
1.1.2 Designing NCF Applications . . . . . . . . . . . . . . . . . .
1.1.3 Some Design Alternatives . . . . . . . . . . . . . . . . . . .
1.2 Java Is the Foundation . . . . . . . . . . . . . . . . . . . . . . . .
. . . .
1.3 Universal Support for the Servlet Programming Model
Chapter 2. Servlets . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
2.1 Overview of Java Servlets
2.1.1 Advantages of Servlets . . . . . . . . . . . . . . .
2.1.2 Servlets and CGI-BINs . . . . . . . . . . . . . . .
. . . . . . . . . . . . . .
2.1.3 The Hello World Servlet
. . . . . . . . . . .
2.2 Structure of the Java Servlet API
2.2.1 Interface javax.servlet.Servlet . . . . . . . . . . .
2.2.2 Interface javax.servlet.ServletConfig . . . . . . .
2.2.3 Interface javax.servlet.ServletContext . . . . . .
2.2.4 Interface javax.servlet.ServletRequest . . . . . .
2.2.5 Interface javax.servlet.ServletResponse . . . . .
2.2.6 Interface javax.servlet.http.HttpServletRequest
2.2.7 Interface javax.servlet.http.HttpServletResponse
2.2.8 Class javax.servlet.GenericServlet . . . . . . . .
2.2.9 Class javax.servlet.ServletInputStream . . . . .
. . .
2.2.10 Class javax.servlet.ServletOutputStream
2.2.11 Class javax.servlet.http.HttpServlet . . . . . . .
. . . . . . . .
2.2.12 Class javax.servlet.http.HttpUtils
. . .
2.2.13 Exception javax.servlet.ServletException
2.2.14 Exception javax.servlet.UnavailableException .
. . . . . . . . . . . . . . . . . . . . .
2.3 Servlet Structure
2.3.1 The init(), service() and destroy() Methods . . .
2.3.2 Parameters Passed by the Server . . . . . . . .
2.3.3 Servlet Life Cycle . . . . . . . . . . . . . . . . . .
2.4 Extending Lotus Domino Go Webserver with Servlets
. . . . . . . . . . . . .
2.4.1 Document Root Directory
. . . . . . . . . . . . . . . . . .
2.4.2 Servlet Directory
2.4.3 Other Configurations . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . .
2.5 Creating a Servlet
2.5.1 Compiling and Installing a Servlet . . . . . . . .
2.5.2 Invoking a Servlet . . . . . . . . . . . . . . . . . .
. . . . . . . . .
2.5.3 Debugging and Testing Servlets
2.6 Advantages of Servlets over CGI-BIN . . . . . . . . .
. . . . . . . .
2.6.1 CGI-BIN Processing HTML Forms
2.6.2 Java Servlets Processing Forms . . . . . . . . .
2.6.3 GET and POST HTML Methods . . . . . . . . . .
2.6.4 Multithreading . . . . . . . . . . . . . . . . . . . .

Copyright IBM Corp. 1998

. . . . . . .
. . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .

. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .

v
xi
xi
xii
1
1
2
2
4
9
10
11
11
12
14
15
16
17
17
18
19
19
19
19
20
20
20
21
21
21
22
22
22
25
26
28
29
29
30
33
33
36
38
38
38
44
49
62

iii

2.7 A Sample Servlet . . . . . . . . . . . . . . . . . . . .


. . . . . . . . . . . . . . .
2.7.1 Creating the Servlet
2.7.2 Compiling and Installing the Servlet . . . . . .
2.7.3 Invoking the Servlet . . . . . . . . . . . . . . . .
. . . . . .
2.7.4 Debugging and Testing the Servlet
2.8 Servlet Tag Technique . . . . . . . . . . . . . . . . .
2.8.1 Another Example of the Servlet Tag Technique
Chapter
3.1 The
3.1.1
3.1.2
3.1.3
3.1.4
3.1.5
3.1.6

3. Connectors . . . . . . .
. . .
Role of a Connector
CICS Applications . . . . .
CICS Internet Gateway . .
CICS Gateway for Java . .
MQSeries Internet Gateway
MQSeries Client for Java
eNetwork Host On-Demand

. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .

Chapter 4. Net.Data Database Scenario


. . . . . .
4.1 Software Configuration
. . . . . . . . .
4.2 Net.Data Scenario
.
4.2.1 Create an SQL Query Tool
4.2.2 Using Java Applets . . . . . .

. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .

Chapter 5. JDBC Database Scenario . . . . . . . . . . . . . . . . . . . . .


. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.1 What Is JDBC?
. . . . . . . . . . . . . . . . . . . . . . . . . .
5.2 Software Configuration
5.2.1 DB2 CAE Configuration . . . . . . . . . . . . . . . . . . . . . . . .
5.3 JDBC Client/Server Scenario . . . . . . . . . . . . . . . . . . . . . . .
5.4 JDBC Client/Server Scenario Using Java Beans . . . . . . . . . . .
5.5 JDBC Client/Server Database Server Scenario Using Java Servlets
Chapter 6. Transaction Server Scenario (NT and S/390)
. . . . . . . . . . . . . . .
6.1 Application Environment
. . . . . . . . . . . .
6.2 Servlets and IBM Connectors
Chapter 7. Special Notices

. . .
. . .
. . .
. .

113
113
114
116
133
154
173
184
197
197
208
209
216
229
229
232
232
240
245
258

. . . . . . . . . . . . .

265
266
276

. . . . . . . . . . . . . . . . . . . . . . . . . . . . .

289

How to Get ITSO Redbooks


. . . . . . . . . .
How IBM Employees Can Get ITSO Redbooks
How Customers Can Get ITSO Redbooks . .
. . . . . . . . . . .
IBM Redbook Order Form

. . . . . . . . . . . . .

. . . . . . . . .
. . . . . . . .
. . . . . . . . .
. . . . . . . . .

291
291
291
291

. . . . . . . . . . . . . . . . . . .

293
293
294
295

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

297

ITSO Redbook Evaluation

iv

. . .

. . . . . . . . . . . .

Chapter 8. Related Publications


. . . . . . . . . . . . . . . . .
8.1 International Technical Support Organization Publications
8.2 Redbooks on CD-ROMs . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . .
8.3 Other Publications

Index

. . .
. . .

67
68
73
77
83
87
96

Network Computing Framework for e-business Guide

. . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

299

Figures
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.

Copyright IBM Corp. 1998

The NCF Model


. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
Code Sample for a Simple NCF Application
ServletEmbed Syntax for Lookup . . . . . . . . . . . . . . . . . . . . . .
Client/Server Communication Supported by NCF . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
The NCF Model
. . . . . . . . . . . . . .
Process Flow from a High-Level Perspective
Servlets Versus CGI-BIN Applications . . . . . . . . . . . . . . . . . . .
Invoking the Hello World Servlet . . . . . . . . . . . . . . . . . . . . . .
A Simple Way for Servlets to Test the ServletContext Object . . . . .
GenericServlet Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
The Simplest Possible Servlet Contains a Single Life Cycle Method,
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
service()
Graphical Representation of a Servlet Life Cycle . . . . . . . . . . . .
Confirmation for the Java Servlet Support . . . . . . . . . . . . . . . .
Java Virtual Machine Configuration . . . . . . . . . . . . . . . . . . . .
Servlet Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Servlet Initialization Parameters . . . . . . . . . . . . . . . . . . . . . .
Control Panel Window . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Services Window
Restart the Lotus Domino Go Webserver . . . . . . . . . . . . . . . . .
Restarting the Lotus Domino Go Webserver . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . .
Invoking the SimplestServlet Servlet
. . . . . . . . . . . . . . . . . .
HTML Form Invoking a CGI Perl Script
. . . . . . . . . . . . . . . . .
HTML Code Generating the HTML Form
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Fill Out the Form
. . . . . . . . . . . . . . .
CGI Perl Script Processing the HTML Form
HTML Page Dynamically Generated by the CGIServlet CGI Perl Script
HTML Form Invoking a Java Servlet . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
HTML Code Generating the HTML Form
Java Servlet Processing the HTML Form . . . . . . . . . . . . . . . . .
servlet-log File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Fill Out the Form
HTML Page Dynamically Generated by the ServletCGI Java Servlet
HTML Code Invoking the ServletCGI Servlet with the POST Method
A Security Information Window Is Displayed with the POST Method
HTML Code Invoking the CGIServlet Perl CGI Script with the POST
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Method
. . . . .
HTML Page Not Correctly Generated by the CGI Perl Script
HTML Form Generated by the FormInfo.html File . . . . . . . . . . . .
HTML Code Generating the Form Info HTML Page . . . . . . . . . . .
Java Code for the FormInfo Java Servlet . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
Loops of a Typical Structure in Servlets
HTML Form Filled with Our Data . . . . . . . . . . . . . . . . . . . . . .
HTML Page Generated Using the GET Method - Request Information
.
HTML Page Generated Using the GET Method - Request Headers
HTML Page Generated Using the GET Method - Servlet Parameters
HTML Page Generated Using the POST Method - Request Information
HTML Page Generated Using the POST Method - Request Headers
HTML Page Generated Using the POST Method - Servlet Parameters
. . . . . . . . . . . . . . . . . . . . . . . . . .
ConterServlet Java Code
First HTML Page Dynamically Generated by CounterServlet . . . . .

. .
. .
. .
. .
. .
. .
. .
. .
. .
. .

. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
.
. .
. .
. .
. .
. .
. .
. .
. .

. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
.
. .
.
. .
. .

2
5
6
8
10
12
15
16
18
20
23
27
28
30
31
32
34
35
35
36
37
39
39
41
42
44
45
45
46
47
48
49
50
51
51
52
53
54
55
57
58
59
59
60
61
61
62
63
65

50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.

vi

Second HTML Page Dynamically Generated by CounterServlet


. . .
Third HTML Page Dynamically Generated by CounterServlet . . . . .
Java Code of the EmployeeSearch Servlet . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Database Text File
Parsing the Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . .
EmployeeSearch Servlet Initialization Parameters
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Confirmation Page
. . . . . . . . . . . . . . . . . . . . . . . . .
Restart Confirmation Page
EmployeeSearch Servlet Configuration . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . .
IBM EmployeeSearch Servlet Window
Insert the Name of the Employee You Are Searching For . . . . . . .
. . . . . . . . . . . . . . . . .
IBM EmployeeSearch Servlet Response
Appending the Encoded Key to the Servlets URL . . . . . . . . . . . .
. . . . . . . . . . . . . .
IBM EmployeeSearch Servlet New Response
Error Message . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Debugging Information in the Log . . . . . . . . . . . . . . . . . . . . .
servlet-log File after EmployeeSearch Servlet Initialization . . . . . .
. . . . .
servlet-log File after the destroy() Method Has Been Called
The Servlet Is Activated Even If Its Configuration Is Incorrect . . . . .
No Response Is Displayed When the SUBMIT Button Is Clicked . . .
The servlet-log File Is Needed to Debug the Program . . . . . . . . .
HTML Code of the Experiment.shtml File . . . . . . . . . . . . . . . . .
. . . . . . . . . . .
Java Source Code of the Experiment.java Servlet
HTML Page Statically and Dynamically Generated . . . . . . . . . . .
HTML Source Code after the Dynamic Portion Has Been Embedded
. . . . . . . . . . . .
The Servlet Has Been Initialized Multiple Times
Filling Out the Servlet Configuration Form for the Experiment Servlet
HTML Page Statically and Dynamically Generated . . . . . . . . . . .
The init() Method Is Called Only the First Time the Servlet Is Invoked
IncludedCounter.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
StoredData.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Page1.shtml
The Page1.shtml File Has Been Reloaded Three Times . . . . . . . .
The servlet-log File after the First Experiment . . . . . . . . . . . . . .
The Page1.shtml File Loaded from a Different Client Machine . . . .
The servlet-log File after the Second Experiment . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Page2.shtml
. .
The Page2.shtml File Has Been Loaded by the Clients Browser
. . . . . . . . . . . . .
The servlet-log File after the Third Experiment
Both the Files Page1.obj and Page2.obj Are Still Empty . . . . . . . .
Both the Files Page1.obj and Page2.obj Are No Longer Empty . . . .
The servlet-log File after the Fourth Experiment . . . . . . . . . . . . .
The Page1.shtml File Has Been Loaded after the Web Server Was
Restarted . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
The servlet-log File after the Fifth Experiment . . . . . . . . . . . . . .
IBM Network Computing e-Business Enterprise Connectors Page . .
CICS Programming Styles . . . . . . . . . . . . . . . . . . . . . . . . . .
CICS Internet Gateway . . . . . . . . . . . . . . . . . . . . . . . . . . . .
CICS Internet Gateway: Current Gateway Settings . . . . . . . . . . .
CICS Internet Gateway: TimeOutInternet Occurred . . . . . . . . . . .
CICS Internet Gateway: CICS Console Messages . . . . . . . . . . . .
. . . . . . . .
CICS Internet Gateway - CIGD.INI File for Windows NT
. . . . . . . . .
CICS Internet Gateway: How to Start It Automatically
. . . . . . . . . . . .
CICS Internet Gateway: Customized Initial Page
CICS Internet Gateway: Customized Header and Trailer HTMLs . . .

Network Computing Framework for e-business Guide

66
67
. 68
. 70
. 73
. 74
. 75
. 76
. 77
. 78
. 79
. 80
. 81
. 82
. 83
. 83
. 84
. 84
. 85
. 86
. 86
. 89
. 90
. 91
. 92
. 93
. 94
. 95
. 96
. 98
100
101
103
104
105
105
106
107
108
108
109
109

. .
. .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

110
110
114
116
117
120
120
121
122
126
127
127

104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.

CICS Internet Gateway: Configuration Scenario . . . . . . . . . . . . . .


CICS Internet Gateway - Start a Hidden Transaction . . . . . . . . . . .
. . . . . . .
CICS Internet Gateway - HTML Tags Added on CICS Map
CICS Internet Gateway: Click on to Start Your CICS Transaction . . . .
CICS Internet Gateway: CICS Transaction Response . . . . . . . . . . .
CICS Internet Gateway: Default ExitPage . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
CICS Gateway for Java Overview
. . . . . . . . . . . . . . . .
CICS Gateway for Java Directory Structure
. . . . . . . . .
CICS Gateway for Java: Start with the Default Options
CICS Gateway for Java: Start with the User Options . . . . . . . . . . .
CICS Gateway for Java: Get Help on the Startup Options . . . . . . . .
. . . . . . . . .
CICS Gateway for Java: Start Command Using an Icon
CICS Gateway for Java: Stand-Alone Catalog Demo . . . . . . . . . . .
CICS Gateway for Java: TestECI Program Running As an Application
. . .
CICS Gateway for Java: TestECI Program Running in a Browser
. . . . .
CICS Gateway for Java: HTML Used to Run TestECI Program
CICS Gateway for Java: TestEPI Program Running in an Appletviewer
CICS Gateway for Java: TestECI Java Source Sample . . . . . . . . . .
CICS Gateway for Java: TestEPI Java Source Sample . . . . . . . . . .
.
CICS Gateway for Java: Scalability and Access to Multiple Systems
MQSeries Internet Gateway: Typical Scenario . . . . . . . . . . . . . . .
MQSeries Internet Gateway: Defining MQ Resources for the Sample .
MQSeries Internet Gateway: DQSAMP1 Process Input Form . . . . . .
MQSeries Internet Gateway: DQSAMP1 Process Output Form (1 of 3)
MQSeries Internet Gateway: DQSAMP1 Process Output Form (2 of 3)
MQSeries Internet Gateway: DQSAMP1 Process Output Form (3 of 3)
MQ Internet Gateway: DQSAMP1 Process Output Form without Context
MQ Internet Gateway: Configurator Program New Configuration File .
. .
MQ Internet Gateway: Configurator Program Default DMQ.INI File
. . . . .
MQ Internet Gateway: Sample Form with Provided Keywords
. . . . . . . . . .
MQ Internet Gateway: Customized Reply Retry Form
MQ Internet Gateway: Customized Reply Retry Form Source File . . .
MQ Internet Gateway: DMQSAMP1 BuildHTTP and ParseString
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Routines
MQSeries Internet Gateway: Web-Aware Linking Non-Web-Aware
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Applications
MQ Client for Java: Web Browser Running the Verification Program .
.
MQ Client for Java: Appletviewer Running the Verification Program
. . . . . . . .
MQ Client for Java: Trace Written into the Java Console
. . . . . . . . . . . . . . . . . . . . .
MQ Client for Java: Sample Applet
MQ Client for Java: Receive a Message Using a Correlation ID . . . .
MQ Client for Java: Receive a Message Using a Correlation ID . . . .
MQ Client for Java: Example Source Code . . . . . . . . . . . . . . . . .
eNetwork Host On-Demand: Configuration Scenario . . . . . . . . . . .
eNetwork Host On-Demand: Communication Server for Windows NT .
eNetwork Host On-Demand: Installation Steps . . . . . . . . . . . . . . .
eNetwork Host On-Demand: Installation Steps . . . . . . . . . . . . . . .
eNetwork Host On-Demand: Example Provided by sample2.htm . . . .
. . . . . . . . . . . .
eNetwork Host On-Demand: General Help Screen
eNetwork Host On-Demand: How to Use the Keyboard Screen . . . . .
eNetwork Host On-Demand: How Do I Screen . . . . . . . . . . . . . . .
. . . . . .
eNetwork Host On-Demand: 3270 VTAM Connection Screen
eNetwork Host On-Demand: 3270 Application . . . . . . . . . . . . . . .
Servlets and IBM Connectors Architecture . . . . . . . . . . . . . . . . .
The Whole Environment of Windows NT Scenario . . . . . . . . . . . . .

128
130
131
132
132
132
134
135
136
137
137
138
139
140
141
142
143
144
147
154
155
157
158
159
160
161
162
163
164
165
166
167

Figures

vii

169
173
176
177
178
180
180
181
182
185
186
186
187
189
190
191
192
193
194
196
197

157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.

viii

The Hierarchy of Net.Data Directory . . . . . . . . . . . . . . . . . . . . .


The Configuration File of Net.Data . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
The Original Configuration File of Net.Data
The Modified Configuration File for Net.Data . . . . . . . . . . . . . . . .
Create Database Connection . . . . . . . . . . . . . . . . . . . . . . . . .
Select How to Create the Connection . . . . . . . . . . . . . . . . . . . .
Select the Target Database . . . . . . . . . . . . . . . . . . . . . . . . . .
Select the Target Database from the List . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
Select Database from the List
. . . . . . . . . . . . . . . . . . . . . . . .
Select Database from the List
. . . . . . . . . . . . . . . . .
Select Protocol to Use to Find the Server
. . . . . . . . . . . . . . . . . . . . . . . . . .
Server Is Found in the List
Select the Target Database from the List . . . . . . . . . . . . . . . . . .
Specify the Local Name for the Target DB2 Database . . . . . . . . . .
. . . . . . . . . . . . . . . . . . .
Click on Done to Build the Connection
The Connection Configuration Was Added Successfully . . . . . . . . .
Enter ID and Password for the Database . . . . . . . . . . . . . . . . . .
The Connection Test Was Successful . . . . . . . . . . . . . . . . . . . .
Available DB2 Database . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . .
Try to Connect Database from DB2 Command Window
Use Control Center to Show You the Details of Database . . . . . . . .
The Macro File to Access Database Sample . . . . . . . . . . . . . . . .
Query the Table Staff from Database Sample . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
Result from Query Table Staff
Connect to Database by DB2 Command Window . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
Query Table Staff by DB2 Command Window
. . . . . . . . . . . . . . . . . . . . . . . .
Result from Query Table Staff
Query the Table Employee from Database Sample . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . .
Result from Query Table Employee
. . . . . . . . . . . . . . . . . . . . .
Result from Query Table Employee
. . . . . . . . . . . . . . . . . . . . . . . . . . .
The Details of Table Staff
The HTML Input Section of test.mac . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . .
The Results from HTML Report Section of test.mac
. . . . . . . . . . . . .
The Results from Applet Running from test.mac
The HTML Input Section of test.mac . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . .
The Results from HTML Report Section of test.mac
. . . . . . . . . . . . .
The Results from Applet Running from test.mac
. . . . . . . . . . . .
The Macro File test.mac That Contains an Applet
. . . . . . . . . . . . . . . . .
The Source Code of Applet Netdata1.java
. . . . . . . . . . . . . . . . . . . . . . .
The java.sql JDBC API Package
Client Configuration Assistant Welcome Window . . . . . . . . . . . . .
Selecting the Source in the Add Database SmartGuide Window . . . .
Target Database Section for the Add Database SmartGuide Window .
. . . . . . . . . . . . . . . . . . . .
Expanding the Known Systems Field
Selecting the Target Database . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . .
Select the Protocol to Find the Server
DB2 Message Window . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . .
Giving an Alias to the Target Database in the Local Workstation
Confirmation Message . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Connecting to the DB2 Database . . . . . . . . . . . . . . . . . . . . . . .
The Connection Test Was Concluded Successfully . . . . . . . . . . . .
Available DB2 Databases in the Client Configuration Assistant Window
Using the DB2 Command Line Processor for Testing the Connection .
DB2 Connection Information Using the DB2 Command Line Processor
The Flow of the JDBC Client/Server Scenario . . . . . . . . . . . . . . .

Network Computing Framework for e-business Guide

198
198
199
199
200
201
201
202
202
203
203
204
204
205
205
206
206
207
207
208
209
211
213
213
214
214
215
215
216
216
217
218
219
220
221
221
222
223
227
230
233
234
234
235
235
236
236
237
237
238
238
239
239
240
241

212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.

Retrieve.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . .
The Application Is Terminated If No URL Is Passed
Output Generated by the Retrieve JDBC Application . . . . . . . . . . .
. . .
The Flow of the JDBC Client/Server Scenario Using Java Beans
. . . . . . .
The JDBC Select Bean Placed onto the BeanBox Window
SelectCustomizer Panel When an SQLException Is Thrown . . . . . . .
MS-DOS BeanBox Window When an SQLException Is Thrown . . . . .
. . . . . . . . . . . . . . .
The SelectCustomizer Panel Correctly Filled
. . . . . . . . . . . . . . .
Available Tables for the SAMPLE1 Database
The SelectCustomizer Panel after Some Columns Have Been Selected
The MS-DOS BeanBox Window Registers All Our Choices . . . . . . .
The JDBC Select Bean Displays All Requested Data . . . . . . . . . . .
Properties Window for the JDBC Select Bean . . . . . . . . . . . . . . .
. .
Flow of the JDBC Three-Tier Model Scenario Using Java Servlets
The File RetrieveForm.html . . . . . . . . . . . . . . . . . . . . . . . . . .
The Form Contained in the RetrieveFrom.html Page . . . . . . . . . . .
. . . . . . . . . .
The Clients Browser Displays the Retrieved Results
The RetrieveServlet.java File . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
The Scenarios Environment
The Index for the CICS Demos . . . . . . . . . . . . . . . . . . . . . . . .
Source for CICS Demos . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Customized cigstart
The NCF Home Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
NCFSTART - Sample Operations . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
Surfing on CICS Transaction
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
CICS Signon Screen
. . . . . . . . . . . . . . . . . . . . . . . . .
The Tech Demo Transaction
The Tech Demo Transaction - Inquiry Panel . . . . . . . . . . . . . . . .
. . . . . . . . .
The Tech Demo Transaction - Inquiry Response Panel
Logical Representation of the Scenario Involving CICS and Servlets .
CicsServlet.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Directory Tree Necessary to Make the CicsServlet Run . . . . . . . . .
. . . . . . . . .
The ncfcxserv.htm HTML File Invoking the CicsServlet
How to Start the CXNT120 CICS Region for NTNCF120 . . . . . . . . . .
IBM Transaction Server - Start CICS Region . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
CXNT120 CICS Region Busy
CXNT120 CICS Region Started . . . . . . . . . . . . . . . . . . . . . . . .
CICSTERM - CICS Server Selection Window . . . . . . . . . . . . . . . .
. . . . . . .
CICSTERM - CICS Client 3270 Terminal Emulator Window
. . . . . . . . . . . .
The CICS Client 3270 Terminal Emulator Is Active
CICS Java Gateway Icon . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . .
The IBM CICS Gateway for Java Has Been Correctly Activated
. . . . . . . . . . . . . . . . . . .
Applications Running in This Scenario
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Query Connector
Entering User ID and Password in the CICS Client Messages Window
The Response Is Displayed On the Clients Browser . . . . . . . . . . .
The CICS Gateway Window Registers the Client Has Connected and
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Disconnected
259. The Transaction Count Field for the commarea String Has Been
Updated . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Figures

242
243
245
246
248
250
251
252
253
255
256
257
257
259
260
261
262
263
266
267
268
270
273
273
274
274
275
275
276
277
278
280
281
281
282
282
283
283
284
284
284
285
285
286
286
287
287
288

ix

Network Computing Framework for e-business Guide

Preface
This redbook provides an overview of the recently announced Network
Computing Framework (NCF), as well as specific implementation examples to
help explain the different pieces in the framework. For example, there are
scenarios that show how to use the various connectors that are available, as
well as how to implement database calls using Net.Data and also using JDBC.
In addition, there are many examples of how to use and implement servlet
support within the Network Computing Framework. This book is a subset of a
more in-depth redbook, which has an order number of SG24-2119.
While it provides a broad understanding of this new architecture, this book also
gets very specific about how to install components that are used in the
framework. In addition, examples of servlets and beans are provided to give you
a better understanding of the technologies that are involved.

The Team That Wrote This Redbook


This redbook was produced by a team of specialists from around the world
working at the Systems Management and Networking ITSO Center, Raleigh.
Barry D. Nusbaum is a Consulting Technical Support representative at the
Systems Management and Networking ITSO Center, Raleigh. He writes
extensively and teaches IBM classes worldwide on all areas of TME systems
management on the NT and AIX platform. He is also currently working on
projects related to the Network Computing Framework. Before joining the ITSO
six years ago, he worked in Professional Services in the United States as a
National Communications Specialist.
Marco Pistoia is an International Technical support representative at the
Systems Management and Networking ITSO Center, Raleigh. He holds a degree
in Pure Mathematics from the University of Rome and a Masters degree in
Computer Science. He has been with IBM for three years. His areas of
expertise include network computing and Enhanced Digital Video Broadcasting
(EDVB). He has designed and developed a number of interactive multimedia
prototypes in TV/PC environments for major European efforts, for which he
received an Outstanding Technical Achievement Award (OTAA) in 1996.
Giancarlo Rochester is an NCS specialist in Italy. He has four years of
experience in network computing providing solutions to integrate existing
applications to the Web. His areas of expertise include distributed transaction
processing based on the CICS and MQSeries product family. He has
participated in GUIDE and SHARE Europe activities since 1989 and has been a
member of the Network Computing Advisor Board of IBM Italy since September
1996.
Thomas Liu is a System Specialist in IBM Taiwan. He holds a Masters degree
of Computer Science from New York University. He has two years of experience
in the telecommunication field, and two years of experience in the Internet world,
specifically in Java language. His areas of expertise include GUI design in both
UNIX and Windows platforms and data communication. Now he concentrates on
eCommerce and has successfully finished some pilot projects in Taiwan.

Copyright IBM Corp. 1998

xi

Thanks to the following people for their invaluable contributions to this project:
Mike Conner, Bill Lawton
IBM Austin
Mark Fisher, Ernest Evans, Ken McCauley, John Shin
IBM RTP
Nino Lusardi
IBM Italy

Comments Welcome
Your comments are important to us!
We want our redbooks to be as helpful as possible. Please send us your
comments about this or other redbooks in one of the following ways:

Fax the evaluation form found in ITSO Redbook Evaluation on page 299 to
the fax number shown on the form.

Use the electronic evaluation form found on the Redbooks Web sites:
For Internet users
For IBM Intranet users

Send us a note at the following address:

redbook@vnet.ibm.com

xii

http://www.redbooks.ibm.com
http://w3.itso.ibm.com

Network Computing Framework for e-business Guide

Chapter 1. Overview
The Networking Computer Framework (NCF) supplies the underlying services
needed by network applications, while providing an open, standards-based
framework within which developers can integrate products from a variety of
vendors. It provides a unified programming model based on Java and
JavaBeans technology. Client-side and server-side functions are enhanced by
JavaBeans that provide access to all services. Its modular approach makes it
very flexible. What starts as a simple online application can grow quickly and
easily. As a developer you can leverage JavaBean components and
object-oriented technologies to quickly build applications and systems.
By following the NCF model of building network computing solutions, developers
can:

Leverage Internet standards to better serve end users

Bring efficiency to all development efforts, consolidating all programming


into one cohesive environment that addresses most users and platforms

Quickly deploy new solutions throughout an organization or customer base,


with minimal hassle, while taking full advantage of existing enterprise
systems

Swiftly augment solutions to address new user needs and increase


competitiveness

Quite simply, the NCF provides a better way to program.

1.1 Developing Applications in the Network Computing Framework


The Network Computing Framework (NCF) is a comprehensive software roadmap
for implementing e-business solutions. IBM and its subsidiary, Lotus
Development Corp., announced plans for NCF in April of this year. Working with
customers over the last year, IBM has delivered some of the industrys most
ambitious network computing solutions. The IBM Network Computing Framework
is based on the lessons learned from that experience.
The Internet and private Intranets represent great new opportunities to tackle
fundamental business problems. Based on well-accepted Internet standards,
applications can connect disparate systems and decentralized technologies.
These standards are very good news for anyone who is trying to make sense of
a diverse, multivendor technology world.
The NCF provides an integrated development and execution environment based
on the Java programming language that allows developers to leverage all of the
great new opportunities coming from the World Wide Web. NCF allows
developers to work in a single programming language and yet exploit all of the
features of browser-based clients and have full access to their preexisting
application and data resources. This section is a brief introduction to
programming in the NCF.

Copyright IBM Corp. 1998

1.1.1 An Overview of NCF


The Network Computing Framework is a comprehensive framework for
Web-based applications, consisting of:

An open, pluggable framework

A set of Web application servers that are accessed through standard


protocols and JavaBean component interfaces

A set of clients that exploit just in time components such as Kona Beans

Tools that exploit the JavaBean component standard

Standard technologies to link components (for example, HTTP or IIOP)

A set of built-in groupware solutions and a foundation for e-business


applications

A set of connectors to existing data and transactions

The elements of the NCF are shown in Figure 1.

Figure 1. The NCF Model

1.1.2 Designing NCF Applications


Designing NCF applications is like designing other applications. One must design
the user interface and the application logic (sometimes called the application
model). Sometimes it is best to start with the user interface design and let that
drive the design of the application logic and sometimes it is better to reverse the
process and start with the application logic (or model) and then design one or
more user interfaces to go with it. This section briefly illustrates a possible
design approach for a simple NCF application to look up names in a company
directory.

Network Computing Framework for e-business Guide

In this example, one might start with designing a JavaBean that wraps access to
the companys directory application. This bean would be a pure Java class
definition with properties that allow it to be configured. For example, it might
have a property for the domain name of the server where the directory
application runs and it might have several properties that control how name
matching is to be done or that set the default company location. It would likely
have a property for the lookup name pattern and other access qualifiers such as
location or department. It would also be likely to have a read only property that
contains the result of a lookup, say in the form of a two dimensional array of
strings where each row is one directory entry and each column is a different
aspect of the directory information such as first name or employee ID.
It would probably support a method to look up directory information based on its
current property settings. It might also support a number of event listener
interfaces to make it more usable in traditional graphical user interfaces, but this
is not necessary in our example where it will only be used by a servlet (a Java
class derived from javax.servlet.GenericServlet).
This bean could be developed and tested without concern for HTML, or servlets,
or other Web issues. Once the bean was developed, one could design a servlet
that uses the bean to look up directory information and then format the
information into an HTML table of the results. One way to design this servlet
would be to define a method, say lookup, that takes appropriate parameters,
does the lookup, and writes the HTML table to an output stream that was passed
in as a parameter. This method could be called from the servlets service
method, which would extract the required parameters (including the output
stream) from the HTTP request and then call lookup to do the actual work. The
advantage of this design is that one could add a main method so that the servlet
class also could be used as a Java application for testing purposes. The main
method could take command-line arguments for the lookup parameters and then
cause the output to go to System.out. This allows much of the servlets logic,
including the production of the HTML output, to be tested outside of a Web
server and without use of a Web client. Once the servlet was working in this
mode, it could be installed into the Web server (as little as putting it in the right
place in the Web servers file system and possibly involving setting up an alias
and/or access controls).
Once the servlet is finished, it would be necessary to design a Web page to
invoke the servlet. This page would contain a form similar to the one shown in
Figure 2. However, in this design example we chose to have our servlet produce
only an HTML table with the results of the directory lookup. We still need to
provide a way to generate an entire HTML page to send back to the client. There
are a number of choices here. A wrapper servlet can be defined that writes the
rest of the page with a call to the lookup servlet made at the appropriate point.
(Servlets can invoke other servlets by just calling their service methods and
forwarding the calling servlets service method parameters to the called servlet.)
Another alternative would be to use a ServletEmbed in an HTML page.
ServletEmbeds are described in more detail later in this section. Briefly, they
are HTML syntax that can be embedded into an HTML page. The ServletEmbed
expression in the HTML page is replaced with the output of the called servlet
while the Web server is sending the page to the client, so the client Web
browser never sees the ServletEmbed, just the HTML that is produced by the
called servlet.

Chapter 1. O v e r v i e w

1.1.3 Some Design Alternatives


There are many alternatives to this design. For example, one might have the
lookup servlet generate the call to a Java applet rather than a simple HTML
table. The applet could provide a more dynamic interface to the lookup results.
Also, suppose that the amount of data returned from a lookup might be very
large. Then one might want to design an applet that would use an IIOP session
back to a servlet to access and display partial lookup results, fetching and
displaying more results in response to user actions. These designs are clearly
more complex but given the power and completeness of the Java programming
environment, it is possible to develop broadly usable applets, servlets, and class
libraries that greatly simplify these designs. For example, one of the Lotus Kona
Beans is a spreadsheet-like Java applet. This would be used to display the
query results as easily as generating an HTML table (just generate the call to
the appropriate Kona Bean applet). However, you now have a live presentation
of the lookup results.
Another alternative would be to add access control to a lookup servlet. This
could be done by having the lookup servlet check the identity of the client user. If
it is necessary to authenticate the user, then the servlet can be registered with
the Web server so that it requires an HTTPS connection. Then the Web server
and the Web browser could exchange certificates to verify the users identity.
This also insures that the data flowing between the client and the server is not
tampered with. It is also possible to request that the client/server communication
be fully encrypted for privacy.
NCF provides tools that can help with each of the above steps. For example,
VisualAge for Java can be used to define and test the lookup bean and then
define and test (in application mode) the lookup servlet. NetObjects Fusion can
be used to design the initial lookup Web page and the response Web page that
contains the ServletEmbed. Also, the NCF programming model is based on
widely adopted standards so there are a number of third-party tools such as
Symantec Cafe and Borland JBuilder that can be used to develop beans, applets
and servlets. Also, there are many tools that can be used to develop HTML and
its supporting graphics.

1.1.3.1 The Parts of an NCF Application


NCF applications consist of content (HTML, images, and such) and Web
server-based programs called servlets. The content is sent to the Web browser
and processed by it. Therefore, NCF applications may leverage any features of
HTML that are supported by their target Web browsers. In particular they may
leverage Java applets. Servlets are Java objects that typically respond to HTTP
requests coming from the client, usually a Web browser, and respond with
HTML. Servlets are open-ended Java programs. They can use any Java library,
communicate with programs on other machines and access both local and
remote resources.
The simple NCF application to look up names in a company directory, discussed
above, would consist of an initial HTML page with a simple form on it. The form
would have a text entry field where a user could enter an employee name
pattern. When the user submits the form, it generates an HTTP get request and
invokes a servlet on the Web server passing the servlet the form data. Figure 2
illustrates how the form part of the HTML page might be coded.

Network Computing Framework for e-business Guide

Fraction of an HTML page that invokes a servlet with form data.


<FORM METHOD=GET ACTION= / servlet/LookupNameServlet>
<p>Employee Name: <INPUT TYPE=text NAME=employeeName SIZE=60>
<p><INPUT TYPE=submit Name=SubmitButton Value=Submit></FORM>
Figure 2. Code Sample for a Simple NCF Application

When the servlet, called LookupNameServlet in this example, is invoked, it can


use the form data passed in the HTTP request to construct a request to an
existing directory application (say via a TCP/IP session), get the response from
this application, and format it into HTML that it writes back to the client browser.
This simple example illustrates four primary aspects of NCF applications:
content, servlets, client/server communication and back-end access.

Content: Content refers to MIME data that is sent to a client system to provide
the user interface to an NCF application. NCF applications produce MIME data of
various types, such as: HTML, GIF, TIF or JPEG. An NCF applications content
can come from:

Static files: HTML files with fixed data.

Dynamic files: HTML files that contain references to Java servlets called
ServletEmbeds that run as the file is being sent to the client and dynamically
provide part of the files content. (These are discussed in more detail
below.)

Rich text format data in a Domino store that is dynamically converted to


HTML by the Domino system.

Servlets that run in response to HTTP requests and generate MIME data.

The only restriction on the MIME data produced by an NCF application is that it
must be processable by the client. NCF is open with respect to client systems.
However, to fully leverage the NCF features and infrastructure, a client system
should support both HTML and Java programs called applets that run in the
client system. Clients are expected to fully support at least the features of Java
1.02, and some of the advanced client support in NCF requires that the client
support Java 1.1.
NCF provides tools including NetObjects Fusion, Lotus BeanMachine, and
VisualAge Java that can be used to construct content, especially applets.
However, NCF leverages standard content types; therefore, there are many
third-party tools that can also be used, especially in the generation of HTML or
images.

Servlets: At the center of every NCF application is one or more Java servlets.
Servlets are very similar to CGI-BIN programs and Web server plugins
(programs written to Web server plugin APIs such as NSAPI, ISAPI, or ICAPI),
except that they are written in Java and run in a Java Virtual Machine managed
by the Web server. These servlets coordinate the steps of the application and
provide most of its function. Servlets are Java classes that support the
javax.servlet.Servlet interface.
Essentially, a servlets job is to process a request (usually an HTTP or HTTPS
request) and produce MIME data (usually HTML). Servlets are registered with the
Web server and can be named in URLs in HTML forms or even in simple HTML

Chapter 1. O v e r v i e w

links. When the form is submitted or the link is followed, the Web browser will
construct an appropriate HTTP or HTTPS request including parameters, and/or a
query string as specified in the HTML. The Web server will receive this request
and direct it to the appropriate servlets service [ 1 ] method, first creating an
instance of the servlet if necessary. The servlets service method is passed two
parameters, a javax.servlet.Request and a javax.servlet.Response. The request
parameter gives the servlet convenient access to information in the HTTP
request including:

The URL of the request, including the query parameters, and the query string

The identity of the remote user and how the user was authenticated

Context information about the client system and the server

The type of the request (for example, GET or POST)

Any cookies transmitted with the request

The response parameter provides methods that allow the servlet to respond to
the HTTP request. In particular, the response provides a stream to which the
servlet can write. The stream also delivers anything that the servlet writes (for
example, HTML) to the Web browser as the content of the HTTP response.
The details of the Java servlet interfaces and classes are defined in the standard
Java packages javax.servlet and javax.servlet.http. JavaSoft provides the Java
Servlet Toolkit which you can download from the JavaSoft Web site at
www.javasoft.com. This toolkit contains the interfaces and classes related to
servlets. JavaSoft has also produced a white paper on servlets that can be
found on the JavaSoft Web site. This JavaSoft white paper provides a good
introduction to what servlets are and how to work with them.

ServletEmbeds: One of the features of NCF is support for ServletEmbeds.


ServletEmbeds allow one to separate the static parts of an HTML page from the
dynamic parts. For example, if a page needed to contain a table with data
extracted from a database but the rest of the page was always the same, then
the static part of the page could be authored in HTML and a ServletEmbed could
be used to generate the dynamic part. The HTML syntax for a ServletEmbed is
shown below.

<servlet name=Lookup
<param name=foo1 value=bar>
<param name=foo2 value=baz>
</servlet>
Figure 3. ServletEmbed Syntax for Lookup

This would call the servlet registered under the name Lookup. The two named
parameters are passed to the servlet just like form data parameters are passed.
Other forms of the ServletEmbed syntax allow the class of the servlet to be
specified and initialization parameters to be passed. In all cases, when the
servlet is called, it receives the HTTP context of the page, so it can inquire about
the remote user and such, just like a top-level servlet.

Network Computing Framework for e-business Guide

The Web server processes ServletEmbeds as it is sending their containing page


to the client Web browser. When it gets to a ServletEmbed, it invokes the
specified servlet and directs the servlets output HTML to the client Web browser
so that it is inserted into the page in place of the ServletEmbed expression.
This allows a separation of concerns between programmers writing servlets and
content developers writing HTML. It also allows one to leverage HTML editing
tools to produce Web pages with dynamic content.
In a future release of the NCF technology, we expect to support full server-side
scripting. This will extend the ServletEmbed mechanism by allowing fragments of
programming logic to be inserted in the HTML page. While this does not enable
servlets and ServletEmbeds to do anything more than they already do now, it
does make servlets more generic and improves their reusability.

Client/Server Communication: NCF provides both client and server support for
HTTP, HTTPS, and IIOP. HTTP is the standard protocol for client/server
communication on the Web. However, it is fairly inefficient and insecure. HTTPS
is an industry-standard extension to HTTP that adds security based on SSL
Version 3. This is a public-key/private-key based protocol that allows an
untrusting client to set up a secure session with an untrusting server. In this
session the server knows the clients identity and the client knows the server s
identity. In addition, data is sent encrypted and incorruptible.
NCF also supports the Object Management Group s CORBA IIOP standard for
remote method call support. With this support an applet running in the client can
establish a connection to a servlet running in the Web server and pass method
calls back and forth. NCF supports IIOP in both a standard mode that allows
interoperability with other IIOP clients and servers and an enhanced mode that
allows IIOP requests to be carried over HTTP sessions (therefore leveraging
HTTP session setup) and to carry object parameters by value as well as
reference (the norm). When objects are passed by value, a new object is created
in the target process with a copy of the calling process objects value. This
allows the target process to call methods on the object without incurring the
overhead of a remote method call as would be required if the object was passed
by reference. The NCF support of IIOP allows programmers to use either Java or
CORBA IDL to define object interfaces for use with the IIOP support.
Figure 4 on page 8 illustrates the two primary forms of client/server
communication supported by NCF. Note that the IIOP form uses a standard
NCF-provided servlet to receive IIOP requests. This servlet dispatches IIOP
requests to Java objects that the application designer has defined. The
application supports the dispatch process by implementing a simple interface
that maps object keys to objects, and objects to object keys. The IIOP servlet
uses this interface to marshal and demarshal object references.

Chapter 1. O v e r v i e w

Figure 4. Client/Server Communication Supported by NCF

Back-End Access: Most Web applications need to leverage external data or


preexisting applications. NCF provides a comprehensive set of connectors (Java
libraries and gateway programs) to access:

DB/2 and other relational databases

IMS

CICS

MQSeries

Encina and other DCE servers

Lotus Notes

Information about each of these connectors can be found at


www.ics.raleigh.ibm.com/ibmconnectors and at
www2.lotus.com/developers/tools/ei.nsf. Information about access to the Notes
store is still being developed, but it is precisely the same interface that is
provided to server-side LotusScript programs translated into Java, so you can
refer to the Notes LotusScript documentation for insight about these interfaces.

Network Computing Framework for e-business Guide

In addition to access libraries, NCF provides JavaBean interfaces for some


back-end access. This is done in a variety of ways. For example, there are
SQLBeans that leverage technology from the Net.Data product to provide
high-level, optimized access to SQL data sources. This support includes
database connection management to reduce the overhead of setting up and
taking down database connections. Some of the NCF tools also provide bean
level support for back-end access in the form of visual development tools that
walk a developer through a series of dialogs to generate a bean that represents
a specific query or interaction. This kind of support is currently available in
VisualAge for Java for database access and CICS transaction access.
Access libraries also are provided for accessing standard Internet services such
as POP3, NNTP, FTP, NMTP, and LDAP.

1.2 Java Is the Foundation


Java underlies every part of the NCF programming model. It is the only
programming language needed to access any of the NCF features. Java has a
number of unique and great features that make it an ideal choice for NCF,
including the following:

Write once, run anywhere.

The NCF Java-based programming model will be supported in all the major
Web servers and on all the major system platforms, including IBMs high-end
server platforms. This is only possible because of the unique portability of
Java.

Secure operation.
Java is unique among mainstream programming languages in its support for
secure operation. Only Java is practical for Web downloads. Relying on code
signing alone is just not enough given the fine-grained nature of Web
downloads.

Extensive network support.


Java provides extensive support for networking including TCP/IP, Sockets,
HTTP, URLs, remote resource loading, and of course, downloading of Java
class definitions.

Great programming language:

Simple but powerful object model

Built-in support for threads and exceptions

Automatic memory management (no more core leaks, no more dangling


references)

Strong typing

No pointer errors

No array errors

In addition, Java provides a component model called JavaBeans. JavaBeans


defines how a Java class (or collection of classes and supporting resources)
should be packaged to be ready for use in visual development tools such as
IBMs VisualAge for Java, Symantecs Visual Cafe, or Borlands JBuilder.
JavaBeans standardizes the aspects of Java classes necessary to support visual
builder environments: self-description, event linking, and externalization.
Chapter 1. O v e r v i e w

1.3 Universal Support for the Servlet Programming Model


As part of NCF, IBM offers the Lotus Domino Go Webserver. This Web server is
the base product for a family of Web server products including Domino Mail,
Domino, Universal Database Web Server, and Transaction Series Web Server.
Each of the other family members offers additional features and functions beyond
the Lotus Domino Go base, but they all, including Lotus Domino Go, fully support
the servlet programming model discussed in this section. The only differences
come from the functional differences in the servers. An application developed for
Lotus Domino Go runs unchanged and without being recompiled on any member
of the NCF Web server family on any platform supported by NCF.
IBM also offers the Webrunner ServletWorks product that provides the full NCF
programming model on Web servers produced by Microsoft, Netscape, and the
Apache server. Thus, when you develop a Web application according to the NCF
guidelines, it will run on any of the major Web servers and on any platform that
has such a server and that provides quality support for Java as illustrated in the
figure below:

Figure 5. The NCF Model

10

Network Computing Framework for e-business Guide

Chapter 2. Servlets
This chapter shows:

An overview of what Java servlets are

The structure of the Java servlet API

How servlets work with Lotus Domino Go Webserver

How to create servlets

Some examples of server-side HTML scripting

2.1 Overview of Java Servlets


Servlets are protocol and platform-independent server-side software
components, written in Java. Servlets run on a Web server machine inside a
Java-enabled server, that is a server able to start the Java Virtual Machine
(JVM) in order to support the use of Java servlets. They dynamically extend the
capabilities of the server because they provide services over the Web using the
request-response paradigm. We provide a list of the services that are provided
in 2.1.1, Advantages of Servlets on page 12.
Servlets were initially supported in the Java Web Server from JavaSoft. Since
then, several other Java-based Web servers have supported the standard servlet
API. Lotus Domino Go Webserver Release 4.6, which has been installed on our
NT and AIX platforms, supports the JavaSoft Java Servlet API 1.0. Information
about the JavaSoft Java Servlet API is available from:
http://jserv.javasoft.com/products/java-server/sdk/index.shtml. Servlets were
introduced to interactively view and modify data and to generate dynamic Web
content. From a high-level perspective, the process flow would be:

The client sends a request to the server.

The server sends the request information to the servlet.

The servlet builds a response and passes it to the server. That response is
dynamically built and the contents of the response usually depends on the
clients request.

The server sends the response back to the client.

The flow is shown in the following window:

Copyright IBM Corp. 1998

11

Figure 6. Process Flow from a High-Level Perspective

Servlets look like ordinary Java programs. The servlets import particular Java
packages that belong to the Java servlet API. Since servlets are object
bytecodes that can be dynamically loaded off the Net, we could say that servlets
are to the server what applets are to the client. But, since servlets run inside
servers, they do not need a graphical user interface (GUI). In this sense servlets
are also called faceless objects.

2.1.1 Advantages of Servlets


Java servlets offer a lot of advantages:

12

A servlet can interact with other resources (files, databases, applets,


applications written in Java or in other languages) to construct the response
that will be sent back to the client and, if needed, to save information about
the request-response interaction (see 2.7, A Sample Servlet on page 67
and 5.5, JDBC Client/Server Database Server Scenario Using Java
Servlets on page 258).

With a servlet approach, the server can grant full access to local facilities,
such as databases, and trust that the servlet itself will control the amount
and precise nature of access that is effectively afforded to external users.
So, for example, the Java servlet API provides all the methods to monitor
and verify the origin of all requests (see the example shown in Figure 39 on
page 55 and discussed in the following pages). Moreover, on the Internet
Connection Secure Server, servlets cannot be loaded from the network.
They must reside on the local system. As a consequence, if a proprietary
algorithm is built into a servlet, the code never passes beyond the
boundaries of the server; only the results that it produces do. If the code is
not passed to the client, it cannot be saved or disassembled.

Network Computing Framework for e-business Guide

Servlets can be client programs of other services, for example, when they
are used in distributed application systems. We discuss this important way
to use servlets in 3.1.6.3, Servlets and IBM Connectors on page 194 and in
5.5, JDBC Client/Server Database Server Scenario Using Java Servlets on
page 258.

It is possible to invoke them from a local or remote disk across the network.
All the examples that are described in this chapter demonstrate this.

Servlets can be chained. This means that one servlet can call another
servlet, thus becoming its client. It can also call several servlets in
sequence.

They can be dynamically called from within HTML pages, using the servlet
tag technique as shown in 2.8, Servlet Tag Technique on page 87.

The servlet API is protocol-independent. It does not assume anything about


the protocol used to transmit it on the Internet. The example shown in
Figure 48 on page 63 demonstrates how you can write a servlet without
having to consider what the transmission protocol will be.

Like all Java programs, servlets can use all the capabilities of the
object-oriented Java language:

They can be rapidly developed.

Lack of pointers promote robust applications (unlike C).

A servlet service routine is only a thread and not an entire operating


system process. That is the reason why a servlet can handle
connections with multiple clients, accepting requests and downloading
responses back to the multiple clients (see Figure 48 on page 63). This
is a more efficient mechanism then using CGI-BINs.

Servlets are portable. They run on a variety of servers without needing


to be rewritten.
Note
You can take the same Java source code and compile it, using the
Java compiler javac, on different platforms (AIX, Solaris, DOS,
Windows, OS/2, Macintosh and more) without having to make any
changes. You can even compile it on one platform and then use the
same bytecode class file on different platforms. In reality, there are
experiments that we could do with any Java program and we did that
successfully working on the AIX and NT platforms.
Another experiment that we performed was we took the Java source
code EmployeeSearch.java of the EmployeeSearch servlet (shown in
Figure 52 on page 68) and we compiled it on the AIX and NT
platforms. Besides the fact that we successfully took the
EmployeeSearch.class file that was generated on one platform and
used it on the other one, we also compared the two obtained class
files using the AIX command, cmp, without finding any difference.

Memory access violations are not possible, so faulty servlets will not
crash servers.

Chapter 2. Servlets

13

2.1.1.1 Disadvantages of Servlets


One disadvantage of Java over CGI-BINs is that it is an interpreted language and
its performance may not be as good as if it was compiled. Just In-Time (JIT)
compilers should resolve this problem.

2.1.2 Servlets and CGI-BINs


From a high-level perspective servlets can perform the same functions as
CGI-BINs. In 2.6, Advantages of Servlets over CGI-BIN on page 38 we
explicitly show how servlets are very powerful, especially when compared with
CGI-BINs.
CGI-BIN applications are hard to develop since you need technical knowledge on
how to work with parameter passing. This is not a common skill. They are not
portable; a CGI-BIN application written for a specific platform will only be able to
run in that environment. Each CGI-BIN application lives in a specific process
that is activated by a clients request and is destroyed after the client has been
served. This causes high startup, memory and CPU costs and implies that
multiple clients cannot be served by the same process.
On the other hand, servlets offer all the advantages of Java programs; they are
portable and robust applications and they are easy to develop. Servlets also
allow you to generate dynamic portions of HTML pages embedded in static
HTML pages using the servlet tag.
However, the main advantage of servlets over CGI-BINs is that a servlet is
activated by the first client that sends it a request. Then it continues running in
the background, waiting for further requests. Each request generates a new
thread, not an entire process. Multiple clients may be served simultaneously
inside the same process and typically the servlet process is destroyed only when
the Web server is shut down.
The following diagram is a graphical representation of what we covered in the
previous paragraphs:

14

Network Computing Framework for e-business Guide

Figure 7. Servlets Versus CGI-BIN Applications

2.1.3 The Hello World Servlet


To better understand how easy it is to write a Java servlet we show a typical
example of one. We also go into more detail later in the chapter.

Chapter 2. Servlets

15

 import

java.io.*
import javax.servlet.*;

public class SimplestServlet extends GenericServlet


{
public void service(ServletRequest request, ServletResponse response)
throws ServletException, IOException
{
PrintStream out = new PrintStream(res.getOutputStream());
out.println(Hello World! ) ;
}
}

This servlet only contains a single life cycle method, service(), that displays on
the clients browser the phrase Hello World!. To obtain this, you must compile
the Java source code of the servlet, copy the generated class file in a specific
directory called servlet and then invoke the servlet by pointing to its URL with
your browser.

Figure 8. Invoking the Hello World Servlet

With this overview as an example, we analyze the general structure of a servlet


and then show some examples that explicitly demonstrate advantages of
servlets over CGI-BIN.

2.2 Structure of the Java Servlet API


Servlets are ordinary Java programs, but they use some additional packages
found in the Java servlet API. When you write the code for a Java servlet, you
must import at least one of the following two packages:

javax.servlet

javax.servlet.http

These two packages contain seven interfaces, five classes and two exceptions.
Before going on with this chapter, it is helpful to have a visual idea of the
structure of the Java servlet API. The following table should help.

16

Network Computing Framework for e-business Guide

Table 1. Structure of the Java Servlet API


javax.servlet

Interfaces

Classes

Exceptions

javax.servlet.http

Servlet
ServletConfig
ServletContext
ServletRequest
ServletResponse

GenericServlet
ServletInputStream
ServletOutputStream

HttpServletRequest
HttpServletResponse

HttpServlet
HttpUtils

ServletException
Unavailable Exception

Note
Generally speaking, a Java class is composed of two things: variables and
methods. In addition, all Java variables and methods must be a member of a
class. Instance variables are what describes an object and typically, in pure
object-oriented languages such as Java, they are encapsulated; which means
that only the objects themselves can change these variables. To do this,
objects use functions called methods.

As you can see, the amount of material introduced by the Java servlet API is not
too big. Nevertheless, these few interfaces, classes and exceptions are able to
make a Java server very powerful.
Table 1 shows fourteen items. It would be good to have a general description of
each of them before moving onto the next section.
Note: The description of the Java Servlet API provided here is based upon the
official information located at: http://www.javasoft.com.

2.2.1 Interface javax.servlet.Servlet


The public interface servlet interface is used to develop servlets and it is very
important. In fact, all servlets implement this interface, usually by extending
either the GenericServlet class or the HttpServlet class. That is a
GenericServlets descendent. The servlet interface defines the method init() to
initialize a servlet, the method service() to receive and respond to client
requests and the method destroy() to unload the servlet and its resources.
These are known as life cycle methods. Other methods defined by the servlet
interface are getServletConfig(), which returns a ServletConfig object containing
any initialization parameters and startup values for this servlet and
getServletInfo(), which returns a string containing information about the servlet.
Examples of that might be its author, version or copyright (see Figure 11 on
page 23).

2.2.2 Interface javax.servlet.ServletConfig


The public interface ServletConfig interface is implemented by services in order
to pass configuration information to a servlet when it is first loaded. The
ServletConfig interface can also be implemented by servlets. For example, the
GenericServlet can be implemented by servlets. When implemented by a
servlet, the methods in the interface make getting the configuration data more
convenient.

Chapter 2. Servlets

17

By configuration data we mean all of the servlet initialization parameters. Those


parameters are the ones that the servlet init() method will use to initialize the
servlet. The Lotus Domino Go Webserver 4.6 allows you to set the configuration
data either by filling out and submitting the Java Servlet Configuration form or by
editing the servlet section of the Configuration file (see 2.4.3.3, Servlet
Initialization Parameters on page 31). We show an example of how to set
servlet initialization parameters in 2.7.2, Compiling and Installing the Servlet
on page 73.
The ServletConfig interface provides two methods to handle the configuration
data: getInitParameterNames() and getInitParameter(). getInitParameterNames()
returns the names of the servlets initialization parameters as an enumeration of
strings or an empty enumeration if there are no initialization parameters. By
passing each name to the getInitParameter() method, you can retrieve the single
value for a specified parameter or null if the parameter does not exist.
Of course, if you already know the name of the servlet initialization parameters,
you do not need to use the getInitParameterNames() method to retrieve those
names, but you can directly call the getInitParameter() method to obtain the
relative values. We see how to do that in the example shown in Figure 52 on
page 68.
The ServletConfig interface also provides the getServletContext() method, which
returns a ServletContext object. A servlet could implement getServletContext()
by writing the following:

public ServletContext getServletContext() {


return getServletConfig().getServletContext();
}
Figure 9. A Simple Way for Servlets to Test the ServletContext Object

Using the public interface ServletConfig provides access to the servlets context
with a single call to the method getServletContext().

2.2.3 Interface javax.servlet.ServletContext


The public interface ServletContext gives servlets access to information about
their environment. In fact it provides the following methods:

getAttribute() returns the value of the named attribute of the network service
or the value null if the attribute does not exist.

getMimeType() returns the mime type of the specified file or null if not
known.

getRealPath() applies alias rules to the specified virtual path and returns the
corresponding real path.

getServerInfo() returns the name and version of the network service under
which the servlet is running.

getServlet() returns the servlet of the specified name or null if not found.

getServlets() returns an enumeration of servlet objects in this server.

The information returned by all these methods relates to the servlet s


environment.

18

Network Computing Framework for e-business Guide

The ServletContext interface also allows servlets to log significant events.


Servlet writers decide what data to log using the log() method, which writes the
given message string to the servlet log file. The example shown in Figure 67 on
page 84 shows how to do that.
The ServletContext interface is implemented by services and used by servlets.
Servlets get the ServletContext object with the getServletContext() method of the
ServletConfig object. This object is provided to the servlet at initialization and is
accessible using the servlets getServletConfig() method (see Figure 9 on
page 18).

2.2.4 Interface javax.servlet.ServletRequest


The public interface ServletRequest interface is used to get data from the client
to the server from a service request. Network service developers implement the
ServletRequest interface. Its methods are then used by the servlets when the
service() method is executed. The ServletRequest object is passed as an
argument to the service() method. Some of the data provided by the
ServletRequest object includes: parameter names (getParameterNames()) and
values (getParameterValues()), attributes (getAttribute()) and an input stream
(getInputStream()). Subclasses of ServletRequest can provide additional
protocol-specific data. For example, HTTP data is provided by the interface
HttpServletRequest, which extends ServletRequest.

2.2.5 Interface javax.servlet.ServletResponse


The public interface ServletResponse interface is used for sending data from the
servlet service() method back to the client. Network service developers
implement this interface. Its methods are then used by servlets when the
service() method is run, to return data to clients. The ServletResponse object is
passed as an argument to the service() method. This interface provides the
method getOutputStream(), which returns an output stream for writing response
data.

2.2.6 Interface javax.servlet.http.HttpServletRequest


The public interface HttpServletRequest extends ServletRequest interface,
represents an HTTP servlet request. It gets data from the client to the servlet for
use in the service() method. It allows the HTTP protocol specified header
information to be accessed from the service() method.
We show several examples in this chapter of how to use the HttpServletRequest
interface and its methods. The most significant one is shown in Figure 39 on
page 55. We use that example to describe all the methods for this interface. In
particular we show how to retrieve the request HTTP header using the
getHeaderNames() and getHeader() methods (see Figure 43 on page 59 and
Figure 46 on page 61).

2.2.7 Interface javax.servlet.http.HttpServletResponse


The public interface HttpServletResponse extends ServletResponse interface,
represents an HTTP servlet response. It allows a service() method to manipulate
HTTP protocol specified header information and return data to its client.
This interface is often used when the Web server must send the response back
to the clients browser. An example of some code that will work with this
interface inside the service() method follows:

Chapter 2. Servlets

19

 ServletOutputStream

out = response.getOutputStream();
response.setContentType(text/html ) ;
out.println(How to use the interface HttpServletResponse ) ;
out.close();

The response is the HttpServletResponse object passed as a parameter to the


service() method (see, for example, Figure 38 on page 54).

2.2.8 Class javax.servlet.GenericServlet


The GenericServlet class implements the servlet interface (see Figure 9 on
page 18) and the ServletConfig interface. Servlet developers typically subclass
GenericServlet or its descendent HttpServlet.

public abstract class GenericServlet


extends Object
implements Servlet, ServletConfig
Figure 10. GenericServlet Class

Note
If you are writing a servlet that interacts with HTML Web pages containing
forms, you will probably create your servlet by subclassing HttpServlet. For
all other servlets you will probably start by subclassing GenericServlet.

A servlet that communicates directly with an applet on the clients browser is an


example of a servlet that would not use HTTP for its communications. You would
create a servlet like that by subclassing GenericServlet instead of HttpServlet.
The GenericServlet provides simple versions of the life cycle methods init() and
destroy() and the methods in the ServletConfig interface. The servlet developer
must override only the service() method.

2.2.9 Class javax.servlet.ServletInputStream


The public abstract class ServletInputStream extends InputStream class is an
abstract class that will be implemented by network services developers. An
object from this class provides an input stream for reading servlet requests and
it provides an efficient readLine() method. For some application protocols, such
as the HTTP POST and PUT methods, servlet developers use the input stream to
get data from clients. They access the input stream using the ServletRequest s
getInputStream() method available from within the servlets service() method.

2.2.10 Class javax.servlet.ServletOutputStream


The public abstract class ServletOutputStream extends OutputStream class is an
abstract class that will be implemented by network services developers. An
object in this class provides an output stream for writing servlet responses.
Servlet writers use the output stream to return data back to clients. They access
it using the ServletResponses getOutputStream() method available from within
the servlets service() method.

20

Network Computing Framework for e-business Guide

2.2.11 Class javax.servlet.http.HttpServlet


The public abstract class HttpServlet extends GenericServlet class is called the
HttpServlet class. It is an abstract class that simplifies writing HTTP 1.0 servlets.
It extends the GenericServlets base class. Servlet developers implement the
servlet interface usually by extending either the GenericServlet class or the
HttpServlet class. Because it is abstract, servlet writers must subclass it and
override at least one method.
You subclass the HttpServlet class typically when your servlet must interact with
HTML pages containing forms. The information entered into the form on the
client Web page is passed to the servlet for processing. Two different HTML
methods can be used to do this: GET and POST, depending on what is coded on
the form present in the HTML page on the client. We discuss the options relative
to GET and POST in 2.6.3, GET and POST HTML Methods on page 49, as well
as provide some examples.
The methods in the HttpServlet class that are normally overridden are:

doGet() - If the information entered in the form on the clients browser is


provided by the GET method.

doPost() - If the information entered in the form on the clients browser is


provided by the POST method.

It is up to the servlet developer to override the doGet() or doPost() methods in


order to accept the clients request and give a response back to it.
This class implements the service() method, which in the GenericServlet class
was abstract (see 2.2.8, Class javax.servlet.GenericServlet on page 20).
Therefore, servlet developers can accept it if they are supporting HTTP 1.0. To
support HTTP 1.1 methods (for example, OPTIONS, PUT, DELETE and TRACE)
they will probably override the service() method and handle those additional
HTTP methods directly.

2.2.12 Class javax.servlet.http.HttpUtils


The class that provides a collection of static utility methods useful to HTTP
servlets is public class HttpUtils extends Object. For example, getRequestURL()
takes an HttpServletRequest object as an argument and reconstructs the URL
used by the client to make the request. This class also provides two other
utilities:
1. parsePostData() - Parses the data that is posted to the server using the HTTP
POST method from a form in the clients browser.
2. parseQuesryString() - Parses the query string.
Both these methods return a Hashtable object which maps keys to values.

2.2.13 Exception javax.servlet.ServletException


The exception class that is provided to indicate a servlet problem is public class
ServletException extends Exception. The example shown in Figure 52 on
page 68 shows how and when you can throw a ServletException object (see 4 on
page 71).

Chapter 2. Servlets

21

2.2.14 Exception javax.servlet.UnavailableException


The exception that indicates that a servlet is unavailable is public class
UnavailableException extends ServletException. There are two types of this
exception:
1. Permanent
The servlet will not be able to handle client requests until some
administrative action is taken to correct a servlet problem. For example, the
servlet might be configured incorrectly or the state of the servlet might be
corrupted.
2. Temporary
The servlet cannot handle requests at this moment, due to a system-wide
problem. For example, another server might be accessible or there may be
insufficient memory or disk storage to handle requests.
Network services might safely treat both types of exceptions as permanent, but it
is better to have the option to indicate a temporary outage to provide more
flexibility as well as a possible means to report on the types of outages. For
example, requests to the servlet might be blocked or deferred for an amount of
time suggested by the servlet, rather than being rejected until the service itself
restarts.

2.3 Servlet Structure


This section describes the structure of a servlet. In particular we see the life
cycle of a servlet.

2.3.1 The init(), service() and destroy() Methods


Notice that both the classes GenericServlet and HttpServlet are abstract; that is,
they contain methods that have not been completed. It is up to the subclasses of
the abstract class to override at least one method. You can recognize a typical
Java application because of the presence of the main() method. It is
automatically executed when the application is loaded. Java applets are
event-driven. This is done with a series of methods that are created by
inheritance from the applet classes:

init()

start()

stop()

destroy()

paint()

repaint()

Servlets look like ordinary Java programs. How do you recognize them? First of
all they must implement the servlet interface, usually by extending either the
GenericServlet class (see 2.2.8, Class javax.servlet.GenericServlet on page 20)
or the HttpServlet class (see 2.2.11, Class javax.servlet.http.HttpServlet on
page 21). Both the GenericServlet and the HttpServlet classes contain three
methods, which they take by inheritance from the servlet interface:
1. init()

22

Network Computing Framework for e-business Guide

2. service()
3. destroy()
These methods are used by the servlet to communicate with the server. As we
already said (see 2.2.1, Interface javax.servlet.Servlet on page 17), these three
methods are called life cycle methods. You will work with these three methods
in a slightly different way, depending on whether you are extending the
GenericServlet class or the HttpServlet class.
However, the simplest possible servlet defines the single service() life cycle
method. In other words, the service() method is required and the others are
optional.

import java.io.*
import javax.servlet.*;
public class SimplestServlet extends GenericServlet
{
public void service(ServletRequest request, ServletResponse response)
throws ServletException, IOException
{
PrintStream out = new PrintStream(res.getOutputStream());
out.println(Hello World! ) ;
}
public String getServletInfo()
{
return This servlet defines the single service() life cycle method ;
}
}
Figure 11. The Simplest Possible Servlet Contains a Single Life Cycle Method, service()

It would be helpful to have a general description of each of them before moving


on to the next section. Notice that this servlet also presents the getServletInfo()
method for the servlet interface. This method is not really required, which
means that this example could be made even simpler. We just want to show the
use of this method in order to return general information about a servlet, for
example, its author.
The init() and the destroy() methods have the same properties for the
GenericServlet class or the HttpServlet class. Descriptions of these methods
follow:

The init() method is run only once when the server loads the servlet and the
servlet is started. It is guaranteed to finish before any service() requests are
accepted. The servlet can be activated when the server starts or when the
first client accesses the servlet. The biggest advantage is that the init()
method is called only once, without considering how many clients access the
servlet. As we see (Figure 30 on page 47) the default init() method logs the
servlet initialization and it is possible to configure it in order to save other
information.
The default init() method can usually be accepted as it is, without the need to
override it, because it is not abstract. Servlet developers may, if they want,
provide their own implementation of this method, overriding it and creating a
custom init(). A custom init() is typically used to perform setup of
servlet-wide resources only once, rather than once per request (see

Chapter 2. Servlets

23

Figure 79 on page 98). For example, you might want to write a custom init()
to load GIF images one time only, where the servlet returns the images
multiple times in response to multiple client requests to the servlet. Further
examples may be initializing sessions with other network services or getting
access to their persistent data (stored in a database or in a file).
For example, the custom init() method of the EmployeeSearch servlet that we
show in 2.7, A Sample Servlet on page 67 reads a database file name as
an initial parameter, tries to open the database text file, calls another
method, named readDB(), to build a Hashtable and throws a
ServletException object if an error occurred.
Note
When you write your own code overriding:

public void init(ServletConfig config) throws ServletException


you should always invoke super.init(config), as shown in the example in
Figure 29 on page 46. In fact, the init() method is called automatically,
by default, by the network service each time it loads the servlet. The
most important function the init() method provides when it is called is to
return the config object for use to the servlet. If you override it without
calling the super.init() method, this function will no longer be provided
and the config object will no longer be initialized by the server.

The destroy() method is run only once when the server stops the servlet and
unloads it. The servlet-log file gives information about all the initialized and
destroyed methods (Figure 30 on page 47) and this is a way to see if, for
example, a servlet is unloaded. Moreover the servlet-log file offers a good
way to debug, as we show in 2.7.4, Debugging and Testing the Servlet on
page 83.
Usually, the servlets are unloaded when the server is shut down. The
default destroy() method also can be accepted as is, without the need to
override it, because it is not abstract like the init() method. Servlet writers
may, if they wish, override the destroy call, providing their own custom
destroy() method. A custom destroy() method is often used in the
management of servlet-wide resources. For example, the server might
accumulate data when it is running and you might want to save this data to a
file when the servlet is stopped (see for example Figure 79 on page 98).

The service() method is the heart of the servlet. In fact, as we said, the simplest
possible servlet defines only the service() method. Unlike the init() and destroy()
methods, it is called for each client request, and not only once in the life cycle of
the servlet. Moreover, it must be handled differently when it is based on the
GenericServlet class or in the HttpServlet class.
If the servlet is based on the GenericServlet class, the service method is
abstract, so you must override it. The service() method obtains information
about the client request, prepares the response and returns this response to the
client. You should also consider that multiple clients might have access to the
service() method at the same time, so you also have to include threads and
synchronized code (see 2.6.4, Multithreading on page 62).
If the servlet is based on the HttpServlet class, the service method is not
abstract. Therefore, you can accept it if you are supporting the HTTP 1.0
protocol. The service() method determines whether the information entered onto

24

Network Computing Framework for e-business Guide

the form on the clients browser is provided by GET or POST. If the answer is
GET, the service() method calls the doGet() method of the HttpServlet class. If
the answer is POST, the service() method calls the doPost() method of the
HttpServlet class. It is up to the servlet developer to override the doGet() or
doPost() methods in order to accept the clients request and give a response
back to it, as appropriate. If you are supporting the HTTP 1.1 protocol, then you
will probably override the service() method to support HTML 1.1 extensions
(OPTIONS, PUT, DELETE and TRACE). Calling super.service() from within the
overridden service method provides the default handling on the other methods
(such as GET and POST).
Note: When writing your servlets, you can write your own code overriding the
following servlet class methods:

init()

service()

destroy()

getServletInfo()

doGet()

doPost()

All other Java servlet API methods are implemented by the Domino Lotus
Go Webserver for its processing. You should make sure that you do not
override any other Java servlet API methods or you will be overriding the
servers code.
In addition you should never call the java.lang.System.exit() method,
because it terminates the JVM currently running and servlets will no
longer run until your Java-enabled Web server is restarted.

2.3.2 Parameters Passed by the Server


The service() method, as we said, is the heart of a servlet. It is through the
service() method that the server and servlet can exchange data. In fact, when
the server invokes the servlet service() method, it also passes two objects as
parameters, as is shown in Figure 12 on page 27.

If the servlet is based on the GenericServlet class, the two objects are
instances of:

ServletRequest

ServletResponse

If the servlet is based on the HttpServlet class, the two objects are instances
of:

HttpServletRequest

HttpServletResponse

These objects, lets call them request and response for convenience,
encapsulate the data sent by the client, providing access to parameters and
allowing the servlets to report status including errors if they occurred. You can
decide to write to System.out and System.err using the println() method and you
can decide to write in the servlet-log file using the log() method. An example of
the above is described in 2.7.4, Debugging and Testing the Servlet on page 83.

Chapter 2. Servlets

25

The server creates an instance for the request and response objects and passes
them to the servlet. Both these objects are used by the server to exchange data
with the servlet.
The servlet invokes methods from the request object in order to discover
information about the client environment, the server environment and all the
information provided by the client, for example, all the data entered on a form on
the clients browser and set by the GET and POST methods. The specific
methods of the request object that the servlet uses to retrieve information from
the client are:

getParameterNames()

getParameter()

getParameterValues()

The exact way the servlet discovers all this information is fully explained in the
example described in Figure 39 on page 55. The method getInputStream()
returns a ServletInputStream object by reading the request body (see Figure 11
on page 23). An additional method, getQueryString() is available for
HttpServletRequest objects only.
The servlet invokes methods for the response object to send the response that it
has already prepared back to the client. The primary method of the response
object that the servlet uses to send the response back to the client is the
getOutputStream() method. This method returns a ServletOutputStream object
(see Figure 11 on page 23) and you may use the print() and println() methods of
this object for writing the servlet response back to the client (see Figure 29 on
page 46).
The input stream that the servlet gets using the getInputStream() method and the
output stream that the servlet gets using the getOutputStream() method may be
used with data in whatever format is appropriate. For example, HTML and
several image formats may be valid data formats.

2.3.3 Servlet Life Cycle


The diagram represented in the following figure is a graphical representation of
the servlet life cycle.

26

Network Computing Framework for e-business Guide

Figure 12. Graphical Representation of a Servlet Life Cycle

The servlet life cycle can be summarized in the following way:

The servlet is loaded. This operation is typically performed dynamically, that


is, when the first client has access to the servlet 1. However, servers will
usually provide an administrative option to force loading and initializing
particular servlets when the server starts up.

The server creates an instance to the servlet 2.

The server calls the servlet init() method 3.

A client request arrives at the server 1. A client request is already at the
server if the client request initiated the servlet load.

The server creates a request object 4.

The server creates a response object 5.

The server invokes the servlet service() method 6, passing the request 7
and response 8 objects as parameters.

The service() method gets information about the request object and
processes the request accessing the other resources 9 and getting the
necessary information 10.

Chapter 2. Servlets

27

The service() method uses methods of the response object to pass the
response 11 back to the server 12 and then to the client 13. The
service() method may invoke other methods to process the request, such as
doGet() or doPost() or new methods that the servlet developer wrote.

For additional client requests, the server creates new request and responses
objects, again invokes the service() method of the servlet and passes to it
those two objects as parameters. Therefore, this loop is repeated, but
without the need to re-call the init() method. The servlet, in general, is
initialized only once.

When the server no longer needs the servlets (typically when the server is
shut down), the server invokes the servlet destroy() method.

2.4 Extending Lotus Domino Go Webserver with Servlets


We have just seen an overview of the architecture of servlets. Before we set up
examples of Java servlets, we still need to know the appropriate Web server
locations where we will copy the compiled class files and all the associate HTML
files. This section describes these simple steps relative to Lotus Domino Go
Webserver Version 4.6, which has been installed in both our NT and AIX
environments.
The Lotus Domino Go Webserver 4.6 supports JavaSoft Java Servlet API 1.0 and
it automatically supports Java servlets when you install it. The servlet support is
automatically turned on when you install it on the AIX platform. The installation
on the NT platform is a little different, because it allows you to decide if you want
to enable the Java servlet support, as shown in the following window:

Figure 13. Confirmation for the Java Servlet Support

When Lotus Domino Go Webserver 4.6 is installed, it is installed in a specific


location. In our case INSTALL_LOCATION was set to C:\WWW for the NT
platform and /usr/lpp/internet/server_root for our AIX system.
When you install the Lotus Domino Go Webserver, you can accept the default
configuration information. All of the default settings can be easily changed using
the Configuration and Administration Forms or by editing the configuration file
located in C:\WINNT\httpd.cnf for NT and /etc/httpd.conf for AIX.

28

Network Computing Framework for e-business Guide

2.4.1 Document Root Directory


The HTML files are placed in a subdirectory under the directory that was defined
by the variable install_directory. It is called the document root directory. By
default, this subdirectory is C:\WWW\HTML for NT and it is
/usr/lpp/internet/server_root/pub for AIX.
HTML files can also be placed in subdirectories of the document root directory.
When the clients browser invokes an HTML page, it simply has to specify the
servers IP address (or its host name), followed by the location of the HTML page
relative to the document root directory. For example, if PAGE.HTML is the name
of the page that the client wants to browse and it is stored directly in the
document root directory, the URL of the HTML file should be as follows:
http://servers IP address/PAGE.HTML.
Otherwise, if PAGE.HTML is stored in the subdirectory SUBDIR of the document
root directory, its URL must be specified as: http://servers IP
address/SUBDIR/PAGE.HTML.
You do not have to specify INSTALL_LOCATION in the URL. The server already
knows that it has to look there as its starting point (or root) for HTML files. It
knew that from its configuration file.

2.4.2 Servlet Directory


The servlet directory is the specific directory where servlet classes must be
stored once they have been compiled. The purpose of the servlet directory is
similar to the document root directory. The server knows that servlet class files
are located in a particular directory, which by default is C:\WWW\Servlets\Public
for NT and /usr/lpp/internet/server_root/servlets/public for AIX. If you want to
have access to the servlet MyServlet, you can point your browser to:
http://servers IP address/servlet/MyServlet.
In the URL you specify the symbolic servlet location servlet rather than the
actual servlet directory.
Notes:
1. The class extension of the servlet must not be specified.
2. The servlets name is case-sensitive in UNIX and on NT.
3. All the servlets must be in the servlet directory.
4. If you want to place servlets in a subdirectory of the servlet directory and
have access to them, you must specify that in the configuration file. You do
that by directly editing it or by modifying it using the Administration and
Configuration Forms.
Point 4 introduces the problem of how you can modify the servlet directory that
has been configured by default during the installation of Lotus Domino Go
Webserver 4.6. To do this you access the Administration and Configuration
Forms and then select External Servlet. You will get access to the Java Servlet
Configuration form. You then modify the variable Java classpath in the section
of the form called Java Virtual Machine Configuration, as shown in the following
window:

Chapter 2. Servlets

29

Figure 14. Java Virtual Machine Configuration

The Java classpath variable has more then just the servlets directory. It also
has to point to the servlet JVMs classpaths that are the paths to the files
classes.zip and icsclass.zip. In addition, the path to the servlet class files must
be appended to the two classpaths in the Java classpath variable.

2.4.3 Other Configurations


The Java Servlet Configuration form is divided into three sections:
1. Java Virtual Machine Configuration (see Figure 14)
2. Servlet Configuration (see Figure 15 on page 31)
3. Servlet Initialization Parameters (see Figure 16 on page 32)
Each one of these sections allows you to configure some variables.

2.4.3.1 Java Virtual Machine Configuration


This section allows you to set the value of the Java classpath variable (see 2.4.2,
Servlet Directory on page 29) as well as the Java executable and Java shared
library variables (see Figure 14). The directories that you should be aware of
are:

Java executable directory


The Java executable directory variable specifies the directory in which the
JDK executable used to start the JVM is located.

Java shared library directory


The Java class directory variable specifies the directory in which the JDK
shared libraries are located.

2.4.3.2 Servlet Configuration


The configuration for this section is shown in the following window:

30

Network Computing Framework for e-business Guide

Figure 15. Servlet Configuration

This servlet configuration window shown in Figure 15 allows you to configure


two variables:

Maximum number of Java threads


Maximum number of Java threads specifies the maximum number of threads
the server will use to process Java servlets. The default is 10.

Servlet message log


The servlet message log specifies the name and the location of the log file
for messages generated by the Java servlet log() method that we introduced
in 2.2.3, Interface javax.servlet.ServletContext on page 18. This log file will
not be automatically deleted. By default its name is servlet-log and it is
located in directories pointed to by the variable INSTALL_LOCATION.

2.4.3.3 Servlet Initialization Parameters


The configuration for this section is shown in the following window:

Chapter 2. Servlets

31

Figure 16. Servlet Initialization Parameters

The list shows all the servlets for which you have defined initialization
parameters. (The list in Figure 16 is empty and shows only an example.) These
are the parameters the servlet init() method will use to initialize the servlet.
To define the initialization parameters for a particular servlet:
1. Specify the name of the servlet instance.
2. Specify the name of the servlet class.
3. Specify the servlet initialization parameters. Parm_name = Parm_value is
the format for the parameters. For multiple parameters, put each parameter
on a separate line.
4. Click on Add.
5. Click on Apply to update the server with your new settings or click Reset to
return to the values that were onto the form before you made the changes.
To remove a servlets initialization parameters:
1. Select the index of the servlet shown in the list.
2. Click on Remove.
3. Click on Apply to update the server with your new settings or click on Reset
to reset the values to what they were before you started to modify the
current screen.

32

Network Computing Framework for e-business Guide

2.5 Creating a Servlet


This section describes how to create a servlet. After you write the Java source
code you have to compile it in order to create a bytecode file, a file written in
Java Virtual Machine language. Then you must install it on your server so that
the client machine can have access to it.
We examine each single step of the servlet creation later in this chapter (see
2.7.4, Debugging and Testing the Servlet on page 83).

2.5.1 Compiling and Installing a Servlet


Compiling a servlet is a very easy operation (assuming there are no errors in
the source code). After you have written the Java source code for your servlet,
you must treat it as a normal Java program. That means that you have to name
it with the same name that you gave to the class it defines, and give it an
extension of .java. For example, the very simple servlet that we wrote in
Figure 11 on page 23 defines the SimplestServlet class, so we save it as
SimplestServlet.java.
To compile a Java servlet, you run the Java compiler javac as you do for all
Java applications. The only difference is that now you need to recall the Java
servlet API. Therefore, the Java compiler should be run with the -classpath
option. For example:

javac -classpath CLASSPATH SimpleServlet.java


On AIX the classpath is:

/usr/lpp/internet/server_root/java/lib/classes.zip:
/usr/lpp/internet/server_root/cgi-bin/icsclass.zip:
/usr/lpp/internet/server_root/servlets/public
For Windows NT you would use:

C:\WWW\Bin\Java\lib\classes.zip;
C:\WWW\CGI-Bin\icsclass.zip;
C:\WWW\Servlets\Public
You can also decide to set CLASSPATH as an environment variable on the
platform you are using. If you do that, when you compile the SimplestServlet
servlet, you simply enter: javac SimplestServlet.java (see 2.4.2, Servlet
Directory on page 29).
Now you have to copy the new servlet class file SimplestServlet.class into the
servlet directory (see 2.4.2, Servlet Directory on page 29). You should also put
any HTML files associated with your servlet in the document root directory (see
2.4.1, Document Root Directory on page 29). If your servlet needs to read
some initialization parameters, you have two choices:
1. If your servlet is invoked from within an HTML file using the < s e r v l e t > tag,
the initialization parameters will be specified inside the <servlet> tag itself
(see 2.5.2, Invoking a Servlet on page 36).
2. If you invoke your server by pointing directly to its URL, then you must
specify its initialization parameters directly in the configuration file or fill out
the Servlet Configuration section of the Administration and Configuration

Chapter 2. Servlets

33

form (see 2.4.3.3, Servlet Initialization Parameters on page 31 and 2.7.2,


Compiling and Installing the Servlet on page 73).
If your servlet had already been initialized and you have recompiled it, updating
your servlet requires that you stop and restart your Web server. If your platform
is AIX, all you have to do is execute the following two commands:
1. stopsrc -s httpd
2. startsrc -s httpd
If your platform is Windows NT, then do the following:
1. Click on Start.
2. Click on Settings.
3. Click on Control Panel and open the Control Panel window.

Figure 17. Control Panel Window

4. Double-click on the Services icon and open the Services window:

34

Network Computing Framework for e-business Guide

Figure 18. Services Window

5. Select Lotus Domino Go Webserver and click on Stop.


6. The Service window asks you if you really want to stop the Lotus Domino Go
Webserver. Click on Yes.
7. The Lotus Domino Go Webserver will be stopped. To restart click on the
Start button.

Figure 19. Restart the Lotus Domino Go Webserver

On Windows NT, you can also enter the following commands to stop and start
the Lotus Domino Go Webserver:
1. net stop lotus go Webserver
2. net start lotus go Webserver
In most cases, it is enough that Lotus Domino Go Webserver is restarted to read
the new configuration. On Windows NT, you can simply maximize the Lotus
Domino Go Webserver window, open the File menu and select Restart, as shown
in the following screen:

Chapter 2. Servlets

35

Figure 20. Restarting the Lotus Domino Go Webserver

This will force Lotus Domino Go Webserver to read the new configuration without
completely shutting down.
Now you can reinvoke your servlet from the browser.

2.5.2 Invoking a Servlet


Lets take another look at the SimplestServlet servlet, whose code is shown in
Figure 11 on page 23. After we compiled it, we copied the SimplestServlet.class
file into the servlet directory. We can then invoke this servlet directly from a
browser by pointing to its URL: http://servers IP
address/servlet/SimplestServlet

36

Network Computing Framework for e-business Guide

Figure 21. Invoking the SimplestServlet Servlet

In general you can always invoke a servlet from a browser, pointing directly to
its URL, but you must be sure that the servlet does not require any initialization
parameters. When you write a Java servlet, you should initialize all of the
parameters that you dont want the client to have to set up (for example, the
name of a file that the servlet must open). If the servlet does require
initialization parameters, you can set them to their initial values following the
procedure that we described in 2.4.3.3, Servlet Initialization Parameters on
page 31 and that we see in 2.7.2, Compiling and Installing the Servlet on
page 73.
Moreover, it may be possible that the servlet you are invoking needs to set other
parameters. All the others are simply called parameters and usually their
values are dynamically generated by clients by filling out the fields of a form. If
you want, you can pass these parameters to the servlet by appending a query
string (a URL-encoded string) to the servlets URL, after a question mark ?. For
example:

http://server s IP address/servlet/MyServlet?firstname=Marco&lastname=Pistoia
Where MyServlet is the generic name of one servlet.
We discuss this technique in 2.6.2, Java Servlets Processing Forms on
page 44. We also show another way to call a servlet from the <form> tag of
an HTML form, using either the GET or the POST methods. The correct syntax is
one of the following:

<form method=GET action=/servlet/MyServlet> ... </form>

<form method=POST action=/servlet/Myservlet> ... </form>

Servlets can handle both the GET and the POST method in a very simple way.
When you invoke a servlet from a form that uses the GET method a question
mark ? is implicitly added after the servlets URL. The ? gets appended to a
query string that encodes the information you have requested. Unfortunately,
there is a chance that the query string will get truncated, so, if it is very long,
you should use the POST method. If you use the POST method, the information
supplied by the user is not appended to the servlets URL but it is submitted as a
Chapter 2. Servlets

37

separate stream. The information is still URL-encoded but this time there is no
danger that it will get truncated.
If you want, you can also invoke a servlet from within an HTML file. The output
of a servlet is usually an entire HTML page, but with this technique you divide
your page in two sections. The first is static and it is the same for all clients that
will have access to your servlet. The second is dynamic and it is automatically
created dependent upon what the clients requests are. The static portion of the
HTML page contains the two tags <servlet> and </servlet>, and every thing
between these two tags and the two tags themselves will be dynamically
overwritten by the dynamic portion of the HTML file. Moreover this technique
allows you to pass to the servlet all the parameters it needs, including the
initialization parameters from within the HTML page. Of course, the Web server
must be able to recognize the presence of the two tags <servlet> and
</servlet>, invoke the appropriate servlet, pass it the right parameters and
send the complete HTML page, composed by the dynamic and the static
sections, back to the client. Lotus Domino Go Webserver 4.6 has this ability and
we dedicate an entire section to the servlet tag technique in 2.8, Servlet Tag
Technique on page 87.

2.5.3 Debugging and Testing Servlets


Debugging and testing servlets is an operation that can be performed by
combining the log() method of the GenericServlet class and the ability of the
servlet to write exceptions when errors occur. The log() method writes custom
information into the servlet-log file. Therefore, we can log each operation the
servlet does and verify the status of the servlet.
For a complete description of how you can use this technique see the example
described in 2.7.4, Debugging and Testing the Servlet on page 83.

2.6 Advantages of Servlets over CGI-BIN


Common Gateway Interface (CGI) programs, most commonly written in Perl,
shell scripts or C, are able to provide dynamic content to the client; that is
content that can be different each time a client browser accesses a page.
In this section we see how the same form is handled using a servlet extension
instead of a CGI extension to the Web server. The way that parameters are
defined within an HTML form and how they are passed to CGI scripts is similar
to what we show for servlets. The following examples were done using
Netscape Communicator 4.01 for NT as a client and Lotus Domino Go Webserver
4.6 for AIX as the server. We tried to use platform-independent descriptions
when possible. Similar examples could also have been done using different
platforms (for example, Lotus Domino Go Webserver 4.6 for NT as the server
platform).

2.6.1 CGI-BIN Processing HTML Forms


In order to better understand CGI-BIN processing, consider the HTML form
shown in the following window:

38

Network Computing Framework for e-business Guide

Figure 22. HTML Form Invoking a CGI Perl Script

The form shown in Figure 22 was generated with the HTML code
CGIServlet.html, stored in the Marco subdirectory of the document root directory.

<html>
<head>
<title>This HTML page invokes the CGIServlet CGI Perl Script</title>
</head>
<body>
<h1>This HTML page invokes<br>the CGIServlet CGI Perl script</h1>
<form method=GET action= / cgi-bin/CGIServlet.pl>
<pre>
First Name: <input type=text name=firstname>
Last Name: <input type=text name =lastname>
<input type=submit> <input type=reset>
</pre>
</form>
</body>
</html>

Figure 23. HTML Code Generating the HTML Form

This form is processed by the CGI Perl script CGIServlet.pl, stored in the CGI-BIN
subdirectory based off of the INSTALL_DIRECTORY. The INSTALL_DIRECTORY
is just a variable that points to the actual directory. On AIX, you have to set the
file mode of the CGI Perl script to executable. To do this, let
INSTALL_DIRECTORY/cgi-bin be the current directory and then enter the
following command:

chmod +x CGIServlet.pl
Chapter 2. Servlets

39

The input to a CGI script is called an HTTP request and the output is called an
HTTP response. The HTML page containing the form passes the input request to
the server when the user clicks on the Submit Query button. The CGI script
reads the input data as key-value pairs or name-value pairs, processes the data
and generates an output response that the server passes back to the client
(browser) that submitted the form.
The HTML code that generated the form used the GET method of passing data to
the CGI script:

<form method=GET action= / cgi-bin/CGIServlet.pl>


This means that the name parameters will be encoded and appended to the URL
that invokes the CGI script.
The HTML form specified two input fields, called First Name and Last Name. The
following HTML code generated those two input fields:

First Name: <input type=text name=firstname>


Last Name: <input type=text name =lastname>
In addition, two input buttons are in the HTML form: Submit Query and Reset.
Those buttons do not have names associated with them, so their values will not
be passed on as part of the data:

<input type=submit> <input type=reset>


These are standard HTML form inputs that have specific behaviors associated
with them. An input of type submit causes the form to be submitted to the
server when selected. An input of type reset causes all fields to be reset to their
default values without submitting the form.
Filling out the form with the First Name field set to Marco and the Last Name
field set to Pistoia will cause the following URL to be invoked when the Submit
Query button is chosen:

http://aixncf10/cgi-bin/CGIServlet.pl?firstname=Marco&lastname=Pistoia

40

Network Computing Framework for e-business Guide

Figure 24. Fill Out the Form

Notes:
1. The equal symbol ( = ) separates each input field name from its value.
2. An ampersand (&) separates individual name-value pairs.
3. The parameter data follows the question mark (?).
4. The location of the script is relative to the INSTALL_DIRECTORY.
The part of the URL following the question mark (?) is the value assigned to the
environment variable QUERY_STRING.
The Perl CGI script to be invoked uses the form tag:

<form method=GET action= / cgi-bin/CGIServlet.pl>


The following figure shows the code for the CGIServlet.pl CGI Perl script, which
processes the client request:

Chapter 2. Servlets

41

#!/usr/local/bin/perl
print <<EOM;
Content-type: text/html
<html>
<head>
<title>
HTML Page Dynamically Generated by the CGIServlet CGI Perl Script
</title>
</head>
<body>
<h1>HTML Page Dynamically Generated<br>
by the CGIServlet CGI Perl Script</h1>
<pre>
EOM
$query_string = $ENV{ QUERY_STRING } ;
$query_string = s/%([\dA-Fa-f][\dA-Fa-f])/pack (C, hex ($1))/eg;
$query_string = s/\+/ /g;
@pairs = split (/&/, $query_string);
foreach $pair (@pairs) {
($key, $value) = split (/=/, $pair);
$form_data{$key} = $value;
}
$firstname = $form_data{firstname};
$lastname = $form_data{lastname};
print \n<h2>Data received</h2>\n ;
print Hello, $firstname $lastname. Thank you for your visit!\n\n ;
print <<EOM;
</pre>
</body>
</html>
EOM
close OUT;
Figure 25. CGI Perl Script Processing the HTML Form

Anything appearing after a pound sign (#) on a line is a comment. The first line
(#!/usr/local/bin/perl) is a special comment, because it forces the script file to be
interpreted by the Perl interpreter, located in the /usr/local/bin directory. The
Perl interpreter must have its file mode set to executable.
Everything between print <<EOM; and EOM is printed to the standard output of
the CGI script, which is the dynamically generated page. You will notice that in
the CGI Perl script there are two blocks delimited by two special tags (EOM).
The first block is similar to a standard HTML header:

42

Network Computing Framework for e-business Guide

print <<EOM;
Content-type: text/html
<html>
<head>
<title>
HTML Page Dynamically Generated by the CGIServlet CGI Perl Script
</title>
</head>
The second block is similar to the end of an HTML page:

print <<EOM;
</pre>
</body>
</html>
The central part of the script provides the dynamic generation of the HTML code.
It is dynamic because it depends upon the CGI input parameters.
The content of the QUERY_STRING environment variable can be retrieved using
the following instruction:

$query_string = $ENV{ QUERY_STRING } ;


The string is encoded to make it conform to the requirements of the URL
specification. In other words, some particular characters that appear in the URL
need to be encoded to avoid confusion, because they could also be used as
special URL characters. Some examples of this are:

Forward slashes (/) become %2F.

Question marks (?) become %3F.

Plus signs (+) become %2B.

A special non-alphanumerical character, which cannot be part of a legal URL,


becomes a percent sign (%) followed by the hexadecimal ASCII code of the
character, while the spaces are transformed into plus signs (+).
The following Perl instruction decodes any hex encoding in the query:

$query_string = s/%([dA-Fa-f]dA-Fa-f])/pack (C, hex ($1))/eg;


And the next expression turns the plus signs (+) back into spaces:

$query_string = s/+/ /g;


Then the query is split into an array of pairs using the ampersand (&) as a field
separator:

@pairs = split (/&/, $query_string);


You will then have an array of two strings:

[0] firstname=Marco
[1] lastname=Pistoia
Each element of the array is split into key and value components, with the equal
sign in each string as a field delimiter:
Chapter 2. Servlets

43

($key, $value) = split(/=/, $pair)


At this point each parameter is broken up into a name and a value and it is
added to a Hashtable called form_data:

$form_data{$key} = $value
This Hashtable allows you to retrieve the values by using the name as a key:

$firstname = $form_data{firstname};
$lastname = $form_data{lastname};
The dynamic content portion of the page can be generated with:

print n<h2>Data received</h2> ;


print Hello, $firstname $lastname. Thank you for your visit!\n\n ;
The real dynamic content portion is provided to the clients browser by the
second statement, which causes the display of a greeting containing the first
name and the last name of the person who submitted the form, as shown in the
following window:

Figure 26. HTML Page Dynamically Generated by the CGIServlet CGI Perl Script

2.6.2 Java Servlets Processing Forms


Now we show how an HTML form can invoke a Java servlet and how the Java
servlet can generate dynamic HTML content.
Lets consider the HTML form shown in the following picture:

44

Network Computing Framework for e-business Guide

Figure 27. HTML Form Invoking a Java Servlet

This HTML form is very similar to that shown in Figure 22 on page 39. It was
generated by the following HTML file, called ServletCGI.html and stored in the
subdirectory Marco in INSTALL_LOCATION:

<html>
<head>
<title>This HTML Page Invokes the ServletCGI Servlet</title>
</head>
<body>
<h1>This HTML Page Invokes<br>the ServletCGI Servlet</h1>
<form method=GET action=/servlet/ServletCGI>
<pre>
First Name: <input type=text name=firstname>
Last Name: <input type=text name =lastname>
<input type=submit> <input type=reset>
</pre>
</form>
</body>
</html>
Figure 28. HTML Code Generating the HTML Form

Chapter 2. Servlets

45

You can see that the only difference between this code and the code shown in
Figure 23 on page 39, besides the title, is the value of the action parameter. In
this case it calls the ServletCGI servlet. As we explained in 2.4.2, Servlet
Directory on page 29, the compiled class of every servlet must be stored in the
servlet directory that is identified by the symbolic name servlet, in order to be
recognized by the Web server.
The source code of the ServletCGI servlet is very simple, as you can see in the
following figure:

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class ServletCGI extends HttpServlet
{
public void init(ServletConfig config) throws ServletException
{
super.init(config);
log( ServletCGI has been initialized ) ;
}
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
ServletOutputStream out = response.getOutputStream();
response.setContentType ( text/html ) ;
out.println(<title>HTML Page Dynamically Generated by the ServletCGI Servlet</title> ) ;
out.println(<h1>HTML Page Dynamically Generated<br>by the ServletCGI Servlet</h1> ) ;
String firstname = request.getParameter( firstname ) ;
String lastname = request.getParameter( lastname ) ;
out.println(<h2>Data received</h2> ) ;
out.println( Hello, + firstname + + lastname + . ) ;
out.println( Thank you for your visit! ) ;
out.close();
}
}

Figure 29. Java Servlet Processing the HTML Form

The name of this file is ServletCGI.java. It is required that the Java source file,
whose extension is .java, and the relative compiled file, whose extension is
.class, have the same name. The .java file also is stored in the servlet directory.
This is convenient but not necessary.
You can immediately see that the Java servlet source code is much simpler than
the corresponding CGI Perl script.
We needed to import the three packages: javax.servlet, javax.servlet.http and
java.io. The class defining the servlet extends the HttpServlet class rather than
the GenericServlet class, since this servlet must interact with an HTML form.
The two life cycle methods that are implemented are: init() and service().
The init() method is invoked when the servlet is first loaded. This occurs on the
first request for the service only. At that point, the servlet remains in memory
until the server is shut down. This is different from CGI-BINs, which do not
remain in memory. This can be easily demonstrated. After you have compiled
and installed the servlet in the servlet directory, you can modify the source code
of the servlet, recompile it and reinstall it in the servlet directory. This will
overwrite the old version. You will see that what the client s browser display is
updated with the new version of the servlet only when the Web server is stopped
and restarted. This can be done by entering, in an AIX platform, the two
following commands:

46

Network Computing Framework for e-business Guide

1. stopsrc -s httpd
2. startsrc -s httpd
In this example, the init() method is passed on to the superclass HttpServlet. The
default init() method initializes the servlet and logs the initialization in the
servlet-log file in the logs directory below INSTALL_LOCATION. The default
string written by the init() method in the servlet-log file consists of the name of
the servlet class followed by : init, as well as the destroy() method. The
destroy() method, which is usually invoked when the server is shut down, writes
in the servlet-log file the name of the servlet class followed by : destroy. The
servlet-log file can give us information about initialized and destroyed servlets.
It is possible to customize both the init() and destroy() methods so that more
than the default amount of information is stored. For example, in this case we
asked the init() method to log the following string into the servlet-log file:

THE ServletCGI SERVLET HAS BEEN INITIALIZED


After initializing the ServletCGI servlet the servlet-log file looks like the following
figure:

Figure 30. servlet-log File

As you can see, the servlet-log file gives information about all the servlets that
have been initialized and destroyed.
We have just seen a way to verify that servlets remain in memory until the
server is shut down. Another advantage of servlets over CGI-BINs is that
generating dynamic content is much simpler. You can retrieve the parameter
values that you want from the request argument of the service() method and
then you print them:

String firstname = request.getParameter(firstname ) ;


String lastname = request.getParameter(lastname ) ;
out.println(Hello, + firstname + + lastname + . ) ;
The output is not written to standard output as in a CGI script, but it is sent back
to the server and then to the clients browser by writing to an output stream that
can be retrieved from the response argument of service().
Chapter 2. Servlets

47

The first thing to do is to set the content type of the response. This is done
through the setContentType() method of the HttpServletResponse interface:

response.setContentType(text/html ) ;
It is important to note that this operation is not done through the output stream.
Only the HTML code and actual content are written directly to the output stream.
Moreover, the output stream must be closed before exiting, to make sure that
the stream buffer is flushed. This is done with the following method: out.close();.
It is worth noting that the Java servlet overrides the service() method. An option
is leaving the service() method intact and instead overriding doGet() or doPost(),
depending on the HTTP method parameter specified in the HTML file. In that
case we would override the doGet() method.
We now see what happens when we fill out the form shown in Figure 27 on
page 45, for example, setting the first field to Marco and the second field to
Pistoia.

Figure 31. Fill Out the Form

We submit the form by clicking on Submit Query. The following screen shows
that the URL is automatically set to:

http://aixncf10/servlet/ServletCGI?firstname=Marco&lastname=Pistoia
It also shows that the dynamic HTML page is sent to the clients browser:

48

Network Computing Framework for e-business Guide

Figure 32. HTML Page Dynamically Generated by the ServletCGI Java Servlet

Notice that decoding the form parameter data that is passed to the servlet is not
required with servlets as it was with CGI scripts. Basic functions inherited from
the HttpServlet class handles the decoding automatically. Therefore, you can
access the key-value pairs created and encoded by the client browser directly
inside the servlet service() method. The decoded key-value pairs can be
retrieved directly from the first argument of the service() method of the
HttpServlet class.

2.6.3 GET and POST HTML Methods


The ServletCGI servlet shown in Figure 29 on page 46 takes the parameters
entered by the client and dynamically builds an HTML page. The service()
method does not need to call either the doGet() or the doPost() methods of the
HttpServlet class.
We didnt want to change the code of the servlet. We just changed the HTML
page that invokes the servlet by replacing GET with POST, as shown in the
following figure.

Chapter 2. Servlets

49

<html>
<head>
<title>This HTML Page Invokes the ServletCGI Servlet</title>
</head>
<body>
<h1>This HTML Page Invokes<br>the ServletCGI Servlet</h1>
<form method=POST action=/servlet/ServletCGI>
<pre>
First Name: <input type=text name=firstname>
Last Name: <input type=text name =lastname>
<input type=submit> <input type=reset>
</pre>
</form>
</body>
</html>
Figure 33. HTML Code Invoking the ServletCGI Servlet with the POST Method

The HTML page generated by this file is identical to that shown in Figure 27 on
page 45. Filling out the form with the First Name field set to Marco and the Last
Name field set to Pistoia and submitting the form will create the correct
ServletCGI servlet. A screen similar to Figure 32 on page 49 is displayed on the
clients browser.
Every time you use the POST method, the Security Information window is
displayed. This occurs before the data that was entered by the client is
submitted to the server.
The user must click the Continue button to go on.

50

Network Computing Framework for e-business Guide

Figure 34. A Security Information Window Is Displayed with the POST Method

Next we try the same process with a Perl CGI script and replace GET with POST
as follows:

<html>
<head>
<title>This HTML page invokes the CGIServlet CGI Perl Script</title>
</head>
<body>
<h1>This HTML page invokes<br>the CGIServlet CGI Perl script</h1>
<form method=POST action= / cgi-bin/CGIServlet.pl>
<pre>
First Name: <input type=text name=firstname>
Last Name: <input type=text name =lastname>
<input type=submit> <input type=reset>
</pre>
</form>
</body>
</html>
Figure 35. HTML Code Invoking the CGIServlet Perl CGI Script with the POST Method

The HTML page generated by this file is identical


page 39. Filling out the form with the First Name
Name field set to Pistoia and submitting the form
implementation of the CGIServlet Perl CGI script,
window:

to that shown in Figure 22 on


field set to Marco and the Last
will cause an incorrect
as we can see in the following

Chapter 2. Servlets

51

Figure 36. HTML Page Not Correctly Generated by the CGI Perl Script

We can conclude that the same servlet can handle both GET and POST methods
when receiving parameters from a clients browser request, but if you wanted to
handle both GET and POST methods by submitting a form and using normal CGI
scripts, you would need two different scripts or two different code branches with
some conditional logic. With servlets you can switch between GET and POST
methods while requesting pages without altering any code in the servlet that
handles and responds to the request.
The next example shows how a servlet can discover information about the
server, the client environment and all the data sent by the client. It also
describes loops of a typical structure in servlets (see Figure 40 on page 57).
The HTML form shown in the following window is generated by the HTML file
named FormInfo.html.

52

Network Computing Framework for e-business Guide

Figure 37. HTML Form Generated by the FormInfo.html File

Chapter 2. Servlets

53

<html>
<head>
<title>Form Info HTML Page</title>
</head>
<body>
<h1>Form Info HTML Page</h1>
<form method= GET action=/servlet/FormInfo>
<P>
Your age: <input type= text Name= age size=2><br>
Your gender:
<input type= radio name= gender value= M>Male
<input type= radio Name= gender value= F>Female<br>
Your favourite foods:
<input type= checkbox name= ItalianFood>Italian
<input type= checkbox name= ChineseFood>Chinese
<input type= checkbox name= MexicanFood>Mexican
<input type= checkbox name= FrenchFood>French<br>
The country where you would spend your holydays:
<select name= CountryHolydays>
<option>USA
<option selected>Italy
<option>Taiwan
<option>Canada
<option>Spain
<option>Great Britain
<option>China
<option>Japan
<option>France
<option>Greece
<option>Germany
<option><i>None of the above</i>
</select><br>
What of these cities have you already visited?
<select name= VisitedCity multiple size=3>
<option value= American>New York
<option value= Italian>Rome
<option value= Canadian>Montreal
<option value= French>Paris
<option value= Italian>Venice
<option value= English>London
<option value= Russian>Moscow
<option value= Mexican>Mexico City
</select><br>
Enter your comments:
<textarea name= Comments rows=2 cols=40></textarea><br>
When you are done with the above responses, please submit this form:
<input type= submit value= Submit this form>
<input type= reset value= Reset this form>
</form>
<p>
Thank you!
</body>
</html>

Figure 38. HTML Code Generating the Form Info HTML Page

This HTML form invokes the Java servlet FormInfo.class using the HTML GET
method. The following figure shows the Java code for this servlet:

54

Network Computing Framework for e-business Guide

import
import
import
import

java.io.*;
java.util.*;
javax.servlet.*;
javax.servlet.http.*;

public class FormInfo extends HttpServlet


{
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
ServletOutputStream out = response.getOutputStream();
response.setContentType( text/html ) ;
out.println(<html><head><title>Form Information</title></head> ) ;
out.println(<body><h1>Form Information</h1> ) ;
out.println( HTML Method: + request.getMethod() + <br> ) ;
out.println( URI: + request.getRequestURI() + <br> ) ;
out.println( Protocol: + request.getProtocol() + <br> ) ;
out.println( Servlet Path: + request.getServletPath() + <br> ) ;
out.println( Path Info: + request.getPathInfo() + <br> ) ;
out.println( Path Translated: + request.getPathTranslated() + <br> ) ;
out.println( Query String: + request.getQueryString() + <br> ) ;
out.println( Content Length: + request.getContentLength() + <br> ) ;
out.println( Content Type: + request.getContentType() + <br> ) ;
out.println( Server name: + request.getServerName() + <br> ) ;
out.println( Server port: + request.getServerPort() + <br> ) ;
out.println( Remote User: + request.getRemoteUser() + <br> ) ;
out.println( Remote Address: + request.getRemoteAddr() + <br> ) ;
out.println( Remote Host: + request.getRemoteHost() + <br> ) ;
out.println( Authentication Scheme: + request.getAuthType() + <br> ) ;
out.println(<p> ) ;
Enumeration names = request.getHeaderNames();
while (names.hasMoreElements())
{
String header = (String) names.nextElement();
out.println(header + : + request.getHeader(header) + <br> ) ;
}
out.println(<p> ) ;
names = request.getParameterNames();
while (names.hasMoreElements())
{
String key, value;
key = (String)names.nextElement();
value = request.getParameter(key);
out.println( KEY: + key + VALUE: + value + <br> ) ;
}
out.println(<p> ) ;
while (names.hasMoreElements())
{
String key = (String)names.nextElement();
String [] values = (String []) request.getParameterValues(key);
if (values != null)
{

out.println( KEY: + key + VALUES: ) ;


for (int i = 0; i < values.length; i++)
out.println(values[i] +
);
out.println(<br> ) ;

}
}
out.close();
}
}

Figure 39. Java Code for the FormInfo Java Servlet

This example demonstrates how you


This servlet parses an arbitrary form
HTML page, so it can be very useful
several HttpServletRequest methods

can handle very complex data in a servlet.


request and echoes the data back in an
for testing forms. In addition, it uses
to get information:

getMethod() returns the method used to submit the request.

getRequestURI() returns the URI that was requested.

Chapter 2. Servlets

55

getProtocol() returns the protocol and the version of the request.

getServletPath() returns the part of the request URI that refers to the servlet
being invoked.

getPathInfo() returns optional extra path information following the servlet


path, but immediately preceding the query string. It returns the value null if
not specified.

getPathTranslated() returns extra path information translated into a real path


and returns null if no extra path information was specified.

getQueryString() returns the query string part of the servlet URI or null if
none.

getContentLength() returns the size of the request entity data or -1 if not


known.

getContentType() returns the Internet media type of the request entity data or
null if not known.

getServerName() returns the host name of the server that received the
request.

getServerPort() returns the port number of the port on which the request was
received.

getRemoteUser() returns the name of the user making the request or null if
not known.

getRemoteAddr() returns the IP address of the agent that sent the request.

getRemoteHost() returns the fully qualified host name of the agent that sent
the request.

getAuthType() returns the authentication scheme of the request or null if not


known.

getHeaderNames() returns an enumeration of strings representing the


header names for this request. By passing each name to the getHeader()
method, you can retrieve the value of the corresponding header or null if not
known.

getParameterNames() returns the parameter names for this request as an


enumeration of string or an empty enumeration if there are no parameters or
the input stream is empty. By passing each name to the getParameter()
method, you can retrieve the lone value of the specified parameter or null if
the parameter does not exist. For example, it is the getParameter() method
that retrieves the value of the age parameter. If the parameter has or could
have more values, the getParameterValues() method returns the values of
the specified parameter or null if the named parameter does not exist, for
example, it is the getParameterValues() method that retrieves the values of
the VisitedCity parameter.

There is one more piece of code not yet explained. This piece of code was not
necessary in the example in Figure 29 on page 46 because we knew all of the
names of the parameters we were expecting to send. The example we describe
now is more general, because it can be used to test forms that have names of
parameters that we dont know in advance. This is the reason why we parse all
the parameters with an enumeration:

Enumeration names = request.getParameterNames();

56

Network Computing Framework for e-business Guide

We can now use the hasMoreElements() method to test for the end of the
parameter list:

while (names.hasMoreElements())
{
...
}
Inside the while cycle, we can retrieve the next parameter name or key from the
nextElement() method of enumeration:

String key, value;


key = (String)names.nextElement();
Given the key string, we can look up the parameter value from the response
argument to the servlet with the getParameter() method:

value = request.getParameter(key);
Now we can do whatever processing or output we like with key and value:

out.println(KEY: + key + VALUE: + value + <br> ) ;


We see frequent loops of this structure in servlets:

while (names.hasMoreElements())
{
String key, value;
key = (String)names.nextElement();
value = request.getParameter(key);
out.println(KEY: + key + VALUE: + value + <br> ) ;
}
Figure 40. Loops of a Typical Structure in Servlets

Now we are ready to fill out the form:

Your age: 28

Your gender: Male

Your favorite foods: Italian and Chinese (Multiple selections are allowed.)

The country where you would spend your holidays: USA (A single selection is
allowed.)

Which of these cities have you already visited?


Venice (Multiple selections are allowed.)

Enter your comments: Thank you very much!

New York, Rome, London and

The form will appear as in the following window:

Chapter 2. Servlets

57

Figure 41. HTML Form Filled with Our Data

When the Submit this form button is selected, the FormInfo servlet will generate
an HTML page with all the requested information. Moving the scroll bar, we
show the dynamic HTML content divided into three windows:
1. The request information window:

58

Network Computing Framework for e-business Guide

Figure 42. HTML Page Generated Using the GET Method - Request Information

2. The request headers window:

Figure 43. HTML Page Generated Using the GET Method - Request Headers

3. The servlet parameters window:

Chapter 2. Servlets

59

Figure 44. HTML Page Generated Using the GET Method - Servlet Parameters

Notice that the value of the URL and the query string variables is encoded. (The
part of the string not visible in the window is readable in the URL.)
If we now replace GET with POST in the HTML code:

<form method=POST action=/servlet/FormInfo>


and fill out the form as shown before and submit it, the FormInfo servlet works
correctly again, as demonstrated by the following:
1. The request information window:

60

Network Computing Framework for e-business Guide

Figure 45. HTML Page Generated Using the POST Method - Request Information

2. The request headers window:

Figure 46. HTML Page Generated Using the POST Method - Request Headers

Chapter 2. Servlets

61

3. The servlet parameters window:

Figure 47. HTML Page Generated Using the POST Method - Servlet Parameters

2.6.4 Multithreading
CGI scripts are completely platform-dependent. While the language with which
they are written can vary, they cant be transported from a Windows machine to
a Macintosh.
Servlets are platform-independent since they are written in Java. They can be
moved between machines with ease and without recompiling. Servlets can also
take advantage of clever Java threading mechanisms and provide fast
turnaround and efficient processing of data. In addition, there is some work
under way to improve Java performance with Just in Time (JIT) compilers.
A servlet can continue to run in the background after it has finished processing a
request, so that it is ready to process the next request without incurring
additional start up costs (memory and CPU). On an active server, the overhead
of starting CGI programs is significant. Furthermore, a servlet can use threads
to process simultaneous requests more efficiently.
The following example is a counter servlet that tells the reader how many times
a page has been accessed since the servlet started running. This servlet does
not need to process an InputStream or read any parameters.
The following window shows the code for the servlet:

62

Network Computing Framework for e-business Guide

import java.io.*;
import java.util.*;
import javax.servlet.*;
public class CounterServlet extends GenericServlet
{
static int count = 0;
static Date today = new Date();
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException
{
ServletOutputStream out = res.getOutputStream();
res.setContentType(text/html ) ;
out.println(<html><head><title>Access Counter</title></head> ) ;
out.println(<body><h1>Access Counter</h1> ) ;
Date now;
synchronized(this)
{
++count;
now = new Date();
}
out.println(At the moment, it is <h2> + now + </h2> ) ;
out.println(This servlet has been accessed<h2>+count+</h2> ) ;
out.println(times since<h3>+today+</h3> ) ;
out.println(</body></html> ) ;
out.close();
}
}

Figure 48. ConterServlet Java Code

This code introduces two static fields:

The static int count field holds the number of times this servlet was invoked.

The static Date today field holds the time when the servlet was first
constructed.

There is one trick in this servlet that is worth noting. By their nature, Web
servers are multithreaded. Only one copy of the servlet is loaded, but it is likely
that multiple threads from multiple client requests can access the servlet
concurrently. Multiple concurrent access by multiple threads can cause
problems if the servlet is not made thread safe . It is therefore extremely
important for servlets to pay attention to synchronization issues. In this servlet,
you must synchronize access to the count field. The Date variable, today, is
read-only after the servlet is first constructed, so access to it does not need to
be synchronized. We also introduced another Date variable, now . Access to
now is synchronized, so that today holds the time this servlet was first invoked
and this value does not change until the servlet is unloaded, while the value of
now is updated every time the servlet is accessed.

Chapter 2. Servlets

63

Note
How do we synchronize access to the count and now fields? We do this by
indicating the block of code where we have access to count and now as
synchronized, inside the service() method:

synchronized (this)
{
++count;
now = new Date();
}
The object name in the parentheses after the synchronized modifier generally
indicates which lock the block of code should wait to acquire. In this case,
we used the this object, referring to the class itself.

class ClassName
{
void method()
{
...

// non synchronized code

synchronized (this)
{
...
// synchronized code
}
...

// non synchronized code

}
}
By using the synchronized modifier in this way, the method only requires the
use of the lock for the minimum amount of time necessary, allowing it to be
used by other threads.

Servlets like this are useful because they can be invoked either as independent
servlets or otherwise using the servlet tag technique. When used with the
servlet tag technique, their outputs are inserted into the HTML files sent to the
clients. We can now invoke CounterServlet directly as an independent servlet
entering its URL: http://aixncf10/servlet/CounterServlet, where aixncf10 is the
host name of our server. The result is shown in the following window:

64

Network Computing Framework for e-business Guide

Figure 49. First HTML Page Dynamically Generated by CounterServlet

After clicking the Reload button on the Netscape window, the servlet is reloaded
and the count and now variables are updated, while today does not change its
value, as shown in the following screen:

Chapter 2. Servlets

65

Figure 50. Second HTML Page Dynamically Generated by CounterServlet

You get the same results accessing the servlet from another client. For
example, you can open a new window running Netscape and recall the
CounterServlet:

66

Network Computing Framework for e-business Guide

Figure 51. Third HTML Page Dynamically Generated by CounterServlet

In order to have a real update of the count and now variables, be sure that you
have reset the history of your browser (selecting the Clear History button in the
Preferences window) and both the memory and the disk caches. (Clicking both
the Clear Memory Cache and Clear Disk Cache buttons in the Cache window.
They can be accessed from the Advanced Preferences window.)

2.7 A Sample Servlet


The next important topic that we cover shows a sample servlet. This servlet is
called EmployeeSearch because it is for reading information about IBM
employees. For purposes of this example, we can assume that the client
invokes the EmployeeSearch servlet by requesting the corresponding URL. The
servlet sends an HTML form back to the client. The user enters the last and first
name of the employee he or she wants to search for and then selects the Submit
button. The servlet dynamically builds a table containing the employees name,
electronic address and telephone number, unless the employees name is not
stored into the database.
In this section we describe all the details that are necessary to have a working
servlet.
Chapter 2. Servlets

67

2.7.1 Creating the Servlet


The Java code for this servlet is shown in the following figure:

import
import
import
import

java.io.*;
java.util.*;
javax.servlet.*;
javax.servlet.http.*;

public class EmployeeSearch extends HttpServlet


{
Hashtable employeeInfo = null;

public void readDB(BufferedReader buffread)


throws IOException
{
int tab, rawNumber;
String name, values;
employeeInfo = new Hashtable();
rawNumber = 0;
try
{
try
{
String raw = buffread.readLine();
while (raw != null)
{
rawNumber++;
if ((tab=raw.indexOf(&)) < 0)
{
log( Uncorrect employee database file at line + rawNumber + . ) ;
raw=buffread.readLine();
continue;
}
name = raw.substring(0, tab).toUpperCase();
values = raw.substring(tab+1, raw.length());
employeeInfo.put(name, values);
raw = buffread.readLine();
}
}
catch (EOFException e)
{
;
}
}
catch(IOException e)
{
log( I/O Error: + e.getMessage() + . ) ;
throw e;
}
log( EmployeeSearch has read + rawNumber + lines. ) ;
log( EmployeeSearch hashtable has + employeeInfo.size() + entries. ) ;
}

Figure 52 (Part 1 of 3). Java Code of the EmployeeSearch Servlet

68

Network Computing Framework for e-business Guide

public void init(ServletConfig config)


throws ServletException
{
super.init(config);
FileInputStream entry;
String employeeFile = getInitParameter( dbfile ) ;
log( The EmployeeSearch servlet has been correctly activated. ) ;
log( DB file + employeeFile + . ) ;
try
{
entry = new FileInputStream(employeeFile);
}
catch(FileNotFoundException e)
{
log( File Error: DB file + employeeFile + not found. ) ;
log( File Error: + e.getMessage() + . ) ;
throw new ServletException(e.getMessage());
}
catch(IOException e)
{
log( I/O Error: DB file + employeeFile + cannot be opened. ) ;
log( I/O Error: + e.getMessage() + . ) ;
throw new ServletException(e.getMessage());
}
try
{
readDB(new BufferedReader(new InputStreamReader(entry)));
}
catch (IOException e)
{
throw new ServletException( I/O Error: + e.getMessage());
}
log( Servlet EmployeeSearch working ) ;
}

public void service(HttpServletRequest request, HttpServletResponse response)


throws ServletException, IOException
{
ServletOutputStream out = response.getOutputStream();
response.setContentType( text/html ) ;
out.println(<html><head><title>IBM Employee Search</title></head><body> ) ;
out.println(<form method=\ GET\ > ) ;
out.println(<hr><h1>IBM Employee Search</h1><hr> ) ;
out.println( Enter last name and first name of the IBM employee you search for: ) ;
out.println(<p><input type=\ text\ name=\ key\ value=\ ) ;
String key = request.getParameter( key ) ;

Figure 52 (Part 2 of 3). Java Code of the EmployeeSearch Servlet

Chapter 2. Servlets

69

if (key != null)
out.print(key);
out.println( \><p> ) ;
out.println(<input type=\ submit\ value=\ SUBMIT\><p></form><hr> ) ;
if (key != null && key.length() != 0)
{
key = key.toUpperCase();
String values = (String) employeeInfo.get(key);
if (values != null)
{
int tab = values.indexOf( & ) ;
out.println(<table width=\35%\ border=\3\ > ) ;
out.println(<tr><th>Name</th> ) ;
out.println(<td> + key + < / td></tr> ) ;
out.println(<tr><th>Electronic Address</th> ) ;
out.println(<td> + values.substring(0, tab) + < / td></tr> ) ;
out.println(<tr><th>Phone</th> ) ;
out.println(<td> + values.substring(tab+1, values.length()));
out.println( < / td></tr></table> ) ;
}
else
{
out.println(key + not found ) ;
}
}
out.println(<p></body></html> ) ;
out.close();
}

public void destroy()


{
log( EmployeeSearch servlet destroy() called. ) ;
}
}

Figure 52 (Part 3 of 3). Java Code of the EmployeeSearch Servlet

The database containing all the information about IBM employees is a text file
called employee.txt. It contains the name, electronic address and telephone
number for all the IBM employees. It is assumed that each line of the text file is
divided into three fields separated by an ampersand ( &). There is a line for each
employee. The first field has the employees name. The second field has the
employees electronic address. The third field stores the employees telephone
number. Employees records are stored in alphabetical order in our example.
Our database is simple as shown in the following figure:

BECHARD CLAUDE&WTSCPOK(BECHARD)&352-4539
LIU THOMAS&WTSCPOK(LIU)&352-4543
NUSBAUM BARRY&WTSCPOK(BARRY)&352-4542
This line is wrong
PISTOIA MARCO&WTSCPOK(PISTOIA)&352-3514
ROCHESTER GIANCARLO&WTSCPOK(GROCHEST)&352-4541
Figure 53. Database Text File

Notice that one of the lines of the database is not formatted the same way as the
others:

This line is wrong


It is an error inside the database and we show how the servlet handles this
error.

70

Network Computing Framework for e-business Guide

When the servlet reads the database, it stores all the information in
employeeInfo, which is an instance of the Hashtable class:

Hashtable employeeInfo = null;


The Hashtable class, contained in the java.util package, implements a Hashtable,
which maps keys to values. Our servlet is built to use the employee s name as
the key in order to retrieve the employees electronic address and phone as one
value.
The init() method of the GenericServlet class is overridden by the
EmployeeSearch servlet and the super.init() method is called.

public void init (ServletConfig config)


throws ServletException
{
super.init(config);
The init() method of the EmployeeSearch servlet:
1. Reads the database file name as an initial parameter:

employeeFile = getInitParameter(dbfile ) ;
2. Tries to open the database text file:

entry = new FileInputStream(employeeFile);


3. Calls the readDB() method to build the Hashtable:

readDB (new BufferReader(new InputStreamReader(entry)));


4. Throws ServletException exceptions if errors occurred:

throw new ServletException(e.getMessage());


...
throw new ServletException(I/O Error: + e.getMessage());
The init() method in the EmployeeSearch servlet logs all these operations in the
servlet-log file using the log() method for the GenericServlet class.
The readDB() method has been written to read the database text file and store
the information in a Hashtable:

public void readDB(BufferedReader buffread)


throws IOException
It is called by the init() method:

readDB (new BufferReader(new InputStreamReader(entry)));


The readDB() method:
1. Reads each line of the database text file:

String raw = buffread.readLine();


2. Notes each incorrect line missing the ampersand (&) and goes on to the next
line of the database text file:

Chapter 2. Servlets

71

if ((tab=raw.indexOf(&))<0)
{
...
raw = buffread.readLine();
continue;
}
3. Splits each line into two string components. The first component is the
employees name converted to all uppercase and the second one is a string
having both the employees electronic address and telephone number, still
separated by an ampersand ( &):

name = raw.substring(0, tab).toUpperCase();


values = raw.substring(tab+1, raw.length());
4. Inserts electronic address and telephone number into the Hashtable using
the name as a key:

employeeInfo.put(name, values);
5. Throws an IOException if an input/output error occurred:

throw e;
Also the readDB() method, like the init() method, logs all these operations in the
servlet-log file using the log() method of the GenericServlet class.
The service() method of the EmployeeSearch servlet builds an HTML form and
sends it to the client. The form contains a text input field where the user can
write the name of the employee whose electronic address and telephone number
were requested. The form is built in a very simple way:

out.println(<html><head><title>IBM Employee Search</title></head><body> ) ;


out.println(<form method=\GET\>);
out.println(<hr><h1>IBM Employee Search</h1><hr> ) ;
out.println(Enter last name and first name of the IBM employee you search for: ) ;
Note how the value of the text input field is dynamically created:

out.println(<p><input type=\text\ name=\key\ value=\ ) ;


String key = request.getParameter(key ) ;
if (key != null)
out.print(key);
out.println(\><p> ) ;
This means that if the user invokes the servlet followed by a question mark ?
and by the encoded name of the employee, for example:

http://aixncf10/servlet/EmployeeSearch?key=Pistoia+Marco
then the name Marco Pistoia is also automatically written in the text input field.
Otherwise, if the user simply invokes the servlet without specifying any
parameter, the text input field is empty.
The following statement creates a Submit button:

out.println(<input type=\submit\ value=\SUBMIT\><p></form><hr> ) ;


If the inserted string is correct, it is converted to all uppercase and then it is
used to retrieve the electronic address and telephone number from the
Hashtable.

72

Network Computing Framework for e-business Guide

key = key.toUpperCase();
String values = (String) employeeInfo.get(key);
For each employee an electronic address and telephone number had been
saved in the same string component of the Hashtable, separated by an
ampersand. The following step retrieves both these parameters, creates an
HTML table containing all the information that the user requested and sends it
back to the client.

int tab = values.indexOf( & ) ;


out.println(<table width=\35%\ border=\3\>);
out.println(<tr><th>Name</th> ) ;
out.println(<td> + key + </td></tr> ) ;
out.println(<tr><th>Electronic Address</th> ) ;
out.println(<td> + values.substring(0, tab) + </td></tr> ) ;
out.println(<tr><th>Phone</th> ) ;
out.println(<td> + values.substring(tab+1, values.length()));
out.println(</td></tr></table> ) ;
Figure 54. Parsing the Fields

If the name entered by the user does not match any key in the hashtable, an
error message is sent back to the client:

out.println(key + not found ) ;


Then the service() method closes the HTML page it had dynamically created:

out.println(<p></body></html> ) ;
In addition, it closes the output stream before exiting, to make sure that the
buffer stream is flushed:

out.close();
The destroy() method of the EmployeeSearch servlet is very simple. When the
Web server is shut down, the destroy() method destroys the servlet and logs this
operation in the servlet-log file:

log(EmployeeSearch servlet destroy() called. ) ;

2.7.2 Compiling and Installing the Servlet


Once the Java code for the EmployeeSearch servlet was written
(EmployeeSearch.java), we needed to generate the relative bytecode file for it
(EmployeeSearch.class). To do that, we simply compile the source code using
the Java compiler javac, as indicated in 2.5.1, Compiling and Installing a
Servlet on page 33:

javac EmployeeSearch.java
The EmployeeSearch.class file must be stored in the servlet directory (see 2.4.2,
Servlet Directory on page 29). The EmployeeSearch servlet reads a database
text file, which we called employee.txt. We can place that file anywhere, but we
need to let the servlet know where it will be located. The database text file
name is an initial parameter for the servlet (see 1 on page 71), so we have to
follow the procedure indicated in 2.4.3.3, Servlet Initialization Parameters on
Chapter 2. Servlets

73

page 31. We created a subdirectory called database in the server_root


directory. We stored the employee.txt file there. Then we opened the Lotus
Domino Go Webserver Configuration and Administration Forms and we selected
External Servlet. We then filled out the section called Servlet Initialization
Parameters in the Java Servlet Configuration form as follows (see Figure 16 on
page 32):
1. Click on Add.
2. Set Instance name to EmployeeSearch.
3. Set Class name to EmployeeSearch.
4. Fill in the Parameters field by typing:

dbfile=/usr/lpp/internet/server_root/database/employee.txt .
The init() method of the EmployeeSearch servlet forces the servlet to read the
value of the dbfile initial parameter:

String employeeFile = getInitParameter(dbfile ) ;


The section called Servlet Initialization Parameters of the Java Servlet
Configuration form will look now like the following:

Figure 55. EmployeeSearch Servlet Initialization Parameters

When we click on Apply, a Security Information window appears (see Figure 34


on page 51). We chose the Continue button because we want the form to be
submitted. Then the Lotus Domino Go Webserver Confirmation Page is

74

Network Computing Framework for e-business Guide

displayed on the screen so you can reread all of the configuration information.
In that screen capture we only showed the section relative to the
EmployeeSearch servlet configuration:

Figure 56. Confirmation Page

Two buttons are available:

Configuration Page

Restart Server

We click on Restart Server. This causes the server to read the updated
configuration file and restart without fully shutting down.
The Security Information window reappears on the screen and we click on the
Continue button. The last step is the Restart Confirmation page:

Chapter 2. Servlets

75

Figure 57. Restart Confirmation Page

This page confirms that the server has been successfully restarted. You can
click on the Configuration Page button to continue with further configurations.
We should also remember that if we modify the Java source code of the servlet
and compile the modified source code, we have to stop the Lotus Domino Go
Webserver and restart it by entering:
1. stopsrc -s httpd
2. startsrc -s httpd
Now our servlet is completely installed and its configuration will be present in
the Servlet Initialization Parameters window:

76

Network Computing Framework for e-business Guide

Figure 58. EmployeeSearch Servlet Configuration

2.7.3 Invoking the Servlet


You can invoke the EmployeeSearch servlet by pointing directly to its URL,
http://servers IP address/servlet/EmployeeSearch. The IBM EmployeeSearch
servlet window is displayed:

Chapter 2. Servlets

77

Figure 59. IBM EmployeeSearch Servlet Window

We can fill out the input text file setting the employees name to PISTOIA
MARCO.

78

Network Computing Framework for e-business Guide

Figure 60. Insert the Name of the Employee You A r e Searching For

Clicking the SUBMIT button causes the servlet to give us the following dynamic
response:

Chapter 2. Servlets

79

Figure 61. IBM EmployeeSearch Servlet Response

Remember that we could also invoke the EmployeeSearch servlet by pointing


directly to its URL and appending a question mark (?) followed by the encoded
key with the following information:

http://server s IP address/servlet/EmployeeSearch?key=PISTOIA+MARCO
We already pointed out that the EmployeeSearch servlet is written in order to
dynamically fill out the text input field with the employee s name. For example,
the following window is shown when we enter the following URL:

http://servers IP address/servlet/EmployeeSearch?key=Pistoia+Marco

80

Network Computing Framework for e-business Guide

Figure 62. Appending the Encoded Key to the Servlets URL

We obtain the table with the requested information and the text input field is
automatically updated.

Chapter 2. Servlets

81

Figure 63. IBM EmployeeSearch Servlet New Response

Notice that it is not necessary to use all capital letters in the input text field, even
if all employees names are written in capital letters in the database text file (see
Figure 53 on page 70). The servlet automatically converts the string to
uppercase to see if it matches one of the items in the database text file. You
can see this if you compare Figure 63 and Figure 61 on page 80.
If you type the name of a person who is not included in the database (for
example, Smith John), you will get an error message:

82

Network Computing Framework for e-business Guide

Figure 64. Error Message

2.7.4 Debugging and Testing the Servlet


The EmployeeSearch servlet is a good example to use to show how to get
information about the servlet itself. The Java source code of this servlet is full of
calls to the log() method and exceptions are thrown every time an error occurs.
After the servlet ran correctly we wanted to read what it had stored into the
servlet-log file (see 2.4.3.2, Servlet Configuration on page 30) after its
initialization. According to what we wrote in the Java source code, the
EmployeeSearch servlet has stored the following information:

EmployeeSearch:
EmployeeSearch:
EmployeeSearch:
EmployeeSearch:
EmployeeSearch:
EmployeeSearch:
EmployeeSearch:

init
The EmployeeSearch servlet has been correctly activated.
DB file / usr/lpp/internet/server_root/database/employee.txt .
Uncorrect employee database file at line 4.
EmployeeSearch has read 6 lines.
EmployeeSearch Hashtable has 5 entries.
Servlet EmployeeSearch working

Figure 65. Debugging Information in the Log

Chapter 2. Servlets

83

That debugging information was extracted from the following figure. The other
lines are relative to other life cycles of the servlet.

Figure 66. servlet-log File after EmployeeSearch Servlet Initialization

Notice in particular that the servlet logs information indicating that the fourth line
of the database text file is incorrect. This causes the two messages that follow
about the database text file having six lines but the Hashtable that the servlet
has created has only five entries. This matches Figure 53 on page 70.
If the Lotus Domino Go Webserver is shut down after a client has initialized the
servlet, we see a new line in the servlet-log file as shown in:

EmployeeSearch: EmployeeSearch servlet destroy() called.

Figure 67. servlet-log File after the destroy() Method Has Been Called

Lets restart the Web server and try another experiment. We renamed the
database text file, entering the following command when
/usr/lpp/internet/server_root/database is the current directory:

84

Network Computing Framework for e-business Guide

mv employee.txt employee1.txt
If we do not update the Servlet Configuration form, we can still invoke the servlet
by pointing to its URL, because no error message is displayed on the client s
browser, as the following window demonstrates:

Figure 68. The Servlet Is Activated Even If Its Configuration Is Incorrect

We then try to search for an employee and we enter Pistoia Marco into the input
text field. When we try to submit this form, the URL is modified, but no response
is displayed:

Chapter 2. Servlets

85

Figure 69. No Response Is Displayed When the SUBMIT Button Is Clicked

The servlet didnt work and we didnt get any indication as to why it didnt work.
This is the reason our servlet logs all operations it performs including all errors
that occurred in the servlet-log file.

Figure 70. The servlet-log File Is Needed to Debug the Program

86

Network Computing Framework for e-business Guide

The last five lines of this text screen show what the servlet has logged. They
show that:
1. The servlet has been correctly initialized, as we understood by looking at the
client s browser:

EmployeeSearch: init
EmployeeSearch: The EmployeeSearch servlet has been correctly activated.
2. The servlet read into the configuration file the exact database file name and
the path to it:

EmployeeSearch: DB file / usr/lpp/internet/server_root/database/employee.txt .


This means that the servlet had been configured.
3. The servlet can t find the database file that the Configuration file indicates:

EmployeeSearch: File Error:


DB file / usr/lpp/internet/server_root/database/employee.txt not found
EmployeeSearch: File Error:
/usr/lpp/internet/server_root/database/employee.txt.
This means that a file named employee.txt is not present in the indicated
directory. Checking the content of that directory, we now know that the file
name was wrong and we can fix this error.
In general, a useful technique to debug your servlets is to put try{}catch(){}
blocks around code blocks in the overridden service() method after you have
initialized the ServletOutputStream object. In addition to logging, you can use
the output stream to write the stack trace to the clients browser:

 ...

ServletOutputStream out = response.getOutputStream();


...
try
{
...
//some code which might throw an exception
}
catch(Throwable e)
{
out.println(e.toString());
PrintStream pstr = new PrintStream(out);
e.printStackTrace(pstr);
pstr.close();
out.close();
}
...

2.8 Servlet Tag Technique


We introduced the servlet tag technique in 2.5.2, Invoking a Servlet on page 36
and we said that Lotus Domino Go Webserver 4.6 has the ability to perform it
using a servlet. With the servlet tag technique, the server converts a section of
an HTML file into an alternative dynamic portion each time the document is sent
to the clients browser. This dynamic portion invokes an appropriate servlet and
passes to it the parameters it needs.
The first requirement for the HTML document is that it carries the extension
.shtml rather than the usual .html. Secondly, the point at which the inclusion
should be made is marked with the special <servlet> and </servlet> tags.

Chapter 2. Servlets

87

When the Web server sees the .shtml extension for the HTML file, it
automatically looks for the <servlet> and </servlet> tags inside the
document and tries to build the dynamic HTML portion. The format of the
< s e r v l e t > t a g i s s i m i l a r t o t h e < a p p l e t > t a g . The servlet does not have a
user interface at the client. T h e r e f o r e , a < s e r v l e t > t a g , u n l i k e a n < a p p l e t >
tag, does not require and in fact cannot have a width or height parameter and in
its minimum form looks like this:

<servlet name=ServletName>
...
</servlet>
ServletName specifies a symbolic name for the servlet. Usually it could be the
class name of the servlet without the .class extension. If you wish, the class
name may also be specified in the <servlet> tag as the value of the code
attribute as follows:

<servlet code=ServletCode.class>
...
</servlet>
Please, note that the class name always requires the .class extension.
Moreover, both name and class name for the <servlet> tag may be specified,
so a more complete example for the <servlet> tag is the following:

<servlet name=ServletName code=ServletCode.class>


...
</servlet>
The full format for specifying a servlet tag correctly is:

<servlet name=ServletName code=ServletCode.class init1=Arg1 ... initN=ArgN>


<param name=param1 value=val1>
...
<param name=paramM value=valM>
</servlet>
Using this technique, from within an HTML file you can invoke a servlet and pass
it the N initialization parameters init1,...,initN and the M named parameters
param1,...,paramM. Note that all the initialization parameters must be specified
in the main part of the <servlet> tag, while all the other parameters use the
<param> tag to be specified. The following HTML page, named
Experiment.shtml, specifies two initialization parameters:

City=Raleigh

Country=USA

It also specifies two normal parameters:

88

Company=IBM

Employee=Marco

Network Computing Framework for e-business Guide

<html>
<head>
<title>Experiment SHTML Page</title>
</head>
<body>
<h1>Experiment SHTML Page</h1><hr>
<servlet code=Experiment.class City=Raleigh Country=USA>
<param name=Company value=IBM>
<param name=Employee value=Marco>
</servlet>
<hr>
</body>
</html>
Figure 71. HTML Code of the Experiment.shtml File

This shtml page has very little static content and provides dynamic content by
invoking the Experiment.class servlet. The Experiment.java file is shown in the
following figure:

Chapter 2. Servlets

89

import
import
import
import

javax.servlet.*;
javax.servlet.http.*;
java.io.*;
java.util.*;

public class Experiment extends GenericServlet


{
public void init(ServletConfig config)
throws ServletException
{
super.init(config);
log(init() method called ) ;
}
public void service (ServletRequest req, ServletResponse res)
throws ServletException, IOException
{
ServletOutputStream out = res.getOutputStream();
out.println(<h2>Initialization Parameters</h2><br> ) ;
Enumeration initial = getInitParameterNames();
while (initial.hasMoreElements())
{
String key, value;
key = (String)initial.nextElement();
value = getInitParameter(key);
out.println(<h3>KEY: + key +
VALUE: + value + </h3><br> ) ;
}
out.println(<hr><p><h2>Parameters</h2><br> ) ;
Enumeration actual = req.getParameterNames();
while (actual.hasMoreElements())
{
String key, value;
key = (String)actual.nextElement();
value = req.getParameter(key);
out.println(<h3>KEY: + key +
VALUE: + value + </h3><br> ) ;
}
out.close();
}
public void destroy()
{
log(destroy() method called ) ;
}
}

Figure 72. Java Source Code of the Experiment.java Servlet

Invoking the servlet with the servlet tag technique is very simple. All you have
to do is point the clients browser to the HTML file having an .shtml extension
and call the servlet from within the <servlet> tag. In our case, we entered the
location of the Experiment.shtml file. The result is shown in the following figure:

90

Network Computing Framework for e-business Guide

Figure 73. HTML Page Statically and Dynamically Generated

The Experiment.java servlet is very simple but it is also very useful for checking
if your Web server is able to handle the servlet tag technique. Reading the Java
source code of the Experiment servlet (see Figure 72 on page 90), we see some

Chapter 2. Servlets

91

of the techniques that we already knew. For example, to retrieve the initial
parameters, we first use the getInitParametersNames() method of the
GenericServlet class, which returns the names of the servlets initialization
parameters as an enumeration of strings or an empty enumeration if there are
no initialization parameters. Secondly we use the getInitParameter() method
iterating over all the initialization parameters, following a similar procedure as
indicated in Figure 40 on page 57. The way we retrieve the normal parameters
is not different, but we used the getParameterNames() and the getParameter()
methods of the ServletRequest class.
Looking at the HTML source code in Figure 71 on page 89 and the result
displayed on the clients browser in Figure 73 on page 91, it is interesting to
note how everything between the two tags <servlet> and </servlet>,
including the tags themselves, has been dynamically overwritten and has been
completely replaced by the dynamic portion of the HTML file produced by the
servlet. This replacement takes place at the server-side. This is the reason why
the servlet tag technique is also known as server-side inclusion. A
demonstration of what we are stating can be obtained from the clients browser
itself, while it is displaying the Experiment.shtml page. Clicking on the View
menu of the Netscape window (see Figure 73 on page 91) and then selecting
Page Source, we can see that there is no more trace of the <servlet> and
</servlet> tags and the dynamic portion of the HTML dependent upon all the
parameters passed to the servlet has completely replaced it:

Figure 74. HTML Source Code after the Dynamic Portion Has Been Embedded

Moreover, this demonstrates that the Java code of the servlet is not accessible
from the client-side.
Additional information can be retrieved using the log() method of the
GenericServlet class. We had indicated that the server calls the init() method

92

Network Computing Framework for e-business Guide

only once when the first client requests the servlet. This could not be completely
true if the servlet is invoked from within the <servlet> tag of an HTML page.
Our tests demonstrated the following:
1. The first time you invoke the servlet from within the < s e r v l e t > tag of an
HTML page, you must specify the code attribute, plus all the initialization
parameters.
2. If you specify the name attribute too, you will be able to, from that point,
invoke the servlet only with the name parameter.
3. In this case the servlet is not reinitialized and the initialization parameters
passed to the servlet the first time survive.
4. If the code attribute is specified without the name attribute, the server is
forced to reload the servlet, even if you are using the same identical
configuration (the same code, the same initialization parameters). Multiple
instances of the same servlet are created and they are simultaneously
destroyed when the destroy() method for the servlet is invoked, typically
when the Web server is shut down.
5. If you specify only the name attribute, the server is not forced to reload the
servlet and so initialization parameters passed to the servlet the first time
survive, even if you try to change them by specifying new values.
For example, we can consider the Experiment servlet. It is invoked by the
Experiment.shtml file, from within the <servlet> tag, using the code attribute.
We can see that the server calls the init() method for the Experiment servlet
every time a client requests an HTML file that invokes that servlet from within
the <servlet> tag using the code attribute.
This can be demonstrated by restarting the Lotus Domino Go Webserver,
pointing the browser to the URL of the Experiment.shtml page and reloading the
page a specific number of times. Before reloading the HTML page, we should
be sure to clear the history, the memory cache and the disk cache of our
browser, as indicated at the end of 2.6.4, Multithreading on page 62. Our
servlet logs its initialization and the servlet-log file shows that the Web server
has invoked the init() method each time we reloaded it.

Figure 75. The Servlet Has Been Initialized Multiple Times

Why has the Web server initialized the servlet five times? When a servlet is
invoked from within the <servlet> tag of an HTML file and the code attribute is
specified, the servlet dynamically receives its initialization parameters. These
parameters are no longer passed to the servlet statically, using the Servlet
Configuration form. We want to have the option to use a different HTML file to
Chapter 2. Servlets

93

invoke the same servlet from within a <servlet> tag, passing it different
initialization parameters. That is the reason why the Web server, when the code
attribute also is specified, calls the init() method of the servlet and passes the
initialization parameters to the servlet.
Finally we want to try another test. The Experiment servlet can be invoked
directly by pointing to its URL and without interacting with an HTML page only if
we are able to pass it all the parameters it needs. Its parameters are divided
into two classes:
1. Initialization parameters can be passed to the servlet also by filling out and
submitting the Servlet Configuration form (see 2.4.3.3, Servlet Initialization
Parameters on page 31). Following the same steps we used to install the
EmployeeSearch servlet (see 2.7.2, Compiling and Installing the Servlet on
page 73), we fill out the Servlet Configuration form by setting:

Instance Name to Experiment.

Class Name to Experiment.

Parameters to:

City=Raleigh
Country=USA
You should then click on Apply, as shown in the following screen:

Figure 76. Filling Out the Servlet Configuration Form for the Experiment Servlet

94

Network Computing Framework for e-business Guide

After restarting the Web server, you can invoke the servlet by simply pointing
to its URL, but you still have to communicate its normal parameters to it.
2. Normal parameters can be communicated to the servlet by appending to its
URL a question mark (?) followed by the query string of the requested
parameters, for example:

http://server s IP address/servlet/Experiment/Company=IBM&Employee=Marco
(See 2.5.2, Invoking a Servlet on page 36.)
The following figure shows the result:

Figure 77. HTML Page Statically and Dynamically Generated

This time the HTML page is completely dynamic, because the Experiment servlet
has not been invoked from within a <servlet> tag of any HTML page.
If the servlet is directly invoked in this way, the Web server calls the init()
method only once, when the first client browser points to the servlets URL. In
fact, in this case, when initialization parameters are specified from within the
Servlet Configuration form they cant change.
We can obtain a very simple demonstration of this if we clear history, memory
cache and disk cache from our browser and we call the servlet a number of

Chapter 2. Servlets

95

times. The servlet-log file indicates that the servlet is initialized only the first
time:

Figure 78. The init() Method Is Called Only the First Time the Servlet Is Invoked

2.8.1 Another Example of the Servlet Tag Technique


The example that we are going to describe in this section shows how the servlet
tag technique can be successfully used to build interesting dynamic sections
inside HTML pages. In particular we see how the code and name attributes
must be correctly used within the <servlet> tag.
This example has been successfully tested in both Windows NT and Windows 95
platforms, in order to demonstrate servlets portability between different
operation systems. The screens captured and shown in this section are related
to a scenario (Web server and Web browser) completely based upon Windows
95. For the Windows 95 platform, we installed our servlet inside the servlet
directory C:\WWW\Servlets\Public of the Lotus Domino Go Webserver 4.6 for
Windows 95. To compile a servlet in the Windows 95 environment, the
CLASSPATH environment variable must be correctly set in order for the Java
compiler javac to find the two packages javax.servlet and javax.servlet.http. To
do this, you have to add the following line to the AUTOEXEC.BAT file:

set CLASSPATH=C:\WWW\Bin\Java\lib\classes.zip;
C:-WWW-CGI-Bin-icsclass.zip;C:-WWW-Servlets-Public
After making that change you should reboot your system.
The servlet we built to show the servlet tag technique is called IncludedCounter.
It is not supposed to be invoked directly by pointing to its URL, but it is invoked
from within the <servlet> tag on HTML pages that have a .shtml extension. Its
purpose is to produce a counter that can be dynamically embedded inside an
HTML file that carries the .shtml extension. It counts how many times that HTML
page has been accessed by a particular client machine. Instead of counting how
many times the HTML file has been requested in general by all clients, it holds
different counters for different clients. The output of this servlet is simply an
integer, which is dynamically embedded inside the HTML page by using the
servlet tag technique.
In addition, it is also possible that different HTML pages invoke this servlet,
provided that they call it with different instance names, using the name attribute
o f t h e < s e r v l e t > t a g . In this way, there is an instance for each HTML page and
each instance counts the number of times its related HTML page has been
invoked.
Each instance of the IncludedCounter servlet uses a Hashtable object to register
all the necessary information related to the HTML page invoking that instance.
As we know, the java.util.Hashtable class implements a Hashtable, which maps
keys to values. In this case, when a client machine requests the HTML page

96

Network Computing Framework for e-business Guide

related to a particular instance of the IncludedCounter servlet, its IP address is


the key and the number of times that client machine invoked that HTML page is
the value. IP addresses are held as string objects, while the counter is held by a
support class, named StoredData.
The IncludedCounter servlet also provides an interesting example of how to
write custom init() and destroy() methods. It is required, in fact, that the
Hashtable objects where the servlet instances hold their data are saved in
permanent storage, so that they are not lost when the servlet is destroyed and
can be retrieved when it is reinitialized. For that reason, this servlet, when it is
invoked from within the <servlet> tag of an HTML page, requires an
initialization parameter, filename. It is the name of the file where the servlet
instance stores the Hashtable object when the destroy() method for the servlet is
called, typically when the server is shut down. Different HTML pages use
different files to store their Hashtable objects, so that each HTML page invokes
its own instance of the IncludedCounter servlet and each instance stores its
Hashtable object in its own file.
It is not required that those files are updated each time a client machine
requests an HTML page invoking that servlet, because this would create a slow
mechanism of storing and retrieving data from the hard disk during the servlet
life cycle. The IncludedCounter servlet presents custom init() and destroy()
methods so that the Hashtable object is retrieved when the servlet is initialized
and it is stored when the servlet is destroyed. The destroy() method has been
overridden in each instance to store its Hashtable object in the file that has been
specified as its initialization parameter.
In order to store an object, the Java 1.1 serialization mechanism is used. As we
had indicated, the Hashtable object used by one instance of the IncludedCounter
servlet relates the IP address of a client machine to the number of times that the
client machine has accessed that HTML page. IP addresses are held as string
objects. Notice that both the classes java.util.Hashtable and java.lang.String
implement the java.io.Serializable interface. To store the integer counter
number, a support class called StoredData is used. That class also implements
java.io.Serializable, so that, in effect, serialization is possible.
The description that we have provided for the IncludedCounter servlet should
help you understand the Java source code IncludedCounter.java, shown in the
following figure:

Chapter 2. Servlets

97

import
import
import
import

java.util.*;
java.io.*;
javax.servlet.*;
javax.servlet.http.*;

public class IncludedCounter extends HttpServlet


{
String objFile;
Hashtable table = new Hashtable();
public void init(ServletConfig config) throws ServletException
{
super.init(config);
log(init() method called ) ;
try
{
objFile = getInitParameter(filename ) ;
if (objFile |= null)
{
FileInputStream fis = new FileInputStream(objFile);
ObjectInputStream ois = new ObjectInputStream(fis);
table = (Hashtable)ois.readObject();
fis.close();
}
}
catch(ClassNotFoundException cnfe)
{
log(Class Not Found ) ;
}
catch(FileNotFoundException fnfe)
{
log(File not found ) ;
}
catch(IOException ioe)
{
log(Input/Output Error ) ;
}
}
Figure 79 (Part 1 of 3). IncludedCounter.java

98

Network Computing Framework for e-business Guide

public void service(HttpServletRequest req, HttpServletResponse res)


throws ServletException, IOException
{
log(service() method called ) ;
String remaddr = req.getRemoteAddr();
int number;
synchronized(table)
{
StoredData counter = (StoredData)table.get(remaddr);
if (counter |= null)
number = counter.increment();
else
{
counter = new StoredData(1);
table.put(remaddr, counter);
number = 1;
}
}
ServletOutputStream out = res.getOutputStream();
out.println(number);
out.close();
log(service() method exit ) ;
}
public void destroy()
{
log(destroy() method called ) ;
if (objFile |= null)
{
try
{
FileOutputStream fos = new FileOutputStream(objFile);
ObjectOutputStream oos = new ObjectOutputStream(fos);
synchronized(table)
{
oos.writeObject(table);
}
fos.close();
}
catch (Exception e)
{
log(Exception ) ;
}
}
super.destroy();
}
Figure 79 (Part 2 of 3). IncludedCounter.java

Chapter 2. Servlets

99

public String getServletInfo()


{
return This servlet counts how many times each client accessed
a specified .shtml page ;
}
}
Figure 79 (Part 3 of 3). IncludedCounter.java

Of course, it is necessary to also show the Java source code for the StoredData
class used to wrap all the counters. The following figure shows the
StoredData.java file:

import java.io.*;
public class StoredData implements Serializable
{
int number;
public StoredData(int value)
{
number = value;
}
public int increment()
{
++number;
return number;
}
}
Figure 80. StoredData.java

The StoredData.java file must be compiled before compiling the IncludedCounter


servlet, because this requires the presence of the StoredData class to be
compiled successfully. Once we obtain the StoredData.class file, we place it
inside the servlet directory.
Finally, we want to show a simple HTML file that invokes the IncludedCounter
servlet form within the <servlet> tag of an HTML page, for example, the file
Page1.shtml, shown in the following figure:

100

Network Computing Framework for e-business Guide

<HTML>
<HEAD>
<TITLE>PAGE 1</TITLE>
</HEAD>
<BODY>
<H1>PAGE 1</H1>
This is the <B>first</B> example of a SHTML page invoking the IncludedCounter servlet
<HR>
The file containing the stored data is <B>Page1.obj</B>.
<HR>
<CENTER>
<H2>
You have invoked this page
<H1>
<SERVLET
code=IncludedCounter.class
name=IncludedCounter1
filename= C:\\Objects\\Page1.obj>
</SERVLET>
</H1>
times
</H2>
</CENTER>
</BODY>
</HTML>

Figure 81. Page1.shtml

When the clients browser requests the Page1.shtml file, the .shtml extension
forces the Web server to search the pair of tags (<servlet> and </servlet>)
within the HTML code. Everything between these two tags, plus the tags
themselves, is replaced by the dynamic output of the IncludedCounter servlet.
Notice that this HTML page invokes the IncludedCounter servlet, so that the Web
server automatically creates an instance of that servlet. This instance is called
IncludedCounter1, according to the value of the name attribute within the
< s e r v l e t > t a g . This instance is related to the Page1.shtml file. The filename
initialization paramenter is passed to the servlet with the value
C:\Objects\Page1.obj. This means that the Hashtable object related to the
Page1.shtml file (used to register all the clients that have access to the
Page1.shtml page and the number of the accesses) will be saved in the
Page1.obj file.
In order for the Web server to be able to create the IncludedCounter1 servlet
instance, the init() method is called. This method is used by the servlet to
discover the value of the filename initialization parameter and to retrieve the
Hastable object, named table, from the file. Of course, before running the
servlet, it is necessary to create the empty file Page1.obj inside the directory
C:\Objects, otherwise a FileNotFoundException exception is thrown. Notice that
the first time the servlet is run, the Page1.obj file will be empty and no Hashtable
object will be retrieved. This situation is handled by simply catching an
IOException exception.
The service() method works according to a very simple mechanism. First of all it
retrieves the IP address of the client machine from where the Page1.shtml page
was requested. This function is accomplished by the getRemoteAddr() method
for the HttpServletRequest object, called req and passed to the service() method.

Chapter 2. Servlets

101

Then the service() method creates a StoredData object named counter, used to
retrieve the number of accesses to the Page1.shtml file from the client machine.
Also, the counter.increment() method is invoked to update the counter field.
If that client machine is accessing the Page1.shtml file for the first time, no
counter object can be created starting from the table, so the counter s
constructor is invoked, passing it the int value 1. In this case the table object
must be updated with the IP address of the new client that accessed the
Page1.shtml file and its relative StoredData object.
Finally the service() method produces the dynamic HTML portion to embed
inside the Page1.shtml file.
The destroy() method is invoked only when the Web server is shut down. It is
used to store the table object inside the Page1.obj file.
Notice that accesses to the table objects need to be synchronized in order to
avoid multiple threads from multiple client requests causing problems when
accessing the servlet concurrently.
Now that we have described how the IncludedCounter servlet works, we can
experiment with it. First of all the Page1.obj file must be created, placing it
inside the directory C:\Objects as is required by the Page1.shtml file. To create
this file, it is enough to open and save an empty text file with the MS-DOS editor.
We should be sure that the file we created has the right read and write
permissions.
Before experimenting with the IncludedCounter servlet, it is a good idea to open
the Preferences window for the Netscape browser and to set to 0 the number of
days after which pages in history expire. The Preferences window can be
accessed from the Edit menu. You can also select Advanced and then Cache in
the Preferences window and set Memory Cache and Disk Cache to 0 KB. In this
way, you do not have to clear history, memory cache and disk cache for your
browser each time you request the Page1.shtml file to experiment with the
counter.
If you place the Page1.shtml file in a subdirectory of your Web server below
C:\WWW\HTML, point your browser to its location and then click two times on the
Reload button of the Netscape browser window, you can immediately see how
the IncludedCounter works. The dynamic portion embedded inside the
Page1.shtml file is automatically updated and you can read that you have
effectively invoked that page three times, as shown in the following figure:

102

Network Computing Framework for e-business Guide

Figure 82. The Page1.shtml File Has Been Reloaded Three Times

You can see that the counter, which is the dynamic portion of the HTML page, is
automatically increased each time you reload that page.
After each experiment, we want to immediately check the servlet-log file, placed
inside the directory C:\WWW\Logs. Comparing the servlet-log file with the Java
source code of the IncludedCounter servlet, we can see useful information about
how the servlet really works. In the last release of the Lotus Domino Go
Webserver 4.6, the output of the log() method is saved inside a file called
servlet-log that carries the extension of the current date. This gives you a
servlet-log file for each day your Web server has invoked a servlet. The
following window shows the servlet-log file after we reloaded the Page1.shtml
file three times:

Chapter 2. Servlets

103

Figure 83. The servlet-log File after the First Experiment

Even if the servlet has been invoked three times, notice that it has been loaded
only once. In fact the init() method has been called only once, while the
service() method has been invoked three times. Also notice that the servlet has
been able to find the Page1.obj file, otherwise we would have read that a
FileNotFoundException exception had been caught. Nevertheless an IOException
exception has been caught, because the Page1.obj file was empty and it was not
possible to retrieve any Hashtable object from it.
Another interesting experiment we can try is to invoke the Page1.shtml file from
a different client machine. We see that the IncludedCounter servlet holds two
separate counters for the two different client machines. The following figure
shows the Netscape 2.02 browser for OS/2 after having invoked the Page1.shtml
file:

104

Network Computing Framework for e-business Guide

Figure 84. The Page1.shtml File Loaded from a Different Client Machine

Opening the servlet-log file again, we see that this operation has simply caused
a new call to the service() method:

Figure 85. The servlet-log File after the Second Experiment

Chapter 2. Servlets

105

These tests demonstrate that only one instance of the IncludedCounter servlet
has been loaded, according to the only value given to the name parameter
within the <servlet> tag.
We want to now try a new experiment with a new HTML file, called Page2.shtml.
The HTML code for this file is shown in the following figure:

<HTML>
<HEAD>
<TITLE>PAGE 2</TITLE>
</HEAD>
<BODY>
<H1>PAGE 2</H1>
This is the <B>second</B> example of a SHTML page invoking the IncludedCounter servlet
<HR>
The file containing the stored data is <B>Page2.obj</B>.
<HR>
<CENTER>
<H2>
You have invoked this page
<H1>
<SERVLET
code=IncludedCounter.class
name=IncludedCounter2
filename= C:\\Objects\\Page2.obj>
</SERVLET>
</H1>
times
</H2>
</CENTER>
</BODY>
</HTML>

Figure 86. Page2.shtml

The most important things that we must notice in this second file are the
following:

It forces the Web server to create a second instance for the IncludedCounter
servlet, called IncludedCounter2.

The Hashtable object related to this second instance will be stored into the
Page2.obj file.

Of course we must create the Page2.obj file in the directory C:\Objects before
loading the Page2.shtml file, otherwise a FileNotFoundException exception will
be caught by the init() method.
Pointing our browser to the Page2.shtml file and selecting the Reload button one
time in the Netscape browser, we see a screen similar to the following:

106

Network Computing Framework for e-business Guide

Figure 87. The Page2.shtml File Has Been Loaded by the Client s Browser

This picture demonstrates that even if the client machine is the same one that
requested the Page1.shtml file, the Web server has created a new servlet
instance that holds a separate counter for the Page2.shtml file.
It is worth looking back at the servlet-log file now. It shows an example of a new
instance that has been created for the IncludedCounter servlet, as shown in the
following figure:

Chapter 2. Servlets

107

Figure 88. The servlet-log File after the Third Experiment

Notice that for this second instance an IOException exception has been caught,
because the Page2.obj file that we created is empty.
Before restarting the Web server, we want to check the status of the two files
Page1.obj and Page2.obj, which will be used to store the two Hashtable objects
held by the two instances IncludedCounter1 and IncludedCounter2. The
following figure shows that they are still empty, even if the two instances have
already been created:

Figure 89. Both the Files Page1.obj and Page2.obj A r e Still Empty

In fact it is the destroy() method that will definitively store the two objects inside
these two files. The destroy() method is called by the Web server itself when it
is shut down. After restarting the Web server, we can see that the two files are
no longer empty, as shown in the following figure:

108

Network Computing Framework for e-business Guide

Figure 90. Both the Files Page1.obj and Page2.obj A r e No Longer Empty

The servlet-log file is now very interesting, because it shows that both the
IncludedCounter1 and IncludedCounter2 instances have been destroyed as soon
as the Web server has been restarted:

Figure 91. The servlet-log File after the Fourth Experiment

The next experiment shows the init() method functions. We wrote a custom init()
that should now be able to retrieve the Hashtable objects stored inside the
Page1.obj and Page2.obj files. If we open our browser, which last time had
invoked Page1.shtml three times, and we point it to the Page1.shtml file, the
dynamic counter informs us that this is the fourth time we have access to that
page, as shown in the following figure:

Chapter 2. Servlets

109

Figure 92. The Page1.shtml File Has Been Loaded after the Web Server Was Restarted

Since the Page1.obj file effectively contained a Hashtable object stored inside it,
no IOException exception has been caught this time and the servlet-log file
simply indicates that both the init() and the servlet() method have been called a
single time:

Figure 93. The servlet-log File after the Fifth Experiment

Other tests could be done modifying the configurations within the <servlet>
tag. For example we demonstrated the following:

110

If we specify only the code attribute within the servlet tag and we do not
specify any value for the name attribute, the Web server creates new
instances for the servlet each time we click the Reload button of the
Netscape browser window. Each one of these instances reads the same
Hashtable object from the same file, so we see that the counter field is
updated only the first time. All these instances are destroyed when the Web
server is shut down. This demonstrates that it is necessary to specify a

Network Computing Framework for e-business Guide

value for the name attribute, in order to create only one instance of the
servlet for each HTML page and to get the counter really updated.

It is also possible to avoid the creation of the file with the extension .obj,
before the HTML file is invoked. The servlet automatically creates the file
when the destroy() method is called and stores the Hashtable object inside
it.

If the value for the name attribute is also specified, the initialization
parameter specified at the moment the servlet instance was created survives
even if we try to change it by modifying it within the <servlet> tag of the
HTML page.

Chapter 2. Servlets

111

112

Network Computing Framework for e-business Guide

Chapter 3. Connectors
This chapter describes all the connectors that we use on AIX and Windows NT
and shows how to set them up.

3.1 The Role of a Connector


In todays fast changing technological world, corporations are looking to provide
their existing enterprise applications and data to intranet and Internet users.
IBMs NCF database and transaction connectors allow this data and these
applications to work together with Web clients and servers. A Web server
combined with NCF connectors provides a powerful and robust environment
where you can build new services based on new Internet technologies integrated
with existing data, applications and collaboration services. The results are
flexible and dynamic applications that link people with business and work flow
process.
IBM connectors are built on robust and mature products and make it easy for
developers to create Java servlets to tie data and applications together. In this
section we discuss how to develop servlets that use IBM connectors at the
server and the advantages of this solution.
The IBM offerings include IBM connectors and Lotus Domino.Connect. The IBM
connectors are:

CICS Internet Gateway

CICS Gateway for Java

MQSeries Internet Gateway

MQSeries Client for Java

eNetwork Host On-Demand

DCE Encina Lightweight Client

Net.Data (DB2 and ODBC)

IMS Connectors

Lotus Domino.Connect is a complete solution that integrates the Domino


applications with a broad range of relational databases, transaction and
enterprise application systems. Lotus Domino.Connect is a modular offering that
lets you install only the components that you really need for your business. It
provides access to:

MQSeries

Databases - IBM DB2 Universal Database, Oracle Universal Server and


others

CICS

DCE servers

Applications provided by SAP, BAAN and others

To download and test the IBM NCF connectors you can link to
http://www.ics.raleigh.ibm.com/ibmconnectors as shown in Figure 94 on
page 114.
Copyright IBM Corp. 1998

113

Figure 94. IBM Network Computing e-Business Enterprise Connectors Page

3.1.1 CICS Applications


CICS became available in late 1960 and is one of the most widely used and
popular transaction managers in the world. Since then, customers and software
vendors have built a huge number of application programs based on Application
Programming Interfaces (APIs) provided by CICS. Therefore, it is easy to find
applications written using different styles since the CICS programming interface
has matured over time.
CICS transaction can be conversational or pseudo-conversational. In a
conversational mode, all resources required for the process are maintained until
the user ends the conversation. This could potentially include several user
interactions before the transaction is complete. The conversational transaction
also waits and maintains all resources used during the time that the user is
thinking about the transaction. Thus, until the transaction is complete, all the
resources may be tied up. Pseudo-conversational mode is the recommended
way to write CICS applications and it is also the most commonly used today.
The CICS transaction does not wait for a user response; it simply terminates and
saves all information needed for the next transaction in a scratch pad area
known as the communications area (COMMAREA). The next transaction will
start when the user presses Enter and it will receive the data saved in the
COMMAREA from CICS.
As with CICS transactions, the CICS programming style may be important to a
development group. In an application program we can identify three parts:

114

Presentation Logic

Network Computing Framework for e-business Guide

Business Logic

Data ACCESS logic

All of these parts may be included in a single program or can be split into two or
more programs linked through the CICS API: EXEC CICS LINK. In the past, the
most common programming methodology was to include all three components
inside a single module where the presentation logic was generally based on
3270 screens. More recently, applications started to be written in a client/server
style where the presentation logic (3270 or graphical user interface), could call
the business logic using a CICS LINK, passing and receiving data through the
COMMAREA. CICS provides the ability to invoke a local program, inside the
same CICS region where the calling program runs, or a remote program, in a
different region where the calling program runs across the network. In a
distributed CICS environment you can call a program using the following
functions:

Distributed program link (DPL) is the ability to call a remote CICS program
between CICS servers. The CICS API used is EXEC CICS LINK where the
called program location can be explicitly included into the API command or
you can use the CICS program definition. Using the program definition is the
recommended way since you do not have to recompile the program if you
change the called program location, just update the program definition.

External call interface (ECI) is the ability to call a CICS server program from
a CICS client.

To invoke a CICS program that includes all three components (3270 presentation,
business and data access logic), you have to present the request the same way
that a 3270 device does. CICS allows this by using:

Front End Programming Interface (FEPI) - A CICS API available on MVS/ESA


and OS/390 operating systems that allows a CICS program to emulate a 3270
device to invoke a 3270 transaction (CICS, IMS).

External Presentation Interface (EPI) - A CICS client API that allows a


workstation or UNIX program to invoke a CICS server transaction sending
and receiving 3270 data streams. This function is available on every
platform where the CICS client is supported.

When you have to integrate different application environments with CICS


applications you can take advantage of CICS built-in functions.
It is advisable to write new CICS applications splitting out the presentation logic,
especially if you are only using 3270 terminals, because it is easier to link to the
applications from other environments, as you can see in Figure 95 on page 116.

Chapter 3. Connectors

115

Figure 95. CICS Programming Styles

3.1.2 CICS Internet Gateway


The CICS Internet Gateway provides an interface between a Web server and
CICS applications, allowing the conversion of 3270 data streams into HTML
format as well as HTML into 3270 data streams. The CICS applications can be
accessed by any Web browser without making any changes. Security functions
used by the browsers and by the CICS server are passed through the gateway.
The CICS Internet Gateway is a CGI server program that translates the input
requests coming from the Web browser into the appropriate CICS External
Presentation Interface (EPI) call. It will get sent to the CICS server where it will
schedule the appropriate transaction to be performed. It is as if it were a real
CICS terminal requesting the transaction. During the first user request, the CICS
server will create a terminal definition that will be associated with the user
request. This permits it to build a session between the CICS server and the Web
browser. The gateway will maintain knowledge of this session and will refer to
the same terminal for all requests from that user. When the CICS Internet
Gateway builds a session, it stores the state information in variables held in

116

Network Computing Framework for e-business Guide

memory. This happens when the user starts his or her first transaction. The
state information includes a session identifier that is placed in a hidden field on
every HTML page sent to the browser and the terminal identifier obtained during
the first request sent to the CICS server. It is used in all subsequent EPI
requests. A browser session will terminate, and all resources will be deleted,
when:

The user clicks on the Quit button.

The user sends the CICS sign off transaction.

A request has set AutoExit to ON.

Any timeout values expire (3.1.2.2, Customization on page 118).

The CICS Internet Gateway supports both conversational and


pseudo-conversational CICS applications. There are some limitations that you
can read in the Guide for Browser Users section of the documentation shipped
with the CICS Internet Gateway. You can also see the documentation online at:
http://Webserver/cig/html/index.htm after you have installed the product.
Note: You should be aware that the CICS Internet Gateway gives you access to
CICS 3270 applications. It cant be used with applications that issue EXEC
CICS START and EXEC CICS RETURN IMMEDIATE statements. In
addition, there is no support for 3270 colors and text attributes and for
3270 numeric field attributes.
The CICS Internet Gateway (see Figure 96) is available on AIX, Windows NT and
the OS/2 platform.
This solution could be considered an easy and inexpensive way to permit Web
users to run CICS transactions.

Figure 96. CICS Internet Gateway

Chapter 3. Connectors

117

3.1.2.1 Installation
The CICS Internet Gateway solution is distributed with CICS client products and
the installation steps are documented in Network Computing Framework
Component Guide , SG24-2119. You can download the CICS client from:
http://www.hursley.ibm.com/cics/clients or from: http://service.software.ibm.com
for free if you already have a license for any CICS transaction server.
The CICS gateway may be installed when the CICS client is installed, or at any
time afterwards by running the CICS Client Installation utility program and
selecting the CICS Internet Gateway as an additional component to install. The
CICS gateway is installed into the cig directory under the main CICS client
directory.
The installation step when completed successfully modifies your system
environment. This depends upon the platform you are using. For example, in
Windows NT two keys are added to the Windows NT registry.
All the documentation that you need is provided in HTML format. You can
retrieve it using your Web browser and opening the file
file:///c:/cicscli/cig/html/Index.htm after you have installed the code.

3.1.2.2 Customization
CICS Internet Gateway requires two actions:
1. Configuring the CICS gateway
The CICS gateway has a configuration file called CIGD.INI located in the
c:\CICSCLI\CIG\BIN directory on Windows NT and OS/2, or CIGD.ENV located
in /usr/lpp/cig/bin/ on AIX. You have to verify that the following paths were
set correctly.


For Windows NT and OS/2
Trace = c:\cicscli\cig\admin\cigtrace.log
Error = c:\cicscli\cig\admin\cigerror.log
Info
= c:\cicscli\cig\admin\ciginfo.log
Header = c:\cicscli\cig\html\headtext.htm
Trailer = c:\cicscli\cig\html\tailtext.htm
ExitPage = c:\cig\cigstart.htm

For AIX
Trace = /tmp/cigtrace.log
Error = /tmp/cigerror.log
Info
= /tmp/ciginfo.log
Header = /usr/lpp/cig/html/prime/headtext.htm
Trailer = /usr/lpp/cig/html/prime/tailtext.htm
ExitPage = /cig/cigstart.htm

As you can see in Figure 100 on page 122 the configuration file has two
sections:

118

Default section - Defines features that can not be overridden when the
request to start a transaction is submitted.

Override section - Defines features that can be modified when the


request to start a transaction is submitted.

Network Computing Framework for e-business Guide

In the default section it is important that you calculate timeout values to


prevent a high utilization of resources. The parameters are described
below:

TimeOutInternet - When the user does not complete his or her


requests in the TimeOutInternet interval during a browser session,
the gateway will notify CICS to delete the associated terminal and it
will free any resources, threads and memory that were dedicated to
that user. You can see in Figure 98 on page 120 the message that
will get sent to the user when he or she asks for a next transaction
after the expired TimeOutInternet time. In Figure 99 on page 121 the
CICS log shows the session created at the first user request and
when it will be deleted. The client session is an auto-installed
terminal that will be uninstalled when it terminates.

TimeOutCICS - How long the gateway will wait for CICS to respond
to a user request. When that interval expires the gateway will free
up all resources associated with that browser session.

TimeOutGateway - How long the two components of the gateway,


the CGI program and the daemon (long-running process), can stay
without hearing from each other during a user request. When that
interval expires the gateway will free up all resources associated
with that browser session.

The MaxUsers parameter specifies the maximum number of concurrent


users that the gateway can manage. If this number is reached, new
users will receive an error message from the gateway. This gives added
importance to the timeout parameters. Without the timeout parameter, a
single user could tie up resources for a long time
You can query the value of these parameters as shown in Figure 97 on
page 120.

Chapter 3. Connectors

119

Figure 97. CICS Internet Gateway: Current Gateway Settings

Figure 98. CICS Internet Gateway: TimeOutInternet Occurred

120

Network Computing Framework for e-business Guide

Figure 99. CICS Internet Gateway: CICS Console Messages

You can provide your header and trailer logo images or use what is
provided by IBM. Just modify the Header and Trailer path in the CICS
Gateway configuration file.
The parameters described in the override section could be used to
customize solutions as we show in 3.1.2.6, How to Use CICS Internet
Gateway on page 129.

Chapter 3. Connectors

121

;----------------------------------------------------------------------; IBM CICS Internet Gateway Initialization File


;----------------------------------------------------------------------; Format:
; Comment lines which have a ; in the first column.
; Blank lines.
;
; [Section]
; Parameter = Value
; Parameter = Value
; ...
;
; [Section] must be either Default or Override. There must be
; just one of each section. It must be enclosed in square brackets.
; For each type of section, a set of Parameters and associated Values may
; be defined. Often these may be omitted and will then assume sensible
; default values, but when defined, they must be in the correct section.
; This sample file lists all the parameters that are available and which
; section they must reside in.
;----------------------------------------------------------------------; Default section - This section defines features which can not be
;
overridden with start tran.
;
;Trace
- This parameter specifies the name of the trace file,
;
when trace is enabled.
;
This will default to cigtrace.log
;Error
- This parameter specifies the name of the error file.
;
This will default to cigerror.log
;Info
- This parameter specifies the name of the information
;
file. This will default to ciginfo.log
;
This parameter is not relevant on the OS/2 platform,
;
which provides a Graphical User Interface (GUI) instead.
;Cursor
- This specifies the character that will be interpreted
;
as the cursor position. It should be specified in Hex.
;
This will default to 0x23 ( # ).
;MaxUsers
- This parameter specifies the maximum number of
;
concurrent users on this gateway.
;
This will default to 15.
;TimeOutCICS
- This parameter specifies how long the system will
;
wait for CICS to respond. It is specified in seconds.
;
This will default to 60 seconds.
;TimeOutInternet - This parameter specifies how long the system will
;
wait for the Internet to respond. It is specified in
;
seconds.
;
This will default to 600 seconds ( 10 Mins ).
;TimeOutGateway - This parameter specifies how long the system will
;
wait for the Gateway to respond. It is specified in
;
seconds.
;
This will default to 60 seconds.

Figure 100 (Part 1 of 3). CICS Internet Gateway - CIGD.INI File for Windows NT

122

Network Computing Framework for e-business Guide

[Default]
Trace = C:\CICSCLI\cig\admin\cigtrace.log
Error = C:\CICSCLI\cig\admin\cigerror.log
Info = C:\CICSCLI\cig\admin\ciginfo.log
Cursor = 0x23
MaxUsers = 15
TimeOutCICS = 60
TimeOutInternet = 600
TimeOutGateway= 60
;----------------------------------------------------------------------; Override section - This section defines features which can be
;
overridden with start tran.
;
;Header
- This specifies the fully qualified path name to a
;
piece of HTML that will be imbedded at the top of
;
every page.
;
This will default to no header.
;Trailer
- This specifies the fully qualified path name to a
;
piece of HTML that will be imbedded at the bottom of
;
every page.
;
This will default to no trailer.
;ExitPage
- This specifies the URL of the exit page that will be
;
displayed at the end of the session. This can either
;
be local ( eg. /cig/cigstart.htm )
;
or remote ( eg. http://saints/cig/cigstart.htm )
;
NB. A local URL will be faster.
;
It can also be the URL of a cgi script to call on exit
;
( eg. /cig-bin/cleanup )
;
This will default to /cig/cigstart.htm
;ExitAid
- In some cases it will be necessary to back out of a
;
transaction. This parameter specifies the name of the
;
key which will be entered to exit. This value should
;
be specified in Hex. e.g. 0x33 for PF3 .
;
This will default to 0x00 (i.e. don t attempt to
;
cleanly exit a transaction when an error occurs).
;
Note: This could mean that the terminal cannot be
;
be deleted because the EPI still believes that the
;
transaction is still active
;PFKey24
- In some CICS applications 24 PF keys are required.
;
This option allows you to specify whether you would
;
like these PF 13 to 24 keys to be displayed. A value of
;
On will enable displaying of these PF keys.
;
Note: Loading these extra graphics will be slower.
;
This will default to Off.
;PAKeys
- In some CICS applications the 3 PA keys are required.
;
This option allows you to specify whether you would
;
like these extra PA keys to be displayed. A value of
;
On will enable displaying of these PA keys.
;
Note: Loading these extra graphics will be slower.
;
This will default to Off.

Figure 100 (Part 2 of 3). CICS Internet Gateway - CIGD.INI File for Windows NT

Chapter 3. Connectors

123

;GraphicKeys
;
;
;
;
;
;AutoExit
;
;
;
;
;ImbedHTML
;
;
;
;
;
;
;AppendEXE
;
;
;
;
;
;

- The function keys can be displayed either as Web


Browser submit keys or as graphic images (GIF files).
A value of On will enable displaying of these GIF
images.
Note: Loading these extra graphics will be slower.
This will default to non graphic keys.
- At the end of a session, a CICS terminal would
normally expect to run another transaction. A valueof
On in this parameter will force the gateway to display
the ExitPage.
This will default to Off.
- A transaction may contain the character < , if it does
a Web browser would interpret this as an HTML tag. This
also allows the transaction to send valid HTML tags such
as picture references. If ImbedHTML is set to On then
tags will be passed, otherwise the browser will display
them as raw text.
This will default to Off.
- Some Web servers (for example Microsoft Internet
Information Server) require URLs which refer to CGI
programs to include a .EXE extension after the name
of the CGI program. If AppendEXE is set to On, then
when returning HTML, the gateway will append .EXE to
any URLs which refer to a CGI program.
This will default to Off.

[Override]
Header = C:\CICSCLI\cig\html\headtext.htm
Trailer = C:\CICSCLI\cig\html\tailtext.htm
ExitPage = /cig/cigstart.htm
ExitAid = 0x00
PFKey24 = Off
PAKeys = Off
GraphicKeys = Off
AutoExit = Off
ImbedHTML = Off
AppendEXE = Off

Figure 100 (Part 3 of 3). CICS Internet Gateway - CIGD.INI File for Windows NT

2. Configuring the Web server


This step is dependent upon which Web server you are using. We show you
what to do if you are using the Lotus Domino Go Webserver. You can also
find similar notes for the Netscape, NCSA and CERN servers in the
documentation provided by the CICS Internet Gateway.
You have to add to the Web servers configuration file the following paths:

124

Network Computing Framework for e-business Guide


LotusGo Webserver Windows NT file: WINNT\HTTPD.CNF
Exec
Exec
Pass

/cig-bin/*
/cig-admin/*
/cig/*

c:\cicscli\cig\cgi\*
c:\cicscli\cig\admin\*
c:\cicscli\cig\html\*

The above entries must be placed before the generic Pass directive
below, which already exist in the file.
Pass

/*

c:\www\html\*

LotusGo Webserver AIX

file: /etc/httpd.conf

Exec
Exec
Pass

/usr/lpp/cig/cgi/*
/usr/lpp/cig/admin/*
/usr/lpp/cig/html/prime/*

/cig-bin/*
/cig-admin/*
/cig/*

Where prime is the name of your locale. The above entries must be
placed before the generic Pass directive below, which already exist
in the file.
Pass

/*

/usr/lpp/internet/server_root/pub/*

You can protect the directory cig-admin so that requests for access to it will
require a user ID and password. For a simple setup, where the Web server
administrator and the CICS Gateway administrator are the same person, the
cig-admin directory may be protected by replicating and changing the
existing administrators protection in the Web server configuration file:


LotusGo Web Server Windows NT file: WINNT\HTTPD.CNF
Protect /admin-bin/*
Protect /cig-admin/*

LotusGo Web Server AIX

PROT-ADMIN
PROT-ADMIN

/* an existing line */
/* inserting line */

file: /etc/httpd.conf

Protect /cig-admin/* {
ServerId
Private_Authorization
AuthType
Basic
GetMask
A11@(*)
PutMask
A11@(*)
PostMask
A11@(*)
Mask
A11@(*)
PasswdFile
/usr/lpp/internet/server_root/Admin/Webadmin.passwd

3.1.2.3 Starting the CICS Gateway


When you have finished customizing your CICS gateway you will be ready to run
it. Following are instructions for starting the gateway on Windows NT and on
AIX:

Windows NT
The CICS gateway runs as a Windows NT service. To start it, open the
Window NT Control Panel application and click on the Services program.
Select IBM CICS Internet Gateway and click on the Start button. If you wish
to start it automatically every time that the machine is started, you have to
select Startup and change Startup Type to Automatic (shown in Figure 101
on page 126).

Chapter 3. Connectors

125

Figure 101. CICS Internet Gateway: How to Start It Automatically

AIX
The CICS gateway has to run as a user in the same primary group as the
Lotus Domino Go Webserver, not just a group set. (A group is a collection of
users than can share access authority to protect resources; a group set
specifies the groups in which the user is a member.)
Make sure that the LANG environment variable is exported to a suitable
value (for example, LANG=en_US) to have messages in the language that
you want.
To start it, enter: /usr/lpp/cig/bin/cigd &. Alternatively, you can add the
following entry to your /etc/inittab file after the Web server and DCE entries:

cig:2:wait:su gateway -c /usr/lpp/cig/bin/cigd > /dev/console 2>&1 &


This will start your CICS gateway each time you boot your system.
You can now test your environment by pointing your Web browser to:
http://Webaddress/cig/index.htm and http://Webaddress/cig/cigstart.htm.
We suggest that you leave cigstart.htm as it is. It provides examples of how to
query gateway settings, list the available CICS systems and start transactions in
different ways. It also has administration functions.
You can then train yourself and build your own start page as shown in
Figure 102 on page 127 and Figure 103 on page 127.

126

Network Computing Framework for e-business Guide

Figure 102. CICS Internet Gateway: Customized Initial Page

Figure 103. CICS Internet Gateway: Customized Header and Trailer HTMLs

3.1.2.4 Configuration
The CICS Internet Gateway requires the CICS client to send and receive its EPI
requests to a CICS server. The configuration that you set up should consist of a
Web server, CICS Internet Gateway and CICS client connected to the CICS
application servers.
If your CICS server does not support the CICS Client EPI (for example, the CICS
EPI function is available starting with CICS/ESA 4.1 in MVS/ESA or OS/390
operating system), you can bypass this problem with the following configuration:

Chapter 3. Connectors

127

Web server, CICS Internet Gateway, CICS Client and CICS server, on the same
machine as shown in Figure 104 on page 128. The client is connected to the
CICS application using the CICS Inter System Communication (ISC). The EPI
requests are sent from the CICS client to the CICS server installed in the same
system. It will then get routed to the other CICS servers using the CICS
transaction routing function. This requires a remote transaction definition.
Please refer to 3.1.2.5, Security for security considerations.
If the CICS application server does not support a TCP/IP connection with CICS
clients or another CICS server, you have to provide a Systems Network
Architecture (SNA) connection and SNA support on the Web server system.

Figure 104. CICS Internet Gateway: Configuration Scenario

3.1.2.5 Security
CICS Internet Gateway allows you to use your existing CICS security
environment generally based on an external security manager. An example of
this would be the IBM RACF product. CICS has its own built-in security. It uses
a sign-on table (SNT). The user has to invoke the CICS sign-on transaction
(CESN) at the first request, complete the security procedure and then they can
have access to the authorized CICS resources. If you implemented a CICS
server on the same machine that the CICS Internet Gateway and the CICS client
are installed, you should be aware that the sign-on requests will be processed
by that CICS server. This means that you have to download security profiles
from the CICS application servers and put them on the CICS server that has the
Web server. However, you have to define as remote transactions only the
transactions that you want to be accessed over the Web. The list of transactions
can be a subset of all your applications. In this case, the transactions that are
not defined as remote could not be executed. This could be considered a
security block that can reduce the effort to download all security profiles used in
the CICS application environment.
You may also want to use encryption for passwords and sensitive data. That
service is provided by the SSL function on the Web server.
If you are providing an Internet or extranet solution, you may also want to place
your Web server and CICS Internet Gateway outside your firewall.

128

Network Computing Framework for e-business Guide

3.1.2.6 How to Use CICS Internet Gateway


When you are designing a network computing solution you have to know what
type of users will use it:

Enterprise users - This means an intranet solution.

Partners - This means an extranet solution.

Internet users - This means anyone will have access to it.

This is important because a business partner or an Internet user requires


different access to your applications and data than an enterprise system user.
For example, you can not easily provide a list of CICS transaction codes and
provide training on each of them to nonenterprise users. (You can use a list box
to list the transactions, but it would not be easy to provide training for each of
the transactions.) We provide some examples of how to use the CICS Internet
Gateway to better explain this:

Map simple transactions to your Web browser


With the few examples we have shown, you can provide CICS transactions
using Web browsers for enterprise users. As the keyboard is emulated with
buttons that you click on, these types of solutions can be targeted to users
that have to perform just a few CICS transactions. You do not have to
provide any special connections. What your users need is a Web browser
and access to your intranet. The way to use existing CICS applications still
remains the same.

Minor customization
It is possible to provide an easy way to start new CICS transactions or add
hyperlinks to existing applications with some minor customization. This will
help extend the functions of an application. The way you do this is:

Start a predetermined transaction


For example, when a user clicks on the button Please click here to
perform identify process as shown in Figure 102 on page 127, they will
submit the CESN CICS logon transaction that you can see displayed in
Figure 103 on page 127. In Figure 105 on page 130 we show the HTML
that was used.

Chapter 3. Connectors

129

<!doctype html public html2.0>


<html>
<head>
<title>The CICS Internet gateway - Sample </title>
<meta name= abstract content= The CICS Internet gateway>
<meta name= copyright content= ( C)Copyright IBM Corporation, All Rights Reserved>
<meta name= keywords content= CICS gateway transaction>
<meta name= owner
content= saints@hursley.ibm.com>
<meta name= review
content=1995>
<meta name= security content= public>
</head>
<!-- end ibmhead--------------------------------------------------------- -->
<body>
<table>
<tr><th>
<td>
<h1>Welcome to the SunShine</h1>
</td>
<td>
<img src= / cig/smile.gif alt= Smile>
</td>
<td>
<h1>NCF Enterprise</h1>
</td>
</table>
<hr>
<p>This page gives you the access to our services.
<!**********************************************************************>
<!-- with a predetermined system and transaction
-->
<p>
<form method= post action= / cig-bin/cigcgi/StartTran>
<input type= hidden name= SystemName size=8 maxlength=8 value= CICSTCP> 1
<input type= hidden name= TranName size=4 maxlength=5 value= CESN >
2
<input type= submit value= Please click here to perform identify process>
3
</form>
<hr>
<!**********************************************************************>
<!-- end ibmbody--------------------------------------------------------- -->
</body>
</html>

Figure 105. CICS Internet Gateway - Start a Hidden Transaction

In 1 and 2(see Figure 105), you can see that the CICS system name
CICSTCP and the name of the transaction CESN, are hidden and
provided using the value parameter. The user can just click on the
Submit button to start the transaction 3.

Add Internet value


It is possible to add HTML tags that can add value to your application
with minor modifications to CICS maps or by inserting tags as part of the
data.
The parameter ImbedHTML is by default set to OFF, and the CICS
Internet Gateway will modify any < or > characters in the 3270 data
stream so that they are displayed as < or >.
If you have added HTML tags and you want the browser to take actions
based upon the tags, you will have to change the ImbedHTML value to
ON. That way, the HTML tags included in the CICS applications will be
sent to the Web browser unchanged.
Figure 105 shows you how you can modify a CICS map that is used in a
CICS host environment just by adding an HTML tag. It is important to
note that the map field has an attribute DRK. This lets other 3270 users
see the map unchanged and it also lets the Web browser have a link to
another page.

130

Network Computing Framework for e-business Guide

***************************************************************
* cicssda DDW1IT -- July 1996 Test Internet
***************************************************************
DDW1IT DFHMSD TYPE=&SYSPARM,MODE=INOUT,LANG=COBOL,STORAGE=AUTO, X
DSATTS=(COLOR,HILIGHT),MAPATTS=(COLOR,HILIGHT),
X
TIOAPFX=YES,COLOR=GREEN,HILIGHT=OFF
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
SUR3

DFHMDF POS=(5,44),LENGTH=15,JUSTIFY=(LEFT,ZERO),
ATTRB=(PROT,NORM)
DFHMDF POS=(5,60),LENGTH=1,JUSTIFY=(LEFT,ZERO),
ATTRB=(PROT,NORM)

DFHMDF POS=(6,07),LENGTH=72,JUSTIFY=(LEFT,ZERO),
ATTRB=(PROT,DRK),
INITIAL=<A HREF=http://ntncf120/Stories.html>
Employ Story</a>

X
X
X

DFHMDF POS=(07,20),LENGTH=11,JUSTIFY=(LEFT,ZERO),
ATTRB=(PROT,NORM),INITIAL= First name:

. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
DDW1IT DFHMSD TYPE=FINAL

Figure 106. CICS Internet Gateway - HTML Tags Added on CICS Map

Single transaction
A single transaction can provide the function that is required. An
example of this is if you have an inquiry or an order entry transaction
where the user has to insert a CICS transaction code and the data.
When it ends, the browse session could terminate. Another situation
where you can apply this solution is when a CICS application issues an
EXEC CICS RETURN without specifying the next transaction code. This
would always occur with pseudo-conversational transactions.
It is very simple to provide a multimedia menu that can start the
transaction directly without knowing every CICS transaction code and
how to complete the transactions. Using a Web browser lets you
potentially have one click of the mouse to get a result.
You can provide this service by setting the AutoExit parameter to ON and
setting the ExitPage parameter to permit the user to navigate between
CICS transactions without knowing transaction codes. In the screen
below we show the HTML form used to test the AutoExit parameter. The
results are shown in Figure 107 on page 132 and Figure 108 on
page 132. Clicking on the Please click here to continue link will retrieve
the default ExitPage shown in Figure 109 on page 132.

 <p>

<form method=post action= / cig-bin/cigcgi/StartTran>


<input type=hidden name=SystemName size=25 maxlength=99
value=CICSTCP>
<input type=hidden name=TranName size=25 maxlength=99
value=TTEE>
<input type=hidden name=AutoExit size=8 maxlength=8 value=On>
<input type=submit value=Schedule your CICS transaction>
</form>

Chapter 3. Connectors

131

Figure 107. CICS Internet Gateway: Click on to Start Your CICS Transaction

Figure 108. CICS Internet Gateway: CICS Transaction Response

Figure 109. CICS Internet Gateway: Default ExitPage

132

Network Computing Framework for e-business Guide

3.1.3 CICS Gateway for Java


The CICS Gateway for Java provides an interface between a Java program and a
CICS application. A Java applet running in a Java-enabled browser or network
computer can invoke existing CICS applications using the CICS client ECI and
EPI requests.
There are two main components involved:

Java classes
They run on the users computer and support ECI and EPI requests from a
local Java applet or application and they are dynamically downloaded at the
users request.
The gateway Java classes are:

GatewayRequest - Is the root class that all the different types of gateway
requests are built from. A user program cant create a GatewayRequest
object.

JavaGateway - Manages the connection between a program and a CICS


Gateway for Java. You will need a JavaGateway object for each gateway
that you wish to connect to (see 3.1.3.4, CICS Gateway for Java
Application Flow on page 143).

Callbackable - Defines the methods that a callback object must provide.


When an asynchronous call is complete, the user-supplied callback
object is called with the results of the asynchronous call.

ECIRequest - Contains the details of an ECI request for the gateway. To


execute the request, the ECIRequest object should be sent to the
gateway using the JavaGateway.flow method (see 3.1.3.4, CICS Gateway
for Java Application Flow on page 143).

EPIRequest - Contains the details of an EPI request for the gateway. To


execute the request, the ECIRequest object should be sent to the
gateway using the JavaGateway.flow method.

The first three classes are used to establish communication with the long
running gateway process using Javas socket protocol. ECIRequest and
EPIRequest are used to specify the CICS ECI and EPI calls that are sent to
the gateway.

Gateway
The CICS Gateway for Java is a long running process that must reside on
the same processor as the Web server (a Java security feature) and
supports multiple concurrent ECI or EPI requests from the Java client. The
gateway channels ECI and EPI calls through a CICS client to selected CICS
server applications. It is able to manage many communication links to the
connected browsers or network computers and controls asynchronous
conversations to the CICS server systems.
The gateway can communicate with CICS servers either on the same
processor or across a TCP/IP or SNA communication link provided by the
CICS client.

Since the CICS gateway is written in the Java programming language it can run
on any server platform that is Java-enabled and that supports the CICS client
interface. It is available on AIX, Windows NT, OS/2 and Sun Solaris and it will
soon be available on the S/390 platform.

Chapter 3. Connectors

133

The process is multithreaded and the sockets communication used by the


gateway is very efficient. It is able to support a large number of users. (In a test
OS/2 environment the gateway ran with 500 concurrently attached users, as is
reported at www.hursley.ibm.com/cics/internet/cicsgw4j/cjgate.html.)
You can download the CICS Gateway for Java for free from:
http://www.hursley.ibm.com/cics or http://service.software.ibm.com.
In Figure 110 you can see CICS Gateway for Java in a three-tier environment.

Figure 110. CICS Gateway for Java Overview

3.1.3.1 Installation
Before you download the IBM CICS Gateway for Java you have to check if your
environment has the minimum level of Java Development Toolkit (JDK) installed:

OS/2 - JDK 1.0.2

AIX - JDK 1.0.2 or 1.1.1

Windows NT - JDK 1.0.2 or 1.1.1

Sun Solaris SPARK - JDK/JIT 1.1.1 Native-threads

You also need to install one of the following CICS clients:

IBM CICS Client for OS/2 1.1 or later


If you have your Web server and CICS for OS/2 on the same workstation, you
do not require a CICS client.

IBM CICS Client for AIX 2.1.1 or later

IBM CICS Client for Windows NT V2 or later

IBM CICS for Solaris Client V.2.1.1.1

When you download CICS Gateway for Java, you obtain a compressed file that
will be a zip file for OS/2 and NT or a tar file for AIX and Solaris. You can place
this file anywhere, but all of the documentation refers to the JGATE directory as

134

Network Computing Framework for e-business Guide

being the root directory. When you expand it you will get a directory structure
similar to the one in Figure 111 on page 135.

Figure 111. CICS Gateway for Java Directory Structure

In the JGATE directory you will find a readme.txt file where you will find the
following important information:
Note: Unfortunately, a restriction has been discovered with the CICS client,
which effects the CICS Gateway for Java. In order to run concurrent ECI
and EPI requests via the CICS Gateway for Java you will need to open
two CICS gateways listening on different TCP/IP ports. You should then
make all ECI requests via one CICS gateway and all EPI requests via the
other CICS gateway. To specify the CICS gateway port use the -port
command line option as described in the product documentation. This
restriction applies on all supported platforms.
All documentation is provided in HTML form and includes:

CICS Gateway for Java User s Guide

CICS Gateway for Java Technical Information


Chapter 3. Connectors

135

CICS Gateway for Java Programming Guide

To complete the installation you have to open the


http://Webserver/jgate/html/doc/index.html file and click on Read the CICS
Gateway for Java User Guide.
Following the user guide, the next step is to configure your Web server inserting
the directory where you installed the CICS Gateway for Java, and add
JGATE/classes to your CLASSPATH environment if you wish to compile or run
Java applications. You can see these two steps documented in the following
screens:

Web Server
Pass

/jgate/*

e:\jgate\*

 Setting

Classpath

c:\set classpath
CLASSPATH=c:\jdk1.1.3\lib\classes.zip;e:\jgate;e:\jgate\classes;

3.1.3.2 Starting and Stopping the CICS Gateway for Java


You can start the CICS Gateway for Java from a command prompt window.
There are three different ways to do so:
1. Start it using the default options
Select your directory JGATE/bin/ [ platform ] and type JGate at your command
prompt and press Enter (see Figure 112).

Figure 112. CICS Gateway for Java: Start with the Default Options

2. Start it with user options


You can override the default options during the start command as shown in
Figure 113 on page 137.

136

Network Computing Framework for e-business Guide

Figure 113. CICS Gateway for Java: Start with the User Options

3. Get help on the startup options


Select your directory JGATE/bin/ [ platform ] and type JGate ? at your
command prompt and press Enter. You can see the results of the help
command and all the options that you can override in Figure 114.

Figure 114. CICS Gateway for Java: Get Help on the Startup Options

You can store your start command in a file and associate it with an icon or
shortcut to avoid typing it in often, as shown in Figure 115 on page 138.

Chapter 3. Connectors

137

Figure 115. CICS Gateway for Java: Start Command Using an Icon

To stop your CICS Gateway for Java you have to select its console session. Then
type Q and press Enter. This is possible if you have started the gateway with the
default option or if you did not select the -noinput option. If you selected the
-noinput option, this disables the CICS Gateway for Java application from
reading any input from the console. You have to choose another method. For
example:

138

Ctrl+C in the gateway console for NT and OS/2

Use the Task Manager in Windows NT

Use the kill command in AIX

Network Computing Framework for e-business Guide

3.1.3.3 Testing Your CICS Gateway for Java


Now you can test your CICS Gateway for Java to verify that all components work
correctly.
The first test could be running the demo distributed with the gateway. You have
to link your Web server using http://Webserver/jgate/html/doc/index.html (this is
to be able to check if your Web server is configured for the gateway) and select
Explore the CICS Gateway for Java demo. From there you can run the demo in
stand-alone mode to test your environment as shown in Figure 116. If you
choose to try the version where you are connected to the network, it will link you
to the IBM Hursley laboratory to run the demo.

Figure 116. CICS Gateway for Java: Stand-Alone Catalog Demo

To test your entire environment, including CICS client and CICS server
components, you have to select Read the CICS Gateway for Java Programming
Guide from jgate/html/doc/index.html. This section explains how to write a Java
applet that includes the gateway classes and two sample programs: TestECI and
TestEPI.
TestECI is a sample program that allows you to test the functions of the CICS
Gateway for Java by sending one or more ECI requests to a CICS server. Be
aware that TestECI does not pass the CICS COMMAREA to the called program,
so you have to modify it to display the COMMAREA data in output report. The
source for TestECI is provided in the directory jgate/java/ibm/cics/jgate/test.
To run the sample you can use your Java-enabled browser or start it as an
application. The parameters that you need to pass to the TestECI program

Chapter 3. Connectors

139

depends on how you plan to implement it. The parameters that you can set for
the program are shown in the screen below:

<applet code=TestECI
<param name=jgate
<param name=jgateport
<param name=server
<param name=userid
<param name=password
<param name=prog0..9
<param name=status
<param name=trace
</applet>

... ... >


value=jgate_server>
value=jgate_port>
value=cics_server>
value=cics_userid>
value=cics_password>
value=prog_name>
value=yes>
value=yes>

You can see the output of EciTest run as an application and the parameters used
in Figure 117. The same process that was run in a browser session is shown in
Figure 118 on page 141 with the HTML page source in Figure 119 on page 142.

Figure 117. CICS Gateway for Java: TestECI Program Running As an Application

140

Network Computing Framework for e-business Guide

Figure 118. CICS Gateway for Java: TestECI Program Running in a Browser

Chapter 3. Connectors

141

Figure 119. CICS Gateway for Java: HTML Used to Run TestECI Program

TestEPI is a sample that allows you to test one or more EPI requests with a CICS
server. The source of TestEPI and the classes that it invokes, RequestDetails
and EPIStrings, are available in the jgate/java/ibm/cics/jgate/test directory where
you can also find the sample HTML page, testepi.html.
You can run TestEPI from your browser or from an appletviewer using the same
testepi.html file. It presents a panel where you have to provide some
information:

Java Gateway Name - The TCP/IP address or the host name where your
CICS Gateway for Java runs.

Java Gateway Port - TestEPI starts port 2006 (the default port used by the
gateway). You can override this default with the port that you have defined.
If it is wrong, you will receive the following error message when you try to
connect:

CCL6551E : Unable to connect to Gateway. [address=...,port = ... ]


[java.net.ConnectException: Connection refused]

142

CICS Server Name - If it is not provided, the default CICS server that is
defined in the CICSCLI.INI configuration file will be used. If it is provided,
this must be a CICS server that your CICS client can connect to.

CICS Server device type - This is an important parameter, because it is the


device type that will be used during the EPI request. Your CICS server has
to recognize it in order to install the relative terminal correctly. In our
environment we used ibm-cics-client.

Network Computing Framework for e-business Guide

After you have provided all the input fields you can select one of the two
following options:

List CICS servers (the default option)

Run Transaction CECI

When you click the Execute EPI request button, the TestEPI program will start a
new thread that will show you the results of any actions that the program made.
You can see the an example of TestEPI using the appletviewer command
appletviewer testepi.html in Figure 120.

Figure 120. CICS Gateway for Java: TestEPI Program Running in an Appletviewer

3.1.3.4 CICS Gateway for Java Application Flow


In this section we describe in more detail how to use Java classes, described in
3.1.3, CICS Gateway for Java on page 133, and how to design a Java applet
that links to an existing CICS application. To do that we use the two Java
programs TestECI and TestEPI that are distributed with the CICS Gateway for
Java. We also use parts of its source to show you the linkage between the
program flow and the statements.
The simplest way to use the CICS Gateway for Java classes is to link a CICS
program using an ECI call. See Figure 121 on page 144 for the following
references:

The Java program creates an instance of an


ibm.cics.jgate.client.JavaGateway object. 1
This class has two methods: close() to close the connection to the CICS
Gateway for Java and flow() to flow the specified GatewayRequest to the
CICS Gateway for Java and then wait for the reply.

Chapter 3. Connectors

143

The Java program creates an instance of an ibm.cics.jgate.client.ECIRequest


object containing the request that it wishes to make. This class extends the
GatewayRequest. 2

The program then sends the request to the CICS Gateway for Java using the
flow method of the Java object. 3

The Java program checks the return code of the flow operation to verify if
the request was successful. 4

The Java program closes the JavaGateway object using the close method of
JavaGateway class. 5

/************************************************************************/
/*
*/
/* STATEMENT
Licensed Materials - Property of IBM
*/
/*
(C) Copyright IBM Corporation 1996
*/
/*
See Copyright instructions.
*/
/*
All rights reserved.
*/
/*
U.S. Government Users Restricted Rights - use, */
/*
duplication or disclosure restricted by GSA
*/
/*
ADP Schedule Contract with IBM Corp.
*/
/*
*/
/*
NOTICE TO USERS OF THE SOURCE CODE EXAMPLES
*/
/*
*/
/* AUTHOR
Andrew R. Dean
*/
/* STATUS
Version 1.0
*/
/* NOTES
This is a general sample to demonstrate the basic */
/*
functions of the CICS Gateway for Java
*/
/*
*/
/************************************************************************/
package ibm.cics.jgate.test;
import ibm.cics.jgate.client.*;
import
import
import
import

java.net.*;
java.io.*;
java.awt.*;
java.applet.*;
/*
* Create a new JavaGateway to use
*/

1 jgaConnection = new JavaGateway(strJGateName, iJGatePort);


displayMsg(Successfully created JavaGateway\n ) ;
/*
* Find out what systems are available
*/
eciRequest = ECIRequest.listSystems(10);
3 jgaConnection.flow(eciRequest);
displayMsg(=== Available Servers ===\n ) ;
4 if (eciRequest.getRc() == 0)
{
displayMsg(=== Call Programs ===\n ) ;

Figure 121 (Part 1 of 3). CICS Gateway for Java: TestECI Java Source Sample

144

Network Computing Framework for e-business Guide

2

eciRequest =
new ECIRequest(strServerName, // CICS Server
strUserId,
// UserId, null for none
strPassword, // Password, null for none
null,
// Program name
null,
// Commarea, null for none
ECIRequest.ECI_NO_EXTEND,
ECIRequest.ECI_LUW_NEW);
for (int iCallLoop = 0; iCallLoop < iNoOfProgNames;
iCallLoop++)
{
eciRequest.Cics_Rc = 0;
/*
* Set the program name in the eciRequest
*/
eciRequest.Program = astrProgNames[iCallLoop];
/*
* Set ECI_NO_EXTEND on the last call only, otherwise
* set ECI_EXTENDED
*/
eciRequest.Extend_Mode =
(iCallLoop == (iNoOfProgNames - 1)) ?
ECIRequest.ECI_NO_EXTEND :
ECIRequest.ECI_EXTENDED;
/*
* Flow the request via the JGate to CICS
*/
displayMsg(About to call : + eciRequest.Program);
displayMsg( Extend_Mode : + eciRequest.Extend_Mode);
displayMsg( Luw_Token : + eciRequest.Luw_Token);

3

jgaConnection.flow(eciRequest);
displayMsg(Return code
displayMsg(Abend code

: + eciRequest.Cics_Rc);
: + eciRequest.Abend_Code);

}
}
}

Figure 121 (Part 2 of 3). CICS Gateway for Java: TestECI Java Source Sample

finally
{
try
{
if (jgaConnection != null)
{
jgaConnection.close();
displayMsg(Successfully closed JavaGateway ) ;
}
}
catch (IOException eClose)
{
displayMsg(Exception during close : + eClose);
}

5

}
}

Figure 121 (Part 3 of 3). CICS Gateway for Java: TestECI Java Source Sample

To integrate a 3270 CICS existing application we have to use an EPI call and the
Java applet acts like a terminal to CICS. This requires you to be aware of the

Chapter 3. Connectors

145

3270 data streams that may flow from CICS and the 3270 data streams that the
CICS application expects to receive. It also important to be aware of the rules
that govern native CICS client EPI programming and the differences that exist
when you invoke a CICS transaction on different platforms. When getting events
from CICS it is recommended that you use the EPI_WAIT option, and ensure that
the EPIRequest objects field size is set to the maximum size of the 3270 data
stream that CICS may return.
An EPI program written using the CICS Gateway for Java generally follows the
steps outlined in Figure 122 on page 147. The steps are:
1. Open a connection to the gateway. 1
2. Add a terminal. 2
3. Start a transaction. 3
4. Get events until either the event received is an end transaction, a converse,
or a severe error. 4
5. If the event received is a converse, then send the reply and return to the get
event loop. 5
6. If the event received is an end transaction, delete the terminal and one more
get event to obtain the end terminal event. 6
7. Close the connection to the gateway. 7

146

Network Computing Framework for e-business Guide

/************************************************************************/
/*
*/
/* STATEMENT
Licensed Materials - Property of IBM
*/
/*
(C) Copyright IBM Corporation 1996
*/
/*
See Copyright instructions.
*/
/*
All rights reserved.
*/
/*
U.S. Government Users Restricted Rights - use, */
/*
duplication or disclosure restricted by GSA
*/
/*
ADP Schedule Contract with IBM Corp.
*/
/*
*/
/*
NOTICE TO USERS OF THE SOURCE CODE EXAMPLES
*/
/*
*/
/* AUTHOR
Emma Eldergill
*/
/* STATUS
Version 1.1.1
*/
/* NOTES
This is a general sample to demonstrate the EPI */
/*
class of the CICS Gateway for Java
*/
/*
*/
/************************************************************************/
package ibm.cics.jgate.test;
import ibm.cics.jgate.client.*;
import
import
import
import
import

java.net.*;
java.io.IOException;
java.awt.*;
java.util.Vector;
java.applet.*;

//*---------------------------------------------------------------------------//* Class : TestEPI


/** Run as an applet
*/
//*---------------------------------------------------------------------------public class TestEPI extends Applet implements Runnable
1 jgaTest

= new JavaGateway(strJGateName, iJGatePort);

strMessage = strStatus + Thread.currentThread().getName() +


: new JavaGateway() connection\n ;
displayMsg(strMessage);
/*
* Invoke EPIRequest Static method to construct an EPIRequest Object
* (suitable for adding a terminal)
*/
2 epiReq = EPIRequest.addTerminal(strServer,strNetName,strDeviceType);

Figure 122 (Part 1 of 7). CICS Gateway for Java: TestEPI Java Source Sample

Chapter 3. Connectors

147

/*
* Flow the addTerminal request
*/
jgaTest.flow(epiReq);
strRC = EPIStrings.getStringRC(epiReq.Cics_Rc);
strMessage = strStatus + Thread.currentThread().getName() +
: addTerminal() RC = + strRC + , termIndex =
+ epiReq.termIndex + \n ;
displayMsg(strMessage);
/*
* If RC = OK
*
Flow the startTran request
*/

3

if (epiReq.Cics_Rc == EPIRequest.EPI_NORMAL)
{
epiReq.startTran(strTransid,abytData,iSize);
jgaTest.flow(epiReq);
strRC = EPIStrings.getStringRC(epiReq.Cics_Rc);
strMessage = strStatus + Thread.currentThread().getName() +
: startTran() RC = + strRC + , termIndex =
+ epiReq.termIndex + \n ;
displayMsg(strMessage);
}
else
{
bLoop
= false;
bDelTerm = false;
}
/*
* Note: the startTran() Cics_Rc may be EPI_NORMAL but the transid
* not recognised, therefore it may be necessary to scan the next
* getEvent() data to see whether
* it says that the transaction id was not recognized.
*/
/*
* Create loop getting events until get to END_TRAN event
* CECI is a conversational task on OS/2.
*/
while (bLoop)
{
if ( epiReq.Cics_Rc
|| epiReq.Cics_Rc
|| epiReq.Cics_Rc
|| epiReq.Cics_Rc
{

==
==
==
==

EPIRequest.EPI_NORMAL
EPIRequest.EPI_ERR_MORE_DATA
EPIRequest.EPI_ERR_MORE_EVENTS
EPIRequest.EPI_ERR_NO_EVENT)

Figure 122 (Part 2 of 7). CICS Gateway for Java: TestEPI Java Source Sample

148

Network Computing Framework for e-business Guide

4

getNextEvent(jgaTest,epiReq);
if (epiReq.event == EPIRequest.EPI_EVENT_END_TRAN)
{
bLoop = false;
if (epiReq.Transid != null)
{
if ( ! (epiReq.Transid.equals(
)) )
{
strMessage = strStatus
+ Thread.currentThread().getName()
+ : Pseudoconversation, next Transid =
+ epiReq.Transid + \n ;
displayMsg(strMessage);
}
}
}
else if (epiReq.event == EPIRequest.EPI_EVENT_CONVERSE)
{
replyFlow(jgaTest,epiReq);
}
}
else
{
bLoop = false;
}

5

}
}
catch (IOException exIO)
{
strMessage = strStatus + Thread.currentThread().getName() +
: Error: IOException\n ;
displayMsg(strMessage);
strMessage = strStatus + Thread.currentThread().getName() +
: Error details: + exIO.getMessage() + \n ;
displayMsg(strMessage);
}
finally
{
/*
* If we are not in the middle of a transaction then we can delete
* the terminal.
* Flow the delTerminal request
* Close the connection
*/

Figure 122 (Part 3 of 7). CICS Gateway for Java: TestEPI Java Source Sample

Chapter 3. Connectors

149

try
{
if (jgaTest != null)
{
if (bDelTerm)
{
strMessage = strStatus + Thread.currentThread().getName() +
: about to delete Terminal \n ;
displayMsg(strMessage);
6

epiReq.delTerminal();
jgaTest.flow(epiReq);
strRC = EPIStrings.getStringRC(epiReq.Cics_Rc);
strMessage = strStatus + Thread.currentThread().getName() +
: delTerminal() RC = + strRC + \n ;
displayMsg(strMessage);
/*
* Get the EPI_EVENT_END_TERM event or the termIndex
* value will keep incrementing
*/
getNextEvent(jgaTest,epiReq);
if (epiReq.event == EPIRequest.EPI_EVENT_END_TERM)
{
strMessage = strStatus + Thread.currentThread().getName()
+ : received END_TERM event\n ;
displayMsg(strMessage);
}
else
{
strMessage = strStatus + Thread.currentThread().getName()
+ : Error, did not receive END_TERM event\n ;
displayMsg(strMessage);
epiReq.Cics_Rc = 99;
}
if (epiReq.Cics_Rc == 0)
{
bOK = true;
}
}

Figure 122 (Part 4 of 7). CICS Gateway for Java: TestEPI Java Source Sample

150

Network Computing Framework for e-business Guide

7

jgaTest.close();
strMessage = strStatus + Thread.currentThread().getName() +
: closed JavaGateway connection\n ;
displayMsg(strMessage);
}
}
catch (IOException exIO)
{
strMessage = strStatus + Thread.currentThread().getName() +
: Error during cleanup: IOException\n ;
displayMsg(strMessage);
strMessage = strStatus + Thread.currentThread().getName() +
: Error during cleanup details: + exIO.getMessage() + \n ;
displayMsg(strMessage);
}
}
return bOK;
}
/*-----------------------------------------------------------------/*
Method : getNextEvent
/** Invoke EPIRequest s getEvent method, and flow() this request
*/---------------------------------------------------------------public void getNextEvent(JavaGateway jgaTest, EPIRequest epiRequest)
throws IOException
{
String strMessage;
String strRC;
String strEvent;
int iWaitState = EPIRequest.EPI_WAIT;
int iSize
= 2000;
try
{
epiRequest.getEvent(iWaitState,iSize);
jgaTest.flow(epiRequest);
/*
* If the event is a SEND or CONVERSE
*
then there may be data with it
*
(check the size to see there is)
*/
if ( epiRequest.event == EPIRequest.EPI_EVENT_SEND
|| epiRequest.event == EPIRequest.EPI_EVENT_CONVERSE )
{

Figure 122 (Part 5 of 7). CICS Gateway for Java: TestEPI Java Source Sample

Chapter 3. Connectors

151

strRC
= EPIStrings.getStringRC(epiRequest.Cics_Rc);
strEvent = EPIStrings.getStringEvent(epiRequest.event);
strMessage = strStatus + Thread.currentThread().getName() +
: getEvent() RC = + strRC + , event = + strEvent +
, size of datastream returned = + epiRequest.size + \n ;
displayMsg(strMessage);
GatewayTrace.hexDump(epiRequest.data, datastream array ) ;
}
else
{
strRC
= EPIStrings.getStringRC(epiRequest.Cics_Rc);
strEvent = EPIStrings.getStringEvent(epiRequest.event);
strMessage = strStatus + Thread.currentThread().getName() +
: getEvent() RC = + strRC + , event = + strEvent + \n ;
displayMsg(strMessage);
}
}
catch (IOException exIO)
{
throw exIO;
}
}
//------------------------------------------------------------------------/*
Method : replyFlow
/** Invoke EPIRequest s sendReply method, and flow() this request
*///----------------------------------------------------------------------public void replyFlow(JavaGateway jgaTest, EPIRequest epiRequest)
throws IOException
{
String strMessage;
String strRC;
/* byte array for 3270 data stream (in ASCII) */
byte[] abytData = new byte[3];
int iSize

= 3;

/* Create exit datastream */


/*
* AID
= 0x33 (F3)
* Cursor = 0x20 0x20
*/
abytData[0] = (byte) 0x33; // ASCII F3
abytData[1] = (byte) 0x20; // ASCII row 1
abytData[2] = (byte) 0x20; // ASCII column 1

Figure 122 (Part 6 of 7). CICS Gateway for Java: TestEPI Java Source Sample

152

Network Computing Framework for e-business Guide

/*
* Flow the sendReply (to exit the task)
*/
try
{
epiRequest.sendReply(abytData,iSize);
jgaTest.flow(epiRequest);
strRC = EPIStrings.getStringRC(epiRequest.Cics_Rc);
strMessage = strStatus + Thread.currentThread().getName() +
: sendReply() RC = + strRC + , termIndex =
+ epiRequest.termIndex + \n ;
displayMsg(strMessage);
}
catch (IOException exIO)
{
throw exIO;
}
}

Figure 122 (Part 7 of 7). CICS Gateway for Java: TestEPI Java Source Sample

3.1.3.5 CICS Gateway for Java Values


This solution combines the strengths of Java and CICS family functions to
provide robust, flexible and scalable solutions for business-critical Internet
applications.
Since Java applets are downloaded dynamically, all new applets or new versions
of the existing applets are automatically placed in service by end-user requests.
This is one of the most important advantages of the Java architecture that
reduces or eliminates the need for software distribution. That is a major problem
in most client/server architectures.
Security is provided using either Java, CICS or both. For example, each ECI call
can use a user ID and password. Since the browser maintains a continuous
connection during a Logical Unit of Work (LUW), the conversational state can be
maintained by the server application. Communications from applet to CICS
Gateway for Java is based on Java-to-Java sockets that can use all the security
functions that the Java architecture supports or will support in the future (as
secure sockets).
Java uses TCP/IP to communicate but the CICS client can communicate to CICS
servers across SNA, TCP/IP or NetBIOS. A single gateway can communicate
through a CICS client over multiple protocols to multiple servers as required by
the server.
The gateway is a long running process that can manage multiple requests from
its clients. It does not have the overhead of creating one process for every
request, as CGI solutions do (see Chapter 2, Servlets on page 11). It
maintains a pool of threads, which services the connecting applets. ECI and EPI
requests flow from the gateway to the CICS client and to the CICS servers
across never-ending connections. The CICS ECI and EPI classes are very small.
This minimizes the time to download applets and the storage required in the
browsers cache. (Caching applets in the browser reduces the frequency of
downloading them.) The lack of user code on the Web server and the large
capacity of the gateway offer better performance than standard CGI solutions.
Chapter 3. Connectors

153

This is discussed further in 3.1.2, CICS Internet Gateway on page 116. The
CICS Gateway for Java offers scalable solutions. It is possible to use multiple
gateways as a front-end to single or multiple application servers as shown in
Figure 123 on page 154.
The Java architecture guarantees the portability of applets across all platforms
and browsers that support Java. This also applies to the CICS Java classes.
CICS Gateway for Java requires you to develop applets that will manage the
presentation logic and will make ECI and EPI calls to the existing applications.
Java offers powerful GUI support and application development tools. VisualAge
for Java includes support to CICS Java classes.

Figure 123. CICS Gateway for Java: Scalability and Access to Multiple Systems

3.1.4 MQSeries Internet Gateway


The MQSeries Internet Gateway provides a bridge between the Internet and
MQSeries applications. This solution is very interesting because it combines the
synchronous requests coming from the Web with the asynchronous messaging
and queueing application model implemented by MQSeries products. It allows
you to maintain separate environments and provide flexible and robust
integration at the same time. Another interesting aspect is due to the MQSeries
products that are available on more than 20 different platforms. This lets you
integrate applications that reside on those platforms even if they do not have
Internet or intranet solutions available. MQSeries Messaging Queueing Interface
(MQI) is available for a large number of application environments and it is easy
to integrate them into the Internet or intranet. This is especially true if they don t
have any other interface available to do that. For example, you can receive
incoming data from the Internet and combine that with messages that were
stored by MQSeries in queues. You can take the resulting information and
process it in a batch job on MVS to build a reply to be sent to the user.

154

Network Computing Framework for e-business Guide

The MQSeries Internet Gateway can be installed on systems that are running
MVS, AIX, OS/400, Sun Solaris, OS/2 or Windows NT, and support the CGI, ICAPI
and NSAPI Web server interfaces.
For more information about MQSeries architecture, products and solutions you
can go to http://www.hursley.ibm.com/mqseries. Figure 124 shows a typical
MQSeries Internet scenario.

Figure 124. MQSeries Internet Gateway: Typical Scenario

3.1.4.1 Installing MQSeries Internet Gateway


The MQSeries Internet Gateway is available from the Internet at
http://www.hursley.ibm.com/mqseries or http://www.software.ibm.com/ts. The
documentation is in HTML and it is included in the MQSeries Internet Gateway
package.
The installation of the gateway is dependent upon the operating system that you
will install it on. We show the installation steps for Windows NT and AIX
platforms.

Windows NT
1. Shut down the Web server that you want to use with the MQSeries
Internet Gateway.
2. Unpack the mqignt.zip file that you have downloaded. This will create a
directory called mqignt, which contains the files needed to install the
gateway code.
3. Run the setup.exe program in the mqignt directory. A set of panels will
guide you through the installation procedures. At the end the MQSeries
Internet Gateway is installed into the dmqgate directory.

AIX
1. Shut down your Web server before starting the installation procedure
using the command: stopsrc -s httpd.
2. Unpack the mqigaix.tar file that you have downloaded using: tar -xvf
mqigaix.tar. The result will be a dmqgate100.img file extracted into the
current directory.
3. To install the gateway files on your Web machine you have to use the
smitty command.

Chapter 3. Connectors

155

Log in as root.

Run smitty.

Choose Software Installation and Maintenance.

Choose Install and Update Software.

Choose Install/Update Selectable Software (Custom Install).

Choose Install Software Products at Latest Level.

Choose Install New Software Products at Latest Level. When


prompted, enter the full path to the directory containing
dmqgate100.img and press Enter.

Accept the default options and press Enter to start the installation.

4. To enable the Web server to access MQ resources, its user name must
be included in the mqm group. You can use a name that already exists
in your mqm group or you can create a new one dedicated to your Web
server and add it to the group. You have to stop and start your queue
manager using that user.
At this point you have to configure your Web server. This procedure depends
upon which Web server you are using. We show you how to configure a Lotus
Domino Go Webserver product. You can find the same type of information for
Netscape and Microsoft Internet Information Server in the user s guide in:
file:/// [ dmqgate disk ] /dmqgate/doc/index.htm


LotusGo Webserver Windows NT
Exec
Pass

/dmq-bin/*
/dmq/*

file: WINNT\HTTPD.CNF

c:\dmqgate\bin\*
c:\dmqgate\doc\*

The above entries must be placed before the generic Pass directive
below, which already exist in the file.
Pass

/*

LotusGo Webserver

c:\www\html\*

Exec
Pass

AIX

/dmq-bin/*
/doc/*

file:

/etc/httpd.conf

/usr/lpp/dmqgate/bin/*
/usr/lpp/dmqgate/doc/*

Where prime is the name of your locale. The above entries must be
placed before the generic Pass directive below, which already exist
in the file.
Pass

/*

/usr/lpp/internet/server_root/pub/*


Now you can restart your Web server.

156

Network Computing Framework for e-business Guide

3.1.4.2 Testing the Installation


The MQSeries Internet Gateway provides a sample that requires you to define
some resources on your queue manager. If you have MQSeries running on your
machine, you have to use the runmqsc command to add the resources. Select
the dmqgate\samples directory and insert the following command:

runmqsc <dmqsamp.tst> dmqsamp.out


In the dmqsamp.out file you can verify the result of the command, as shown in
Figure 125.

29H1019,5697-177 (C) Copyright IBM Corp. 1994, 1995. ALL RIGHTS RESERVED.
Starting MQSeries Commands.
: ********************************************************************/
: *
*/
: * Program name: DMQSAMP.TST
*/
: *
*/
: ********************************************************************/
:
1 :
DEFINE QLOCAL( DMQGATEWAY ) REPLACE +
:
DESCR( Gateway Queue )
AMQ8006: MQSeries queue created.
:
2 :
DEFINE QLOCAL( DMQSAMP1 ) REPLACE +
:
DESCR( Queue for sample Serving Application 1 - wrap )
AMQ8006: MQSeries queue created.
:
: ********************************************************************/
: *
*/
: * END OF DMQSAMP.TST
*/
: *
*/
: ********************************************************************/
2 MQSC commands read.
0 commands have a syntax error.
0 commands cannot be processed.

Figure 125. MQSeries Internet Gateway: Defining MQ Resources for the Sample

Now you are ready to test your environment. Start the Web browser and:

Select http://Webserver/dmq/index.htm to verify your Web server definition.

Click on MQSeries Internet Gateway Users Guide.

Click on Entering your MQSeries message on an HTML form which is a


subtopic of Using MQSeries Internet Gateway.

There is a sample written for the CGI, ICAPI and NSAPI Web server interface.
The sample lets you fill in a form that will be sent to the MQSeries queue
DMQSAMP1. That is read by a back-end program DMQSAMP1. You can find the
back-end program in the c:\dmqgate\samples directory. To start it you have to
enter the following command:

dmqsamp1 DMQSAMP1 qmgr-name


DMQSAMP1 is the name of the queue where the gateway will insert its message.
The gateway expects to retrieve the answer in the queue called DMQGATEWAY.
As you can see in Figure 126 on page 158 the form is a survey application you
have to fill in and then click the Submit button.

Chapter 3. Connectors

157

Figure 126. MQSeries Internet Gateway: DQSAMP1 Process Input Form

The back-end program reads data coming from the Web and writes a response
to a reply queue using MQSeries API calls. The message sent back to the
browser contains all of the HTTP parameters and data used in this sample. This
is shown in Figure 127 on page 159, Figure 128 on page 160 and Figure 129 on
page 161.

158

Network Computing Framework for e-business Guide

Figure 127. MQSeries Internet Gateway: DQSAMP1 Process Output Form (1 of 3)

Chapter 3. Connectors

159

Figure 128. MQSeries Internet Gateway: DQSAMP1 Process Output Form (2 of 3)

160

Network Computing Framework for e-business Guide

Figure 129. MQSeries Internet Gateway: DQSAMP1 Process Output Form (3 of 3)

Chapter 3. Connectors

161

Figure 130. MQ Internet Gateway: DQSAMP1 Process Output Form without Context

3.1.4.3 Configuring the MQSeries Internet Gateway


To configure your MQSeries Internet Gateway you can modify the default
parameters provided in [ dmqgatedisk ] /dmqgate/bin/dmq.ini or build a new
configuration file with your own values.
To change the value of the keywords in dmq.ini or to create a new configuration
file you have to use a configurator program (see Figure 131 on page 163 and
Figure 132 on page 164), which is supplied with MQSeries Internet Gateway.
You have to insert your keyword, value and descriptions in the input fields. They
will get stored in the configuration file. To store your updates, you have to click
on the Apply button. If you want delete a keyword stored in the configuration
file, you have to select the Delete box corresponding to the keyword and click on
the Apply button.
Note: It is not recommended for you to use the regular editor to modify the
configuration file, as to avoid the possibility that it corrupt the format of
the configuration file.

162

Network Computing Framework for e-business Guide

Figure 131. MQ Internet Gateway: Configurator Program New Configuration File

Chapter 3. Connectors

163

Figure 132. MQ Internet Gateway: Configurator Program Default DMQ.INI File

The MQSeries Internet Gateway keywords available are:

164

MQIGwQueue - Is the queue name where the Internet Gateway writes the
messages using the MQI MQPUT call.

MQIGwReplayQueue - Is the queue name where the Internet Gateway


retrieves the reply messages.

MQIGwQueueManager - Is the name of MQSeries queue manager that is to


be used.

MQIGwWaitInterval - Is the time that the Internet Gateway should wait for a
reply.

MQIGwWaitHTML - Is the name of the HTML page that gets displayed if a


timeout occurs. In this page you should provide information to the user
about what has happened and a button to enable him or her to retrieve reply
messages later. There is an example on how to do that at
[ dmqgatedisk ] /dmqgate/bin/timedout.htm.

MQIGwContext - Which context information should be sent to the application:

None - None of the contextual information is passed to the serving


application. The result of the example survey form (see Figure 126 on
page 158) with MQIGwContext (set to none) is shown in Figure 130 on
page 162.

All - All the contextual information is passed to the service application.


You can see the entire list in Figure 127 on page 159 through Figure 129

Network Computing Framework for e-business Guide

on page 161, or you can refer the MQSeries Internet Gateway


documentation.

MQIGwIniFile - Is the name of the INI file used to hold the parameter s
values.

The value of these keywords could be provided in the following ways:


1. All keywords are provided in the HTML form that is used to send messages.
This is the only way to provide your own configuration file (setting the
MQIGwIniFile parameter) as shown in Figure 133.
2. All the values are stored in your configuration file.
3. The default values are supplied in the dmq.ini file. Note that the default
values are provided for the following parameters:

MQIGwReplayQueue = DMQGATEWAY

MQIGwWaitInterval = 10000 (milliseconds)

MQIGwContext = All

The MQSeries Internet Gateway searches the values using the following order:
1. HTML form
2. Configuration file defined using the MQIGwIniFile keyword
3. dmq.ini file
Only one keyword can be set for the values listed above. To avoid unpredictable
results, only set one of the values.

<HEAD>
<TITLE>NCF MQSeries Internet Gateway CGI Sample</TITLE>
</HEAD>
<HR>
<H3>Sample Form</H3>
<P>Click on <b>Submit</b> to run the CGI sample.</P>
<center><h3>Example Survey of Internet Browsers</h3></center>
<FORM ACTION= / dmq-bin/dmqcgi METHOD=POST>
<INPUT NAME=MQIGwQueue TYPE=hidden VALUE=DMQSAMP1>
<INPUT NAME=MQIGwWaitInterval TYPE=hidden VALUE=10000>
<INPUT NAME=MQIGwIniFile TYPE=hidden value=ncfdmq.ini>
<INPUT NAME=MQIGwWaitInterval TYPE=hidden value=ncftime.htm>
</FORM>
</BODY>
</HTML>
Figure 133. MQ Internet Gateway: Sample Form with Provided Keywords

When the keyword MQIGwWaitInterval is set, you have to provide a reply retry
form that will be displayed when the wait interval expires. If you dont supply
your own form, the sample timedout.htm form will be used. It is stored in the
[ dmqgatedisk ] /dmqgate/bin directory. If you write your own reply form, you can
use any style but you must include the following FORM tag:

Chapter 3. Connectors

165

 <FORM

ACTION= / dmq-bin/dmqcgi METHOD=POST>


<i><INPUT TYPE=submit NAME=dmqretry VALUE= Retry ></i>
</FORM>

You can modify only the following form areas:

The message area.

The VALUE attribute on the INPUT button to display a word or sentence of


your choice.

The ACTION attribute on the FORM tag to match the Web server interface
that you are using as shown in the following table.

Table 2. MQS Internet Gateway: Web Server Interface Available


Web server interface

ACTION

CGI

/dmq-bin/dmqcgi

ICAPI

/dmq-bin/dmqicapi

NSAPI

/dmq-bin/dmqnsapi

ISAPI

/dmq-bin/dmqisapi

Figure 134 shows the result of a customized reply retry form and Figure 135 on
page 167 shows the source used:

Figure 134. MQ Internet Gateway: Customized Reply Retry Form

166

Network Computing Framework for e-business Guide

<HTML>
<HEAD>
<TITLE>MQSeries Internet Gateway Status</TITLE>
</HEAD>
<body bgcolor=#ffffff background= / doc/dmqdg08.gif>
<!-- beginning of message area -->
<table>
<tr><th>
<td>
<h1>SunShine</h1>
</td>
<td>
<img src= / cig/smile.gif alt=Smile>
</td>
<td>
<h1>NCF Enterprise</h1>
</td>
</table>
<HR ALIGN=center SIZE=4>
<p>This is a sample timed-out form that is sent if the Wait Interval has
been exceeded.
<P>To check if your reply is available press <b>Retry</b>
(and wait again).
<center>
<!-- end of message area -->
<FORM ACTION= / dmq-bin/dmqcgi METHOD=POST>
<i><INPUT TYPE=submit NAME=dmqretry VALUE= Retry ></i>
</FORM>
</center>
<!-- beginning of footage area -->
<hr>
<p>
<h3>
<p>We are terrible sorry that this was happen. If you wish send a claim,
please click on SunShine General Manager Mail link.
</h3>
<center>
<img src= . . / dmq/shark.gif alt=Shark>
<hr>
<B><A HREF= . . / dmq/ncfcgi1.htm>Back to the input form</A></B>
<B><A HREF= . . / dmq/ncfboss.htm>SunShine General Manager</A>
</B>
<!-- end of footer area -->
</BODY>
</HTML>
Figure 135. MQ Internet Gateway: Customized Reply Retry Form Source File

3.1.4.4 How to Use the MQSeries Internet Gateway


Since the MQSeries Internet Gateway is a CGI application, it has to run on the
same system as the Web server. The data flows from the HTML pages to
MQSeries queues through the CGI process. Queues can be local or remote.
When a queue is local, all applications that have access to the queue have to
run on the same system where the queue is defined. If the queue is defined as
remote, the queue manager sends the data to the queue manager where the

Chapter 3. Connectors

167

queue is defined as local. This network computing solution can take advantage
of MQSeries-specific functions such as:

Assured delivery - Messages are never lost.

Trigger process - Ability to start a process automatically.

Automatic character conversion - Between different platforms.

Message priority - Messages are processed in fifo order into the same
message priority. The priority can be set by the application.

Application environment - MQI API is available in many different application


environments and it is a powerful integration tool.

Multiplatform - MQSeries is present in more than 20 different platforms,


including IBM and non-IBM.

Multiprotocol - MQSeries supports all the typical communication protocols,


such as SNA, TCP/IP, NetBIOS and Decnet.

As you can see when you run the DMQSAMP1 sample, as shown in Figure 127
on page 159 through Figure 129 on page 161, the MQ message coming from the
HTML pages can include all the HTML form input data and user data or only the
user data as shown in Figure 130 on page 162. This depends upon the
MQIGwContext keyword value. However, the application has to provide the
response in a special format to let the MQSeries Internet Gateway repackage it
into an HTML file and to send it to the Web browser for display. The application
program that will get the message and send back the answer is described as
Web-aware.
Web-aware MQ applications do not use any new or specific MQ calls, but they
need to be written in a specific manner. You can refer to the source of
DMQSAMP1 program in the dmqgate\samples directory to see the format of data
that the MQSeries Internet Gateway uses to write the message and the format
that the Web-aware application uses to build the return message. Figure 136 on
page 169 shows the three parts of the DMQSAMP1 program:

BuildHHTP is used to convert response data to HTML format.

ParseString is used to parse the incoming data from the MQSeries Internet
Gateway.

168

URLDecode is used to remove + symbols with spaces and convert the next
two characters following the % symbol.

Network Computing Framework for e-business Guide

/**************************************************************************/
/*
*/
/* Local function definitions
*/
/*
*/
/**************************************************************************/
void ReturnMsgData( MQHCONN Hconn, char *pBuffer,
MQLONG BufferLength );
void GetMsgData( MQHCONN Hconn, char *pBuffer,
PMQLONG pBufferLength );
void BuildHTTP( char *pHTTPBuffer );
void ParseString( char *pString );
char *GetValue( char *pName );
int URLDecode(char *string_to_decode);

/* Parse the string into name/value pairs and


* perform URL Decode
*/
ParseString( wBuffer );

BuildHTTP( mBuffer);
/**************************************************************************/
/*
*/
/* BuildHTTP
*/
/* Convert response data to HTML(Hypertext Markup Language) format so
*/
/* it can be displayed on a Web browser.
*/
/* This function creates a table of name values pairs.
*/
/*
*/
/**************************************************************************/
void BuildHTTP( char *pHTTPBuffer )
{
int i=0;
/*
* specify that the
*/
strcpy(pHTTPBuffer,
strcat(pHTTPBuffer,
strcat(pHTTPBuffer,
strcat(pHTTPBuffer,
strcat(pHTTPBuffer,
strcat(pHTTPBuffer,
strcat(pHTTPBuffer,
strcat(pHTTPBuffer,
strcat(pHTTPBuffer,
strcat(pHTTPBuffer,

output data is in HTML document format


Content-type:text/html ) ;
\n\n<html>\n ) ;
<head>\n ) ;
<title>Application Information</title>\n ) ;
< / head>\n ) ;
<body bgcolor=#FFFFCC>\n ) ;
<CENTER> ) ;
<h1>Variable Information</h1>\n ) ;
<hr>\n ) ;
<p>\n ) ;

Figure 136 (Part 1 of 4). MQ Internet Gateway: DMQSAMP1 BuildHTTP and ParseString
Routines

Chapter 3. Connectors

169

/*
* specify table format and headings
*/
strcat(pHTTPBuffer, <TABLE BORDER=1 CELLPADDING=4>\n ) ;
strcat(pHTTPBuffer, <TR> ) ;
strcat(pHTTPBuffer, <TD ALIGN=CENTER><FONT COLOR=RED> ) ;
strcat(pHTTPBuffer, Variable</FONT></TD> ) ;
strcat(pHTTPBuffer, <TD ALIGN=CENTER><FONT COLOR=RED> ) ;
strcat(pHTTPBuffer, Value</FONT></TD></TR>\n ) ;
/*
* add each name value pair to the table
*/
for (i=0;i<VarCount;i++ )
{
strcat(pHTTPBuffer, <TR><TD ALIGN=right><B> ) ;
strcat(pHTTPBuffer, pVar[i][NAME]);
strcat(pHTTPBuffer, < / B></TD><TD> ) ;
if ( strlen(pVar[i][VALUE]) > 0)
{
strcat(pHTTPBuffer, pVar[i][VALUE]);
}
else
{
strcat(pHTTPBuffer, <I>none</I> ) ;
}
strcat(pHTTPBuffer, < / TD></TR>\n ) ;
}
/*
* end the table and document
*/
strcat(pHTTPBuffer,
strcat(pHTTPBuffer,
strcat(pHTTPBuffer,
strcat(pHTTPBuffer,

< / TABLE>\n ) ;
< / CENTER> ) ;
< / body>\n ) ;
< / html>\n ) ;

Figure 136 (Part 2 of 4). MQ Internet Gateway: DMQSAMP1 BuildHTTP and ParseString
Routines

170

Network Computing Framework for e-business Guide

/**************************************************************************/
/*
*/
/* ParseString
*/
/* Data from the Web consists of a series of names and their respective
*/
/* values. Name value pairs are separated by the & character and
*/
/* a name is separated from a value by the = character.
*/
/* This function parses request data by replacing = and &
*/
/* characters by a null terminator.
*/
/* This function also calls function URLdecode which decodes each name
*/
/* and value. The decoded name value pairs are then printed.
*/
/*
*/
/**************************************************************************/
void ParseString( char *pString )
{
int i;
char *p;
i=strlen(pString);
pVar[VarCount][NAME] = pString;
printf( Parsing request data...\n ) ;
for (p=pString; i ;p++,i-- )
{
if ( *p == & )
{
*p = \0 ;
pVar[VarCount][NAME] = p+1;
}
else if ( *p == = )
{
*p = \0 ;
pVar[VarCount][VALUE] = p+1;
VarCount++;
}
}
for (i=0;i<VarCount;i++ )
{
URLDecode( pVar[i][NAME] );
URLDecode( pVar[i][VALUE] );
printf( \tName <%s> Value<%s>\n ,
pVar[i][NAME],
pVar[i][VALUE]) ;
}
}

Figure 136 (Part 3 of 4). MQ Internet Gateway: DMQSAMP1 BuildHTTP and ParseString
Routines

Chapter 3. Connectors

171

/**************************************************************************/
/* URLDecode
*/
/* Each name and value are decoded by replacing plus signs with spaces
*/
/* and then replacing characters that were encoded as a per cent sign
*/
/* followed by a hexadecimal number by the actual characters.
*/
/**************************************************************************/
int URLDecode(char *string_to_decode)
{
char c1, c2;
/* holders for hex digits of escape sequence */
int len;
/* length of original string */
int j;
/* index for reading from encoded string */
int k;
/* index for writing to decoded string */
len=strlen(string_to_decode);
/*
Run down the length of the encoded string, examining each
character. If it s a +, we write a space to the decoded string.
If it s a %, we discard it, read in the next two characters,
convert their hex value to a char, and write that. Anything
else, we just copy over.
*/
for (j=0, k=0;j<len;j++, k++) {
switch(string_to_decode[j]) {
case + :
string_to_decode[k]= ;
break;
case % :
c1=tolower(string_to_decode[++j]);
if (isdigit(c1)) {
c1-= 0 ;
} else {
c1=c1- a+10;
}
c2=tolower(string_to_decode[++j]);
if (isdigit(c2)) {
c2-= 0 ;
} else {
c2=c2- a+10;
}
string_to_decode[k]=c1*16+c2;
break;
default:
string_to_decode[k]=string_to_decode[j];
break;
}
}
string_to_decode[k]= \0 ;
return(k);
}

Figure 136 (Part 4 of 4). MQ Internet Gateway: DMQSAMP1 BuildHTTP and ParseString
Routines

You can provide one or more Web-aware applications that can receive the
message from the MQ Internet Gateway. It processes the messages and sends
them to one or more MQSeries application across the MQSeries network as
shown in Figure 137 on page 173. MQI correlates each request message with
the relative response message using the message identifier (msgid) and/or the
correlation identifier (correlid). In this way you can provide a strong integration
with all existing MQSeries applications with the Web and you can split a single
request and re-join the responses. Another useful way to use msgid and
correlid is to split the Web-aware application into two programs:

One receives data from the Web and sends it to the non-Web-aware
application.

The other receives the response from the non-aware application and
repackages it into an HTML file.

In this way you do not have to wait to complete a single request/response loop
before processing the subsequent incoming request.

172

Network Computing Framework for e-business Guide

Figure 137. MQSeries Internet Gateway: Web-Aware Linking Non-Web-Aware


Applications

3.1.5 MQSeries Client for Java


MQSeries Client for Java enables Web browsers and Java applets to issue calls
and queries to MQSeries giving access to mainframe and legacy applications
over the Internet without the need for any other MQSeries code on the client
machine.
The messages issued by the MQSeries Client for Java can be read by any MQ
application. They do not have any special format and do not need a Web-aware
MQ application. (This is different from the MQSeries Internet Gateway, which
does require a special format.) More information on this is provided in 3.1.4.4,
How to Use the MQSeries Internet Gateway on page 167.
MQSeries Client for Java is an MQSeries Client written in the Java programming
language and it is the similar to the other MQSeries Clients with a few minor
exceptions:

It only supports the TCP/IP protocol.

It does not read any environment variables at startup.

It does not support connection tables.

Information that would be stored in a connection definition and in


environment variables is stored in an instance of a class called
MQEnvironment.

Error and exception conditions are written to a log specified in the


MQEnvironment class. The default error destination is the Java console.

Application developers can create applets and applications that can run on any
platform that supports the Java run-time environment. They can provide
presentation and business logic that can use MQSeries MQI to exchange data
and process with the existing applications across the Web. This solution lets you

Chapter 3. Connectors

173

write an application once and run it anywhere. It reduces the development time
for multiplatform applications and the cost of distributing and maintaining
software.

3.1.5.1 Installing MQSeries Client for Java


MQSeries Client for Java can be installed on a local hard disk or on a Web
server. It can run on a Java-enabled browser, an appletviewer or in stand-alone
mode. You can download it from http://www.software.ibm.com/ts/mqseries.
Select Downloads and receive the file ma83.zip. Using the unzip utility you can
unpack the ma83.zip file into the following files:

readme.txt

mqc4j.zip - MQSeries Client for Java classes

mqc4jdoc.zip - The documentation in HTML format for the installation and


use of the client

relnotes.txt - Release notes for MQSeries Client for Java

ipla - The IBM general license information

li - The specific license information for this SupportPac

You need to copy the mqc4jdoc.zip file into a directory and unzip it to have all
the documentation you need for this task. Then you can proceed with the type of
installation that you want to implement:

Installation on local disk


Copy the mqc4j.zip file to the directory in which you want to install the
MQSeries Client for Java and unpack it using your unzip utility.

Installation on a Web server


If you install the MQSeries Client for Java on a Web server, you can
download and run MQSeries client applications on systems that do not have
the MQSeries Client for Java installed locally. This could be the most
popular way to use this solution. You have to unpack the mqc4j.zip file in
one directory and insert the directory name in the Web configuration file. We
used mqjava as our directory name:


Pass

/mqjava/*

c:\mqjava\*

After it is installed you can verify your installation by using an applet called
mqjavac.html that can run from a Web browser or with an appletviewer.
We assume that you are working on the Web system where you have installed
MQSeries Client for Java, MQSeries queue manager and the Web server.
Considerations about which queue manager the MQSeries Client for Java can
connect to are discussed in 3.1.5.2, How to Use MQSeries Client for Java on
page 178.
In order to verify your installation you have to provide a channel definition in
your MQSeries environment:
1. Start your queue manager with the strmqm command.
2. Type runmqsc to start the runmqsc program.
3. Define a sample channel called JAVA.CHANNEL by typing:

174

Network Computing Framework for e-business Guide

DEF CHL( JAVA.CHANNEL ) CHLTYPE(SVRCONN) TRPTYPE(TCP) MCAUSR( ) +


DESCRIPTION( Sample channel for MQSeries Client for Java )
If you are using an OS/2 or NT platform, you have to start a listener program
with the following command:

runmqlsr -t tcp [-m QMNAME] -p 1414


Where [ -m QMNAME ] is the queue manager name that is not required if you are
using your default queue manager, and 1414 is the default TCP port for
MQSeries.
If you are using a UNIX operating system, you have to configure the inetd
daemon so that inetd starts the MQ channels. To configure it, perform the
following steps:
1. Edit the file /etc/services. If you do not have the following line in that file,
add it as shown:

MQSeries

1414/tcp

# MQSeries channel listener

2. Edit the file /etc/inetd.conf. If you do not have the following line in that file,
add it as shown:

MQSeries stream tcp nowait root /usr/lpp/mqm/bin/amqcrsta -m


<queue manager name>
3. Run the command inetimp.
4. Run the command refresh -s inetd.
At this point verify your installation at mqjavac.html using a Web browser as
shown in Figure 138 on page 176, or from an appletviewer as shown in
Figure 139 on page 177. When the applet starts you have to provide the host
name, the name of the channel and the queue manager. Then you have to click
on the Test Connection button. A new window will appear with the results of the
test; it tests the connection with the host name and with the MQ queue manager.
It will then:

Open an MQSeries queue.

Put a message on the queue.

Get the message off the queue.

Close the queue.

Disconnect from the queue manager.

Chapter 3. Connectors

175

Figure 138. MQ Client for Java: Web Browser Running the Verification Program

176

Network Computing Framework for e-business Guide

Figure 139. MQ Client for Java: Appletviewer Running the Verification Program

You can use this installation verification applet to allow your users to verify their
access to your queue manager. mqjavac.html includes a set of optional
parameters that allow you to modify the applet to suit your specific
Chapter 3. Connectors

177

requirements. You need to remove the ! from the parameters since that makes
it a comment line, and insert your values. In addition to the parameters that you
used during the installation verification test, you also have:

user ID - Is the user ID used when connecting to the queue manager.

password - Is the password used when connecting to the queue manager.

trace - The client will write a trace log. The value could be 1 to 5, and the
trace will be written on the Java console. In Figure 140 you can see part of
a trace activated with trace=1.

Figure 140. MQ Client for Java: Trace Written into the Java Console

3.1.5.2 How to Use MQSeries Client for Java


MQSeries Client for Java can be installed on a local hard drive. It can be on the
client side or on a Web server. The location can affect the way the client is used
to run the Java applets and which MQ queue manager the applet can connect
with. If the MQSeries Client for Java is used to avoid having to perform software
distribution, it has to be installed on the Web server. When the Web browser
receives an HTML page with an applet that includes the MQ call, it will connect
to an MQ queue manager installed on the Web system with the Java security
feature. The messages coming from the Java applet on the Web browser can be
placed on a local queue owned by the MQ queue manager on the Web server.
That way, a local MQ application can get the message and process it or it can
refer to a remote queue. In that case, the MQ queue manager will reroute the
message to its proper destination.
The Java applet that runs on an appletviewer can bypass the Java security
feature and connect to any MQ queue manager present on the network.
On the other hand, if you installed the MQSeries Client for Java on the local disk
and ran the Java applet using a Netscape Web browser or an appletviewer, it
can connect itself to any MQ queue manager present on the network. If you are

178

Network Computing Framework for e-business Guide

using Microsoft Internet Explorer, the Java applet can connect only to the MQ
queue manager present on the local host.
The following table summarizes the MQ queue manager locations that can be
accessed from each environment.
Table 3. Accessible MQ Queue Manager Locations
Installation Location
Browser

Local Disk

Web Server

Netscape Navigator

any

Web server

Microsoft Internet Explorer

localhost

Web server

appletviewer

any

any

The MQSeries Java programming interface consists of 11 verbs: MQBACK,


MQCLOSE, MQCMIT, MQCONN, MQDISC, MQGET, MQINQ, MQOPEN, MQPUT,
MQPUT1 and MQSET. As Java is an object-oriented language, your program will
consist of a set of MQSeries objects that you can call using their object methods.
In the following example we created a Java program that uses most of the MQI
verbs available. At the top of the applet screen shown in Figure 141 on
page 180, you can see the security part. That is to remind you that with MQ
Java client it is possible to send a user ID and a password. The applet lets you
choose the type of action:

Send/Receive - This means that the applet uses MQPUT to send messages
and MQGET with the wait option to retrieve the response message.

Send a message using MQPUT call.

Receive a message from the queue using MQGET.

It is possible to insert a queue name. If you dont select one, then a default will
be used as the correlation ID. In this sample, the correlation ID is used to
retrieve a specific message from the queue. This could be useful if you have a
queue that receives messages from many users and needs to correlate the
response messages to each users request.

Chapter 3. Connectors

179

Figure 141. MQ Client for Java: Sample Applet

Figure 142. MQ Client for Java: Receive a Message Using a Correlation ID

180

Network Computing Framework for e-business Guide

We inserted several messages using different correlation IDs and we retrieved


them using the same correlation ID as is shown in Figure 142. Also, if there are
other messages in the queue that use a different correlation ID, an MQ error
message, 2033, is issued. This means that there are no more messages for our
correlation ID (MSG2). This is shown in Figure 143.
.

Figure 143. MQ Client for Java: Receive a Message Using a Correlation ID

Figure 144 on page 182 has a piece of the code from the sample just to show
you how to code MQSeries calls using the MQ Java Client. The full API
documentation is available in the MQSeries Java Programmer s Guide distributed
with the product in HTML format.
The program is divided into three different sections, based upon the action types
reported in Figure 141 on page 180 (send/receive, receive and send). A
description of key components in the program follows:
1. You need to import the MQ classes 1.
2. Set some variables, such as the host name, the MQ channel used and the
name of queue manager 2. We need to use them in the MQEnvironment
3.
3. Before you open the queue you have to set the options such as the ones at
4 for input and output.
4. The name of the queue can be retrieved from the screen or you can use the
default name 5. You can define a different queue name for the send and
receive flows, but not for send/receive itself.
5. To make an MQPUT call we need to set up MQPutMessageOptions and
MQGetMessageOptions 6. For an individual send operation we used the

Chapter 3. Connectors

181

default options. Therefore, this part is not significant in the send/receive


flow since we used the MQGMO_WAIT option. We accepted the message if it
was bigger than our buffer MQGMO_ACCEPT_TRUNCATED_MSG. We also
set the waitinterval time to 30 seconds. When the program puts the
message on the queue it will wait for the response message for 30 seconds.
If the wait time expires, it will receive an error message that will be sent to
the screen.
6. The program uses MQFMT_STRING 7 for its output format.
7. To send a message that requires a response in a reply queue, we need to
set the message type as MQMT_REQUEST 8.
8. The correlation ID, if it is specified in the input screen, will be used for send
and receive actions. In the send/receive action the correlation ID is used to
wait for the response message for that particular request 9.

import com.ibm.mq.*;
import DemoMq;

1

public class BollaMq {


private
private
private
private
private
private

String hostname = 9.24.104.120;


String channel = JAVA.CHANNEL ;
String qManager = mqnt120 ;
MQQueue local_queue;
MQQueueManager qMgr;
MQQueue reply_local_queue;

2

MQEnvironment.hostname = hostname; 3


MQEnvironment.channel = channel;
System.out.println( new MQQueueManegr\n ) ;
qMgr = new MQQueueManager( qManager );
openOptions = MQC.MQOO_OUTPUT + MQC.MQOO_FAIL_IF_QUIESCING;
if ( req.nomecoda.getText().equals() )
local_queue = qMgr.accessQueue(MQJAVA.LOCAL.CODA1 ,
openOptions,
null,
null,
null );
else
local_queue = qMgr.accessQueue(req.nomecoda.getText(),
openOptions,
null,
null,
null );

4
5

}
MQMessage output = new MQMessage();
6
output.writeString( req.chiave.getText() );
MQPutMessageOptions pmo = new MQPutMessageOptions();
if ( (!(req.corrid.getText().equals( ) ) ) )
{
System.out.println(put + req.corrid.getText() );
req.corrid.getText().getBytes( 0,
req.corrid.getText().length(),
output.correlationId,
0 );
}
output.format = MQC.MQFMT_STRING;
local_queue.put( output, pmo );

7

Figure 144 (Part 1 of 3). MQ Client for Java: Example Source Code

182

Network Computing Framework for e-business Guide

MQEnvironment.hostname = hostname;
3
MQEnvironment.channel = channel;
System.out.println( new MQQueueManegr\n ) ;
qMgr = new MQQueueManager( qManager );
openOptions = MQC.MQOO_INPUT_AS_Q_DEF + MQC.MQOO_FAIL_IF_QUIESCING; 4
local_queue = qMgr.accessQueue(MQJAVA.LOCAL.CODA1 , 5
openOptions,
null,
null,
null );
MQMessage input = new MQMessage();
MQGetMessageOptions gmo = new MQGetMessageOptions(); 6

}
public void flussoRpc( DemoMq req ) throws MQException, java.io.IOException
{
try
{
int openOptions;
if ( req.start == 0 )
{
MQEnvironment.hostname = hostname;
3
MQEnvironment.channel = channel;
System.out.println( new MQQueueManegr\n ) ;
qMgr = new MQQueueManager( qManager );
openOptions = MQC.MQOO_OUTPUT + MQC.MQOO_FAIL_IF_QUIESCING; 4
if ( req.nomecoda.getText().equals() )
local_queue = qMgr.accessQueue(MQJAVA.LOCAL.CODA3 , 5
openOptions,
null,
null,
null );
openOptions = MQC.MQOO_INPUT_SHARED + MQC.MQOO_FAIL_IF_QUIESCING; 4
reply_local_queue = qMgr.accessQueue(MQJAVA.LOCAL.REPLY ,
5
openOptions,
null,
null,
null );
MQMessage output = new MQMessage();
output.writeString( req.chiave.getText() );
MQPutMessageOptions pmo = new MQPutMessageOptions();

Figure 144 (Part 2 of 3). MQ Client for Java: Example Source Code

Chapter 3. Connectors

183

if ( (!(req.corrid.getText().equals( ) ) ) )
{
System.out.println(put + req.corrid.getText() );
req.corrid.getText().getBytes( 0,
req.corrid.getText().length(),
output.correlationId,
0 );
}
output.messageType = MQC.MQMT_REQUEST;
8
output.format = MQC.MQFMT_STRING ;
7
output.replyToQueueName = new String(MQJAVA.LOCAL.REPLY ) ;
output.report = MQC.MQRO_EXCEPTION_WITH_DATA;
local_queue.put( output, pmo );
MQMessage input = new MQMessage();
MQGetMessageOptions gmo = new MQGetMessageOptions();
6
gmo.options = MQC.MQGMO_WAIT | MQC.MQGMO_ACCEPT_TRUNCATED_MSG;
gmo.waitInterval = 30000;
input.correlationId = output.correlationId; 9
reply_local_queue.get( input, gmo );
String msgText = input.readLine();
req.risultato.setText( msgText );
}

Figure 144 (Part 3 of 3). MQ Client for Java: Example Source Code

3.1.6 eNetwork Host On-Demand


IBM Host On-Demand, a member of the eNetwork software family, is a
Java-based solution that incorporates industry-standard Telnet 3270 (TN3270)
protocols. It provides a high-performance, low-cost solution for intranet and Web
users who need occasional access to their central computer applications or
databases from any Java-enabled end-user platform. Host On-Demand will
operate with any industry-standard Telnet server. Version 2 of Host On-Demand
adds support for Telnet 5250 (TN5250), VT52, VT100 and VT220 connectivity as
well as file transfer.
When using Host On-Demand, you will find that all the software is automatically
downloaded in the form of a Java applet. This applet is deleted once the host
session is terminated. Each time the user initiates a Host On-Demand session
the current Java applet is used. This helps avoid software and maintenance
distribution.
There are many situations where eNetwork Host On-Demand can be used. Any
time there is a need to access host applications (for example, TSO, CICS, IMS,
VM or VSE) using 3270 screens across the Web, you can use Host On-Demand
instead.
eNetwork Host On-Demand can be downloaded without any charge from
http://www.networking.ibm.com/hex/hexprod_en.html for the following platforms:
IBM AIX Server, IBM OS/2 Server, Microsoft Windows NT Server and Novell
NetWare Server. There is a plan to make it available on OS/390 platform.
Customers that do not have TCP/IP installed on their mainframe systems and do
not have plans to install it can use an intermediate platform with an IBM
Communication Server installed:

184

IBM Communication Server for AIX 4.2 or later (with IBM SNA Client Access
for AIX 1.2 or later)

Network Computing Framework for e-business Guide

IBM Communication Server for OS/2 4.1 or later

IBM Communication Server for NT 5.0

Novell NetWare for SAA 2.2 or later

This allows customers to maintain their network configuration on the mainframe


side as shown in Figure 145. In addition, Netscape Communicator Professional
Edition has the Host On-Demand code imbedded in it.

Figure 145. eNetwork Host On-Demand: Configuration Scenario

Host On-Demand V2 no longer requires you to use IBM Communications Server.


It will run with any industry-standard Telnet server. However, if you choose to
run it as an applet, you will need to install it on the same logical machine as
your Telnet server. This is due to the security structure that the Java Virtual
Machine (JVM) provides. The JVM requires socket connectivity to exclusively go
through the applets originating Web server.

3.1.6.1 Installation
You can download Host On-Demand from the IBM Web site and install it in the
same system where the Web and IBM Communications server are running. For
Windows NT server, the Host On-Demand is also packaged with the IBM
Communications Server for NT V5, as shown in Figure 146 on page 186. The
installation is very simple; you can just follow the window prompts, choosing the
disk drive (Figure 147 on page 186), and the program folder where you want to
install the product (Figure 148 on page 187). The only thing that it requires is an
IBM Communication Server installed and configured on your system.

Chapter 3. Connectors

185

Figure 146. eNetwork Host On-Demand: Communication Server for Windows NT

Figure 147. eNetwork Host On-Demand: Installation Steps

186

Network Computing Framework for e-business Guide

Figure 148. eNetwork Host On-Demand: Installation Steps

The customization is very simple. You just have to read the information in the
Host On-Demand readme file in the IBM Communication Server folder. It uses
TCP/IP port number 23. If you want to change it, you have to edit the
c:\IBMCS\hd3270\he3270en.htm file and change the following statement to your
new TCP/IP port number:




<param




name=TN3270E_SERVER_PORT value=23>

To provide a browser link to Host On-Demand, you have to insert the following
statement into your Web server configuration file:




Pass

/hod/*




c:\IBMCS\HD3270\*

The documentation is provided in HTML form and you can retrieve it using the
link Webserver/hod/readme.htm link. There are two samples:

Webserver/hod/sample1.htm
This sample explains how the administrator can implement his or her own
Web page to link Host On-Demand, using a customized style. The
suggestion is to maintain some hyperlinks that provides help information for
your user.

Webserver/hod/sample2.htm
This example shows you how it is possible to invoke Host On-Demand with
the auto-connect option. You have to set the HTML parameter in the
following way:

Chapter 3. Connectors

187


<applet archive=he3270ap.zip code=he3270ap.class width=480
heigth=360 align=center>
<param name=CABBASE value=he3270ap.cab>
<param name=AUTO_CONNECT value=YES>
<param name=SEPARATE_WINDOW VALUE=NO>
</APPLET>

The parameter SEPARATE_WINDOW lets you open a 3270 session inside


your Web browser (yes or no). The applet used in this sample (see
Figure 149 on page 189) has a tool bar that lets you test some options and
retrieve information about:

188

General help as shown in Figure 150 on page 190

How the keyboard is set up as shown in Figure 151 on page 191

How to perform some Host On-Demand tasks as shown in Figure 152 on


page 192

Network Computing Framework for e-business Guide

Figure 149. eNetwork Host On-Demand: Example Provided by sample2.htm

Chapter 3. Connectors

189

Figure 150. eNetwork Host On-Demand: General Help Screen

190

Network Computing Framework for e-business Guide

Figure 151. eNetwork Host On-Demand: How to Use the Keyboard Screen

Chapter 3. Connectors

191

Figure 152. eNetwork Host On-Demand: How Do I Screen

3.1.6.2 Product Description


eNetwork Host On-Demand includes the following interesting features that can
address user requirements and provide good performance:

Emulator functions
As mentioned before, it is the solution for SNA application access through a
standard Java-enabled desktop or Web browser. It provides emulator
functions on-demand by downloading a Java TN3270 to your computer. The
download time is reduced because only the functions needed are sent.

Java implementation
The Java implementation offers advantages not usually found in similar
solutions that use HTML mappers to provide access to the host. It provides
a persistent connection to the server. This allows you to eliminate the
interruptions due to connecting and reconnecting sessions as well as
providing less overhead and better performance. Persistent sessions also
improve network security by denying unauthorized connections to authorized
sessions.
In addition Host On-Demand lets you use the keyboard and PF keys. You
can also use the PF key icons by using your mouse. The TN3270 Java applet
includes: a default windows setting, a menu bar and the support of the
keyboard and mouse.

192

Network Computing Framework for e-business Guide

Customize 3270 windows


It is possible to open the 3270 window within your existing Web browser or
as a new window.
Note: The F10 key does not work since it is reserved for Host On-Demand.
When you need to use it, you have to click on the F10 button located
at the bottom of the Host On-Demand window.

Multiple sessions
Host On-Demand provides multiple session support and lets you access
multiple 3270 applications at the same time. The current version (V1) of Host
On-Demand supports two sessions. The new version (V2) will increase that.

Clients
Host On-Demand supports any Java-enabled client platform. It can be
invoked not only from a Web browser but also from groupware clients such
as Lotus Client (4.5 or later), appletviewer or any operating systems that
support a Java virtual machine (at least JDK 1.02).

eNetwork Host On-Demand is included in Netscape Communicator, which means


that the Java TN3270 applet is distributed with the Netscape product and it does
not have to be downloaded separately. It is currently packaged with the
Netscape Professional Edition. A user working with a Netscape Communicator
4.01 browser can directly connect to 3270 applications on the mainframe if they
have TCP/IP installed.
The use of Host On-Demand is shown in Figure 153 and Figure 154 on page 194.

Figure 153. eNetwork Host On-Demand: 3270 VTAM Connection Screen

Chapter 3. Connectors

193

Figure 154. eNetwork Host On-Demand: 3270 Application

3.1.6.3 Servlets and IBM Connectors


In this chapter we showed you what IBM connectors are and how they can be
used to provide Internet integration with your application environment using
CICS and/or MQSeries. We also explained how the Java programming language
is used inside CICS Gateway for Java and MQ Java Client solutions.
In this section we show you how it is possible to build a more powerful, flexible
and scalable solution using servlets and IBM connectors.
A complete overview and technical description about servlets is available in
Chapter 2, Servlets on page 11.
To show you the difference between the traditional use of IBM connectors and
servlets we review below how they work.
The Web browser downloads an HTML page that includes a Java program called
an applet. The applet will be executed on the Web browsers system and it will
be able to manage the presentation logic, some business logic and via CICS or
MQ Java solutions, is able to invoke existing programs and CICS transactions.
This can offer, as we mentioned in this chapter, a valid alternative to using
common Web CGI solutions. It provides better performance and can reduce the
load on the Web server. However, we have the following concerns:

194

It requires you to develop Java programs that will be downloaded to the Web
browser to provide a user interface. Java programming is more complicated
than building HTML pages and in most cases, the user interface provided by

Network Computing Framework for e-business Guide

HTML can be sufficient. We have to consider that W3C is still working to


improve the HTML language.

Internet or intranet solutions increase the number of potential users that can
access your application and its data. You will need to prepare for this
increased workload, as well as provide help or training for the users of the
applications.
As Java technology is rapidly evolving, new versions of the Java language
can offer more functions and services to build new powerful and robust
applications. This requires you to upgrade the Java Virtual Machine present
in the client operating systems or download new browser versions. It also
requires more CPU processing power as well as additional disk and
memory.

Downloading an applet is surely more of a drain than downloading an HTML


page in terms of network bandwidth and CPU and RAM for the client,
especially if that applet has to interact with a connector.
For example, if an applet has to interface with the IBM CICS Gateway for
Java, at least some of the IBM CICS Gateway for Java classes included into
the ibm.cics.jgate.client package must be downloaded to the client with the
applet itself.

Using servlets and IBM connectors in the Web server system can solve some of
the above problems:

A servlet is a Java program that runs on the Web server. For this reason it
does not have a graphical user interface and can provide high performance
because it is a long running process able to manage simultaneous requests
using a multithreaded process. (Servlets start at the first client request and
stay active all the time that the Web server is active or until a destroy()
method for that servlet is invoked.)

It can be invoked:

By pointing the clients browser directly to its URL

From within the <SERVLET> tag of an HTML page with extension .shtml

From within the <FORM> tag of an HTML page

This means that the user has to download only an HTML page to have a user
interface and to obtain application services. This solves the problem of not
having sufficient network bandwidth and for upgrading the clients software
and hardware to run new Java applets or new versions of Java. Of course
you can still provide Java applet solutions for a specific solution, but with a
servlet environment you only need to maintain your Web servers.

With the servlet approach, the Java classes necessary to invoke the
application server do not need to be downloaded to the clients browser. It
is enough that they are placed into a well-defined location inside the Web
server and are imported by the servlet interfacing to the application server.
Then the client does not connect to the application server directly, but
passes through the servlet.

Servlets are written in Java language and are:

Portable from any server system that supports a Java Virtual Machine

Scalable using a more powerful server or using more Web server


systems

Chapter 3. Connectors

195

CICS and the MQSeries provide the Java classes that servlets can use to invoke:

CICS programs

CICS 3270 transactions

MQSeries applications

This way the servlet processes requests coming from the user in HTML pages
and invokes existing application via CICS Java classes and a CICS client or via
MQ Java classes and MQSeries. In Figure 155 you can see an overview of this
architecture.

Figure 155. Servlets and I B M Connectors Architecture

An example of using servlets and IBM connectors to interface to an application


server is shown in 6.2, Servlets and IBM Connectors on page 276.

196

Network Computing Framework for e-business Guide

Chapter 4. Net.Data Database Scenario


In this scenario we used three machines to demonstrate the interfacing of a
back-end database on NT with a browser and server on other NT systems. The
first system plays the role of client. Its role is to send the request to the Web
server through a browser and also to get back the result from the Web server.
Finally, it will display the results on the browser. The client system is a PC
350-P133 with Windows NT 4.0 and Netscape Navigator 4.0.
The second-tier system plays a key role in the scenario. It is a Web server,
database gateway and also a database client to access the remote database.
This system is a PC 750-P166 with 64 MB of memory. We installed Windows NT
4.0 as the operating system, and the Lotus Domino Go Webserver for the Web
server. In addition, we installed Net.Data 1.0.10 as the database gateway. In
order to connect to a remote database server we also installed DB2 CAE to
configure this machine as a DB2 client to access data from the database that is
on another machine.
The third system was used for the database server. We installed NT Server 4.0
on it and we installed a beta version of DB2 5.0 as the database server. Its
purpose was to support data for the requests that come from the server
machine.
The following figure shows the software we used in this scenario:

Figure 156. The Whole Environment of Windows NT Scenario

4.1 Software Configuration


The software configurations we show are for Net.Data and the DB2 CAE. When
you install Net.Data it creates a directory called db2www. Under that directory
there are some subdirectories. You can see the entire hierarchy in the following
figure:

Copyright IBM Corp. 1998

197

Figure 157. The Hierarchy of Net.Data Directory

We want to point out that the macro subdirectory is the place where Net.Data
macro files are located. In addition, the installation process for Net.Data will
create a file called db2www.ini under \WWW\Html as shown in the following
figure:

Figure 158. The Configuration File of Net.Data

Even though it shouldnt be necessary to modify the default db2www.ini file we


found that we could not get it to work without some modifications. Since it left

198

Network Computing Framework for e-business Guide

the DB2PATH field blank, the system considers the next word INCLUDE_PATH to
be the value of DB2PATH and this caused an error. Therefore, we had to modify
it. This was due to using beta code and should be fixed in the production
version of the code. The original file is shown in Figure 159, and the modified
one is shown in Figure 160.

Figure 159. The Original Configuration File of Net.Data

Figure 160. The Modified Configuration File for Net.Data

The next application that we show is DB2 CAE. It enables the DB2 client to
access data from a remote DB2 server through the network. It is easy to install
but there are some things that you need to be aware of.
You have to first start the Client Configuration Assistant from the DB2 for
Windows NT folder. You will then see a dialog pop up to tell you to add a
database connection. Click on the Add database button as shown in the
following figure:

Chapter 4. Net.Data Database Scenario

199

Figure 161. Create Database Connection

This will bring you to the Add Database SmartGuide. Select Search the network
to search the server that you want to connect to. Then click on Next on the
bottom of the screen as shown in the following figure:

200

Network Computing Framework for e-business Guide

Figure 162. Select How to Create the Connection

The Add Database SmartGuide will show you the system that you want to
connect to (see Figure 163). In this case, double-click on the item Known
Systems to see the systems that you can connect to. Youll see output similar to
Figure 164 on page 202. There are two servers in this case: NTNCF21 and
NTNCF22.

Figure 163. Select the Target Database

Chapter 4. Net.Data Database Scenario

201

Figure 164. Select the Target Database from the List

We double-clicked on NTNCF22 since it was the one that we wanted to connect


to. In Figure 165 you can see that there is a DB2 server and only one database
(SAMPLE) on that server.

Figure 165. Select Database from the List

202

Network Computing Framework for e-business Guide

Highlight the database called SAMPLE and click on the Add System button as
shown in the following:

Figure 166. Select Database from the List

After you click on Add System there will be a dialog pop-up asking you the
protocol of the network as well as the server that you want to connect to. In this
case we chose TCP/IP for the transport protocol and NTNCF22 for the server
(see Figure 167).

Figure 167. Select Protocol to Use to Find the Server


Chapter 4. Net.Data Database Scenario

203

If everything is okay, a message box will appear telling you that the system was
found in the list, as shown in Figure 168 on page 204.

Figure 168. Server Is Found in the List

We then highlighted the database SAMPLE and clicked on the tab Alias at the
top to make this an alias on our system. In this case we called it SAMPLE1 (see
Figure 169 and Figure 170 on page 205).

Figure 169. Select the Target Database from the List

204

Network Computing Framework for e-business Guide

Figure 170. Specify the Local Name for the Target DB2 Database

After you create the alias choose the tab Target Database on the top and click on
the button Done (see Figure 171).

Figure 171. Click on Done to Build the Connection

You will get a confirmation message box from the system. It informs you that
the configuration connection for SAMPLE1 was added successfully. You can test

Chapter 4. Net.Data Database Scenario

205

the connection by clicking on the Test Connection button (see Figure 172 on
page 206).

Figure 172. The Connection Configuration Was Added Successfully

When the system wants to build the connection it needs to know the user ID and
password for that database. You have to provide that in the dialog box as shown
in the following figure:

Figure 173. Enter ID and Password for the Database

If it connects to the database successfully, there will be a message box showing


you that it was successful (see Figure 174 on page 207).

206

Network Computing Framework for e-business Guide

Figure 174. The Connection Test Was Successful

Go back to the Client Configuration Assistant window and you will see that there
is one entry for the database SAMPLE1 that you just connected to from the DB2
server NTNCF22 (see Figure 175).

Figure 175. Available DB2 Database

To try another test from the DB2 command window we issued a command to
connect to database SAMPLE1:

>db2 connect to sample1 user liu using xxxxxxx


liu is the ID for that database, and xxxxxxx is the password (see Figure 176 on
page 208).

Chapter 4. Net.Data Database Scenario

207

Figure 176. Try to Connect Database from DB2 Command Window

Now that you know how to connect to a remote database server by using the
Client Configuration Assistant we go into our scenario and show you how
Net.Data works with the DB2 server over the network.

4.2 Net.Data Scenario


According to Figure 156 on page 197, the scenarios we created in this chapter
are all based on NT systems. We used three machines to build up the
scenarios. Machine A has a browser on it and plays the role of a client. The
first thing the client will do is issue a request for the input form from the macro
file. After the Web server has received this request it passes the request on to
Net.Data. Net.Data will then process the request and pass back the input form in
HTML format to the Web server. From there the Web server will post the form
back on the browser.
Now the client can see the input form from the browser. When the user fills in
the form and clicks on the Submit button, the data will go back to the Web server
with a request for the report form. Again, the Web server passes the request to
Net.Data for further processing. As soon as the request for the report form is
received, Net.Data will query the data from the back-end database. When the
results come back from the database Net.Data will translate that into HTML
format and send it back to the Web server. Finally, the Web server gives that to
the client.
The communication path between the client and Web server is HTTP. The Web
server uses CGI/API programs to talk with Net.Data. Net.Data passes its
dynamic SQL calls to the database. In our scenario, we installed DB2 in a
machine other than the one we had Net.Data on, so we needed CAE to
communicate between Net.Data and DB2 over TCP/IP.

208

Network Computing Framework for e-business Guide

4.2.1 Create an SQL Query Tool


The first scenario we have here is a simple one, but it is also a useful tool when
you develop your project. We created an SQL query tool. Using this tool you
can issue any SQL command to access a remote database. In this case we
connect to the database that we have already connected to with the client
configuration assistant, called SAMPLE. You can see this in Figure 177, which
shows the Control Center in the DB2 for Windows NT folder.

Figure 177. Use Control Center to Show You the Details of Database

We wanted to connect to the database called SAMPLE and try to use the tables
in the database. We show you how to do this with Net.Data. You can see this in
Figure 178 on page 211.
First you could have an HTML section to receive the user input from the client.
This section is called HTML(INPUT) as you can see in 7. That is exactly the
URL that the user should browse. The URL for this one is:
http://ntncf99/cgi-bin/db2www/test0.mac/input.
Input for this URL means that you go to the HTML input section first to enter
some data for the macro file. There is also a form contained in this section at
8. Inside the form there is a text field called querytext. That is the data we get
from the user (see 9), which is followed by a Submit button.
Lets now look back to the first part of this file at 1. This is the definition
section. You should define the database name, login ID and the password here
Chapter 4. Net.Data Database Scenario

209

so that Net.Data can use them to open the database that you want. You can also
define other variables that you need in this section. The second part is the SQL
section. This is the section where you issue your SQL command. You may have
more than one SQL section in a macro file. In this example, we have two SQL
sections. As you can see in 2 the SQL section is called get_row(). It counts
how many rows there are that come back from the SQL query. In the first line
youll see the variable $(querytext). In Net.Data, if you want to refer to the
variable, you should use a $ in front of it. querytext is the parameter that we
receive from the client. It is shown at 9. It means that we replace the variable
$(querytext) with the data that the user enters.
In the report section of this SQL, youll see a variable called $(ROW_NUM). It is
a system variable. It will be automatically filled right after the SQL command is
executed. This is so you will know how many rows there are that match your
SQL command. Another part of the SQL section is the message section. It
receives the SQL return code from your SQL statement and does something with
it. If the code is positive, it means it is just a warning. If it is negative, it means
there is an error. In this case we only care about a code of 100. This indicates
no data found.
The next SQL section, go_sql() at 3, performs the SQL statement and shows
the result. Youll see there is no report section for this one. It just lists them in
the way that they come back from DB2.
At 4we see an HTML report section called query(). It is called from 8 when
the user chooses the Submit button on the form. In this section, we plan how we
want to lay out the page. We could put any HTML tag here. Besides that, we
call the SQL sections here, as you can see in 5 and 6. We call get_row()
first, and then go_sql(). The output will go in this sequence and print out the
total number of rows first and then the details. The variable called $(SQL_CODE)
is also a system variable. It contains the SQL return code from the most
recently SQL command.

210

Network Computing Framework for e-business Guide

1%define {
DATABASE=sample
LOGIN=liu
PASSWORD=xxxxxxx
%}
2%Function(DTW_SQL) get_row() {
$(querytext)
%report{
<h4>There are $(ROW_NUM) rows selected.</h4>
%}
%message{
100:{
<center>
<h3>No data found!</h3>
</center>
%}
%}
%}
3%Function(DTW_SQL) go_sql() {
$(querytext)
%message{
100:{
<center>
<h3>No data found!</h3>
</center>
%}
%}
%}
4%HTML(query){
<HTML>
<HEAD><TITLE>Create Table</title></head>
<BODY>
<H2>Result...</h2>
5@get_row()
<hr>
6@go_sql()
SQL_CODE for this query is $(SQL_CODE)
Figure 178 (Part 1 of 2). The Macro File to Access Database Sample

Chapter 4. Net.Data Database Scenario

211

<hr>
</body>
</html>
%}
7%HTML(INPUT){
<head>
<title>SQL Query.</title>
</head>
<body bgcolor=#FFFFFF>
<center>
<p>
<font color=#800000 size=5><strong>SQL Query...</strong></font>
</p>
8 <form action= / cgi-bin/db2www/test0.mac/query method=POST>
<p>
9 <input type=text name=querytext size=80 maxlength=256>
</p>
<p>
<input type=submit name=Submit value=GoSQL!>
</p>
</form>
</center>
</body>
%}
Figure 178 (Part 2 of 2). The Macro File to Access Database Sample

Now lets try our example. First you have to enter the URL for the macro file and
the HTML input section as you can see in Figure 179 on page 213. Then enter
the SQL command that you want and click on the button GoSQL!.

212

Network Computing Framework for e-business Guide

Figure 179. Query the Table Staff from Database Sample

The result from the remote database should look like the following:

Figure 180. Result from Query Table Staff

There are 35 rows selected by the SQL command. We can also check this by
using the DB2 Command window. The results are shown in Figure 181 on
page 214 thru Figure 183 on page 215.

Chapter 4. Net.Data Database Scenario

213

Figure 181. Connect to Database by DB2 Command Window

Figure 182. Query Table Staff by DB2 Command Window

214

Network Computing Framework for e-business Guide

Figure 183. Result from Query Table Staff

Now we try to select another table from the database. We selected the
employee table. The results are shown in Figure 184, Figure 185 on page 216
and Figure 186 on page 216.

Figure 184. Query the Table Employee from Database Sample

Chapter 4. Net.Data Database Scenario

215

Figure 185. Result from Query Table Employee

Figure 186. Result from Query Table Employee

4.2.2 Using Java Applets


Using the first example from 4.2, Net.Data Scenario on page 208 as a base, we
add a Java applet to the scenario to make it a little more complex. We show you
how Java applets can communicate with the Net.Data macro file.
In this scenario, we query the data in table staff, from database Sample. We
want to analyze the salary field in this table and divide all the staff into four

216

Network Computing Framework for e-business Guide

categories based upon their salary. The first category range is from 0 to $13000,
the second is from $13000 to $16000, the third is from $16000 to $19000 and the
last will be from $19000 to $22000. The details on table staff are shown in the
following figure:

Figure 187. The Details of Table Staff

We use the following URL to connect to the HTML input section:


http://ntncf99/cgi-bin/db2www/test.mac/input
When you connect to the page, youll see that there are five text fields in it, as
shown in the following figure:

Chapter 4. Net.Data Database Scenario

217

Figure 188. The HTML Input Section of test.mac

Then we input select ID, NAME, SALARY from staff for the SQL query command
field, 13000 for Level1, 16000 for Level2, 19000 for Level3 and 22000 for Level4.
This means that the client can enter dynamic values for their analysis. After we
enter all of the fields we click on the GoSQL! button. The result is shown in
Figure 189 on page 219. It comes from an applet, which is shown in Figure 190
on page 220.

218

Network Computing Framework for e-business Guide

Figure 189. The Results from HTML Report Section of test.mac

Chapter 4. Net.Data Database Scenario

219

Figure 190. The Results from Applet Running from test.mac

We did some more testing to see some other results. In Figure 191 on page 221
we changed the ranges that we wanted to check for.

220

Network Computing Framework for e-business Guide

Figure 191. The HTML Input Section of test.mac

Figure 192. The Results from HTML Report Section of test.mac

You can see that the pie chart in Figure 193 on page 222 is a little different than
the one in Figure 190 on page 220 since we selected a different set of ranges.

Chapter 4. Net.Data Database Scenario

221

Figure 193. The Results from Applet Running from test.mac

Now that you have seen the results we show you the source code for the macro
file and the applet and explain the code in detail. The source code for the macro
file is shown in Figure 194 on page 223 and the source code for the applet is
shown in Figure 195 on page 227.

222

Network Computing Framework for e-business Guide

%define {
DATABASE=sample
LOGIN=liu
PASSWORD=xxxxxxx
1netdata1.codebase={http://ntncf99:80%}
upperbound=
lowerbound=
%}
%Function(DTW_SQL) go_sql() {
$(querytext)
%message{
100:{
<center>
<h3>No data found!</h3>
</center>
%}
%}
%}
%Function(DTW_SQL) get_row() {
$(querytext)
%report{
<h4>There are $(ROW_NUM) rows selected.</h4>
%}
%message{
100:{
<center>
<h3>No data found!</h3>
</center>
%}
%}
%}
2%Function(DTW_SQL) get_amount() {
SELECT * FROM staff
WHERE SALARY > $(lowerbound) AND SALARY <= $(upperbound)
%REPORT{
@DTW_ASSIGN(temp, ROW_NUM)
%}
Figure 194 (Part 1 of 3). The Macro File test.mac That Contains an Applet

Chapter 4. Net.Data Database Scenario

223

%message{
100:{
<center>
<h3>No data found!</h3>
</center>
%}
%}
%}

3%Function(DTW_APPLET) netdata1(level1, amount1,


level2, amount2,
level3, amount3,
level4, amount4);
%HTML(query){
<HTML>
<HEAD><TITLE>Create Table</title></head>
<BODY>
<H2>Result...</h2>
@get_row()
<hr>
@go_sql()
SQL_CODE for this query is $(SQL_CODE)
<hr>
4@DTW_ASSIGN(lowerbound,0)
@DTW_ASSIGN(upperbound,level1)
@get_amount()
@DTW_ASSIGN(amount1, temp)
@DTW_ASSIGN(lowerbound,level1)
@DTW_ASSIGN(upperbound,level2)
@get_amount()
@DTW_ASSIGN(amount2, temp)
@DTW_ASSIGN(lowerbound,level2)
@DTW_ASSIGN(upperbound,level3)
@get_amount()
@DTW_ASSIGN(amount3, temp)
Figure 194 (Part 2 of 3). The Macro File test.mac That Contains an Applet

224

Network Computing Framework for e-business Guide

@DTW_ASSIGN(lowerbound,level3)
@DTW_ASSIGN(upperbound,level4)
@get_amount()
@DTW_ASSIGN(amount4, temp)
5@DTWA_netdata1(netdata1.codebase,
level1, amount1,
level2, amount2,
level3, amount3,
level4, amount4)
</body>
</html>
%}
%HTML(INPUT){
<head>
<title>SQL Query.</title>
</head>
<body bgcolor=#FFFFFF>
<center>
<p>
<font color=#800000 size=5><strong>SQL Query...</strong></font>
</p>
<form action= / cgi-bin/db2www/test.mac/query method=POST>
<p>
<input type=text name=querytext size=80 maxlength=256>
</p>6
Level1 : <input type=text name=level1 size=10 maxlength=10>
Level2 : <input type=text name=level2 size=10 maxlength=10>
Level3 : <input type=text name=level3 size=10 maxlength=10>
Level4 : <input type=text name=level4 size=10 maxlength=10>
<p>
<input type=submit name=Submit value=GoSQL!>
</p>
</form>
</center>
</body>
%}
Figure 194 (Part 3 of 3). The Macro File test.mac That Contains an Applet

This macro file is based on the one in Figure 178 on page 211. We just made
some modifications to the applet part. All we want to do is to get the input data
from the HTML input section and pass these as parameters to the applet. In
order to communicate with the applet, we had to set up the environment for it.
For example, for the code base path at 1, we defined the code base for the
applet that included the host name and the port number. In this example, the
host name is ntncf99 and the port number is 80. The netdata1.class is placed in
the default directory for HTML files: c:\www\Html:.
At 3 we declare the prototype of the applet. It includes the applet name as
well as the parameters to be passed. In this case, the name of applet is

Chapter 4. Net.Data Database Scenario

225

netdata1 and we pass eight parameters to it. We have to remember the names
of these parameters, because in the applet we get the values of these
parameters by using the exact same names.
In this example, we created a new SQL section called get_amount(). You can
see it at 2. It is designed to get the row number that fits the dynamic condition
in the where clause. There are two variables that are used in this case. One is
upperbound and the other is lowerbound. These two variables will be generated
before we call this SQL section. When this SQL section is executed, it gets the
row number that fits the condition and sets the value in variable temp. We do
this by issuing the command @DTW_ASSIGN(temp, ROW_NUM).
Look at 6, which is in the HTML input section. We have four text fields in the
page. They represent the four salary levels. Each of them has a name and we
will use these names to refer to the values later in the HTML report section.
In the HTML report section %HTML(query), we call get_row() and go_sql() as
shown in Figure 178 on page 211. The differences are shown at 4 and 5. At
4 we assign values to lower-bound and upper-bound. Then we call the SQL
function get_amount(). As we discussed before, these two variables are for the
dynamic condition in the where clause. Right after the function is called, well
have the row number that fits the range in variable temp so we can assign the
value of temp to amount1. The same procedure is applied to amount2, amount3
and amount4.
At 5, we call the applet at this time by issuing the command:

@DTWA_netdata1(netdata1.codebase,
level1, amount1,
level2, amount2,
level3, amount3,
level4, amount4)
Remember the name following @DTWA_ must be the name of the class. The
first parameter should be the code base of the applet. This is just a rule that
you have to follow.
You have seen how to call an applet inside the macro file and also how to pass
parameters to applets. Now, it is very easy for you to develop an applet. In this
example, we design a pie chart to show the percentage for each category. The
source code is shown in Figure 195 on page 227.

226

Network Computing Framework for e-business Guide

import java.applet.Applet;
import java.awt.*;
import java.lang.*;
class ShapeFrame extends Frame
{
String
level1, level2, level3, level4;
int
amount1, amount2, amount3, amount4;
int
total_amount;
2 public ShapeFrame(String l1, int a1, String l2, int a2,
String l3, int a3, String l4, int a4)
{
super(Salary Range ) ;
setBackground(Color.white);
resize(500, 500);
level1 = l1;
amount1 = a1;
level2 = l2;
amount2 = a2;
level3 = l3;
amount3 = a3;
level4 = l4;
amount4 = a4;
3
}

total_amount = a1 + a2 + a3 + a4;

public void paint(Graphics g)


{
int width = 200;
int height = 200;
Font f = g.getFont();
f = new Font(f.getName(), Font.PLAIN, 32);
g.setFont(f);
g.drawString(Salary Range, 135, 60);
4

g.setColor(Color.red);
g.fillArc(130, 80, width, height,
0, amount1*360/total_amount);
g.drawString(Below + $ + level1, 125, 330);
g.setColor(Color.blue);
g.fillArc(130, 80, width, height,
amount1*360/total_amount, amount2*360/total_amount);
g.drawString($ + level1 + -- + $ + level2, 110, 370);
g.setColor(Color.black);
g.fillArc(130, 80, width, height,
(amount1+amount2)*360/total_amount,
amount3*360/total_amount);
g.drawString($ + level2 + -- + $ + level3, 110, 410);

Figure 195 (Part 1 of 2). The Source Code of Applet Netdata1.java

Chapter 4. Net.Data Database Scenario

227

g.setColor(Color.green);
g.fillArc(130, 80, width, height,
(amount1+amount2+amount3)*360/total_amount,
amount4*360/total_amount);
g.drawString($ + level3 + -- + $ + level4, 105, 450);
}
public boolean handleEvent(Event evt)
{
if (evt.id == Event.WINDOW_DESTROY)
{
dispose();
return true;
}
return super.handleEvent(evt);
}
}
public class
{
ShapeFrame
String
int

netdata1 extends Applet


shapeframe;
level1, level2, level3, level4;
amount1, amount2, amount3, amount4;

public void init()


{
1
level1 = getParameter(level1 ) ;
amount1 = Integer.parseInt(getParameter(amount1 ) ) ;
level2 = getParameter(level2 ) ;
amount2 = Integer.parseInt(getParameter(amount2 ) ) ;
level3 = getParameter(level3 ) ;
amount3 = Integer.parseInt(getParameter(amount3 ) ) ;
level4 = getParameter(level4 ) ;
amount4 = Integer.parseInt(getParameter(amount4 ) ) ;
shapeframe = new ShapeFrame(level1, amount1, level2, amount2,
level3, amount3, level4, amount4);
shapeframe.show();
}
}
Figure 195 (Part 2 of 2). The Source Code of Applet Netdata1.java

In this applet there are two classes: one is netdata1 and the other is
ShapeFrame. netdata1 is the main class in this file. It receives the parameters
that are passed by the Net.Data macro. ShapeFrame takes care of drawing the
pie chart. At 1 youll see how to get parameters by using the function
getParameter(). The parameters are passed to class ShapeFrame as you can
see at 2.
Then we get the total number of staff at 3 and the drawing function will be
done by function paint(). At 4 we used fillArc() to draw a filled arc for each
category of all levels in different color, so you can easily see the percentage for
each one.

228

Network Computing Framework for e-business Guide

Chapter 5. JDBC Database Scenario


This chapter shows proof of the concept of interfacing with DB2 using Java
Database Connectivity (JDBC).

5.1 What Is JDBC?


JDBC is a Java API for connecting databases, executing SQL statements and
processing the results. The following figure shows the set of classes, interfaces
and exceptions, entirely written in the Java programming language, that are part
of the java.sql JDBC API package:

Copyright IBM Corp. 1998

229

Figure 196. The java.sql JDBC API Package

The JDBC APIs are included in the JDK 1.1, so using the JDBC does not require
any product installation besides the JDK 1.1. But, for some specific product
functions, there are add-on pieces from database vendors (for example, Oracle
and Sybase).

230

Network Computing Framework for e-business Guide

JDBC takes the portability of Java, which is a platform-independent programming


language, and adds to it the ability to interface with various databases (for
example, DB2, Oracle, Sybase, Informix and others). In fact, using the JDBC
APIs, developers of database applications simply need to write their programs,
without worrying what the target database will be. Then, using an appropriate
interface (also called a driver) between the Java Virtual Machine and the
database, it will be easy to send queries and receive responses.
The driver that we use in the examples in this chapter is called JDBC-ODBC
Bridge Driver. Microsofts Open Database Connectivity (ODBC) API is a
programming interface commonly used for accessing a lot of different relational
databases. It gives you the ability to have access to almost all databases on
almost all platforms, but it uses a C interface and does not offer you all the
advantages of Java: portability, security, lack of pointers and ease-of-use.
Installing the JDBC-ODBC Bridge Driver and specifying inside the database
application that this is the driver we want to use automatically translates all the
JDBC method calls into ODBC function calls. The JDBC-ODBC Bridge Driver
comes with the package sun.jdbc.odbc that is already part of the JDK 1.1.
The JDBC API supports both of the following models for database access:

Client/server model, where an applet, a client application or a Java bean


interacts directly with the database server.

Client/server database server model, where a client machine, usually


running an HTML browser, sends commands to an application running on a
Web server that interfaces directly with a DB2 server and sends a response
back to the client.

This chapter shows examples for both these models and demonstrates the
capability to integrate the new JavaBeans technology in a database
environment.
The typical flow that a JDBC application follows to interact with a database is
described with the following four steps:
1. The application loads a driver to interface with the database.
2. The application connects to the database using the driver.
3. The application creates and executes SQL statements.
4. The application processes the results.
Looking back to Figure 196 on page 230, there are four important entities that
help database developers to write the appropriate Java programs performing
these functions:
1. The public class DriverManager extends Objects class is responsible for
loading the appropriate JDBC driver and handling the database connection.
2. The public interface Connection interface is responsible for connecting to the
database.
3. The public interface Statement interface is responsible for handling SQL
statements on a connection.
4. The public interface ResultSet is responsible for allowing access to the
results of an executed statement.
We examine the flow followed by a JDBC application in the following sections.

Chapter 5. JDBC Database Scenario

231

5.2 Software Configuration


Before going on to examine the different scenarios, we must underline that they
all have two common components:

One machine implements the role of the DB2 server.


We installed on it DB2 Universal Database (UDB) Version 5 and created a
database called SAMPLE.

The other machine implements the role of the DB2 client.


We installed on it DB2 Client Application Enabler (CAE) Version 5 to connect
to the remote DB2 server through the network.

Installing both of these products was very easy.


The platform where our scenarios have been developed was entirely based upon
Windows NT 4.0. Due to the portability of the Java applications, which are
platform-independent, and of the JDBC database programs, which are
database-independent, the same scenarios described in this chapter could be
recreated in an AIX environment without problems and could even interface with
another type of database.
In our configurations, the DB2 server and the DB2 client were installed on two
different Windows NT 4.0 Personal Computers 750-P166, both having 64 MB of
RAM.
One of the scenarios that we describe uses the Java JDBC Select bean, so it will
require the installation of the Beans Developer Kit (BDK) 1.0. We used the June
1997 version of the BDK. After the project ended a new version of the BDK was
announced, but we did not have the opportunity to use that.
Three-tier model scenarios (client, server and database server) usually also
require the installation of a Web browser on the client machine and of a Web
server on the middle tier machine. We installed Netscape Communicator 4.01 as
the Web browser in the client machine, which was a Windows NT 4.0 Personal
Computer 350-P133 with 64 MB of RAM. We installed Lotus Domino Go
Webserver 4.6 as our Web server on the same machine where DB2 CAE was
installed. Notice that this Web server supports JavaSoft Java Servlet API 1.0,
which means that it supports Java servlets.

5.2.1 DB2 CAE Configuration


The installation of the DB2 CAE was relatively easy. It was necessary to do
some configuration of CAE for the scenario. The steps we followed are similar to
what we did in Chapter 4, Net.Data Database Scenario on page 197, with
some small differences. We repeat those steps below to show what we had to
do.
First of all, we opened the DB2 for Windows NT menu by clicking on the Start
button, then selecting Programs and DB2 for Windows NT. From that menu we
finally selected Client Configuration Assistant. The Client Configuration Assistant
is a utility tool that can be used to create connections to DB2 databases and to
test those connections.
As soon as the Client Configuration Assistant Welcome window came up, we
selected the Add Database button.

232

Network Computing Framework for e-business Guide

Figure 197. Client Configuration Assistant Welcome Window

Then the Source section for the Add Database SmartGuide window was brought
up and we had to select how we wanted to set up a connection. Since our
database was located in the local network, we selected Search the Network, as
shown in the following figure.

Chapter 5. JDBC Database Scenario

233

Figure 198. Selecting the Source in the Add Database SmartGuide Window

Finally, we chose the Next button.


The Add Database SmartGuide window brought us to the Target Database
section, as shown in the following figure.

Figure 199. Target Database Section for the Add Database SmartGuide Window

234

Network Computing Framework for e-business Guide

We expanded the Known Systems field by clicking the plus sign ( + ) next to it.
The NTNCF100 machine was automatically found and displayed.

Figure 200. Expanding the K n o w n Systems Field

We continued expanding the object tree and the Client Configuration Assistant
found three DB2 databases for the NTNCF100 machine. We selected SAMPLE, as
shown in the following figure.

Figure 201. Selecting the Target Database


Chapter 5. JDBC Database Scenario

235

We then clicked on the Add System... button and the following window was
displayed in order for us to select the protocol we wanted to use to find the DB2
server.

Figure 202. Select the Protocol to Find the Server

We set the Protocol text field to TCP/IP and the Hostname text field to NTNCF100,
which was the name of the machine where we installed the DB2 UDB and where
we had created the SAMPLE database. The following DB2 Message window
came up to confirm that our operation was successful.

Figure 203. DB2 Message Window

Then we clicked on SAMPLE as indicated in Figure 201 on page 235 and we also
clicked on the Alias tab on the top of the Add Database SmartGuide window.
That was to give an alias, for example SAMPLE1, to the target database in our
local workstation, as indicated in the following screen.

236

Network Computing Framework for e-business Guide

Figure 204. Giving an Alias to the Target Database in the Local Workstation

At that point we chose the Done button at the bottom of the window and the
following Confirmation window was displayed by the Client Configuration
Assistant to confirm that the connection configuration for SAMPLE1 was added
correctly.

Figure 205. Confirmation Message

We could then test the connection by selecting the Test Connection button. In
order for us to connect to the DB2 database whose alias is SAMPLE1, we had to
enter a user ID and password for that database. Then we had to click the OK
button, accepting the Connection mode set by default to Share, as shown in the
following window.

Chapter 5. JDBC Database Scenario

237

Figure 206. Connecting to the DB2 Database

Finally, we received a confirmation message telling us that the connection test


was successful.

Figure 207. The Connection Test Was Concluded Successfully

We chose the OK button and then the Close button on the Confirmation window
shown in Figure 205 on page 237. We could see that the SAMPLE database on
the NTNCF100 DB2 server machine had become available to the DB2 client
workstation with the alias name set to SAMPLE1, as shown below:

238

Network Computing Framework for e-business Guide

Figure 208. Available DB2 Databases in the Client Configuration Assistant Window

Another test that confirmed that the connection was successful was done by
using the command line processor for DB2 CAE. This tool can be launched by
selecting the Command Line Processor item from the DB2 for Windows NT menu.
At the db2 => prompt, we entered the following command:

connect to sample1 user pistoia using xxxxxxx


where pistoia was the user ID and xxxxxxx was the password for the SAMPLE1
database (see Figure 206 on page 238), as shown in the following window.

Figure 209. Using the DB2 Command Line Processor for Testing the Connection

The output confirmed that the connection was successful, giving us all the
database connection information.

Chapter 5. JDBC Database Scenario

239

Figure 210. DB2 Connection Information Using the DB2 Command Line Processor

5.3 JDBC Client/Server Scenario


This scenario was based upon a two-tier model for database access. In this
scenario a JDBC application communicates with a DB2 database using the
JDBC-ODBC Bridge Driver. As we had already indicated, this scenario was built
using two different Windows NT 4.0 machines, the DB2 client and the DB2 server.
The Java application that we built passes to the Java Virtual Machine the
database URL plus the user ID and the password parameters for that database
(whose alias is SAMPLE1 as shown in Figure 206 on page 238). This database
has nine tables, but the most impressive of them is PISTOIA.EMPLOYEE. It is
already established inside the Java application that this will be the retrieved
table. In addition, PISTOIA.EMPLOYEE has 14 columns and we retrieve the most
important of them. They are FIRSTNME, corresponding to the first names of the
employees and LASTNAME, corresponding to the last name of the employees.
The following diagram describes the flow of this JDBC client/server scenario.

240

Network Computing Framework for e-business Guide

Figure 211. The Flow of the JDBC Client/Server Scenario

Looking at the diagram, we could summarize the flow as follows:


1. The user invokes the JDBC application on the client machine using the java
command. This is followed by the class name of the application, the JDBC
database URL, the user ID and the password parameters that were indicated
during the CAE configuration (see Figure 206 on page 238). This can all be
done on the command line. The JDBC application invokes the JDBC-ODBC
Bridge Driver and all the JDBC operations are automatically translated into
the correspondent ODBC operations.
2. The ODBC connects to the DB2 CAE on the client machine, passing it all the
required parameters:

Database URL

Database user ID

Database password

Selected table

Selected columns

3. The DB2 CAE connects to the DB2 UDB located on the server machine and
passes to it the table and the columns requested.
4. The DB2 server sends the response back to the DB2 CAE on the client
machine. The DB2 CAE passes the response back to the client application
using the JDBC-ODBC Bridge Driver.
We called this application Retrieve, because its function is to retrieve data from
the SAMPLE1 database. The source code for the Retrieve JDBC application is
shown in the following figure.

Chapter 5. JDBC Database Scenario

241

import java.sql.*;
class Retrieve
{
public static void main(String argv[])
{
if (argv.length == 0)
{
System.err.println(No URL passed ) ;
System.exit(1);
}
try
{
Class.forName(sun.jdbc.odbc.JdbcOdbcDriver ) ;
String url = argv[0];
String userid, passwd;
if (argv.length > 1)
userid = argv[1];
else
userid = ;
if (argv.length > 2)
passwd = argv[2];
else
passwd = ;
Connection con = DriverManager.getConnection(url, userid, passwd);
Statement stat = con.createStatement();
ResultSet rs = stat.executeQuery(SELECT FIRSTNME, LASTNAME FROM PISTOIA.EMPLOYEE ) ;
System.out.println();
System.out.println(FIRST NAME and LAST NAME ) ;
System.out.println(________________________);
System.out.println();
while (rs.next())
{
String firstnme = rs.getString(FIRSTNME ) ;
String lastname = rs.getString(LASTNAME ) ;
System.out.println(firstnme + + lastname);
}
stat.close();
con.close();
}
catch(Exception e)
{
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}

Figure 212. Retrieve.java

We can see that writing an application using the JDBC API is not very difficult.
We examine the source code of the Retrieve.java application in order to show
how it works.
First of all, notice that it is assumed that the user on the client machine passes
the JDBC database URL, the user ID and the password when the application is
invoked by the java command. The database URL is a critical piece of
information that must be passed to the JDBC application. If no URL is passed,
the application is terminated by calling the exit() method, java.lang.System. An

242

Network Computing Framework for e-business Guide

example of this is shown in the following MS-DOS window, where the Retrieve
application has been invoked without passing it the required URL.

Figure 213. The Application Is Terminated If No URL Is Passed

Note
We have seen that you need to specify the JDBC URL for the database. What
exactly is a JDBC URL? It is an address that is necessary to identify a
database so that the appropriate driver is able to recognize the database and
to establish a connection with it. A JDBC URL must follow a well-defined
standard syntax, such as:

protocol:subprotocol:subname
A JDBC URL is composed of three different parts separated by colons.
These three parts are defined in the following list:
1. protocol is always jdbc.
2. subprotocol specifies the subprotocol that interfaces with JDBC. For
example, if we want to connect to a database using the JDBC-ODBC
Bridge Driver, this part of the URL will be odbc.
3. subname specifies the data source, which is the way we identify the
database. Of course this part of the JDBC URL can vary, because it
strictly depends on the subprotocol used.
In our scenarios, the JDBC URL is simply:

jdbc:odbc:sample1

Now we should understand the importance of the JDBC URL in a JDBC


application. If that URL were not specified, it would be impossible for the
application to locate the target database. User ID and password are not strictly

Chapter 5. JDBC Database Scenario

243

required, and the application provides an empty string if they are not
communicated on the command line.
Another important thing that we must notice in the source code of that
application is that the Class.forName() method is invoked, passing to it the string
sun.jdbc.odbc.JdbcOdbcDriver as a parameter. In this way the forName()
method locates, loads and links the class JdbcOdbcDriver in the package
sun.jdbc.odbc, which is the JDBC-ODBC Bridge Driver.
The following steps are very simple and they involve the four most important
entities of the java.sql JDBC API package (see 5.1, What Is JDBC? on
page 229):
1. The DriverManager class is used to load the appropriate JDBC driver.
2. Using the DriverManager.getConnection() method with the URL, user ID and
password as parameters, a connection object is created for connecting to the
appropriate database.
3. Using the Connection.createStatement() method, a statement object is
created for executing an SQL statement and obtaining the results produced
by it.
4. Using the Statement.executeQuery() method with the following SQL
statement as a parameter, a ResultSet object is created for allowing access
to the results of the executed statement:

SELECT FIRSTNME, LASTNAME FROM PISTOIA.EMPLOYEE


Results are then sent back to the standard output. This should explain the flow
of this JDBC application.
This application can be compiled in the client machine, where the DB2 CAE has
been installed, without the need to copy the source code to any particular
directory. You simply have to enter the command:

javac Retrieve.java
In fact, the two packages, java.sql JDBC API and sun.jdbc.odbc JDBC-ODBC
Bridge Driver, come with all the classes of JDK 1.1, so Retrieve.java can be
treated as a regular Java file.
Once you have compiled it, you launch it by typing in the following in the same
directory where the file Retrieve.class is stored:

java Retrieve jdbc:odbc:sample1 pistoia xxxxxxx


This automatically generates the flow that we showed in Figure 211 on
page 241. The database SAMPLE1 will be contacted and the FIRSTNME and
LASTNAME columns of the PISTOIA.EMPLOYEE table will be displayed on
standard output as shown in the following figure.

244

Network Computing Framework for e-business Guide

Figure 214. Output Generated by the Retrieve JDBC Application

5.4 JDBC Client/Server Scenario Using Java Beans


This section describes a very impressive example of how it is possible to
integrate Java Beans in a client/server database scenario. We use the JDBC
Select bean that we have already described in Network Computing Framework
Component Guide , SG24-2119.
The scenario that we are going to describe is shown in the following diagram:

Chapter 5. JDBC Database Scenario

245

Figure 215. The Flow of the JDBC Client/Server Scenario Using Java Beans

We can summarize the flow of this scenario as follows:


1. The user enters in the Customizer panel for the JDBC Select bean the JDBC
database URL, the login user ID and the password.
2. If data entered by the user is correct, the user receives back from the DB2
UDB server the list of all the available tables of the selected database.
3. The user is allowed to select one table from the list of all the available tables
and the users request arrives to the DB2 UDB server.
4. The DB2 UDB server sends the list of all the columns for the selected table
back to the user.
5. The user selects one or more columns on the list and the user s request
arrives at the DB2 UDB server.
6. Finally the data requested by the user is sent from the DB2 UDB server back
to the client machine.
The JDBC Select bean imports the java.sql JDBC API package:

import java.sql.*;
In addition, as indicated by Figure 215, it interfaces with the DB2 CAE present on
the database client machine using the JDBC-ODBC Bridge Driver. The following
lines of code demonstrate this:

246

Network Computing Framework for e-business Guide

 static
{

Connection connect(String url,


String user,
String password,
java.awt.Label status)

status.setText(Connecting to + url);
try
{
Class.forName(sun.jdbc.odbc.JdbcOdbcDriver ) ;
}
catch (Exception ex)
{
status.setText(Couldn t load JDBC-ODBC bridge driver ) ;
System.err.println(Caught Exception: + ex);
ex.printStackTrace();
return null;
}
...

Building this JDBC client/server scenario using the JDBC Select bean is very
simple. After you launch the BeanBox application, you must pick the JDBC
Select bean from the ToolBox window and place it onto the BeanBox window, as
shown in the following figure:

Chapter 5. JDBC Database Scenario

247

Figure 216. The JDBC Select Bean Placed onto the BeanBox Window

This Java bean allows itself to be resized. It is convenient to resize it before


going on with this scenario, because it will have to contain and display all the
data retrieved from the database. Resizing the select bean can be done by
clicking the mouse on one of the corners of its black and white boundary,
holding the mouse down and then stretching the corner out.
This bean also needs to be configured, in order to connect to the appropriate
database and to retrieve the requested data. Since this is a complex operation,
the JDBC select bean comes with a customizer. You should notice that a Java
class file called SelectCustomizer is included in the sunw.demo.select package.
The capability to customize the select bean using a customizer is also confirmed
by the fact that you can select the Customize item from the Edit pull-down menu

248

Network Computing Framework for e-business Guide

from the BeanBox window. As soon as you select this item, you will see the
Customize panel appear on the screen. You have three text fields to fill in:
1. JDBC URL, by default set to jdbc:odbc:SQLSERVER:.
2. User, by default set to guest.
3. Password, by default set to guest.
This is shown in the following three lines of code:

 private

String url = jdbc:odbc:SQLSERVER ;


private String user = guest ;
private String password = guest ;

Of course you cant connect to the SAMPLE1 database on the DB2 server
machine using these default values. A java.sql.SQLException would be thrown
since it is the wrong database. This would be immediately registered at the
bottom of the Customizer panel, as shown in the following figure:

Chapter 5. JDBC Database Scenario

249

Figure 217. SelectCustomizer Panel When an SQLException Is Thrown

The MS-DOS window associated with the BeanBox application also would show
this exception, as we can see in the following figure:

250

Network Computing Framework for e-business Guide

Figure 218. MS-DOS BeanBox Window When an SQLException Is Thrown

For this reason, you must fill in those text fields with the proper values. In our
scenario these rules should be respected:
1. JDBC URL must be set to jdbc:odbc:sample1.
2. User must be set to pistoia.
3. Password must be set to xxxxxxx.
After this operation has been performed, the SelectCustomizer panel should
appear similar to the following figure:

Chapter 5. JDBC Database Scenario

251

Figure 219. The SelectCustomizer Panel Correctly Filled

Then you can click the User Tables button for the SelectCustomizer panel without
an SQLException being thrown and the customizer will then display the nine
available tables for the SAMPLE1 database, as shown in the following screen:

252

Network Computing Framework for e-business Guide

Figure 220. Available Tables for the SAMPLE1 Database

Notice that you can select the Back button at the bottom of the SelectCustomizer
panel to go back to the last menu.
You can select a table by simply highlighting it with your mouse. For example,
we selected PISTOIA.EMPLOYEE and the list of all the available columns for that
table was immediately displayed. The top of the SelectCustomizer window
summarizes the content of the panel:

Database: jdbc:odbc:sample1
Table: PISTOIA.EMPLOYEE
Number of columns: 14
You can then choose the columns you want in SQL SELECT. For example, we
selected:
Chapter 5. JDBC Database Scenario

253

1. EMPNO
2. FIRSTNME
3. MIDINIT
4. LASTNAME
5. WORKDEPT
6. JOB
7. BIRTHDATE
8. SALARY
The following window shows the SelectCustomizer panel after those selections
were done:

254

Network Computing Framework for e-business Guide

Figure 221. The SelectCustomizer Panel after Some Columns Have Been Selected

As soon as we select the columns, our choices are automatically registered by


the MS-DOS window associated with the BeanBox application, as shown in the
following window:

Chapter 5. JDBC Database Scenario

255

Figure 222. The MS-DOS BeanBox Window Registers A l l Our Choices

The BeanBox window dynamically updates the displayed data while we are
making our choices. After all the selections are done, it will appear similar to
the following:

256

Network Computing Framework for e-business Guide

Figure 223. The JDBC Select Bean Displays A l l Requested Data

Notice that the Properties window for the JDBC Select bean also dynamically
registers all the choices that we made on the SelectCustomizer panel, including
the final SQL statement, as shown in the following window:

Figure 224. Properties Window for the JDBC Select Bean

Chapter 5. JDBC Database Scenario

257

The Customizer panel provides a GUI that allows the user to enter the SQL
statements in an interactive way. This would have been impossible simply using
the Properties window. Without a customizer, the user could type the SQL
statement relative to the particular data they want to retrieve. That is the reason
why the JDBC Select bean comes with its own customizer.
You can choose the Back button for the SelectCustomizer panel, in order to
select other tables or to connect to different databases or you can choose the
Done button.
This section has demonstrated in a simple way that Java beans can be easily
integrated in a client/server database scenario, with very attractive advantages.
Java beans add code reusability to the Java portability. Moreover, using visible
Java beans inside JavaBeans-aware visual builder tools lets you obtain nice
graphical results.

5.5 JDBC Client/Server Database Server Scenario Using Java Servlets


This section describes an example of a three-tier model scenario, including
client, server and database server.
The client application is a Web browser that is running Netscape Version 4.01.
The client application has access to the database server DB2 UDB Version 5
passing through a middle tier machine, where we have installed the DB2 CAE
Version 5 and the Lotus Domino Go Webserver Version 4.6. The environment
was completely based upon Windows NT 4.0, even if similar scenarios are easily
portable to several different environments. An example of this would be AIX,
using the portability of Java and the ability for JDBC applications to interface to
different databases.
Three-tier model applications are in general more useful than two-tier model
applications since the middle tier machine provides a way to interface with
multiple clients.
The advantage of using Lotus Domino Go Webserver as the Web server
application is that this Web server is servlet-enabled. It supports the JavaSoft
Java Servlet API 1.0.
The scenario that we are going to describe uses this advantage. The application
on the server machine that receives the requests from the client, interacts with
the database to retrieve the requested data and sends the response back to the
client is a Java servlet. Another advantage is that this Java servlet will use the
JDBC protocol, importing and using the java.sql package to interact with the DB2
database.
This scenario shows how to simultaneously use the portability of Java, the
capability for JDBC applications to interact with several different databases and
finally all the advantages offered by Java servlets that we described in 2.1.1,
Advantages of Servlets on page 12.
The following diagram shows the flow of this scenario:

258

Network Computing Framework for e-business Guide

Figure 225. Flow of the JDBC Three-Tier Model Scenario Using Java Servlets

We describe the flow of this scenario in the following list:


1. Users at the client machine point their browser to an HTML file containing a
form.
2. The Web server application in the server machine sends the HTML file
containing the form back to the client.
3. The user fills out the forms entering the JDBC database URL (in this scenario
it is set to the default value jdbc:odbc:sample1), user ID and the password
and then submits the form. The HTML form invokes a servlet inside the Web
server using the GET HTTP method. As soon as this happens, the Web
server initializes the invoked servlet by calling the init() method (if this is the
first time that the serlvet has been called).
4. The Web server creates an HttpServletRequest object and passes it to the
servlet. The servlet is able to retrieve from this object the user ID and
password parameters.
5. The Web server creates an HttpServletResponse object and passes it to the
servlet.
6. The servlet, based upon the JDBC protocol, invokes the JDBC-ODBC Bridge
Driver to interface with the DB2 CAE client application.
7. The DB2 CAE client sends a request to the DB2 UDB database server
application in order to retrieve the requested data.
8. The DB2 UDB database server application sends the requested data back to
the DB2 CAE database client application.
9. The DB2 CAE database client application inside the server machine passes
the retrieved data back to the JDBC servlet using the JDBC-ODBC Bridge
Driver.
10. The JDBC servlet passes the response to the Web server using the
HttpServletResponse object.
11. The Web server sends the response back to the client machine. It then
displays the retrieved data on the Web browser.

Chapter 5. JDBC Database Scenario

259

This scenario is based upon two files that must be written by the developer:

The HTML file containing the HTML form. This file is called
RetrieveForm.html.

The Java servlet that is invoked using the GET HTTP method from within the
H T M L < f o r m > t a g . This Java file is called RetrieveServlet.java.

The file Retrieve.html is very simple and is shown in the following figure:

<HTML>
<HEAD>
<TITLE>RetriveForm</TITLE>
</HEAD>
<BODY>
<H1>Retrieve Data From the DB2 Database</H1>
<HR>
<FORM Method=GET Action= / servlet/RetrieveServlet>
<P>
Please, fill out this form.
<P>
JDBC URL
<BR>
<SELECT>
<OPTION>jdbc:odbc:sample1
</SELECT>
<P>
User ID
<BR>
<INPUT Type=text Name=userid Size=8>
<P>
Password
<BR>
<INPUT Type=password Name=passwd Size=8>
<P>
Please, submit this form.
<BR>
<INPUT Type=Submit Value=Submit>
<INPUT Type=Reset Value=Reset>
</FORM>
<P>
Thank you!
<HR>
</BODY>
</HTML>
Figure 226. The File RetrieveForm.html

After we save this file in the HTML directory of our Web server, we can invoke it
by pointing to its URL. The Web server sends the HTML file containing the HTML

260

Network Computing Framework for e-business Guide

form back to the clients browser and the user can fill out the form by setting
User ID to pistoia and Password to xxxxxx, as shown in the following figure:

Figure 227. The Form Contained in the RetrieveFrom.html Page

Notice that the JDBC URL appears inside a selection menu, without the option to
select different items. This is only a demonstration application, but it would be
easy to include in the selection list new items, corresponding to different
databases.

Chapter 5. JDBC Database Scenario

261

As soon as the user at the clients machine clicks on the Submit button, the
JDBC servlet is invoked. It interacts with the DB2 database and retrieves the
requested data that is displayed on the client s browser, as the following screen
demonstrates:

Figure 228. The Client s Browser Displays the Retrieved Results

262

Network Computing Framework for e-business Guide

Notice that the servlet has been invoked within the <form> tag of the HTML
page using the GET HTTP method. You can see a simple example of this by
reading the URL after the servlet has been invoked.
This JDBC servlet connects to the same database, SAMPLE1, that we saw in
previous examples. It simply retrieves the two columns FIRSTNME and
LASTNAME from the table PISTOIA.EMPLOYEE, just like the Retrieve JDBC
application did (see 5.3, JDBC Client/Server Scenario on page 240). In effect
the source code for this RetreiveServlet servlet class is obtained in a very
simple way from the Retrieve.java file, as we can see comparing the lines of
code shown in Figure 212 on page 242 with those shown in the following figure:

import
import
import
import

java.sql.*;
javax.servlet.*;
javax.servlet.http.*;
java.io.*;

class RetrieveServlet extends HttpServlet


{
public void init(ServletConfig config)
throws ServletException
{
super.init(config);
log(init() method called ) ;
}
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
log(service() method called ) ;
ServletOutputStream out = response.getOutputStream();
response.setContentType(text/html ) ;
try
{
Class.forName(sun.jdbc.odbc.JdbcOdbcDriver ) ;
String url = jdbc:odbc:sample1 ;
String userid = request.getParameter(userid ) ;
String password = request.getParameter(passwd ) ;
Connection con = DriverManager.getConnection(url, userid, password);
Statement stat = con.createStatement();
ResultSet rs = stat.executeQuery(SELECT FIRSTNME, LASTNAME FROM PISTOIA.EMPLOYEE ) ;
out.println(<html><head><title>RetrieveServlet</title></head><body> ) ;
out.print(<h1>FIRST NAME and LAST NAME</h1> ) ;
out.println(<hr> ) ;
while (rs.next())
{
String firstnme = rs.getString(FIRSTNME ) ;
String lastname = rs.getString(LASTNAME ) ;
out.println(firstnme + + lastname + <br> ) ;
}
out.println(</body></html> ) ;
stat.close();
con.close();
out.close();
}
catch(Exception e)
{
out.println(e.getMessage());
e.printStackTrace();
}

Figure 229 (Part 1 of 2). The RetrieveServlet.java File


Chapter 5. JDBC Database Scenario

263

log(service() method exit ) ;


}
public void destroy()
{
log(destroy() method called ) ;
}
}

Figure 229 (Part 2 of 2). The RetrieveServlet.java File

You can see that the main body of code for the Retrieve.java file has not
changed. The most significant statements are in the service() method of
RetrieveServlet. The two methods init() and destroy() do not do anything but log
their activations. The init() method would be more important if it had to retrieve
initialization parameters. Also, the destroy() method would be more significant if
it were used to store some information into a permanent file before killing the
servlet. This scenario does not require these operations, so the service()
methods reuse the more important procedures done by the Retrieve JDBC
application.
There are a few differences:

264

The RetrieveServlet class needs to import the java.sql package, as well as


the Retrieve applications that need it. It needs to import the javax.servlet
and the javax.servlet.http packages that are part of the JavaSoft Java Servlet
API 1.0, and the java.io package. The Retrieve application did not have to
import them.

The retrieved data is not sent to standard output, using the


System.out.println() method, as was true for the Retrieve JDBC application.
The retrieved data needs to be sent back to the clients browser, so we use
the method getOutputStream() for the HttpServletResponse class to get an
instance, out, for the ServletOutputStream class. Then data is sent back to
the client machine by invoking the out.println() method.

The response that the application sends back to the client machine is
formatted in an appropriate HTML form, in order to be displayed by the
clients browser.

Since, in this case it does not make sense to enter parameters on the
command line, the user ID and password are communicated within the HTML
form and then their values must be retrieved by using the getParameter()
method for the HttpServletRequest class.

Network Computing Framework for e-business Guide

Chapter 6. Transaction Server Scenario (NT and S/390)


This chapter shows a proof of concept for interfacing Web servers and CICS on
the NT platform as well as CICS on MVS/ESA.
The transaction server scenario was built to show that it is possible to integrate
CICS transactions running in an existing application environment with the Web
using IBM Connectors. We used three systems:

Client
In our scenario the client is a Web browser located on a Windows NT 4.0
system. We used Netscape Communicator 4.01, Netscape Navigator Gold
3.02 and Microsoft Internet Explorer 3.02. Since we needed to be able to use
Java programs, the only requirement was a Java-enabled browser.

Web Server System


The Web server ran on Windows NT 4.0 where we also installed: Lotus
Domino Go Webserver, CICS Client for Windows NT, IBM Transaction Server
for Windows NT, the IBM Connectors CICS Internet Gateway, CICS Gateway
for Java and IBM SNA Communicator Server for Windows NT V5.

Application Server
The applications ran on the S/390 using CICS/ESA V3.3.

The IBM connectors may all be on the same system if you choose and they can
each provide different solutions, to different users. We used the IBM Transaction
Server for Windows NT because CICS/ESA V3.3 didnt have the EPI CICS client
support. The next release, CICS/ESA V4.1 or IBM Transaction Server for OS/390
does have EPI CICS client support. We used IBM SNA Communication Server V5
to make the SNA connection between CICS/ESA and the Transaction Server for
Windows NT. Figure 230 on page 266 represents the environment and the links
that we used between the three different systems.
For more information on connectors, see Chapter 3, Connectors on page 113.

Copyright IBM Corp. 1998

265

Figure 230. The Scenario s Environment

6.1 Application Environment


The application environment that we used was based on a CICS 3270 transaction
that can read, browse, add and modify a VSAM file. We added to the original
demo application another program in order to provide some more examples. All
the transactions can be activated by the Web browser or by a 3270 terminal.
This helped us to show how an existing and potentially old CICS application can
be used in the new Internet world.
In our example, the CICS Transaction Server for Windows NT has defined all the
transactions as remote. Its role was to route the transactions to CICS/ESA,
where they will be executed and where the VSAM file is located.
To facilitate the use of the demos, we built some Web pages and links that let us
surf inside the demo. To do that we created a subdirectory www\ncfral where
we put all our materials and we used ncf to suffix all our files. The directory
created was also defined in the Web server inserting the following statement in
the mapping section:

Pass /ncf/*

c:\www\ncfral\*

We built the examples based on the CICS Internet Gateway and on CICS
Gateway for Java as shown in the main index of the Web page in Figure 231 on
page 267.

266

Network Computing Framework for e-business Guide

Figure 231. The Index for the CICS Demos

The source for the above Web page follows:

Chapter 6. Transaction Server Scenario (NT and S/390)

267

<!doctype html public html2.0>


<html>
<head>
<title>NCF SunShine Enterprise - CICS Demos index </title>
<meta name=abstract content=NCF Program Overview Raleigh 1997>
<meta name=copyright content= ( C)Copyright IBM Corporation, All Rights Reserved>
<meta name=keywords content=NCF Program Overview>
<meta name=security content=public>
</head>
<!-- end ibmhead--------------------------------------------------------- -->
<body>
<table>
<tr><th>
<td>
<h1>Welcome to the SunShine</h1>
</td>
<td>
<img src= / cig/smile.gif alt=Smile>
</td>
<td>
<h1>NCF Enterprise</h1>
</td>
</table>
<hr>
<table>
<tr><th>
<td>
<img src= / cig/Cigdlrge.gif alt=CICS Gif>
</td><td>
<A HREF= / cig/ncfstart.htm>CICS Internet Gateway: sample operations</A>
<p>
<A HREF= / cig/ncf3270s.htm>CICS Internet Gateway: CICS transactions</A>
<p>
<A HREF= / cig/ncfsurf.htm>CICS Internet Gateway: AutoExit=On</A>
<p>
<A HREF= / cig/ncfstim.htm>CICS Internet Gateway: starting CICS transactions from images</A>
<p>
<A HREF= / jgate/ncfcxjava.htm>CICS Java Gateway demonstration</A>
</td>
</table>
<hr>
<a href= / ncf/ncfhpage.htm>
<img src= / ncf/greyhome.gif alt=Home Page></a>
<a href= / cig/index.htm>
<img src= / cig/cigdoc.gif alt=CICS Internet Gateway Documentation></a>
<!**********************************************************************>
<!-- end ibmbody--------------------------------------------------------- -->
</body>
</html>

Figure 232. Source for CICS Demos

The CICS index page allows you to surf through the CICS applications and show
some of the characteristics of the CICS Internet Gateway and CICS Gateway for
Java. You can build your own index by inserting the transactions or the
programs that you want to access from an Internet or intranet.
We modified the CIGD.INI file in c:cicscli\bin, by placing a personalized header,
trailer and exit page in it. The CICS Internet Gateway will insert our header and
trailer for the 3270 emulator screens, as shown in Figure 235 on page 273. It
will use the specified ExitPage every time that the user closes the session or a
time-out value expires.

268

Network Computing Framework for e-business Guide

cicscli\bin\cigd.ini modified
Header = C:\CICSCLI\cig\html\ncftext.htm
Trailer = C:\CICSCLI\cig\html\ncftail.htm
ExitPage = /cig/ncfcics.htm
ExitAid = 0x00
PFKey24 = Off
PAKeys = Off
GraphicKeys = Off
AutoExit = Off
ImbedHTML = Off
AppendEXE = Off

The personalized header follows:

<table>
<tr><th>
<td>
<h1>Welcome to the SunShine</h1>
</td>
<td>
<img src= / cig/smile.gif alt=Smile>
</td>
<td>
<h1>NCF Enterprise</h1>
</td>
</table>
<HR ALIGN=center SIZE=4>

The personalized trailer follows:

<HR ALIGN=center SIZE=4>


<a href= / cig/endusing.htm>CICS Internet gateway users guide</a>
<p>
<a href=http://ntncf120/>NCF-120 Web Server</a>
<a href=http://ntncf99/>NCF - 99 Web Server</a>

The first topic in the index is called CICS Internet Gateway: sample operations.
It links to a customized cigstart HTML page, distributed with the CICS Internet
Gateway, called ncfstart, as shown in Figure 233 on page 270.

Chapter 6. Transaction Server Scenario (NT and S/390)

269

<!doctype html public html2.0>


<html>
<head>
<title>NCF SunShine Enterprise - CICSTART </title>
<meta name= abstract content= NCF Program Overview Raleigh 1997>
<meta name= copyright content= ( C)Copyright IBM Corporation, All Rights Reserved>
<meta name= keywords content= NCF Program Overview>
<meta name= security content= public>
</head>
<!-- end ibmhead--------------------------------------------------------- -->
<body>
<img src= / cig/cigmast.gif alt= IBM>
<!--->
<h2>Welcome to the WebServer on NCF Project </h2>
<p>This page gives some examples of how to use the CICS Internet gateway:
<ul>
<li>
<a href = #Query>Query the current gateway settings</a>
<li>
<a href = #List>List the available CICS systems</a>
<li>
<a href = #Tran>Different ways to start a transaction</a>
<li>
<!-- Administration functions
-->
<a href = #Admin>Administration</a>
</ul>
<hr>
<!**********************************************************************>
<p>
<h3>
<a name = Query>Query the current gateway settings</a>
</h3>
<p>
<!-- This is useful to the browser user since it lets him know
-->
<!-- the settings that can directly affect him. e.g. the cursor
-->
<!-- character
-->
<form method= post action= / cig-bin/ciginfo/Query>
<input type= submit value= Click here to query the current gateway settings.>
</form>
<p>
<hr>
<!**********************************************************************>
<p>
<h3>
<a name = List>List the available CICS systems</a>
</h3>
<p>

Figure 233 (Part 1 of 3). Customized cigstart

270

Network Computing Framework for e-business Guide

<!-- This function lists the available CICS servers by querying the EPI
-->
<!-- and building a list to present to the user, and allows selection
-->
<!-- of a system from the list
-->
<form method= post action= / cig-bin/ciginfo/List>
<input type= submit value= Click here to list the cics servers.>
</form>
<p>
<hr>
<!**********************************************************************>
<p>
<h3>
<a name = Tran>Different ways to start a transaction</a>
</h3>
<p>
<!-- with a predetermined system and transaction
-->
<p>
<ol>
<li>
A predetermined system and transaction
<p>
<form method= post action= / cig-bin/cigcgi/StartTran>
<input type= hidden name= SystemName size=8 maxlength=8 value= CICSTCP>
<input type= hidden name= TranName size=25 maxlength=99 value= CESN>
<input type= submit value= Click here to perform transaction CESN on
system NTNCF120>
<!-- Note that TranData need not be specified, transaction name and data
-->
<!-- can be specified in TranName
-->
</form>
<hr>
<li>
A predetermined system and transaction but with variable data
<p>
<form method= post action= / cig-bin/cigcgi/StartTran>
<input type= hidden name= SystemName size=25 maxlength=99 value= CICSTCP>
<input type= hidden name= TranName size=25 maxlength=99 value= CECI>
Specify data for CECI transaction
<input type= input name= TranData size=25 maxlength=99
value= INQUIRE TRAN ><br>
<input type= submit
value= Click here to perform transaction CECI on system NTNCF120 >
</form>
<hr>
<li>

Figure 233 (Part 2 of 3). Customized cigstart

Chapter 6. Transaction Server Scenario (NT and S/390)

271

A predetermined system and transaction with variable data and hidden


configuration override (AutoExit)
<form method= post action= / cig-bin/cigcgi/StartTran>
<input type= hidden name= SystemName size=25 maxlength=99 value= CICSTCP>
<input type= hidden name= TranName size=25 maxlength=99 value= CECI>
<input type= hidden name= AutoExit size=8 maxlength=8 value= On>
Specify data for CECI transaction
<input type= input name= TranData size=25 maxlength=99 value= INQUIRE TRAN >
<input type= submit value= Click here to perform transaction CECI
on system NTNCF120 >
</form>
<hr>
<li>
Variable system, transaction and data with user selectable configuration
override (GraphicKeys)
<form method= post action= / cig-bin/cigcgi/StartTran>
Specify a CICS System <input type= input name= SystemName size=8 maxlength=8
value= CICSTCP >
and a Transaction and Data<input type= input name= TranName size=25
maxlength=99 value= CESN ><br><p>
Please select the type of PF keys to display. <br>
Graphic buttons using GIFS <input type= radio name= GraphicKeys value= On checked>
Normal browser buttons <input type= radio name= GraphicKeys value= Off> <p>
<input type= submit value= Click here to perform the transaction>
</form>
</ol>
<hr>
<!**********************************************************************>
<p><h3>
<a name = Admin>Administration functions</a></h3>
<form method= post action= / cig-admin/cigadmin>
<input type= submit value= Click here to query the current number of users.>
</form>
<p>
<form method= post action= / cig-admin/cigadmin/trcon>
<input type= submit value= Click here to turn trace on>
</form>
<form method= post action= / cig-admin/cigadmin/trcoff>
<input type= submit value= Click here to turn trace off>
</form>
<p><hr>
<!**********************************************************************>
<a href= / ncf/ncfcics.htm> <img src= / ncf/backpage.gif alt= Previous Page></a>
<a href= / ncf/ncfhpage.htm> <img src= / ncf/greyhome.gif alt= Home Page></a>
<a href= / cig/index.htm>
<img src= / cig/cigdoc.gif alt= CICS Internet Gateway Documentation></a>
<!-- end ibmbody--------------------------------------------------------- -->
</body>
</html>

Figure 233 (Part 3 of 3). Customized cigstart

As part of our example, we built our own home page at


http://ncf120/ncfhpage.html. That page was a front end to the CICS and
MQSeries demos that are available, as well as the examples that we added.
The following figure shows the front end that we created:

272

Network Computing Framework for e-business Guide

Figure 234. The NCF Home Page

Figure 235 through Figure 240 on page 276 show examples of how to use your
Web browser as the interface to CICS for typical transactions instead of using a
real 3270-type device.

Figure 235. NCFSTART - Sample Operations

Chapter 6. Transaction Server Scenario (NT and S/390)

273

Figure 236. Surfing on CICS Transaction

Figure 237. CICS Signon Screen

274

Network Computing Framework for e-business Guide

Figure 238. The Tech Demo Transaction

Figure 239. The Tech Demo Transaction - Inquiry Panel

Chapter 6. Transaction Server Scenario (NT and S/390)

275

Figure 240. The Tech Demo Transaction - Inquiry Response Panel

6.2 Servlets and IBM Connectors


This section describes a scenario including the three systems that were
mentioned in the beginning of Chapter 6, Transaction Server Scenario (NT and
S/390) on page 265 (a client, Web server and an application server). For this
scenario, a Java servlet that resides inside the Lotus Domino Go Webserver
establishes communication with the CICS server using the CICS Gateway for
Java after it receives a request from a client. It then passes the data back to the
clients browser.
The logical flow of this scenario is the following:
1. The client s Web browser requests an HTML page from the Web using the
HTTP protocol.
2. The Web server returns the requested HTML page containing a very simple
HTML form.
3. The browser submits the request to the Web server.
4. The Web server invokes the CicsServlet servlet, initializes it if it was not yet
initialized and calls its service() method.
5. The Web server passes to the Java servlet a ServletRequest and a
ServletResponse object.
6. The service() method of the servlet creates an instance of the JavaGateway
class to connect to the CICS Gateway for Java.
7. The service() method of the servlet creates an instance of the ECIRequest
class containing ECI calls and sends it to the gateway using the
JavaGateway.flow() method.

276

Network Computing Framework for e-business Guide

8. The gateway receives the request, unpacks it and makes the corresponding
ECI calls to the CICS client.
9. The CICS client passes the ECI calls to the CICS server.
10. The CICS server sends the requested data back to the CICS client.
11. The CICS client sends the requested data back to the CICS gateway.
12. The CICS gateway packs these results and passes them to the Java servlet
running inside the Java-enabled Web server.
13. The Java servlet uses the ServletResponse object to send the requested
data back to the Web server.
14. The Web server sends the response back to the client.
The following screen is a logical (not physical) representation of the above flow:

Figure 241. Logical Representation of the Scenario Involving CICS and Servlets

The source code for the Java servlet, named CicsServlet.java, is shown in the
following figure:

Chapter 6. Transaction Server Scenario (NT and S/390)

277

import
import
import
import

java.io.*;
ibm.cics.jgate.client.*;
javax.servlet.*;
javax.servlet.http.*;

public class CicsServlet extends GenericServlet


{
public void init(ServletConfig config)
throws ServletException
{
super.init(config);
log(init() method called ) ;
}
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException
{
String server, cicsServer, userid, password, program, transid;
ECIRequest cics_eci;
int port, i;
JavaGateway jgCon = null;
byte[] commarea = null;
commarea = new byte[70];
ServletOutputStream out = res.getOutputStream();
for (i=0; i<70; i++)
commarea[i] = 0 ;
try
{
port = 2006;
server = new String(9.24.104.120);
log(Start Connection\n ) ;
jgCon = new JavaGateway(server, port);
}
catch(IOException e)
{
log(Couldn t establish communication with CICS server ) ;
log(e.getMessage());
throw e;
}
cicsServer = new String(CICSTCP ) ;
userid = new String( ) ;
password = new String( ) ;
program = new String (NCFECHO ) ;
transid = new String ( ) ;
log(Start ECIRequest\n ) ;
cics_eci = null;
Figure 242 (Part 1 of 2). CicsServlet.java

278

Network Computing Framework for e-business Guide

cics_eci = new ECIRequest(ECIRequest.ECI_SYNC,


cicsServer,
userid,
password,
program,
transid,
commarea,
70,
ECIRequest.ECI_NO_EXTEND,
ECIRequest.ECI_LUW_NEW);
if (cics_eci == null)
log(NULL\n ) ;
try
{
log(Start flow ) ;
jgCon.flow(cics_eci);
}
catch(IOException e)
{
log(IOException ) ;
}
if (cics_eci.getRc() == 0)
{
log(ECI OK\n ) ;
out.println(new String(commarea));
}
try
{
log(Start Close\n ) ;
jgCon.close();
}
catch(IOException e)
{
log(Couldn t close with CICS server ) ;
}
jgCon = null;
}
public void destroy()
{
log(destroy() method called ) ;
}
}
Figure 242 (Part 2 of 2). CicsServlet.java

As you can see, this servlet sends back to the client a piece of information, the
commarea String object. This is a sample servlet and its purpose is to show the
ability of a servlet to invoke a CICS server. A servlet like this is considered a
client for the CICS server.
Notice that the response dynamically sent by the Web server back to the client is
unique for each request the Web server receives.
Chapter 6. Transaction Server Scenario (NT and S/390)

279

The CicsServlet.java file must be copied and compiled into the servlet directory
WWW\Servlets\Public. It imports the two packages javax.servlet and
javax.servlet.http. Of course it also needs to import the package
ibm.cics.jgate.client, which contains the IBM CICS Gateway for Java classes:

ibm.cics.jgate.client.JavaGateway

ibm.cics.jgate.client.ECIRequest

ibm.cics.jgate.client.EPIRequest

ibm.cics.jgate.client.Callbackable

ibm.cics.jgate.client.GatewayRequest

ibm.cics.jgate.client.GatewayTrace

If you have included the jgate\classes directory in the CLASSPATH environment


variable on your NT platform, all the classes contained in the package
ibm.cics.jgate.client will be found by the Java compiler javac, but they wont be
found when you try to run the CicsServlet. For this reason, it is necessary to
create a directory ibm\cics\jgate\client below the servlet directory. You should
then copy all the IBM CICS Gateway for Java classes inside it, so that the final
directory tree will appear as in the following figure:

Figure 243. Directory Tree Necessary to Make the CicsServlet Run

This scenario was performed in a Windows NT environment using only one


Windows NT 4.0 machine. The same Windows NT 4.0 platform was used as
client, server and application server.
The following listing shows the simple HTML file containing the form that invokes
the servlet:

280

Network Computing Framework for e-business Guide

<HTML>
<HEAD>
<TITLE>NCFCXSERV.HTM</TITLE>
</HEAD>
<BODY>
<H2><I>Servlet and IBM Connectors</I></h2>
<FORM METHOD=GET ACTION=/servlet/CicsServlet>
<INPUT TYPE=SUBMIT>
</FORM>
</BODY>
</HTML>
Figure 244. The ncfcxserv.htm HTML File Invoking the CicsServlet

This file resides in the Web server and can be called by the client browser
simply by pointing to its URL. We now describe all the steps that are necessary
to make the scenario work.
The first thing that has to be done is to start up the CICS Server for Windows NT.
This can be done by choosing the Start button, selecting Programs and then IBM
CICS Server for Windows NT. After that you need to click on the Administration
Utility item in the IBM CICS Server for Windows NT menu. That brings you to the
IBM Transaction Server Administration Window. From the Subsystem menu you
can select Start... to start CXNT120, which was the CICS region for our NTNCF120
machine, as shown in the following screen:

Figure 245. How to Start the CXNT120 CICS Region for NTNCF120

Chapter 6. Transaction Server Scenario (NT and S/390)

281

The IBM Transaction Server - Start CICS Region window is brought up and we
simply click the OK button while the Start type is set to Auto, as the following
figure indicates:

Figure 246. IBM Transaction Server - Start CICS Region

The status of the CXNT120 CICS Region will change from Stopped to Busy as
shown in the following window:

Figure 247. CXNT120 CICS Region Busy

It will then change to Started.

282

Network Computing Framework for e-business Guide

Figure 248. CXNT120 CICS Region Started

We also need to start a local terminal for the IBM CICS Server. To do this we
open the IBM CICS Server for Windows NT menu and select the Start Local
Terminal option. The CICSTERM - CICS server selection window is automatically
displayed. Select the item CXNT120 Named Piped Support for local client and
then choose the OK button, as shown in the following window:

Figure 249. CICSTERM - CICS Server Selection Window

As soon as the CICSTERM - CICS client 3270 Terminal Emulator window came up
we typed TTEE and saw a window similar to the following:

Chapter 6. Transaction Server Scenario (NT and S/390)

283

Figure 250. CICSTERM - CICS Client 3270 Terminal Emulator Window

We then pressed the Ctrl key on our keyboard and the Terminal Emulator
indicated that it was active.

Figure 251. The CICS Client 3270 Terminal Emulator Is Active

In order to make the scenario run we had to start the IBM CICS Gateway for
Java. All you need to do to start it is to double-click on the CICS Java Gateway
icon on the desktop. That icon is graphically represented by the following figure:

Figure 252. CICS Java Gateway Icon

284

Network Computing Framework for e-business Guide

If everything is configured correctly, the CICS Gateway for Java window will
appear indicating that the CICS Gateway for Java has been correctly activated
and that the initial connection and worker threads have been successfully
created. The Lotus Domino Go Webserver must also be up so that the Netscape
Web browser can invoke the ncfcxserv.htm HTML page.

Figure 253. The I B M CICS Gateway for Java Has Been Correctly Activated

Since the scenario was built to work with all the components on the same
system, our Windows NT 4 machine had all the following applications running
simultaneously:

Lotus Domino Go Web Server

IBM Transaction Server Administration

IBM CICS Client 3270 Terminal Emulator

IBM CICS Gateway for Java

Netscape

Figure 254. Applications Running in This Scenario

As soon as the clients browser points to the ncfcxserv.htm HTML file, the
following page is displayed:

Chapter 6. Transaction Server Scenario (NT and S/390)

285

Figure 255. Query Connector

This simple HTML page only requires the user to click the Submit Query button.
The next stop would be to enter the user ID and password for the CICS server.
The CICS Client Messages window is displayed requesting that information:

Figure 256. Entering User ID and Password in the CICS Client Messages Window

Select the OK button. This operation initiates the entire scenario that we just
described so that a response similar to the following is displayed at the client s
browser:

286

Network Computing Framework for e-business Guide

Figure 257. The Response Is Displayed On the Client s Browser

Notice that the ncfcxserv.htm page has automatically invoked the CicsServlet
servlet by using the GET HTTP method, as you can see by reading the URL
displayed in the clients browser.
The CICS Java Gateway for Java will automatically register that the client has
connected and then disconnected, as we can see in the following window:

Figure 258. The CICS Gateway Window Registers the Client Has Connected and
Disconnected

The dynamic response that we obtained is the commarea string object for our
transaction. It is really a dynamic response, because the next time the user
clicks the Submit Query button in the HTML form while the ncfcxserv.htm page is
displayed or clicks the Reload button in the Netscape window they will get a new
transaction count. This is shown in the following window:

Chapter 6. Transaction Server Scenario (NT and S/390)

287

Figure 259. The Transaction Count Field for the commarea String Has Been Updated

288

Network Computing Framework for e-business Guide

Chapter 7. Special Notices


This publication is intended to help programmers and analysts who are new to
the Network Computing Framework better understand the components that make
up the framework. The information in this publication is not intended as the
specification of any programming interfaces that are provided by Lotus Domino
Go Webserver, DB2, MQSeries or CICS. See the PUBLICATIONS section of the
IBM Programming Announcement for Lotus Domino Go Webserver, DB2,
MQSeries and CICS for more information about what publications are considered
to be product documentation.
References in this publication to IBM products, programs or services do not
imply that IBM intends to make these available in all countries in which IBM
operates. Any reference to an IBM product, program, or service is not intended
to state or imply that only IBMs product, program, or service may be used. Any
functionally equivalent program that does not infringe any of IBMs intellectual
property rights may be used instead of the IBM product, program or service.
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
this document.
these patents.
Licensing, IBM

patents or pending patent applications covering subject matter in


The furnishing of this document does not give you any license to
You can send license inquiries, in writing, to the IBM Director of
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.
Such information may be available, subject to appropriate terms and conditions,
including in some cases, payment of a fee.
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 customers ability to evaluate and integrate them into the
customers 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.
Reference to PTF numbers that have not been released through the normal
distribution process does not imply general availability. The purpose of
including these reference numbers is to alert IBM customers to specific
information relative to the implementation of the PTF when it becomes available
to each customer according to the normal IBM PTF distribution process.

Copyright IBM Corp. 1998

289

The following terms are trademarks of the International Business Machines


Corporation in the United States and/or other countries:
AIX
CICS
Client Access
DB2 Connect
Distributed Relational Database
Architecture
IBM
MQ
MVS/ESA
NetView
OS/390
RACF
S/390
SupportPac
VisualAge

AS/400
CICS/ESA
DB2
DB2 Universal Database
DRDA
IMS
MQSeries
Net.Data
OS/2
OS/400
RS/6000
SAA
SystemView
VTAM

The following terms are trademarks of other companies:


C-bus is a trademark of Corollary, Inc.
Java and HotJava are trademarks of Sun Microsystems, Incorporated.
Microsoft, Windows, Windows NT, and the Windows 95 logo are trademarks
or registered trademarks of Microsoft Corporation.
PC Direct is a trademark of Ziff Communications Company and is used
by IBM Corporation under license.
Pentium, MMX, ProShare, LANDesk, and ActionMedia are trademarks or
registered trademarks of Intel Corporation in the U.S. and other
countries.
UNIX is a registered trademark in the United States and other
countries licensed exclusively through X/Open Company Limited.
Other company, product, and service names may be trademarks or
service marks of others.

290

Network Computing Framework for e-business Guide

Chapter 8. Related Publications


The publications listed in this section are considered particularly suitable for a
more detailed discussion of the topics covered in this redbook.

8.1 International Technical Support Organization Publications


For information on ordering these ITSO publications see How to Get ITSO
Redbooks on page 293.

CICS and the WWW , SG24-4547

DB2 Meets Windows NT , SG24-4893

Windows NT Systems Management , SG24-2107

8.2 Redbooks on CD-ROMs


Redbooks are also available on CD-ROMs. Order a subscription and receive
updates 2-4 times a year at significant savings.
CD-ROM Title
System/390 Redbooks Collection
Networking and Systems Management Redbooks Collection
Transaction Processing and Data Management Redbook
AS/400 Redbooks Collection
RS/6000 Redbooks Collection (HTML, BkMgr)
RS/6000 Redbooks Collection (PostScript)
Application Development Redbooks Collection
Personal Systems Redbooks Collection

Subscription
Number
SBOF-7201
SBOF-7370
SBOF-7240
SBOF-7270
SBOF-7230
SBOF-7205
SBOF-7290
SBOF-7250

Collection Kit
Number
SK2T-2177
SK2T-6022
SK2T-8038
SK2T-2849
SK2T-8040
SK2T-8041
SK2T-8037
SK2T-8042

8.3 Other Publications


These publications are also relevant as further information sources:

Copyright IBM Corp. 1998

Web Gateways Tools - Connecting IBM and Lotus Application to the Web ,
SR23-7862

MQSeries for Windows NT System Management Guide , SC33-1643

291

292

Network Computing Framework for e-business Guide

How to Get ITSO Redbooks


This section explains how both customers and IBM employees can find out about ITSO redbooks, CD-ROMs,
workshops, and residencies. A form for ordering books and CD-ROMs is also provided.
This information was current at the time of publication, but is continually subject to change. The latest
information may be found at http://www.redbooks.ibm.com/.

How IBM Employees Can Get ITSO Redbooks


Employees may request ITSO deliverables (redbooks, BookManager BOOKs, and CD-ROMs) and information about
redbooks, workshops, and residencies in the following ways:

Redbooks Web Site on the World Wide Web

http://w3.itso.ibm.com/

PUBORDER to order hardcopies in the United States

Tools Disks
To get LIST3820s of redbooks, type one of the following commands:

TOOLCAT REDPRINT
TOOLS SENDTO EHONE4 TOOLS2 REDPRINT GET SG24xxxx PACKAGE
TOOLS SENDTO CANVM2 TOOLS REDPRINT GET SG24xxxx PACKAGE (Canadian users only)
To get BookManager BOOKs of redbooks, type the following command:

TOOLCAT REDBOOKS
To get lists of redbooks, type the following command:

TOOLS SENDTO USDIST MKTTOOLS MKTTOOLS GET ITSOCAT TXT


To register for information on workshops, residencies, and redbooks, type the following command:

TOOLS SENDTO WTSCPOK TOOLS ZDISK GET ITSOREGI 1998

REDBOOKS Category on INEWS

Online send orders to: USIB6FPL at IBMMAIL or DKIBMBSH at IBMMAIL


Redpieces

For information so current it is still in the process of being written, look at Redpieces on the Redbooks Web
Site ( http://www.redbooks.ibm.com/redpieces.html). 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.

Copyright IBM Corp. 1998

293

How Customers Can Get ITSO Redbooks


Customers may request ITSO deliverables (redbooks, BookManager BOOKs, and CD-ROMs) and information about
redbooks, workshops, and residencies in the following ways:

Online Orders send orders to:

In United States:
I n Canada:
Outside North America:

United States (toll free)


Canada (toll free)

1-800-879-2755
1-800-IBM-4YOU

Outside North America


(+45) 4810-1320 - Danish
(+45) 4810-1420 - Dutch
(+45) 4810-1540 - English
(+45) 4810-1670 - Finnish
(+45) 4810-1220 - French

(long
(+45)
(+45)
(+45)
(+45)
(+45)

distance charges apply)


4810-1020 - German
4810-1620 - Italian
4810-1270 - Norwegian
4810-1120 - Spanish
4810-1170 - Swedish

Mail Orders send orders to:


I B M Publications
144-4th Avenue, S.W.
Calgary, Alberta T2P 3N5
Canada

IBM Direct Services


Sortemosevej 21
DK-3450 Allerd
Denmark

Fax send orders to:


United States (toll free)
Canada
Outside North America

Internet
usib6fpl@ibmmail.com
lmannix@vnet.ibm.com
bookshop@dk.ibm.com

Telephone Orders

I B M Publications
Publications Customer Support
P.O. Box 29570
Raleigh, NC 27626-0570
USA

IBMMAIL
usib6fpl at ibmmail
caibmbkz at ibmmail
dkibmbsh at ibmmail

1-800-445-9269
1-403-267-4455
(+45) 48 14 2207 (long distance charge)

1-800-IBM-4FAX (United States) or USA International Access Code -408-256-5422 (Outside USA) ask for:
Index # 4421 Abstracts of new redbooks
Index # 4422 IBM redbooks
Index # 4420 Redbooks for last six months

On the World Wide Web


Redbooks Web Site
IBM Direct Publications Catalog

http://www.redbooks.ibm.com/
http://www.elink.ibmlink.ibm.com/pbl/pbl

Redpieces
For information so current it is still in the process of being written, look at Redpieces on the Redbooks Web
Site ( http://www.redbooks.ibm.com/redpieces.html). 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.

294

Network Computing Framework for e-business Guide

IBM Redbook Order Form


Please send me the following:
Title

First name

Order Number

Quantity

Last name

Company
Address
City

Postal code

Telephone number

Telefax number

Invoice to customer number

Credit card number

Credit card expiration date

Card issued to

Country
VAT number

Signature

We accept American Express, Diners, Eurocard, Master Card, and Visa. Payment by credit card not
available in all countries. Signature mandatory for credit card payment.

How to Get ITSO Redbooks

295

296

Network Computing Framework for e-business Guide

Index
Special Characters

.shtml extension

HTML table 3
HTTP request 3
HttpServlet class 17, 21, 22
HttpServletResponse object 259

87, 90, 96, 101

B
BeanInfo
bibliography

291

C
certificates 4
CGI-BIN 5, 14, 46
CGI-BIN processing 38
CGI, sample 157
CICS
Internet Gateway 113, 116
CICS Gateway for Java 113, 133, 276
applets 154
downloading 134
connectors 8
conversational transaction 114
CORBA IIOP 7
creating, SQL Query Tool 209

D
destroy() method 20, 22, 23, 24, 73, 93, 102
doGet() method 28
doPost() method 28
downloading, CICS Gateway for Java 134
dynamic 38
content 7, 44, 47
generation 43
response 287
Web content 11

E
e-business solutions 1
ECI call 143
ECI requests 133, 139, 153
EPI requests 127, 133, 153

J
Java
applet 4, 216
servlet 44, 232, 276
servlet API 12, 25, 28
java.io 46
JavaBean
component standard 2
interfaces 9
technology 1
javac 33
javax.servlet 6, 16, 46, 96
javax.servlet.http 6, 16, 46, 96, 264
javax.servlet.Request 6
javax.servlet.Response 6
javax.servlet.Servlet interface 5
JDBC 229, 231, 232
JDBC APIs 230
JDBC application 240, 241
JDBC Select bean 258
JDBC-ODBC Bridge Driver 231, 240, 241, 244
JDK shared libraries 30
Just in Time (JIT) compilers 62

F
FormInfo.class

I
IBM Connectors 195
ibm.cics.jgate.client.ECIRequest object 144
ibm.cics.jgate.client.JavaGateway object 143
ICAPI, sample 157
IIOP session 4
init() method 20, 22, 93, 109
invoking, Java servlet 44
ISAPI 5

54

log() method 19, 25, 38, 92, 103


Lotus BeanMachine 5
Lotus Domino.Connect 113

G
GenericServlet class 17, 20, 22
GET 21, 26, 37, 49, 52

Copyright IBM Corp. 1998

M
MQSeries Client for Java

173, 178

297

N
NetObjects Fusion
NSAPI 5, 157

4, 5

P
paint() method 22
POST 21, 26, 37, 49, 52

R
repaint() method

22

S
service() method 19, 23, 24, 72, 102
servlet 3, 4, 5, 54, 232, 259
classes 29
directory 29, 33
programming model 10
tag technique 87
using in the Web server system 195
servlet-log file 103, 107, 109
SNA application access 192
SQL Query Tool, creating 209
start() method 22
stop() method 22
sun.jdbc.odbc 244

T
TestECI

139

U
using, Java applets

216

V
VisualAge for Java

4, 5, 9

W
wrapper servlet

298

Network Computing Framework for e-business Guide

ITSO Redbook Evaluation


IBM Network Computing Framework for e-business Guide
SG24-5296-00
Your feedback is very important to help us maintain the quality of ITSO redbooks. Please complete this
questionnaire and return it using one of the following methods:

Use the online evaluation form found at http://www.redbooks.ibm.com


Fax this form to: USA International Access Code 914 432 8264
Send your comments in an Internet note to redbook@us.ibm.com

Which of the following best describes you?


__Customer
__Business Partner
__Solution Developer
__None of the above

__IBM employee

Please rate your overall satisfaction with this book using the scale:
(1 = very good, 2 = good, 3 = average, 4 = poor, 5 = very poor)
Overall Satisfaction

____________

Please answer the following questions:


Was this redbook published in time for your needs?

Yes____ No____

If no, please explain:


_____________________________________________________________________________________________________
_____________________________________________________________________________________________________
_____________________________________________________________________________________________________
_____________________________________________________________________________________________________

What other redbooks would you like to see published?


_____________________________________________________________________________________________________
_____________________________________________________________________________________________________
_____________________________________________________________________________________________________

Comments/Suggestions:
(THANK YOU FOR YOUR FEEDBACK!)
_____________________________________________________________________________________________________
_____________________________________________________________________________________________________
_____________________________________________________________________________________________________
_____________________________________________________________________________________________________
_____________________________________________________________________________________________________

Copyright IBM Corp. 1998

299

SG24-5296-00

IBML

SG24-5296-00
Printed in the U.S.A.

IBM Network Computing Framework for e-business Guide

You might also like