Sie sind auf Seite 1von 380

Oracle10g: Build J2EE

Applications
Student Guide Volume 1

D17247GC10
Production 1.0
May 2004
D39456

Authors

Copyright 2004 Oracle. All rights reserved.

Lynn Munsinger
Sunitha Patel

This documentation contains proprietary information of Oracle Corporation. It is


provided under a license agreement containing restrictions on use and disclosure and
is also protected by copyright law. Reverse engineering of the software is prohibited.
If this documentation is delivered to a U.S. Government Agency of the Department of
Defense, then it is delivered with Restricted Rights and the following legend is
applicable:

Technical Contributors
and Reviewers
Anna Atkinson
Scott Brewton
Kenneth Cooper
Craig Hollister
Taj-ul Islam
Istvan Kiss
Peter Laseau
Glenn Maslen
Monica Motley-Mosser
Nagavalli Pataballa
Holger Dindler-Rasmussen
Glenn Stokol
Vasiliy Strelnikov
Venkat Tallapragada

Restricted Rights Legend


Use, duplication or disclosure by the Government is subject to restrictions for
commercial computer software and shall be deemed to be Restricted Rights software
under Federal law, as set forth in subparagraph (c)(1)(ii) of DFARS 252.227-7013,
Rights in Technical Data and Computer Software (October 1988).
This material or any portion of it may not be copied in any form or by any means
without the express prior written permission of Oracle Corporation. Any other copying
is a violation of copyright law and may result in civil and/or criminal penalties.
If this documentation is delivered to a U.S. Government Agency not within the
Department of Defense, then it is delivered with Restricted Rights, as defined in
FAR 52.227-14, Rights in Data-General, including Alternate III (June 1987).
The information in this document is subject to change without notice. If you find any
problems in the documentation, please report them in writing to Education Products,
Oracle Corporation, 500 Oracle Parkway, Redwood Shores, CA 94065. Oracle
Corporation does not warrant that this document is error-free.

Publisher
S. Domingue

Oracle and all references to Oracle Products are trademarks or registered trademarks
of Oracle Corporation.
All other products or company names are used for identification purposes only, and
may be trademarks of their respective owners.

Contents
Preface
1 Introduction
Course Objectives 1-2
Course Environment 1-4
Course Overview 1-5
About the Course Applications 1-8
Order Entry Schema 1-9
Human Resources (HR) Schema 1-10
HR Application Flow Diagram 1-11
Summary 1-12
2 J2EE OverviewObjectives
Objectives 2-2
Java 2, Enterprise Edition Platform 2-3
J2EE Platform 2-4
Benefits of the J2EE Platform 2-5
J2EE Components 2-7
J2EE 1.3 Components 2-8
J2EE Architecture 2-9
Client-Tier Components 2-10
J2EE Web-Tier Components 2-11
What Is a Servlet? 2-13
What Is a JavaServer Page (JSP)? 2-14
Web-Tier Components: Summary 2-15
Business-Tier Components 2-16
Enterprise JavaBeans (EJB) 2-17
J2EE Communication APIs 2-18
J2EE Server 2-19
Oracle Application Server 10g Containers for J2EE (OC4J) 2-21
J2EE Applications 2-22
Packaging J2EE Application Components 2-23
JARs 2-24
WARs 2-25
EJB JARs 2-26
EARs 2-27
EAR File Structure for a J2EE Application: Example 2-28
OC4J Architecture 2-29
OC4J Server Configuration Files 2-30
Relation of Configuration Files 2-31
Data Sources 2-32
Application Logging 2-33
J2EE Application Deployment to
Oracle Application Server 10g 2-34

iii

Oracle Enterprise Manager 2-35


JDeveloper and J2EE 2-36
Oracle JDeveloper 10g Environment 2-37
Oracle JDeveloper 10g Visual Design Tools 2-38
Summary 2-39
Practice 2-1: Overview 2-40
3 Designing J2EE Applications
Objectives 3-2
Realizing J2EE Benefits 3-3
J2EE Issues 3-4
J2EE Design Patterns 3-5
Implementing Design Patterns by Using MVC 3-6
The Model 3-7
The View 3-8
The Controller 3-9
MVC in Oracle Application Server 10g Containers for J2EE 3-10
Designing J2EE Applications 3-11
Flow Diagram: Example 3-12
Summary 3-13
Practice 3-1: Overview 3-14
4 Creating the Web Tier: Servlets
Objectives 4-2
Overview 4-3
About Java Servlets 4-4
Principal Features of Servlets 4-5
Life Cycle of Servlets 4-6
HTTP Servlets 4-7
Inside an HTTP Servlet 4-8
Servlet: Example 4-9
The doGet() Method 4-10
The doPost() Method 4-11
The HttpServletRequest Object 4-12
The HttpServletResponse Object 4-13
Methods for Invoking Servlets 4-14
Your First Servlet 4-15
Handling Input: The Form 4-16
Handling Input: The Servlet 4-17
Initialization and Destruction 4-18
Error Handling 4-19
Debugging a Servlet 4-20

iv

SingleThreadModel 4-21
JDeveloper Environment 4-23
Servlet Mapping 4-24
Servlet Mapping in JDeveloper 4-25
Invoking a Servlet 4-26
Specifying J2EE Web Module Settings 4-27
Creating a Connection to Oracle Application Server 10g 4-28
Deploying to OC4J 4-29
Summary 4-30
Practices 4-1, 4-2, and 4-3: Overview 4-31
5 Accessing the Database with Servlets
Objectives 5-2
Review of JDBC 5-3
Querying in JDBC 5-4
JDBC and Servlets 5-5
Synchronizing Shared Resources 5-6
Transaction Handling 5-7
Connection Pooling 5-9
Data Sources 5-10
Data Source Definition 5-11
data-sources.xml: Example 5-12
Using Data Sources 5-13
Summary 5-14
Practice 5-1: Overview 5-15
6 Using Advanced Techniques in Servlets
Objectives 6-2
Overview 6-3
HTTP Headers 6-4
Request Headers 6-5
Sending a Response 6-6
Response Headers 6-7
Setting Status Codes 6-8
Example 6-9
Sending Multimedia Content 6-10
Cookies 6-12
Setting Cookies 6-13
Retrieving Cookies 6-14
About State Preservation 6-15
State Preservation: Example 6-16

ServletContext 6-17
RequestDispatcher 6-18
RequestDispatcher: Example 6-19
Servlet Filters 6-20
Using Filters 6-21
doFilter() Method 6-22
Using Filters 6-23
Configuring Filters 6-24
Application Lifecycle Events 6-25
ServletContext Events 6-26
HttpSession Events 6-27
Example of an Event Listener 6-28
Error Handling 6-29
Summary 6-30
Practices 6-1 and 6-2: Overview 6-31

7 Maintaining State in J2EE Applications


Objectives 7-2
Overview 7-3
Session Basics 7-4
Threading 7-6
URL Rewriting 7-7
HttpSession 7-8
Session Objects 7-9
Session-Based Page Counter 7-10
Session Life Cycle 7-11
Session Tracking in OC4J 7-12
Sessions and Events 7-13
Creating Distributable Applications 7-17
Summary 7-18
Practice 7-1: Overview 7-19

vi

8 Creating the Web Tier: JavaServer Page


Objectives 8-2
JavaServer Pages 8-3
Comparing Servlets and JSPs 8-4
Invoking JSPs 8-5
The Date JSP 8-6
The Date Servlet 8-7
Automated JSP Features 8-8
JSP Life Cycle 8-9
Basic JSP Elements 8-10
Declarations 8-11
Expressions 8-12
Scriptlets 8-13
Implicit Objects 8-14
Example 8-16
Directives 8-18
include: Example 8-19
page Directive 8-20
JSP and JavaBeans 8-22
Using JavaBeans with JSP 8-23
scope Attribute of <jsp:useBean> Tag 8-25
Accessing and Setting Bean Property 8-26
JSP XML Document 8-28
Traditional Syntax Versus XML Syntax 8-29
JDeveloper and JSPs 8-31
Creating JSPs Visually 8-32
JSP Tag Insight 8-33
Summary 8-34
Practices 8-1, 8-2, and 8-3: Overview 8-35
9 Modularizing JavaServer Pages Development with Tags
Objectives 9-2
Custom Tags 9-3
Custom Tag Library Components 9-4
Tag Handler: Example 9-5
Tag Library Descriptors 9-6
Using a Custom Tag 9-7
Tags with Attributes 9-8
Creating a Custom Tag in JDeveloper 9-9
Tag Libraries in JDeveloper 9-10
Registering Tag Libraries 9-11
Using Tag Insight 9-14

vii

JSP Standard Tag Library (JSTL) 9-15


Core Tag Library 9-16
Utilizing Core Tags 9-18
Expression Language 9-19
Using Iteration Tags 9-20
Using the URL Tags 9-21
XML Tag Library 9-23
SQL Tag Library 9-24
Accessing a Database with SQL Tags 9-25
Querying Using SQL Tags 9-26
Inserting, Updating, and Deleting Data 9-27
Formatting Tags 9-28
Internationalization Concepts 9-29
Internationalizing Strings 9-30
Formatting Numbers and Dates 9-31
Transforming XML Documents 9-34
JSTL in JDeveloper 9-35
Summary 9-36
Practice 9-1: Overview 9-37
10 Communicating in J2EE
Objectives 10-2
Overview of RMI 10-3
Role of RMI in J2EE 10-4
Communication in a J2EE Environment 10-5
How Clients Locate a Distributed Component 10-7
Java Naming and Directory Interface (JNDI) 10-8
J2EE Container and JNDI Interface 10-9
Naming Service 10-10
JNDI Terminology 10-11
Main JNDI Class and Interface 10-12
Accessing an Object in JNDI Namespace 10-13
Getting the JNDI InitialContext 10-14
Initial Context Factories 10-16
lookup() Method 10-17
Obtaining a Reference to a Local Resource 10-18
Obtaining a Reference to a Remote Resource 10-19
Setting JNDI Environment Properties 10-20
Using RMI over HTTP Tunneling 10-24
Using Environment References with JNDI 10-25
Configuring Environment Variables 10-26
Specifying an EJB Reference 10-28

viii

Configuring EJB References 10-29


Configuring Data Source References 10-31
Summary 10-33
Practice 10-1: Overview 10-34

11 Creating the Business Tier: Enterprise JavaBeans


Objectives 11-2
Enterprise JavaBeans (EJB) 11-3
When to Use EJBs 11-4
Types of EJBs 11-5
Session Beans 11-7
Entity Beans 11-9
Message-Driven Beans 11-10
EJB Architecture 11-11
EJB Server 11-12
EJB Container 11-13
Services Provided by the EJB Container 11-14
EJB Client 11-16
EJB Interfaces and Classes 11-17
Remote Interface and Remote Object 11-18
Home Interface and Home Object 11-19
Local Interface and Local Home Interface 11-20
EJB Bean Class 11-21
The EJB Deployment Process 11-22
ejb-jar.xml File 11-23
orion-ejb-jar.xml File 11-24
Creating an EJB in JDeveloper 11-25
Using the EJB Wizard 11-26
Using the EJB Wizard 11-27
Adding Methods to the Bean 11-28
Deploying to Oracle Application Server 10g from JDeveloper 11-29
Summary 11-30
Practice 11-1: Overview 11-31

ix

12 Implementing Business Tasks with Session EJBs


Objectives 12-2
Session Beans 12-3
javax.ejb.SessionBean Interface 12-5
Types of Session Beans 12-7
When to Use Session Beans 12-9
Life Cycle of a Stateless Session Bean 12-11
Home Interface for Stateless Session Beans 12-12
Remote Interface for Stateless Session Beans 12-14
The Session Bean Class 12-15
The Session Bean Class: Business Methods 12-17
Bean Class for the Stateless Session Bean 12-18
Deployment Descriptor 12-19
Client Application 12-20
Client Application for Stateless Session Beans 12-21
Life Cycle of a Stateful Session Bean 12-25
Home Interface for Stateful Session Bean 12-26
Client Application for Stateful Session Bean 12-27
Summary 12-28
Practices 12-1 and 12-2: Overview 12-29
13 Managing Persistent Data in the Business Tier
Objectives 13-2
Entity Beans 13-3
Representing Data in Entity Beans 13-5
When to Use Entity Beans 13-6
Callback Methods to Load and Store Data 13-7
Session Beans Versus Entity Beans 13-9
Types of Entity Beans 13-11
BMP Beans Versus CMP Beans 13-12
Components of an Entity Bean 13-14
Creating, Removing, Finding, and Selecting Entity Beans 13-15
Home Interface of an Entity Bean 13-17
Creating a Bean Instance 13-18
Finding an Entity Bean Instance 13-20
Removing an Entity Bean 13-22
Home Methods of Entity Beans 13-23
Component Interfaces of an Entity Bean 13-24
Primary Key Class of an Entity Bean 13-25
Bean Class of an Entity Bean 13-26
javax.ejb.EntityBean Interface 13-28
Life Cycle of an Entity Bean 13-30

Deployment Descriptor 13-32


Summary 13-35
Practice 13-1: Overview 13-36
14 Achieving State Management in the Business Tier
Objectives 14-2
Features of BMP Entity Beans 14-3
Developing a BMP Entity Bean 14-4
Features of CMP Entity Beans 14-5
Implementing Methods in CMP Beans and BMP Beans 14-7
Developing a CMP Entity Bean 14-9
CMP Bean: Example 14-10
Bean Class of a CMP EJB: CMP Fields 14-11
Remote Interface: Departments 14-12
Home Interface: DepartmentsHome 14-13
Bean Class: DepartmentsBean 14-14
Deployment Descriptor ejb-jar.xml 14-17
Mapping CMP Fields to Database Table Columns 14-21
Default Mapping of CMP Fields to Database Table Columns 14-22
Explicit Mapping of CMP Fields to Database Table Columns 14-23
Client for Departments Bean 14-25
Summary 14-28
Practice 14-1: Overview 14-29
15 Container-Managed Relationships (CMRs)
Objectives 15-2
Relationships 15-3
Implementing Relationships 15-4
Cardinality and Direction of Relationships 15-5
One-to-One Relationships 15-7
One-to-Many Relationships 15-8
Many-to-Many Relationships 15-9
Oracle TopLink 15-10
TopLink: Integration of J2EE Applications with Data Sources at Run Time 15-11
TopLink: Integrated with Oracle JDeveloper 10g 15-12
Implementing Relationships 15-13
Defining Abstract Accessor Methods 15-14
Accessor Methods in 1:1 Relationships 15-15
Accessor Methods in 1:M Relationships 15-16
Checking Relationship Mappings in JDeveloper 15-17
Accessor Methods in M:N Relationships 15-18

xi

Implementing a Relationship in the Deployment Descriptor 15-19


Implementing 1:1 Relationships 15-21
Implementing 1:M Relationships 15-23
Implementing M:N Relationships 15-25
Mapping Relationship Fields to Database 15-27
Default Mapping of Relationship Fields 15-28
Explicit Mapping of Relationship Fields 15-30
Using JDeveloper to Create CMR Beans 15-31
Summary 15-32
Practice 15: Overview

16 Developing Message-Driven Beans


Objectives 16-2
Overview of Messaging Systems 16-3
Types of Message Consumption 16-4
Java Message Service (JMS) 16-6
JMS Application Architecture 16-7
Point-to-Point Model 16-8
Publish-and-Subscribe Model 16-9
Using JMS Interfaces 16-10
JMS Message Structure 16-12
Sending a Message to a Queue 16-13
Receiving Messages 16-15
Asynchronous Message Delivery 16-16
Message-Driven Beans 16-17
MDB Architecture 16-18
Associating JMS Resources with an MDB 16-19
State Diagram of an MDB 16-20
Developing MDBs 16-22
Interfaces to Be Implemented for MDBs 16-23
Implementing an MDB Class 16-24
Receiving Messages in an MDB Class 16-25
Creating the Deployment Descriptor 16-26
ejb-jar.xml: Example 16-28
Mapping in OC4J-Specific Deployment Descriptor 16-29
orion-ejb-jar.xml: Example 16-30
Creating an MDB with JDeveloper 16-31
Testing the MDB 16-34
Summary 16-35

xii

17 Integrating J2EE Components


Objectives 17-2
Overview 17-3
Creating Remote Clients for EJBs 17-4
Importing the EJB Home Interface 17-5
Create a Reference to the EJB 17-6
Passing Arguments to the EJB Method 17-7
Creating an EJB Reference 17-8
Creating Local Clients for EJBs 17-9
ejb-local-ref Element 17-10
EJB Tags 17-11
useHome Tag 17-12
useBean Tag 17-13
createBean Tag 17-14
iterate Tag 17-15
Using the EJB Tags 17-16
Deploying an Application: Web Tier 17-17
Deploying an Application: EJB Tier 17-18
Deploying an Application: EAR File 17-19
Deploying from Oracle Enterprise Manager 17-20
Summary 17-21
Practice 17-1 and 17-2: Overview 17-22
18 Distributing Modular Applications: Introduction to Web Services
Objectives 18-2
What Is a Web Service? 18-3
Web Service 18-4
Service-Oriented Architecture 18-6
Web Services Constituents 18-7
Benefits of Web Services 18-9
Web Services Model 18-11
RPC-Style Web Services 18-12
Document-Style Web Services 18-13
Oracle Support for Web Services 18-14
SOAP: XML Messaging for Web Services 18-15
Communication with SOAP 18-16
SOAP Messages 18-17
Web Services Description Language (WSDL) 18-19
WSDL 18-20
UDDI Registry 18-22
How UDDI Is Used 18-24
Searching for a Web Service by Using UDDI 18-25

xiii

UDDI Specification 18-26


tModel 18-27
UDDI Support in Oracle JDeveloper 10g 18-31
UDDI Browsing with Oracle JDeveloper 10g 18-32
UDDI Publishing and Browsing with Oracle Enterprise Manager 18-33
Summary 18-34
Practice 18-1: Overview
19 Distributing Modular Applications: Developing Web Services
Objectives 19-2
Oracle Application Server 10g Web Services 19-3
Developing a Web Service with a Stateless Java Class 19-4
Defining an Interface 19-5
Defining a Stateless Java Class 19-7
Creating the Web Service 19-10
Creating the Client Application 19-11
Deploying the Web Service 19-13
Testing the Web Service 19-14
Web Service Home Page 19-15
Testing the Deployed Web Service with Home Page 19-16
Testing the sayHello Operation 19-17
Serializing and Encoding Parameters and Results 19-19
Developing a Stored Procedure Web Service 19-20
Generating Wrapper Classes Using JPublisher 19-21
Exposing a Function as a Web Service by Using Oracle JDeveloper 10g 19-22
Publishing the Package as a Web Service 19-23
JMS Web Services 19-24
Summary 19-26
Practice 19-1: Overview
20 Implementing Security in J2EE Applications
Objectives 20-2
Goals of J2EE Security Architecture 20-3
Overview of J2EE Security Architecture 20-4
Java Authentication and Authorization Service (JAAS) 20-5
Authorization of a Client 20-8
JAAS Provider Types in OC4J 20-9
Configuring Security 20-10
Defining the Users, Groups, and Roles 20-11
Managing Users and Groups with the JAZN Admintool 20-13
Defining the Logical Roles 20-15

xiv

Defining and Using Logical Roles in Web Applications (web.xml) 20-16


Defining and Using Logical Roles in EJBs (ejb-jar.xml) 20-18
Mapping Logical Roles to Users and Groups 20-19
Programmatic Access to a Callers Security Context 20-20
Client Authentication 20-21
EJB Client Authentication with the jndi.properties file 20-22
EJB Client Authentication with a Hashtable 20-23
Setting Access Control with JDeveloper 20-24
Creating Web Application Security Roles 20-25
Web Application Login Authentication 20-26
Web Application Authorization 20-27
Creating EJB Security Roles 20-28
Setting Method Permissions 20-29
Method Access in EJB Deployment Descriptors 20-30
Creating a Mapping for the Logical Roles 20-31
Mapping JAZN Identities to a Logical Role 20-32
Mapping Results in orion-ejb-jar.xml 20-34
Accessing the EJB with New Permissions 20-35
Summary 20-36
Practice 20-1: Overview 20-37
21 Oracle Application Server 10g Transaction Support
Objectives 21-2
What Is a Transaction? 21-3
Enterprise JavaBeans (EJB) Support for Transactions 21-4
EJB Transaction Model 21-5
Demarcating Transactions 21-6
Container-Managed Transactions 21-7
CMT: Transaction Attributes 21-8
Transaction Attribute: NotSupported 21-10
Transaction Attribute: Required 21-11
Transaction Attribute: Supports 21-12
Transaction Attribute: RequiresNew 21-13
Transaction Attribute: Mandatory 21-14
Transaction Attribute: Never 21-15
CMT: The setRollbackOnly() Method 21-16
JDeveloper: Setting Transaction Attributes 21-17
Java Transaction API (JTA) 21-19
JTA: The UserTransaction Interface 21-20
Bean-Managed Transactions Demarcation 21-21
BMT Demarcation: Process 21-22
Using UserTransaction Support in EJBs 21-23
Client-Demarcated Transactions Using UserTransaction 21-24
BMT Demarcation: Restrictions 21-25

xv

Local and Global Transactions 21-26


Single-Phase Commit 21-27
Data Source Revisited 21-28
Default data-sources.xml 21-29
Emulated Versus Nonemulated Data Sources 21-30
Retrieve Connection to Data Source 21-31
Global Transaction Resource Request Flow 21-33
Resource Request Flow 21-34
Enlisting Database Resources 21-36
Summary 21-38
A Practice Solutions
B Schema Descriptions
C Oracle JDeveloper 10g Quick Reference
D BMP Entity EJBs J2EE Connector Architecture

xvi

Preface

Preface - 2

Profile
Before You Begin This Course
Before you begin this course, you should have the following qualifications:

Working experience with JDBC

Familiarity with Oracle JDeveloper 10g

Prerequisites

Oracle10g: Java Programming (D17249GC10)

Oracle9i: SQL Basics for Developers or equivalent knowledge of basic SQL

How This Course Is Organized


Oracle10g: Build J2EE Applications is an instructor-led course featuring lectures and hands-on
exercises. Online demonstrations and written practice sessions reinforce the concepts and skills
introduced.

Preface - 3

Typographic Conventions
Typographic Conventions in Text

Convention

Element

Example

Bold

Emphasized words and phrases To navigate within this application, do


in Web content only
not click the Back and Forward buttons.

Bold italic

Glossary terms (if there is a


glossary)

The algorithm inserts the new key.

Brackets

Key names

Press [Enter].

Caps and
lowercase

Buttons,
check boxes,
triggers,
windows

Click the Executable button.


Select the Registration Required check
box.
Assign a When-Validate-Item trigger.
Open the Master Schedule window.

Carets

Menu paths

Select File > Save.

Commas

Key sequences

Press and release these keys one at a


time:
[Alt], [F], [D]

Preface - 4

Typographic Conventions (continued)


Typographic Conventions in Text (continued)

Convention

Object or Term

Example

Courier New,
case sensitive

Code output,
SQL and PL/SQL
code elements, Java
code elements,
directory names,
filenames,
passwords,
pathnames, URLs,
user input,
usernames

Code output: debug.seti (I,300);


SQL code elements: Use the SELECT command to view
information stored in the last_name column of the emp
table.
Java code elements: Java programming involves the
String and StringBuffer classes.
Directory names: bin (DOS), $FMHOME (UNIX)
Filenames: Locate the init.ora file.
Passwords: Use tiger as your password.
Pathnames: Open c:\my_docs\projects.
URLs: Go to http://www.oracle.com.
User input: Enter 300.
Usernames: Log on as scott.

Initial cap

Graphics labels
(unless the term is a
proper noun)

Customer address (but Oracle Payables)

Italic

Emphasized words
and phrases in print
publications, titles of
books and courses,
variables

Do not save changes to the database.


For further information, see Oracle7 Server SQL
Language Reference Manual.
Enter user_id@us.oracle.com, where user_id is
the name of the user.

Plus signs

Key combinations

Press and hold these keys simultaneously:


[Control] + [Alt] + [Delete]

Quotation
marks

Lesson and chapter


titles in cross
references, interface
elements with long
names that have only
initial caps

This subject is covered in Unit II, Lesson 3, Working with


Objects.
Select the Include a reusable module component and
click Finish.
Use the WHERE clause of query property.

Preface - 5

Introduction

Copyright 2004, Oracle. All rights reserved.

Course Objectives

After completing this course, you should be able to do


the following:
Identify the components and architecture of Java
2, Enterprise Edition (J2EE), based on the needs
of specific applications
Describe the Model View Controller (MVC)
architecture and create development plans for
J2EE applications
Build a Web-based database application by using
J2EE components: servlets, JavaServer Pages
(JSP), and Enterprise JavaBeans (EJB)

1-2

Copyright 2004, Oracle. All rights reserved.

Course Objectives
Many businesses rely on the Internet and Web applications for their daily business. Oracle
provides several tools that you can use to easily develop and deploy these applications. The
purpose of this course is to teach you how to develop applications by using the J2EE
components. These components include servlets, JSP, and EJB. Additionally, you should be
able to create applications that adhere to the MVC architecture, which provides easily
maintainable components.

Oracle10g: Build J2EE Applications 1-2

Course Objectives

1-3

Test J2EE components by using Web and Java


clients
Provide versatile access to applications through
Web services, and use a published Web service in
an application
Deploy J2EE applications to Oracle Application
Server 10g
Manage transactions in EJB
Implement J2EE security in applications

Copyright 2004, Oracle. All rights reserved.

Course Objectives (continued)


Additionally, you should be able to describe how to develop client applications for your
J2EE components, and how to create Web services from your applications. This course also
explains how to deploy J2EE applications to Oracle Application Server 10g, and also
addresses the handling of security issues when deploying J2EE applications. Further,
declaratively and programmatically managing transactions when using EJB is also described
in detail.

Oracle10g: Build J2EE Applications 1-3

Course Environment

1-4

The development tool is Oracle JDeveloper 10g,


version 9.0.5.1.
The application server is Oracle Application
Server 10g, version 9.0.4.
The database is Oracle 10g.

Copyright 2004, Oracle. All rights reserved.

Course Environment
In this course, you will use the Oracle JDeveloper 10g integrated design tool to develop
J2EE components. These components will be deployed to the Oracle Application Server 10g
Containers for J2EE (OC4J) server. The OC4J server is provided within JDeveloper, and is
also contained in a full installation of Oracle Application Server 10g. You will deploy
applications to both locations. Additionally, components will access the Oracle10g database.

Oracle10g: Build J2EE Applications 1-4

Course Overview

1-5

Lesson 1: Course Overview


Lesson 2: J2EE Overview
Lesson 3: Design considerations for building J2EE
applications
Lesson 4: Introduction to servlets
Lesson 5: Using JDBC to access the database
from servlets
Lesson 6: Advanced servlet topics
Lesson 7: Maintaining sessions in servlets
Lesson 8: Introduction to JavaServer Pages (JSP)
Lesson 9: Utilizing custom tags in JSP
Copyright 2004, Oracle. All rights reserved.

Oracle10g: Build J2EE Applications 1-5

Course Overview

1-6

Lesson 10: Communication APIs in J2EE


Lesson 11: Introduction to Enterprise JavaBeans
(EJB)
Lesson 12: Creating session EJBs
Lesson 13: Creating entity EJBs
Lesson 14: Managing persistence in EJBs (BMP,
CMP)
Lesson 15: Specifying relationships in EJBs
(CMR)
Lesson 16: Creating Message-Driven Beans (MDB)

Copyright 2004, Oracle. All rights reserved.

Oracle10g: Build J2EE Applications 1-6

Course Overview

1-7

Lesson 17: Integrating servlets, JSPs, and EJBs in


a J2EE application
Lesson 18: Introduction to Web Services
Lesson 19: Developing and publishing Web
Services
Lesson 20: Implementing security in J2EE
applications
Lesson 21: Transaction support in Oracle
Application Server 10g

Copyright 2004, Oracle. All rights reserved.

Oracle10g: Build J2EE Applications 1-7

About the Course Applications

The course uses applications that are derived


from the Order Entry and Human Resources
sample schemas.
In the practices, you write applications that allow
users to:

1-8

Browse available products


Place products in a shopping cart for purchase
View employee details
Update employee data
Send messages to a queue
Use a Web service to validate a credit card

Copyright 2004, Oracle. All rights reserved.

About the Course Applications


The examples, demonstrations, and practices in this course are based on the business model
of fictional Order Entry and Human Resources applications. These schemas are installed by
default with the Oracle database.

Oracle10g: Build J2EE Applications 1-8

Order Entry Schema

1-9

Copyright 2004, Oracle. All rights reserved.

Order Entry Schema


In the companys order entry records, each customer has a unique ID. A customer might
have orders that are detailed in the ORDER_ITEMS table. These orders contain products that
are office supply products.
The company is global and has several warehouses containing inventories of various
products. Some products have photos stored in the product media schema, which is not used
in this course.
This slide and the next show a brief description of the tables in the schema; Appendix B
contains a full description of each table used in the course.

Oracle10g: Build J2EE Applications 1-9

Human Resources (HR) Schema

1-10

Copyright 2004, Oracle. All rights reserved.

Human Resources (HR) Schema


In the companys human resource records, each employee has a unique identification
number, e-mail address, job identification number, salary, and manager.
The company also tracks information about jobs within the organization. Each job has an
identification number, job title, and a minimum and maximum salary range for the job.
The sample company is regionally diverse, so it tracks the locations of not only its
warehouses but also of its departments. Each of the companys employees is assigned to a
department. Each department is identified by a unique department code and a short name.
Each department is associated with one location. Each location has a full address that
includes the street address, postal code, city, state or province, and country code.
For each country where it has facilities, the company records the country name, currency
symbol, currency name, and the region where the country is geographically located.

Oracle10g: Build J2EE Applications 1-10

HR Application Flow Diagram

Employee entity
No
Process
log in

View
employees
process

Administrator?
Yes

Insert
employees
process

1-11

Copyright 2004, Oracle. All rights reserved.

HR Application Flow Diagram


In this course, you will build an application for both an Order Entry and a Human Resources
business scenario. The Order Entry scenario is discussed in detail in later lessons. The slide
above shows a general flow diagram for the Human Resources scenario.
Employees can log in to an application to view the details of the employees in their
department. If the employee who logged in to the application is an HR administrator, then he
or she may insert new employees into the application.

Oracle10g: Build J2EE Applications 1-11

Summary

After completing this course, you should be able to:


Create J2EE components by using best practices
Develop J2EE applications by using servlets,
JSPs, and EJBs
Test J2EE components by using Web and Java
clients
Implement J2EE security in applications
Deploy J2EE applications to Oracle Application
Server 10g
Develop Web services, and provide access to
them

1-12

Copyright 2004, Oracle. All rights reserved.

Summary
In this course, you learn how to create J2EE applications by using servlets, JSP, EJB, and
Web services. You learn how to design and develop J2EE applications by using Oracle
JDeveloper 10g, and make decisions about when to use the various J2EE components.
Additionally, the applications that you create are deployed to Oracle Application Server 10g.

Oracle10g: Build J2EE Applications 1-12

J2EE Overview

Copyright 2004, Oracle. All rights reserved.

Objectives

After completing this lesson, you should be able to do


the following:
Describe the Java 2, Enterprise Edition (J2EE)
platform
Define the various components of J2EE
Describe the deployment options for a J2EE
application
Describe the architecture of Oracle Application
Server 10g Containers for J2EE (OC4J)
Describe the directory structure and the uses of
the configuration files of OC4J

2-2

Copyright 2004, Oracle. All rights reserved.

Objectives
This lesson discusses each of the components of the J2EE architecture and examines its
purpose in a J2EE application. J2EE applications are deployed to a J2EE server such as
Oracle Application Server 10g. This lesson also describes the configuration and structure of
Oracle Application Server 10g Containers for J2EE.

Oracle10g: Build J2EE Applications 2-2

Java 2, Enterprise Edition Platform

The Java 2, Enterprise Edition (J2EE) platform is a


standard for developing and implementing
enterprisewide applications:
It provides multitier applications support.
It is designed to help improve the process of
developing, deploying, and implementing
enterprisewide applications.

2-3

Copyright 2004, Oracle. All rights reserved.

Java 2, Enterprise Edition Platform


J2EE is a complete application architecture for enterprise class applications. It was first
proposed by Sun Microsystems and has been included in the Java Community Process to
make it a part of the open systems movement.
J2EE emphasizes a portable, component-based approach to the creation, deployment, and
management of complex applications. J2EE supports components on four tiers: client, Web,
business, and the Enterprise Information System (EIS).

Oracle10g: Build J2EE Applications 2-3

J2EE Platform

Is a multitiered, distributed application model


Supports component-based J2EE applications
Servlet

2-4

Browser

JSP Page

Web clients

Web components

Application

Enterprise
Beans

EJB clients

EJB components

Client tier

Middle tier

EIS tier

Copyright 2004, Oracle. All rights reserved.

J2EE Platform
J2EE defines a platform for developing, deploying, and executing applications in a
multitiered, distributed application model. That is, the application logic of a J2EE
application can be divided into components based on their functions and distributed to the
appropriate tier on the multitiered architecture.
The slide shows a standard multitiered J2EE application model where the application logic
is distributed into the following tiers:
Client-tier components, such as a Web browser, run on the client machine.
Presentation logic is built with Web-tier components such as JavaServer Pages (JSP)
and Java servlets that run on the J2EE server.
Server-side business logic is distributed as business-tier components that run on the
J2EE server. Enterprise JavaBeans (EJB) and the J2EE framework Business
Components for Java (BC4J) are examples of business-tier components.
Data is stored in the Enterprise Information System (EIS) tier that runs on the database
server, such as Oracle10g.
The J2EE application components are developed in Java programming language. When the
J2EE platform is used, the J2EE components are assembled into a J2EE application, verified
according to the J2EE specification, and deployed to the J2EE server. The deployed
applications are run and managed by the J2EE server.
Oracle10g: Build J2EE Applications 2-4

Benefits of the J2EE Platform

2-5

Write once, run anywhere provides simplified


component development.
Multiple server products and vendors support the
J2EE standard, thus giving more deployment
choices.
Integration with legacy systems through standard
APIs is possible.
J2EE separates client requirements from business
logic.
J2EE provides multiple development and design
scenarios.

Copyright 2004, Oracle. All rights reserved.

Benefits of the J2EE Platform


J2EE takes advantage of many features of Java 2 Platform, Standard Edition (J2SE), such as
the write once, run anywhere portability. This portability is ensured because there are
multiple vendors who support the J2EE specification, making it easy to integrate distributed
applications. J2EE separates business and presentation logic, making the applications easier
to maintain. There are several design choices for J2EE development, including varied client
access. This is discussed later in the course.
The vendors who provide the J2EE platform (Database, Application Server) are called
J2EE Product Providers. A vendor or person who creates Web components, enterprise
beans, or application clients for use in J2EE applications is called an Application
Component Provider. A Tool Provider is a vendor who creates development, assembly,
and packaging tools that are used by the Component Providers. These names are assigned
along with various other J2EE roles that are discussed in the next slide.

Oracle10g: Build J2EE Applications 2-5

Benefits of the J2EE Platform

2-6

J2EE separates development tasks into specific


skill areas.
Web designers can create JSP components.
Application behavior is created by Java
programmers.
Business logic and rules are created by Java
programmers and business experts.
Assembly and deployment can be assigned to
production environment teams.

Copyright 2004, Oracle. All rights reserved.

Benefits of the J2EE Platform (continued)


The J2EE platform allows for developer specialization by component type and functionality.
For example, an EJB developer can create business logic, focusing on the business rules of
the enterprise. These EJBs are used by Web component developers, who focus on the
presentation of data and the user interface. These components are assembled by an
Application Assembler, who is responsible for the deployment and administration of the
application.
An Application Deployer is the company or person who configures and deploys the J2EE
application. An Application Administrator is a person who administers the computing and
networking infrastructure where the J2EE applications run.

Oracle10g: Build J2EE Applications 2-6

J2EE Components

J2EE is a component-based architecture for the


development and deployment of enterprisewide
applications.
A component is an application-level software unit.
Components can be easily updated as business
needs change.
Components are reusable.
There are several types of components:
Client-side components
Web components
Business-tier components

2-7

Copyright 2004, Oracle. All rights reserved.

J2EE Components
There are several types of J2EE components. This course focuses on the most widely used
components, those of the Web and the business tier. These components are reusable, that is,
they are available to other components and applications. For example, the business rules that
are included in a software component called Process Order can be used by multiple
applications that allow customers to order the products or services of a company.

Oracle10g: Build J2EE Applications 2-7

J2EE 1.3 Components

The J2EE 1.3 Specification lists the following


components:
Java Message Service
Servlet 2.3
1.0.2
JavaServer Pages 1.2
Java Transaction API 1.0
Enterprise
Java Authentication and
JavaBeans 2.0
Authorization Service
JDBC 2.0
1.0
RMI-IIOP
J2EE Connector
JNDI 1.2
Architecture 1.0
Web services 1.1
SOAP with Attachments
API for Java 1.1
2-8

Copyright 2004, Oracle. All rights reserved.

J2EE 1.3 Components


The slide above shows many of the components that are listed in the J2EE 1.3 Specification.
A description of these components is provided on the next page. Additionally, the following
components are also included in the specification:
JavaMail 1.2
Java IDL 1.0
Java API for XML Parsing (JAXP) 1.1

Oracle10g: Build J2EE Applications 2-8

J2EE Architecture
The J2EE architecture provides a component-based and platform-independent environment,
in which each component is assembled and deployed into its corresponding container. The
J2EE server provides services to handle transaction and state management, multithreading,
resource pooling, and other complex low-level details, in the form of these containers.
Because these underlying services are provided by the J2EE server, the developer can
concentrate on solving business problems.
J2EE components communicate with each other by using several APIs. The J2EE
architecture provides the following APIs to support remote procedure calls:
Java Naming and Directory Interface (JNDI): Provides naming and directory
functionality to applications written in Java
Remote Method Invocation (RMI): Enables you to create distributed Java
technologybased applications, in which the methods of remote Java objects can be
invoked from other Java virtual machines, possibly on different hosts
Java Database Connectivity (JDBC): Enables you to access any tabular data source
such as database, spreadsheets, or flat files from the Java programming language
Java Transaction API (JTA): Specifies standard Java interfaces between a
transaction manager and the parties involved in a distributed transaction system: the
resource manager, the application server, and the transactional applications
Java Messaging Services (JMS): Enables applications to create, send, receive, and
read messages by defining a common set of interfaces and associated semantics that
allow programs written in the Java programming language to communicate with other
messaging implementations
JavaMail: Provides a set of abstract classes that model a mail system. The API
provides a platform-independent and protocol-independent framework to build Java
technology-based mail and messaging applications.
JavaBeans Activation Framework (JAF): Provides standard services to determine
the type of an arbitrary piece of data, to encapsulate access to it, to discover the
operations that are available on it, and to instantiate the appropriate bean to perform
the said operations. For example, if a browser obtains a JPEG image, this framework
enables the browser to identify that stream of data as a JPEG image. Then the browser
can locate and instantiate an object that can manipulate or view that image.
Additionally, the JavaMail API uses the JAF API for data content handling.

Oracle10g: Build J2EE Applications 2-9

Client-Tier Components

A Web browser:
Is used for a Web-based J2EE application
Downloads static or dynamic Web pages from Webtier components
Is a thin client

An application client:

2-10

Is used for a non-browser-based J2EE application


Executes on the client machine
Can contain a graphical or command-line interface
Is a thick client
Accesses business-tier components or a servlet on
the Web tier
Copyright 2004, Oracle. All rights reserved.

Client-Tier Components
Web Browser Client
For a Web-based J2EE application, the users Web browser is the client component. The
Web browser downloads static or dynamic Web pages from the Web tier to a client
machine.
Dynamic Web pages are generated by servlets and JSPs from the Web tier. JSPs do not
require Java plug-ins or security policy files to be downloaded to the client machine.
A downloaded Web page can contain an embedded applet that executes in the Java Virtual
Machine (JVM) in the Web browser. An applet may require a Java plug-in and a security
file to successfully execute in the users Web browser.
Web-based clients are typically thin clients, which do not perform operations such as
executing complex business rules, connecting to the database, and querying the database.
These operations are generally performed by business-tier components.
Application Client
An application client executes on a client machine for a non-browser-based J2EE
application. It can contain a graphical user interface (GUI) created from Swing or Abstract
Window Toolkit (AWT) APIs or a command-line interface. Application clients can directly
access business-tier components. They can also access a servlet that is running in the Web
tier through an HTTP connection.
Oracle10g: Build J2EE Applications 2-10

J2EE Web-Tier Components

A Web tier may consist of:


Java servlets
JSPs

Servlets and JSPs:

Work on a request-response model


Generate HTML dynamically
Access the database through JDBC
Access the business-tier components
Handle user-centric events, such as an HREF link or
form submission
Usually generate visual interfaces such as a Web
page
2-11

Copyright 2004, Oracle. All rights reserved.

Web-Tier Components
J2EE Web-tier components can be either servlets or JSPs that can statically and dynamically
generate HTML, Wireless Markup Language (WML), or Extensible Markup Language
(XML) pages. Java servlets provide a simple yet powerful API for generating Web pages by
dynamically processing the client requests and constructing responses. JSPs simplify the
process of dynamically generating the content, by allowing Java as the scripting language
inside HTML pages. JSPs are translated and compiled into Java servlets, which are then run
in a Web server like any other servlet.
Web components can access the business-tier components that access the database by using
JDBC. Web components can handle requests from the client, such as form submission.
Some advantages of using Web components are listed below:
The HTML interface that is generated by a Web component is lightweight when
compared with the applets that require heavyweight downloads to the clients at run
time. Also, the HTML interface does not require prior installation on the client
machines, whereas the conventional clients require redeployment of the applications
on the client machines.

Oracle10g: Build J2EE Applications 2-11

Web-Tier Components (continued)


The HTTP protocol, over which the clients request for Web pages are served, can pass
through most firewalls.
Thus, a combination of Web components and EJBs allows:
Presentation logic for generating Web pages through Web components
Transactional business logic through EJBs

Oracle10g: Build J2EE Applications 2-12

What Is a Servlet?

Servlet

Browser

Client info (host name,


form data)

Request

Process results
(access database)
Format results and produce
HTML

Success or failure

Send page back to client


Response
2-13

Copyright 2004, Oracle. All rights reserved.

What Is a Servlet?
A servlet is a Java program that runs on a server, such as Oracle Application Server 10g, and
produces dynamic pages typically in response to client requests. The pages are then sent
back to the clients Web browser. Typically, the output format for servlets is HTML, but any
other output format, including XML, can be used.
Before returning HTML pages, a servlet can perform any operation that a Java application
can perform. For example, in a business environment, servlets access the database through
JDBC, so that you can send custom HTML pages and forms with embedded data to your end
users.
Because servlets contain Java code, they are best suited for programs that perform more
processing than presentation. Presentation is best left to JSPs, which are discussed in the
next slide.

Oracle10g: Build J2EE Applications 2-13

What Is a JavaServer Page (JSP)?

A JSP:
Is a text-based document that includes:
HTML
JSP tags
Java code (including calls to JavaBeans
and servlets)

2-14

Cleanly separates content creation from


presentation logic
Focuses on rapid development and easy
modification of the user interface
Provides presentation-centric method of
developing servlets
Copyright 2004, Oracle. All rights reserved.

What Is a JavaServer Page (JSP)?


JSPs are servlets that are written differently. The JavaServer Pages technology separates the
user interface from dynamic content generation, so that designers can easily change the
overall page layout without altering the dynamic content. JSP technology supports a
reusable component-based design, making it easy and fast to build Web-based applications.
A key feature of the JavaServer Pages technology is simplified page generation: HTML-like
tags and scriptlets written in the Java programming language encapsulate the logic that
generates the content for the page. By separating the presentation design from the
application logic that generates the data, JSP-enabled pages make it easier for organizations
to reuse and share application logic through custom tags and JavaBeans-based components.
This also separates the job responsibilities of the Web designer and the Java programmer.
For example, custom tags and beans can be developed by the Java programmer and
implemented by the Web designer.

Oracle10g: Build J2EE Applications 2-14

Web-Tier Components: Summary

Web-tier components generate dynamic content.


Servlets:
Extend Web server functionality
Are designed more for processing than for
presentation

JSPs:
Combine HTML (or other markup) and Java
Are designed to separate content creation from
presentation logic
Are precompiled and converted to servlets at run
time

2-15

Copyright 2004, Oracle. All rights reserved.

Oracle10g: Build J2EE Applications 2-15

Business-Tier Components

Business-tier components:
Are EJBs
Handle business logic
Receive data from client programs
Retrieve data from database storage
Process the data and communicate with the
database and the client program
Can be invoked by the Web-tier components

2-16

Copyright 2004, Oracle. All rights reserved.

Business-Tier Components
EJBs are the components that run in the business tier. These distributed components contain
business logic that meets the needs of a particular business domain such as banking, order
entry system, or human resources management. The business-tier components can receive
data from client programs, process the data, and send the processed data to the database
server for storage. The business-tier components can also retrieve data from the database,
process it, and send it back to the client program.
The Web-tier components might invoke the business-tier components where the business
logic is handled. For example, a servlet might invoke an enterprise bean to insert new
customer details and return any processed data back to the client.

Oracle10g: Build J2EE Applications 2-16

Enterprise JavaBeans (EJB)

Enterprise JavaBeans:
Are server-side components written in Java
Contain the business logic of an enterprise
application
Are hosted in EJB containers
Are based on Remote Method Invocation (RMI)
communication
Are platform independent
Provide remote services for clients
Can be exposed as Web services
Use JDBC to connect to a database
2-17

Copyright 2004, Oracle. All rights reserved.

Enterprise JavaBeans (EJB)


Enterprise JavaBeans (EJB) is an architecture for developing transactional applications as
distributed components in Java. EJB is a powerful development methodology for distributed
application development. When applications are developed with enterprise beans, neither the
bean developer nor the client application programmer needs to be concerned with details
such as transaction support, security, remote object access, and many other complicated and
error-prone issues. These are provided transparently for the developer by the EJB container.
EJBs offer portability. A bean that is developed on one EJB container will run on other EJB
containers that meet the EJB specification. Oracle Application Server 10g implements the
EJB specification by providing a server and a container that hosts the Enterprise JavaBeans.
EJB specifies Remote Method Invocation (RMI) as the transport protocol. EJBs access the
EIS-tier database through JDBC.
EJBs are accessed using Javas RMI (Remote Method Invocation) framework, which can be
implemented with different network protocols. Oracle Application Server 10g provides the
RMI/Internet Inter-ORB Protocol (IIOP) protocol, as well as a platform-specific, optimized
protocol called Oracle Remote Method Invocation (ORMI).
Additionally, a stateless session EJB can be exposed as a Web service. Web services are a
standard for building interoperable distributed applications that are platform and
programming-language independent. Stateless session EJBs and Web services are discussed
in detail later in this course.
Oracle10g: Build J2EE Applications 2-17

J2EE Communication APIs

J2EE provides component communication


through APIs.
The APIs include:
RMI
JNDI
JDBC

2-18

These APIs facilitate communication between the


J2EE components.

Copyright 2004, Oracle. All rights reserved.

J2EE Communication APIs


RMI, JNDI, and JDBC are Java communication APIs. RMI and JNDI allow J2EE
components to communicate with one another, whereas JDBC allows J2EE components to
interact with the database.

Oracle10g: Build J2EE Applications 2-18

J2EE Server

The J2EE server provides:


Containers for each component type of a J2EE
application
System-level services to components:
Naming and directory services (JNDI)
Security services for Web components and EJBs
(JAAS)
Transaction architecture (JTA)
Remote client connectivity:
Enterprise beans (RMI/IIOP, ORMI)
Servlet/JSP (HTTP, HTTPS, FTP)

2-19

Copyright 2004, Oracle. All rights reserved.

J2EE Server
The J2EE server is the run-time portion of a J2EE product. A J2EE server provides EJB and
Web containers. The Web-tier and business-tier components can themselves be clients for
the other J2EE application components.
An advantage of the J2EE standard is that all the container providers must abide by the same
J2EE standards. This is much easier for developers because the application assembly is the
same in any J2EE-compliant environment.
The J2EE server provides system-level services to the J2EE application components:
J2EE naming services provide the J2EE application components with access to the
Java Naming and Directory Interface (JNDI) lookup services. Using the JNDI lookup
service, the components can locate user-defined objects, environment entries,
enterprise beans, JDBC DataSource objects, and messaging connections.
The security services enable you to configure Web-tier and business-tier components
so that only authenticated and authorized users can access the system resources.
The transaction architecture enables you to specify relationships among methods that
make up a single transaction so that all methods in one transaction are treated as a
single unit.

Oracle10g: Build J2EE Applications 2-19

J2EE Server (continued)


The remote connectivity service manages the low-level communications between
clients and J2EE components. This provides location transparency to the clients. The
client accesses the components as if both of them (the client and the Web-tier or
business-tier components) are on the same Java virtual machine.

Oracle10g: Build J2EE Applications 2-20

Oracle Application Server 10g Containers


for J2EE (OC4J)

OC4J is the J2EE server implementation in Oracle


Application Server 10g
Key features:

2-21

Implements J2EE 1.3 Specification


Runs on standard JVM
Provides high performance and scalability
Is productive for developers to use
Is simple to manage and deploy
Provides clustering for high availability and failover

Copyright 2004, Oracle. All rights reserved.

Oracle Application Server 10g Containers for J2EE (OC4J)


Oracle Application Server 10g provides a complete J2EE server, called Oracle Application
Server 10g Containers for J2EE (OC4J). It is written in Java and executes on the standard
Java Virtual Machine (JVM). OC4J is installed in three ways:
Is included in Oracle Application Server 10g
Is included in Oracle JDeveloper 10g
Is available as a stand-alone version (that is, without any other software)
In this class, OC4J is installed with Oracle Application Server 10g as well as Oracle
JDeveloper 10g. This means that you can test applications on OC4J by using JDeveloper,
and deploy them to Oracle Application Server 10g.

Oracle10g: Build J2EE Applications 2-21

J2EE Applications

J2EE applications consist of J2EE components and


are deployed in the form of modules:
Web modules contain the user interface: HTML,
JSP, and servlets.
EJB modules contain reusable EJB components.
Client modules provide access to remote
application code.
Packaging information identifies dependencies
between modules.

2-22

Copyright 2004, Oracle. All rights reserved.

J2EE Applications
J2EE applications are server-side applications that contain standard components such as
servlets, JSPs, and EJBs. Applications are deployed in the form of modules that package all
necessary code for deployment to a J2EE server such as Oracle Application Server 10g.
Modules are archive files in a standard format, specified by the J2EE architecture.

Oracle10g: Build J2EE Applications 2-22

Packaging J2EE Application Components

1. ejb.jar
Bean class, Home and Remote
interfaces, other supported files, DD
2. webtier.war
Java servlets, JSP files, HTML, GIF files,
DD (references to EJBs)
J2EEapplication.ear
3. J2EEappClient.jar
J2EE application client (Java class),
DD (references to EJBs)
4. DD for J2EE application (.xml)
DD = XML Deployment
Descriptor
2-23

5. Resource adapter (.rar)

Copyright 2004, Oracle. All rights reserved.

J2EE Application Components


The diagram in the slide shows the components of a J2EE application. A J2EE application is
typically archived into an Enterprise Archive (EAR) file. This file contains the following:
A Java Archive (JAR) file that contains the archive of EJB componentsEJB class
files, Home and Remote interfaces, and EJB deployment descriptor that contains
information about transaction attributes, security roles, and so on.
A Web Archive (WAR) file that contains the archive of Web componentsJava
servlets, JSP files, HTML, GIF files, and a deployment descriptor that contains
references of the EJBs being accessed, in ejb-ref tags.
A JAR file that contains the archive of a J2EE application client in the form of a Java
class, and a deployment descriptor that contains references to the EJBs from which the
business methods are being accessed. The J2EE application client is a Java application
that runs in an environment that allows it to access J2EE services.
A deployment descriptor of the J2EE application, which is a reference file for
deployment, that contains information about the .war, .jar files, and security
information.
An optional resource adapter archive (RAR), which is a driver that either an
application server or an application client uses to connect to a specific EIS. Examples
of resource adapters are JDBC drivers to connect to a relational database, or an ERP
resource adapter to connect to an ERP system.
Oracle10g: Build J2EE Applications 2-23

JARs

2-24

Are simple Java Archive files


Are used to package application files together
(for example, classes, images, and so on)
Can be included in Web Archives (WARs) and
Enterprise Archives (EARs)
Can be included in library paths

Copyright 2004, Oracle. All rights reserved.

JARs
A standard JAR file has the following structure:
|-------META-INF
|
-------manifest.mf
|-------Java classes
Typically, JAR files are used to hold groups of related Java packages (such as JDBC or
Swing). To simplify deployment or make operational access more efficient, you may want to
include them in EJB-JAR files, WAR files, or EAR files.

Oracle10g: Build J2EE Applications 2-24

WARs

Are specialized archives for packaging J2EEcompliant Web applications


Have a fixed directory structure
Have a deployment descriptor for the Web
application
WEB-INF
web.xml
classes
lib
index.html

Contain servlet code and


JavaBeans not in standard
JAR files
Contains required classes
that are packaged in
standard JAR files

welcome.jsp

2-25

Copyright 2004, Oracle. All rights reserved.

WARs
Each WAR file is created with the Web application and its XML files, which are structured
as follows:
|-------WEB-INF
|
|-------web.xml
|
|-------classes
|
|-------Servlet classes (may be included inside packages)
|
|-------lib
|-------index.html
|-------JSPs
Note that a WAR file may contain both HTML and JSPs, as well as many other supporting
files.

Oracle10g: Build J2EE Applications 2-25

EJB JARs

Are specialized JARs for packaging EJBs


Have a fixed directory structure
Have a deployment descriptor for the EJB
components
myEJB
META-INF
ejb-jar.xml
EJB Classes
Remote, Home and
Bean classes

2-26

Contain the class files


for the EJBs, usually
in a package directory
structure

Copyright 2004, Oracle. All rights reserved.

EJB JARs
Each EJB file is created with the EJB application classes and XML files, which are
structured as follows:
|-------META-INF
|
|-------ejb-jar.xml
|
|-------orion-ejb-jar.xml
|
|-------EJB classes
J2EE specifications recommend the use of an application directory to locate all applicationspecific XML files. This is recommended because it keeps the global and default
configuration files separate from the application-specific configuration files. The orionejb-jar.xml file is used by OC4J to deploy EJBs. Its use is discussed in detail later in
the course.

Oracle10g: Build J2EE Applications 2-26

EARs

The EAR files:


Are specialized archives for packaging J2EEcompliant enterprise applications for deployment
Have a deployment descriptor
May have Web modules
May have EJB modules
May have client modules

2-27

Copyright 2004, Oracle. All rights reserved.

EARs
As J2EE applications became larger and more complex, there was a need to simplify
distribution. The J2EE specification addresses this issue. Organizations can use EAR files to
package all the client modulesHTML pages, JSPs, Servlets, EJBs, manifest files, and
XML configuration filesthat are needed to distribute an entire application. All these files
are contained in a single archive file with a standard organization.

Oracle10g: Build J2EE Applications 2-27

EAR File Structure for a


J2EE Application: Example
<appname>
|-------META-INF
|
|-------application.xml
|-------<ejb_module>
|
|-------EJB classes
|
|-------META-INF
|
|-------ejb-jar.xml
|-------<web_module>
|
|-------index.html
|
|-------JSP pages
|
|-------WEB-INF
|
|----web.xml
|
|----classes
|
|-------Servlet classes
|-------<client_module>
|
|-------Client classes
|
|-------META-INF
|
|-------application-client.xml

2-28

Copyright 2004, Oracle. All rights reserved.

EAR File Structure for a J2EE Application: Example


The diagram in the slide indicates a suggested directory path for deploying your J2EE
applications.
The names of the META-INF and WEB-INF directories and application.xml, ejbjar.xml, web.xml, and application-client.xml files are predefined in the
OC4J server according to the J2EE specifications. There are separate directories to clearly
separate modules of the application. The application.xml file, which acts as the
manifest file, defines these modules.
In this example, the directories containing the separate modules (ejb_module,
web_module, and client_module), and the directory that contains the modules
(appname), may have arbitrary names. These names must match the values in the manifest
file (application.xml).
For EJB modules, the top of the module represents the start of a search path for classes. As a
result, classes belonging to packages are expected to be located in a nested directory
structure beneath this point. For example, a reference to a class in a package
myapp.ejb.demo is expected to be located in the
<appname>/ejb_module/myapp/ejb/demo directory.

Oracle10g: Build J2EE Applications 2-28

OC4J Architecture

Oracle HTTP
Server
HTTP

JNDI
AJP

mod_oc4j

AJP13

Web
container

JMS
JDBC
JTA

Client
JAAS
ORMI

EJB
container

JCA
JavaMail

ORMI
JAF
EJB client

2-29

OC4J server process

Copyright 2004, Oracle. All rights reserved.

OC4J Architecture
OC4J implements the J2EE infrastructure. The OC4J Web container and the OC4J EJB
container use the J2EE virtual machine.
The J2EE containers perform services for applications, such as providing access to the APIs
and life-cycle management.
When Oracle HTTP Server receives a request, such as
http://myserver.com/j2ee/HelloWorldServlet, from the URL, it determines
the modules that are configured to handle this request, based on the mapping in the
configuration file (httpd.conf or mod_oc4j.conf).
In this case, Oracle HTTP Server resolves that mod_oc4j is responsible for this request,
because the /j2ee virtual path is mapped to the OC4J server. mod_oc4j then contacts a
specified OC4J instance by using Apache JServ Protocol (AJP). AJP is faster than HTTP,
through the use of binary formats and efficient processing of message headers.
Oracle Remote Method Invocation (ORMI) is the protocol through which EJB clients access
EJBs that are deployed to the container. This and the other APIs shown in the slide are
discussed in detail later in the course.
Additionally, HTTP is available directly to the OC4J process for development purposes.
Oracle10g: Build J2EE Applications 2-29

OC4J Server Configuration Files


OC4J Server XML Files
Server Configuration
server.xml

Web site
Web
Website
site

jazn.xml*
jazn-data.xml*

default-website.xml

data-sources.xml
rmi.xml
jms.xml
Oracle HTTP Server
configuration files
mod_oc4j.conf

2-30

Copyright 2004, Oracle. All rights reserved.

OC4J Server Configuration Files


The OC4J server is configured by using XML-based configuration files. These files are
standard for J2EE servers. In later lessons, you see how OC4J extends these files.
These configuration files provide a way of integrating components with the OC4J
framework. There is no need to modify the XML files that are contained in JARs, WARs,
and EARs while they are being deployed.
There is an implied hierarchy to these configuration files:
server.xml
|------>rmi.xml
|------>jms.xml
|------>application.xml
|
|------>principals.xml
|
|------>data-sources.xml
|------>global-web-application.xml
|------>default-web-site.xml
|------>default-web-app
|------>web-app
*The jazn.xml and jazn-data.xml files describe the security configuration by using
the OC4J JAAS provider. If Java Authentication and Authorization Service (JAAS) is not
used, then these files need not be configured.
Oracle10g: Build J2EE Applications 2-30

Relation of Configuration Files

When an application is deployed, an entry is made in


the \config\server.xml file:

<application name="lesson02"
path="../applications/lesson02.ear" />

For each Web module within the application, a context


root is defined in \config\default-web-site.xml:
<web-app application="lesson02" name="webapp1"
root="/lesson02"/>

The modules of the application are defined in


\applications\lesson02\METAINF\application.xml:
<web><web-uri>webapp1.war</web-uri></web>

2-31

Copyright 2004, Oracle. All rights reserved.

Relation of Configuration Files


The server.xml, default-web-site.xml, and application.xml files work
together to define the configuration for an application. If an application named lesson02 is
deployed by using a lesson02.ear file (which contains webapp1.war), the
deployment will create entries in the corresponding files, as shown in the slide above. Note
that the default-web-site.xml file is used for those applications that are deployed to
Oracle Application Server 10g installations. If the applications are deployed to the
embedded OC4J server that is installed with Oracle JDeveloper 10g, then the http-website.xml file is used instead. The mod_oc4j.conf configuration file is used to specify
which OC4J instance will handle requests for each context root.

Oracle10g: Build J2EE Applications 2-31

Data Sources

A data source is the instantiation of an object that


implements the javax.sql.DataSource interface,
which enables you to retrieve a connection to a
database server.
OC4J data sources are defined in datasources.xml.

2-32

J2EE applications use JNDI to look up these


DataSource objects.

Copyright 2004, Oracle. All rights reserved.

Data Sources
Data sources are a portable method for creating JDBC connections. The datasources.xml file is preinstalled with a default data source named OracleDS. However,
you can also add your own customized data source definitions. The default data source from
data-sources.xml is listed below:
<data-source
class="com.evermind.sql.DriverManagerDataSource"
name="OracleDS"
location="jdbc/OracleCoreDS"
xa-location="jdbc/xa/OracleXADS"
ejb-location="jdbc/OracleDS"
connection-driver="oracle.jdbc.driver.OracleDriver"
username="scott" password="tiger"
url="jdbc:oracle:thin:@localhost:5521:oracle"
inactivity-timeout="30"
/>

Oracle10g: Build J2EE Applications 2-32

Application Logging

Application logging in Oracle Application Server


10g is configured by specifying the location of a
log file in the application.xml file:
<log>
<file path="practice02-oc4j-app.log"/>
</log>

To create a log file formatted in XML, use Oracle


Diagnostic Logging (ODL):
<log>
<odl path="practice02-oc4j-app.log"/>
</log>

2-33

Copyright 2004, Oracle. All rights reserved.

Application Logging
In Oracle Application Server 10g, you can use the OC4J application.xml
configuration file to specify that a log file be created. The path attribute is relative to the
location of the application.xml file. The resulting log file is useful for debugging
applications during development, as well as tracing run-time errors. An example of the
output generated in a log file is as follows:
04/02/25 01:04:35 Started
04/02/25 01:04:36 practice02-login-webapp: JDevOJSP: init
04/02/25 01:04:36 practice02-login-webapp: 9.0.4.0.0 Started
04/02/25 01:04:36 practice02-login-webapp: LoginServlet: init

Oracle10g: Build J2EE Applications 2-33

J2EE Application Deployment to


Oracle Application Server 10g
Deploying to OC4J can be done in multiple ways:
Step 1: Create WAR,
EAR file

Step 2: Deploy
Step 2: Deploy

Use a commandline tool (such as


ANT).

Use Oracle Enterprise Manager


(installed with Oracle Application
Server 10g): Access the
Enterprise Manager Web site
Use JDeveloper specifyhttp://localhost:1810
an
Application Server and click
'Deploy'
(requires
login).
Use JDeveloper.
Use JDeveloper: Specify an
application server and click
Deploy.

2-34

Copyright 2004, Oracle. All rights reserved.

J2EE Application Deployment to Oracle Application Server 10g


A J2EE application can be deployed by using a command-line tool to copy WAR, EAR, and
JAR files to the proper location on the J2EE server. However, several tools are available to
make this process easier. JDeveloper supports the deployment of a J2EE application to a
J2EE server (such as Oracle Application Server 10g) by using a deployment profile.
Additionally, OC4J can be administered and applications can be deployed to an OC4J
instance by using Oracle Enterprise Manager Application Server Control. You can also
deploy by using a command-line deployment tool, such as ANT.

Oracle10g: Build J2EE Applications 2-34

Oracle Enterprise Manager

localhost

2-35

Copyright 2004, Oracle. All rights reserved.

Oracle Enterprise Manager


The slide above shows the OC4J home page, where you can stop and restart OC4J instances,
and also deploy applications. You can access the OC4J home page by following the
OC4J_home link from the Oracle Enterprise Manager home page on the default port 1810.

Oracle10g: Build J2EE Applications 2-35

JDeveloper and J2EE


JDeveloper provides:
Integrated development, deployment, and testing
support for Web-tier and business-tier
components
A J2EE framework for rapid development
Application Development Framework (ADF)
business components
Data tags

2-36

Integration with Struts


UML modeling
JDeveloper
Visual editors for Web clients
Easy deployment to Oracle Application Server 10g

Copyright 2004, Oracle. All rights reserved.

JDeveloper and J2EE


JDeveloper is an Integrated Development Environment (IDE) that is used to build, test, and
debug J2EE applications. In Oracle JDeveloper 10g, workspaces and projects are used to
organize the files that you need for your application. To effectively work with the files in
JDeveloper, you can use projects to work with individual files, and workspaces to manage
one or more projects. You must have a workspace before you can create projects. It is a
common practice to create workspaces around functions of applications, such as human
resources management; and to separate technologies into projects, such as having separate
projects for the model, view, and controller. By using the UML Modeler, you can model
business processes, build J2EE components, test and debug them, and easily deploy the
business processes to Oracle Application Server 10g or other J2EE servers.

Oracle10g: Build J2EE Applications 2-36

Oracle JDeveloper 10g Environment

Customizable code editor


Wizards for
JSPs,
servlets, and
EJBs
Error
checking
for HTML
and JSP
EAR, WAR
deployment
to J2EE
server
2-37

Code insight
Copyright 2004, Oracle. All rights reserved.

Oracle JDeveloper 10g Environment


JDeveloper provides you with several helpful development features. Wizards for creating
servlets, JSPs, and EJBs make it easy to start building a Web application. The code editor is
customizable and code insight makes it easy to develop code without having to remember
each package and class name. Debugging is provided in both local and remote modes, and
errors in HTML and JSPs are identified within the IDE. Additionally, JDeveloper automates
the packaging of J2EE applications into WAR or EAR files for deployment to a J2EE server.
Oracle Application Server 10g Containers for J2EE (OC4J) is provided within the tool to
test and debug the J2EE applications.

Oracle10g: Build J2EE Applications 2-37

Oracle JDeveloper 10g


Visual Design Tools

Drag JSP, HTML


elements

Design in visual
or code views

2-38

Modify values
in property
inspector
Copyright 2004, Oracle. All rights reserved.

Oracle JDeveloper 10g Visual Design Tools


Oracle JDeveloper 10g enables you to choose between editing in code or visual views for
JSP and HTML documents. You can drag JSP and HTML elements from the component
palette to the visual or code views, and elements can be modified directly in the code or
visual editor, or in the property inspector. The code editor, visual editor, property inspector,
and another visual tool, the structure pane, are all synchronized so that a change in one
propagates immediately to all other representations of the data.

Oracle10g: Build J2EE Applications 2-38

Summary

In this lesson, you should have learned that:


J2EE is a set of Java technologies that support
end-to-end application development
Components are the foundation of the J2EE
architecture
Web components (servlets, JSPs) generate
dynamic content
Business components (EJBs) are server-side
components that contain business logic
Applications can be built by using Oracle
JDeveloper 10g and deployed to a J2EE server,
such as Oracle Application Server 10g
2-39

Copyright 2004, Oracle. All rights reserved.

Summary
J2EE components include servlets, JSPs, and EJBs. These components are divided into
functions of business and presentation logic. J2EE applications can be built by using Oracle
JDeveloper 10g and deployed by using JDeveloper, Oracle Enterprise Manager Application
Server Control, or other tools.

Oracle10g: Build J2EE Applications 2-39

Practice 2-1: Overview

This practice covers the following topics:


Navigating to the OC4J console by using Oracle
Enterprise Manager
Mapping a data source in OC4J
Restarting the OC4J server instance from Oracle
Enterprise Manager
Deploying an EAR file by using Oracle Enterprise
Manager

2-40

Copyright 2004, Oracle. All rights reserved.

Oracle10g: Build J2EE Applications 2-40

Practice 2-1
In this practice, you navigate to the Oracle Enterprise Manager console, modify the default
data source, and restart the OC4J server. Additionally, this practice gives you the
opportunity to view the files that OC4J uses to configure a J2EE application. You also
deploy an existing application by using Oracle Enterprise Manager.
1. Navigate to the Oracle Enterprise Manager console.
a. Open a browser and navigate to http://localhost:1810.
b. Enter the username ias_admin and the password welcome1.
c. Navigate to the home instance page by clicking the home link.
2. Create a data source reference.
a. Click the Administration tab and click the Data Sources link.
b. Click Create and enter these details:
Name: hrDS
Description: hr
Data Source Class: com.evermind.sql.DriverManagerDataSource
JDBC URL: The URL provided to you by your instructor
JDBC Driver: oracle.jdbc.driver.OracleDriver

In Datasource Username:
Username: oraxx (as provided to you by your instructor)
Use a cleartext password of oracle
In JNDI Locations:
Location: jdbc/hrCoreDS
Transactional location: jdbc/xa/hrXADS
EJB location: jdbc/hrDS
Leave all other fields blank or set to the default.
c. Click Create and restart OC4J when prompted.
3. Verify the change that you made to the data source.
a. Navigate to the oraas10g directory and locate the j2ee\home\config
directory.
b. Open data-sources.xml in WordPad. Note that the data source that you
added in step 2 is defined here.
c. You may also want to view application.xml, server.xml, and other
configuration files that are discussed in this lesson.
4. Deploy an existing J2EE application by using Oracle Enterprise Manager. The
application you deploy in this step is actually the application that you will build in
practice 17.
a. Click the applications tab from the OC4J home page and click Deploy EAR File.
b. Browse to the <JDEV_HOME>\jdev\mywork\practice02 directory and
select application1.ear.
c. Name the application practice02 and click Continue.
d. Modify the URL Mapping as /practice02 and click Next.
e. Enter jdbc/hrCoreDS for the JNDI location name and click Next.

Oracle10g: Build J2EE Applications 2-41

Practice 2-1 (continued)


f. Because there is no user security defined for this application, click Next in the
following page.
g. Click Deploy to deploy the application.
h. Click OK after the application has been deployed.
5. Access the application.
a. Enter the following URL in the browser:
http://localhost/practice02/loginservlet
b. Enter 100 in the Employee ID field and King in the Employee Name field and
click Login.
c. View the Employees in Kings department and click the Insert link.
d. Enter the following information in the form.
ID: 500
First Name: Your first name
Last Name: Your last name
Email: Your e-mail account
Hire Date: A date in the format of dd-mon-yy
Job ID: AD_VP
e. Verify whether the employee was inserted by using SQL*Plus to query the
EMPLOYEES table.

Oracle10g: Build J2EE Applications 2-42

Designing J2EE Applications

Copyright 2004, Oracle. All rights reserved.

Objectives

After completing this lesson, you should be able to do


the following:
Describe the various Java 2, Enterprise Edition
(J2EE) patterns
Use the Model View Controller (MVC) architecture
to design more efficient and maintainable
applications
Identify sample architectures and their merits and
demerits

3-2

Copyright 2004, Oracle. All rights reserved.

Objectives
This lesson deals with the design of J2EE applications. After working for several years with
the object-oriented (OO) programming concepts, developers found that the best applications
follow similar patterns. This lesson discusses these patterns and also the principles of
developing an application that adheres to best practices.

Oracle10g: Build J2EE Applications 3-2

Realizing J2EE Benefits

To leverage the full benefits of J2EE, you must design


applications that are:
Portable: You should be able to redeploy the J2EE
applications to different servers, databases, and
so on.
Scalable: Web applications should be able to
handle large numbers of users.
Maintainable: A minimum amount of coding
should be necessary for a new business rule.
Reusable: A class that processes credit cards
should be reused by multiple applications.
Simple: The business need should be solved with
the least amount of complexity.
3-3

Copyright 2004, Oracle. All rights reserved.

Realizing J2EE Benefits


J2EE helps achieve portability, which is particularly important for applications that must be
clustered. Additionally, well-designed J2EE applications are scalable when the number of
users and their actions are difficult to predict, as in Internet applications. J2EE applications
must be able to accommodate new business needs in an organization, because this
application could be used within an organization for many years. Applications that allow
code reuse for minimizing duplication benefit from object-oriented design. Finally,
applications that avoid unnecessary complexity are engineered to meet the needs of the
business, without becoming overcomplicated by using the latest buzzword technology.

Oracle10g: Build J2EE Applications 3-3

J2EE Issues

It is important to follow certain guidelines for the


design and development of any new technology:
Implement generally accepted design patterns and
architectures.
Focus on real business needs rather than simply
adopting new technology.
Employ the simplest technology to solve a
business problem.

3-4

Copyright 2004, Oracle. All rights reserved.

J2EE Issues
Developers are often directed toward J2EE as a complete, effective solution, where
scalability and portability are handled automatically, without the need for good design
patterns. Thus, many J2EE applications are built to use the latest functionality, without
solving the needs of the enterprise. For example, there is a great debate in the J2EE
community about the use of Enterprise JavaBeans (EJB). EJBs solve some problems, but
can add unnecessary complexity to an application that does not require them. The following
guidelines can help you determine when to use EJBs:
When you are developing for a distributed architecture, and developers are
knowledgeable in the use of EJBs, use EJB to manage business objects and their life
cycle and invocation.
If the application is designed to develop scalable, robust applications, and the
developers have little knowledge of EJBs, then you must use Web applications that do
not use EJBs.

Oracle10g: Build J2EE Applications 3-4

J2EE Design Patterns

Recurring application development issues have led to


the acceptance of design patterns. The generally
accepted design patterns include (but are not limited
to) the following:
Presentation-tier patterns
Intercepting filter
Controller servlet

Business-tier patterns
Business delegate
Transfer object

3-5

Copyright 2004, Oracle. All rights reserved.

J2EE Design Patterns


Design patterns describe solutions for common design issues. This slide is an introduction to
some of the more popular design patterns. An explanation of these patterns is as follows:
Presentation-Tier Design Patterns
- Intercepting filter: Facilitates preprocessing and postprocessing of a request, by
applying additional services that are needed to process a request. A servlet filter
(discussed in a later lesson) is an example of an implementation of this pattern.
- Controller servlet: Provides a centralized controller for handling a request. This
is more comprehensive than the intercepting filter approach, because all requests
are maintained in the same controller.
Business-Tier Design Patterns
- Business delegate: Decouples presentation and service tiers and provides a faade
and proxy interface to services by intervening between a remote business object
on the EJB tier and its client
- Transfer object: Facilitates data exchange between tiers by reducing network
load

Oracle10g: Build J2EE Applications 3-5

Implementing Design Patterns by


Using MVC
MVC is a framework that separately identifies the
components of an application as:

Business functionality (Model)

Presentation (View)

Control logic (Controller)

View

Controller

Model
3-6

Copyright 2004, Oracle. All rights reserved.

Implementing Design Patterns by Using MVC


MVC is an aggregate design pattern; encompassing several patterns. The result is a
framework that identifies components in an application as having different functions. Thus,
if the client is a browser in J2EE applications, the Model View Controller (MVC)
architecture helps to separate business and presentation logic within an application.
Separating application functionality in this way minimizes the need to modify business
logic, if a column name changes in the database, or if the user interface must be adapted for
a client browser, a PDA, or a cell phone. This reduces code duplication and minimizes
maintenance.

Oracle10g: Build J2EE Applications 3-6

The Model

The model represents the enterprise data and


business rules, handling access and updates.
You can simplify the model by using two
mechanisms called faade class and command
pattern.
A faade encapsulates and hides the complexity,
and coordinates the operations between
cooperating classes.
A command pattern encapsulates each application
function in a separate class.

3-7

The model is often implemented as EJBs.

Copyright 2004, Oracle. All rights reserved.

The Model
The model of an application contains the business data and the operations that govern access
and modification of the data. Thus, it is often implemented as EJBs. The model notifies a
view when it changes and provides the ability for the view to query the model about its state.
The controller accesses the application functionality that is encapsulated in the model. A
session bean is often used to create the faade. For example, a session faade bean provides
the required interfaces (while hiding the complexities of the interfacing classes from the
client), and manages the relationships between the objects. A command pattern bean
provides the business logic of the interfaces that a session faade bean implements.

Oracle10g: Build J2EE Applications 3-7

The View

The view focuses on presentation and is


responsible for maintaining consistency between
data presentation and model changes. It enables:
Presentation to be changed without altering
programming logic
Development by Web page authors having only
visual design skills

3-8

The view is commonly implemented as JSPs.

Copyright 2004, Oracle. All rights reserved.

The View
The view of an application renders the contents of a model and specifies how data should be
displayed. The view forwards the user input to a controller. For example, a view component
might display rows from a database. The actual querying of the data should be left to the
model, but formatting the data for the client is left to the view. For this reason, view
components are usually JSPs. An application might be designed to accept query parameters
from user input. In this example, the parameters would be passed to the model from the
controller (discussed in the next slide), and the resultant data would be displayed in the
view.

Oracle10g: Build J2EE Applications 3-8

The Controller

The controller provides interaction with the client,


serving as a glue between the model and the
view.
The controller:
Interprets user requests, and controls business
objects to fulfill these requests
Removes navigation coding from the view
Can be implemented in the client, Web, or EJB tier
or in a combination of these tiers

3-9

The controller is usually implemented as a servlet.

Copyright 2004, Oracle. All rights reserved.

The Controller
A controller defines application behavior. It dispatches user requests and selects views for
presentation. The controller determines what happens when the user interacts with the
component, for example, what occurs when the user clicks a button. In the example on the
previous page, the controller would accept the users query parameters and pass them to the
model. A servlet is best suited for this MVC component, because it contains coding logic for
accepting user input and passing it to a model, with little or no presentation coding, such as
HTML. In this way, the controller makes the application more maintainable as a whole. The
database column names or the preferred formatting style could change, without affecting the
navigation and functionality of the application. A developer would simply change either the
model or the view, respectively.

Oracle10g: Build J2EE Applications 3-9

MVC in Oracle Application Server 10g


Containers for J2EE
View

Controller
Selected
view

Model
Method
invocation
Return
result

Servlet

JSP
HTTP
request

Enterprise
JavaBeans

HTTP
response

Browser

3-10

Copyright 2004, Oracle. All rights reserved.

MVC in Oracle Application Server 10g Containers for J2EE


OC4J separates the model, the view, and the controller by using different containers for each
type of J2EE component. A JavaServer Page (JSP) creates dynamic HTML, which is
rendered in a browser. When the user interacts with the JSP (for example, by submitting a
form), the request is processed by the controller. The controller invokes the methods in the
EJBs, and the EJBs return the result to the controller. This result is then passed on to the
view and displayed as specified in the JSP.

Oracle10g: Build J2EE Applications 3-10

Designing J2EE Applications

Use the following techniques when designing J2EE


applications:
Use case analysis: Identify the operations that
each component will perform.
Decide how to distribute application functionality
across tiers:
A JSP or servlet can access the database by using
JDBC, without interfacing with the EJB tier.
Creating EJBs relieves the developer from the task
of managing transactions.

3-11

Copyright 2004, Oracle. All rights reserved.

Designing J2EE Applications


When outlining applications, design analysts must examine the business problems that an
application should solve. This leads to use case analysis, which is the act of outlining each
of the business processes for a desired application, and deciding how these processes will
interact with each other. The designer must then decide how to distribute these processes
across multiple tiers. In the case of J2EE, the MVC architecture outlines a best practice for
dividing these processes based on the most suitable J2EE components.

Oracle10g: Build J2EE Applications 3-11

Flow Diagram: Example

Customer

Receive
order
status

Log in

Place
orders

Fill orders

Browse
products

Update
inventories

Administrator

Vendor

3-12

Copyright 2004, Oracle. All rights reserved.

Flow Diagram: Example


The slide above shows a sample flow diagram for the following business scenario:
An office supply store wants to sell its products to customers on the Internet. Customers
access a Web site that provides an interface for purchasing office products. Customers can
also track their orders. The interface sends orders to the fulfillment center, and updates the
inventories accordingly. Before a purchase, the application displays the order items,
quantities, and pricing for each item, along with the total cost. Because customers are
businesses, they must log in to the application to ensure that proper discounts are applied to
their orders.
Though most tasks are handled automatically, administrators access another interface for
performing managerial tasks in the application, such as updating inventories. There are eight
warehouses in different parts of the world, and one vendor in Sydney who is external to your
company. This vendor should be provided access to the application to update the
inventories.

Oracle10g: Build J2EE Applications 3-12

Summary

In this lesson, you should have learned how to:


Consider generally accepted patterns when
designing J2EE applications
Identify the model, the view, and the controller
components for a J2EE application

3-13

Copyright 2004, Oracle. All rights reserved.

Oracle10g: Build J2EE Applications 3-13

Practice 3-1: Overview

This practice covers using J2EE design patterns and


the MVC architecture to identify components for a
proposed application.

3-14

Copyright 2004, Oracle. All rights reserved.

Oracle10g: Build J2EE Applications 3-14

Practice 3-1
In this practice, you identify the MVC components for a sample application by using the
design patterns and architectures that are discussed in this lesson.
Using the sample flow diagram given in slide 12, decide how the processes are
implemented in the J2EE components. Match each process to its possible
implementation:

Log in
Receive
order
status
Place
orders

Browse
products

Fill orders

Update
inventories

a. EJB methods that query and update


inventories in various warehouses

b. An EJB that maintains the orders


in each customers shopping cart

c. A front controller servlet, accessing


the database by using JDBC

d. An EJB that delivers a message


that there is a new order

e. A JSP that displays


the available items for sale

f. A servlet or JSP that accesses the


customers outstanding orders

Oracle10g: Build J2EE Applications 3-15

Creating the Web Tier: Servlets

Copyright 2004, Oracle. All rights reserved.

Objectives

After completing this lesson, you should be able to do


the following:
Define the role of servlets in a J2EE application
Describe the servlet life cycle
Describe the request and response architecture
Implement HTTP servlet methods
List J2EE servlet mapping techniques
Handle errors in a servlet
Create and run a servlet in JDeveloper
Deploy a J2EE application to Oracle Application
Server 10g
4-2

Copyright 2004, Oracle. All rights reserved.

Objectives
This lesson explains the servlet technology architecture, and discusses the creation of a
servlet in JDeveloper.

Oracle10g: Build J2EE Applications 4-2

Overview

Requests

Client Web browser

Connects to

Servlet
Generates

Responds

Dynamic HTML
4-3

Copyright 2004, Oracle. All rights reserved.

Overview
The basic concepts of servlets are straightforward. A Web browser invokes a URL, which
calls the servlet. The servlet then generates dynamic HTML, Extensible Markup Language
(XML), or other content. The dynamic text may have been generated by connecting to the
database. The following questions arise:
How can multiple clients be satisfied efficiently?
How can the programmers task be simplified, although the program remains powerful
enough to handle all situations?
This lesson discusses the answers to these questions.

Oracle10g: Build J2EE Applications 4-3

About Java Servlets

A servlet is a Java class that implements the


Servlet interface.

A servlet runs in the context of a special process


called a servlet engine.
Servlets can be invoked simultaneously by
multiple clients.

Java application,
Servlet, JSP,
or HTML

Request
Servlet engine
Response

Client
Server
4-4

Copyright 2004, Oracle. All rights reserved.

About Java Servlets


A servlet is a Java object that implements the servlet API. These classes are found in the
javax.servlet package. When you use the servlet API, it takes care of some of the
common tasks that are involved in responding to a request from a client. For instance, the
API supports preinstantiating objects in a Java virtual machine (JVM) if multiple clients
must simultaneously access a particular functionality that you provide as a Java class. This
feature is referred to as the servlet life cycle.
Just as applets run in the context of a Web browser, a servlet runs in the context of a servlet
engine. The Web browser and the servlet engine contain a JVM that is usually functional all
the time. Unlike an applet, a servlet does not use any user interface features of the Java
language, such as the classes in the java.swing package.
As shown in the slide, a multitude of clients can invoke a servlet and can use different
protocols. For example, it is possible to write a servlet that implements the FTP server
protocol.

Oracle10g: Build J2EE Applications 4-4

Principal Features of Servlets

Concurrent requests are possible and common.


Servlet methods are run in threads.
Servlet instances are shared by multiple client
requests.
Request 1

Request 2

Request 3
Server

Clients
4-5

Copyright 2004, Oracle. All rights reserved.

Principal Features of Servlets


This slide shows the main features of a servlet. Two or more requests for the same servlet
are run in multiple threads. This means that you should develop the servlet to be thread-safe.
Similarly, when there are no more requests for a servlet, the instance is not extinguished.
Instead, in anticipation of future requests, the memory and other resources are reused when
necessary.

Oracle10g: Build J2EE Applications 4-5

Life Cycle of Servlets

All actions are carried out inside the server.


After initial setup, the response time is less.
1

Load

Initialize
init()

3
Execute
service()

4
Destroy
destroy()

4-6

Copyright 2004, Oracle. All rights reserved.

Servlet Life Cycle


The life cycle of a servlet has the following characteristics:
Many servlet engines execute within a single Java virtual machine. Additionally, with
Oracle Application Server 10g, you can use multiple Java virtual machines.
Servlets persist between requests as object instances. If an object instance makes a
connection to a database, then there is no need to make another connection for the
second request. Threads also persist as in any Java program, unless they die in the
natural thread life cycle.
You can override the init() method, which is invoked by the servlet engine before
the servicing of client requests, and the destroy() method, which is invoked after
the engine removes the servlet.
A servlet can also be explicitly written in a single-threaded model. In this case, if two
requests are received at the same time, the servlet engine uses another instance. This is
discussed in detail in a later lesson.

Oracle10g: Build J2EE Applications 4-6

HTTP Servlets

HTTP servlets extend the HttpServlet class,


which implements the Servlet interface.

A client makes an HTTP request, which includes a


method type that:
Can be either a GET or POST method type
Determines what type of action the servlet will
perform

The servlet processes the request and sends back


a status code and a response.
Request

Client
4-7

Response
HTTP protocol

Servlet

Copyright 2004, Oracle. All rights reserved.

HTTP Servlets
HTTP servlets extend the javax.servlet.http.HttpServlet class, which extends
the GenericServlet class. The GenericServlet class implements the Servlet
interface. These servlets provide more features than just providing fast responses to clients.
For instance, the GET parameters that are passed through a Web browser to a Web server are
available to the user of the servlet API. Similarly, data submitted by means of a form is sent
to the servlet by using the doPost() method.

Oracle10g: Build J2EE Applications 4-7

Inside an HTTP Servlet

The servlet overrides the doGet() or the


doPost() method of the HttpServlet class.
The servlet engine calls the service() method,
which in turn calls one of the appropriate doXxx()
methods.
These methods take two arguments as input:
HttpServletRequest
HttpServletResponse

HttpServlet subclass
doGet()

Request
service()

Browser
Response

4-8

Copyright 2004, Oracle. All rights reserved.

Inside an HTTP Servlet


When an HTTP servlet is invoked, the servlet engine calls the service() method in your
servlet. This is possible because you have implemented the Servlet interface. If the Web
browser has invoked the GET method in the HTTP protocol, then the service() method
invokes the doGet() method in your object. Therefore, it makes sense to override this
method, which has two parameters as input. Similarly, if the browser invokes the POST
method in the HTTP protocol (for example, when the user submits an HTML form), the
service() method invokes the doPost() method. Sometimes, the functionality that
you want is the same; you often see servlets in which doPost() calls doGet(). Many
examples mention only doGet(), even though the concept is equally applicable for the
doPost() method.
The servlet engine provides the Web browser input to your doGet() method and,
therefore, you do not have to worry about the difference between the two HTTP protocol
methods. This is another advantage of using the servlet API.
Note that other methods are available in servlets, such as doPut() and doDelete(), for
FTP operations.

Oracle10g: Build J2EE Applications 4-8

Servlet: Example

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
public class SimplestServlet extends
HttpServlet
{
public void doGet(HttpServletRequest
request, HttpServletResponse response) throws
ServletException, IOException
{
PrintWriter out = response.getWriter();
out.println("Hello World");
}
}
4-9

Copyright 2004, Oracle. All rights reserved.

Servlet: Example
The code in the slide shows the simplest form of a servlet. This servlet prints the plain text
Hello World when invoked.

Oracle10g: Build J2EE Applications 4-9

The doGet() Method

The most common HTTP request method type


made to a Web server is GET.
The service() method in your servlet invokes
the doGet() method. The service() method is
invoked on your behalf by the Web server and the
servlet engine.
The doGet() method receives two parameters as
input:
HttpServletRequest
HttpServletResponse

Pass parameters by appending them to the URL


http://www.oracle.com/servlet?param1=value1

4-10

Copyright 2004, Oracle. All rights reserved.

The doGet() Method


The doGet() method, which receives two parameters as input, is usually the first method
that you must modify from the JDeveloper-generated stubs. This slide reviews the
doGet() method. Request parameters are passed to the doGet() method by appending
them to the URL, for instance:
http://www.oracle.com/servlet?param1=value1. Multiple parameters can
be accessed by using the following:
http://www.oracle.com/servlet?param1=value1&param2=value2.
Additionally, a helper class, java.net.URLEncoder, exists for encoding the parameters
that are passed in the URL. The encode(String s, String enc) method of this
class converts a string s using the character encoding enc and returns the converted
string. This is helpful for passing parameters that include special characters.
GET requests are generated by a browser in the following instances: when a user enters a
URL in the address line; when a user follows an HREF link from another page; when a user
submits an HTML form that does not specify a method; when the method is specified as
GET: <FORM METHOD="GET">.

Oracle10g: Build J2EE Applications 4-10

The doPost() Method

The doPost() method can be invoked on a servlet


from an HTML form via the following:
<form method="post" action=>

The service() method in your servlet invokes


the doPost() method. The service() method is
invoked by the Web server and the servlet engine.
The doPost() method receives two parameters as
input:
HttpServletRequest
HttpServletResponse

Pass parameters using the form field names


<input type="text" name="param1">

4-11

Copyright 2004, Oracle. All rights reserved.

The doPost() Method


The doPost() method is used in conjunction with an HTML form. When the user clicks
Submit, any specified parameters are passed to the servlet that is specified in the action
tag. Like the doGet() method, the doPost() receives two parameters as input,
HttpServletRequest and HttpServletResponse. Parameter namevalue pairs
are passed to the Web server in an additional HTTP request header (discussed later in this
course), and not by appending them to the URL. Therefore, the advantages of using POST
include the following:
Parameters (like passwords) are not visible in the browsers URL field.
You cannot bookmark a URL containing the parameter values.
Web servers usually limit the amount of characters that can be passed in the URL (24
kilobytes), but there is no theoretical limit to the size of POST parameters.

Oracle10g: Build J2EE Applications 4-11

The HttpServletRequest Object

The HttpServletRequest object encapsulates


the following information about the client:

Servlet parameter names and values


The remote host name that made the request
The server name that received the request
Input stream data

You invoke one of several methods to access the


information:
getParameter(String name)
getRemoteHost()
getServerName()

4-12

Copyright 2004, Oracle. All rights reserved.

The HttpServletRequest Object


The doGet() and doPost() methods take the HttpServletRequest object as a
parameter. The following table describes several methods in the HttpServletRequest
object and their purposes, based on the example URL:
http://bighost:80/finance/servlet/Ledger/June?region=east

Request methods

Return values

getServerName()

bighost

getServerPort()

80

getPathInfo()

/finance/servlet/Ledger/June.class

getServletPath()

/servlet/Ledger.June

getContextPath()

/finance

getRequestURI()

/finance/servlet/Ledger.June

Oracle10g: Build J2EE Applications 4-12

The HttpServletResponse Object

The HttpServletResponse object encapsulates


information that the servlet has generated:
The content length of the reply
The MIME type of the reply
The output stream

You invoke one of several methods to produce the


information:
setContentLength(int length)
setContentType(String type)
getWriter()

4-13

Copyright 2004, Oracle. All rights reserved.

The HttpServletResponse Object


The second parameter for the doGet() and doPost() methods is the
HttpServletResponse object. The first bullet describes that an HTTP response
consists of a status line (whether or not the call to the servlet was successful), one or more
headers (the content type and optional content length), and the actual output, in that order.
The following table describes several methods that are available in the
HttpServletResponse object and their purposes:
setContentType()

setContentLength(
)
sendRedirect()

Sets the Content-Type header for the document. Must be


used for servlets that return document content. Common
settings include text/html, application/pdf, and
image/gif.
An optional method that sets the Content-Length header,
useful for persistent HTTP connections
Sets the Location header and sets the status code to 302.
Status codes are discussed in detail later in the course.

Oracle10g: Build J2EE Applications 4-13

Methods for Invoking Servlets

Invoke servlets from a client by:


Typing the servlet URL in a browser
Embedding the servlet URL in an HTML or a
JavaServer Page (JSP) page, or another servlet (an
href link)
Submitting a form to the servlet (via the action tag)
Using URL classes in client Java applications

4-14

Invoke servlets inside the J2EE container by


defining a chain of servlets or JSPs.

Copyright 2004, Oracle. All rights reserved.

Methods for Invoking Servlets


You can use the following methods to invoke a servlet:
You can directly type the URL in a browser.
Any HTML page can contain a servlet URL by using either the <a href=> or the
<FORM action=> tag.
JSPs provide yet another way of invoking a servlet. The JSP can have Java code
directly embedded in it. JSPs are covered in depth later in this course.
A servlet can be invoked by another servlet through chaining. A servlet chain is a
sequence of servlets in which the output of a servlet is sent to the next servlet in the
chain. The last servlet produces the actual output that is seen by the Web browser. A
servlet chain has the same advantages that the pipe command has in an operating
system. Any number of servlets can be chained together. Additionally, servlet filters
can intercept the request and pass the output to the next filter or servlet in the filter
chain. Servlet filters are covered in detail later in the course.

Oracle10g: Build J2EE Applications 4-14

Your First Servlet


import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class HelloWorld extends HttpServlet {
public void doGet(
HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException{
response.setContentType ("text/html");
PrintWriter out = response.getWriter();
out.println ("<html>");
out.println ("<body>");
out.println ("Hello World!");
out.println ("</body></html>");
}
}
4-15

Copyright 2004, Oracle. All rights reserved.

Your First Servlet


The example in this slide shows the content of a typical doGet() method. The code:
Sets the MIME type of the resulting output to text/html
Obtains a reference to the PrintWriter object
Writes a series of HTML texts to this object
When the resulting HTML text is received by the browser, it displays the "Hello
World!" string.
The slide also shows that the HttpServletRequest and HttpServletResponse
objects, for example, are derived from the javax.servlet.http package.

Oracle10g: Build J2EE Applications 4-15

Handling Input: The Form

You can use an HTML form and the doPost() method


to modify the HelloWorld servlet.
<html><body>
<form method="post" action="newhelloworld">
Please enter your name. Thank you.
<input type="text" name="firstName"> <P>
<input type="submit" value="Submit">
</form>
</body>
</html>

4-16

Copyright 2004, Oracle. All rights reserved.

Handling Input: The Form


The previous example did not use the HttpServletRequest parameter, although it was
passed as an argument. In this slide, an HTML form is used, which passes the input to the
Web server. Your task is to process this input. The HTML output is shown below.

Oracle10g: Build J2EE Applications 4-16

Handling Input: The Servlet

public class NewHelloWorld extends HttpServlet {


public void doPost(
HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException{
res.setContentType("text/html");
PrintWriter out = res.getWriter();
out.println ("<html><body>");
String name = req.getParameter("firstName");
if ((name != null) && (name.length() > 0))
out.println ("Hello: " + name +
" How are you?");
else
out.println ("Hello Anonymous!");
out.println ("</body></html>");
}}
4-17

Copyright 2004, Oracle. All rights reserved.

Handling Input: The Servlet


The previous slide shows an HTML form that passes some input. This slide shows how you
can process the input. Note that the content type, res.setContentType("text/html"),
is set before submitting the document. In the above example, getParameter() is used to
retrieve the case-sensitive firstName parameter as a string from the HTML form. If no
value is found, an empty string is returned, and null is returned if there is no parameter by
that name. getParameter() is used in the same way for GET and POST requests.
Additionally, getParameterValues() can be used to return an array of strings if the
parameter can have more than one value.
What would happen if we ran this servlet directly and not via the previous form?

Oracle10g: Build J2EE Applications 4-17

Initialization and Destruction

Servlets also define the init() and destroy()


methods in addition to the service() method.
init():
Can be used to retrieve initialization parameters
Takes a ServletConfig object as a parameter
Is invoked when the servlet instance is created
Is useful for obtaining database connections from a
connection pool

destroy():
Takes no arguments
Is invoked when the servlet is about to be unloaded
Is useful for releasing resources

4-18

Copyright 2004, Oracle. All rights reserved.

Initialization and Destruction


The ServletConfig object of init() can be used to find the initialization parameters
that are associated with the servlet. It uses the getInitParameter() method to retrieve
the name of the initialization parameter. Note that you must call super.init() in the
init() method if you use the ServletConfig object, because the ServletConfig
object can be used elsewhere in the servlet. For instance,
public void init(ServletConfig config) throws
ServletException
{ super.init(config);
... // your initialization here }

In a J2EE Web application, an initialization parameter is defined in the web.xml file as


follows:
<init-param>
<param-name>message</param-name>
<param-value>Hello From Init Parameter</param-value>
</init-param>

Oracle10g: Build J2EE Applications 4-18

Error Handling

ServletException:
Is generated to indicate a generic servlet problem
Is subclassed by UnavailableException to
indicate that a servlet is unavailable, either
temporarily or permanently
Is handled by the servlet engine in implementationdependent ways

4-19

IOException: Is generated if there is an input or


output error while processing the request

Copyright 2004, Oracle. All rights reserved.

Error Handling
The doXxx() methods throw both the ServletException and the IOException.
The init() method throws the ServletEception. These exceptions contain the same
constructors as the Exception class. Generally, an IOException is returned only when
there is some kind of stream operation on the servlet (in the case of working with applets, for
example). ServletException is returned if the servlet cannot be reached. For
additional exceptions, an error page can be set for error codes in the <web-app> element
of web.xml, as follows:
<error-page>
<exception-type> java.lang.NumberFormatException
</exception-type>
<location>MyExceptionServlet</location>
</error-page>

Oracle10g: Build J2EE Applications 4-19

Debugging a Servlet

Servlets can be debugged in the following ways:


Setting breakpoints and using the debugger in
JDeveloper
Viewing the source of the generated HTML

4-20

Copyright 2004, Oracle. All rights reserved.

Debugging a Servlet
Servlets can be debugged in JDeveloper by setting breakpoints in the code (by clicking the
line number that you want to set) and then by right-clicking the servlet name in the navigator
and selecting Debug in the menu. Additionally, selecting View > Source in the browser
displays the generated HTML of the servlet.
Note that you can also debug servlets or other J2EE components that are running in a
different JVM. The detailed steps to do this are located in the online help of JDeveloper, in
the topic Remote Debugging. There is a wizard to create a project that is configured for
remote debugging.
Typically, you perform these tasks:
1. Specify the source directory and any necessary libraries.
2. Copy the jdev-rt run-time libraries to the remote server.
3. Bind the Web sites in the J2EE server configuration files.
4. Run the servlet (with breakpoints set) in the remote server.
5. Start the debugging process in JDeveloper as in the slide above.
6. Begin debugging the servlet.

Oracle10g: Build J2EE Applications 4-20

SingleThreadModel

You can implement the SingleThreadModel


interface to prevent multithreaded access of data.
public class HelloWorld extends HttpServlet
implements SingleThreadModel{
public void doGet
}

Each concurrent request then has its own


dedicated servlet instance, which is randomly
assigned.

4-21

Copyright 2004, Oracle. All rights reserved.

SingleThreadModel
Normally, the servlet engine creates a new thread for each request. If the servlet implements
the SingleThreadModel interface, then there will never be more than one request
accessing a single instance of the servlet. In this case, the developer need not synchronize
access to fields and other shared data, such as instance variables. The
SingleThreadModel interface is a solution for low-volume servlets that handle
unsynchronized data and cannot be accessed simultaneously by requests, such as when
creating a userID.

Oracle10g: Build J2EE Applications 4-21

SingleThreadModel (continued)
The following table describes types of variables and attributes and whether they are thread
safe:
Variable/Attribute

Thread Safe?

Local variables

Thread safe

Instance variables

Not thread safe, because a single servlet instance may be


servicing multiple requests at any given time

Class variables

Not thread safe, because multiple servlets and requests may


try to access a class variable concurrently

Request attributes

Thread safe, because the request object is a local variable

Session attributes

Not thread safe, because sessions are scoped at web app


level

Context attributes

Not thread safe, because the same context object can be


accessed concurrently

Oracle10g: Build J2EE Applications 4-22

JDeveloper Environment

The Servlet Wizard in JDeveloper makes it easy for you


to write servlets. The wizard:
Provides the doGet() and doPost() method
skeletons
Provides an environment for running the servlet
within the integrated development environment
(IDE)
Dynamically creates the web.xml file for running
the servlet from the IDE
Allows the creation of a deployment file that aids
in deploying to an OC4J server

4-23

Copyright 2004, Oracle. All rights reserved.

JDeveloper Environment
The Servlet Wizard in JDeveloper gives you an easy way to start your servlet development.
It also creates an environment for running and debugging your servlet.

Oracle10g: Build J2EE Applications 4-23

Servlet Mapping

Mapping a servlet refers to how a client can


access a servlet.
You can map a servlet:
To any URL that begins with a certain directory
name
By using the direct URL:
http://host:port/<contextroot>/servlet/<package>.<servlet>

By using the mapped URL:


http://host:port/<contextroot>/servlet/<mappedservletname>

4-24

<context-root> is the mapping for the Web module

Copyright 2004, Oracle. All rights reserved.

Servlet Mapping
The example servlet shown earlier shows how JDeveloper invokes a servlet. Servlet
mapping refers to the process by which a servlet is invoked. This is application server
dependent, but in general you can map a servlet:
To any URL that begins with a certain directory name. In this case, all class files under
the directory are treated as servlets.
By using the direct or mapped URLs:
http://host:port/<context-root>/servlet/<package>.<servlet>
http://host:port/<context-root>/servlet/<mappedservletname>

where host is the host name or IP address of the server machine, and port is the
port number of the server (for example, Apaches default port is 80; OC4Js default
port is 8888)
The context root is the mapping for the J2EE Web module. This is created by default in
JDeveloper as: <Workspacename>-<ProjectName>-context-root and can be changed
in the http-web-site.xml configuration file.

Oracle10g: Build J2EE Applications 4-24

Servlet Mapping in JDeveloper


JDeveloper provides the standard J2EE model for
mapping servlets by using the web.xml file:
<?xml version = '1.0' encoding = 'UTF-8'?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web
Application 2.2//EN" "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">
<web-app>
<servlet>
<servlet-name>MyFirstServlet</servlet-name>
<servlet-class>package1.HelloWorld</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MyFirstServlet</servlet-name>
<url-pattern>/helloworld</url-pattern>
</servlet-mapping>

</web-app>

4-25

Copyright 2004, Oracle. All rights reserved.

Servlet Mapping in JDeveloper


The web.xml file is primarily used to map a servlet to a virtual directory and name it. This
standard J2EE file is created automatically when a servlet is created in JDeveloper, and the
appropriate XML tags are included in the file. To modify the file, right-click the web.xml
file and choose Properties from the context menu. In the above example, the servlet named
HelloWorld.class is mapped to a virtual directory of /helloworld. Therefore, this
servlet can be accessed with either of the following URLs:

http://localhost:8989/<contextroot>/servlet/package1.HelloWorld
http://localhost:8989/<context-root>/helloworld

The virtual directory of /servlet comes from the J2EE Web server configuration. It is
included automatically when running a servlet that is mapped in the web.xml file. Note
that in OC4J, this mapping is set in the global-web-application.xml file.

Oracle10g: Build J2EE Applications 4-25

Invoking a Servlet

4-26

Copyright 2004, Oracle. All rights reserved.

Invoking a Servlet
This slide shows an example of how a servlet can be invoked in JDeveloper. When the
servlet is run, the J2EE server installed with JDeveloper is started, the mapping is retrieved
from the web.xml file, and the resulting servlet is displayed from the default browser.
Note: The context root of this application is demos-lesson04-context-root.

Oracle10g: Build J2EE Applications 4-26

Specifying J2EE Web Module Settings

4-27

Copyright 2004, Oracle. All rights reserved.

Specifying J2EE Web Module Settings


The slide shows the J2EE Web module settings for a project in JDeveloper. This is accessed
by right-clicking the project and selecting Project Properties. The slide shows the default
settings for the lesson04 project in the demos workspace, and can be changed as
necessary.

Oracle10g: Build J2EE Applications 4-27

Creating a Connection to Oracle


Application Server 10g

4-28

Copyright 2004, Oracle. All rights reserved.

Creating a Connection to Oracle Application Server 10g


As stated previously, you can use several methods for deploying an application to Oracle
Application Server 10g. To deploy from JDeveloper, it is necessary to create a connection to
the server.
Select New > Connections > Application Server Connection, and give the connection a
name, as shown in the slide above. Select the type of connection (a local Oracle Application
Server 10g instance in this case), and then the location of ORACLE_HOME for that server.
Now you can deploy an application directly from JDeveloper to Oracle Application Server
10g.

Oracle10g: Build J2EE Applications 4-28

Deploying to OC4J

4-29

Copyright 2004, Oracle. All rights reserved.

Deploying to OC4J
After the connection is created, deploying to OC4J is simple. Right-click the deployment
profile and select Deploy to <yourappserverconnection>.
Note: If you use Oracle Enterprise Manager to deploy an application, then you can still use
the deployment profile to create the application WAR or EAR file.

Oracle10g: Build J2EE Applications 4-29

Summary

In this lesson, you should have learned how to:


Describe the servlet life cycle
Develop and run a servlet in JDeveloper
Map a servlet in a J2EE server
Collect information from a client
Respond to the client
Handle errors in a servlet
Deploy a servlet to Oracle Application Server 10g

4-30

Copyright 2004, Oracle. All rights reserved.

Oracle10g: Build J2EE Applications 4-30

Practices 4-1, 4-2, and 4-3: Overview

These practices cover the following topics:


Creating a servlet that invokes the doPost()
method and running it from an HTML form
Creating a servlet that invokes the doGet()
method to create an HTML form
Deploying a servlet to Oracle Application Server
10g

4-31

Copyright 2004, Oracle. All rights reserved.

Oracle10g: Build J2EE Applications 4-31

Practice 4-1
The purpose of this practice is to create the login form for the J2EE application that you are
developing. You create and run an HTML form and an HTTP servlet. Run JDeveloper by
using the desktop shortcut. Open the practice04 workspace in the practice04 folder
and navigate to the login project.
1. Modify an HTML form for logging in to an application.
a. Expand the login project and the Web Content folder. Open the
login.html file in the code editor by double-clicking the file.
b. There are two text areas in this form (you can switch between the visual and code
views using the Design and Source tabs) . The text areas have labels but no
names. Complete the <input type="text" name=""> code to include a
name for both the text areas. These are the values that you pass to the request
object and, therefore, it is important to follow standard naming conventions so
that you can refer to the value later. You can perform this step by using the code
editor, or by selecting the text item box in the visual editor and modifying the
name property in the property inspector.
c. Modify the form so that the action tag points to firstservlet. You create
the servlet in the next step.
d. Optionally, modify the forms layout. Add a style sheet by selecting CSS from
the component palette dropdown list and then dragging a style sheet to the
.html file.
e. Save the login.html file.
2. Create a new HTTP servlet.
a. With the login project selected, Select File > New from the menu. Select the
Web Tier > Servlets category and then the HTTP Servlet item and click OK.
b. Click Next to dismiss the first page of the wizard.
c. Ensure that the package name is login and name the class FirstServlet.
d. Because you are sending a POST action from the form, select the doPost()
method in the Servlet Wizard, in addition to doGet(). This ensures that the
doPost() skeleton code is generated. Click Next.
e. Click Next to leave the servlet parameters empty for now.
f. The last step in creating a servlet is the mapping details. Select the check box to
specify a name for the servlet, and accept the default values.
g. Click Finish. You have created FirstServlet.java, a servlet with skeleton
code for the doGet() and doPost() methods.
h. Open the web.xml file in the code editor. Note that login.FirstServlet
is mapped to /firstservlet.
3. Modify the HTTP servlet to handle the login.
a. Add code to the doPost() method to retrieve the Customer Name parameter
from the request object. Remember that the value being passed is the
parameter that you specified in step 1.b, not Customer Name. Remove the
out.println statement containing "The servlet has received a POST"
b. Add code to the doPost() method to greet the customer by using his or her
name in the greeting. If the customer does not enter a name, the name is an
empty string. In this case, greet an anonymous user.
Hint: Use the skeleton code that is provided as a template, to properly format
your document by ensuring that the appropriate HTML tags are used.
Oracle10g: Build J2EE Applications 4-32

Practice 4-1 (continued)


c. Right-click FirstServlet.java and select Make to compile the class.
4. Run login.html to test the functionality.
a. Right-click login.html and select Run.
b. Enter any name (ignore the Customer Id field), and click Login.
c. The name that you enter should be welcomed by the doPost() method of the
servlet.

Oracle10g: Build J2EE Applications 4-33

Practice 4-2
In this practice, you use the doGet() method to combine the login process completed in
Practice 4-1 into a single servlet. The servlet creates the login form and runs initially, rather
than login.html.
1. Create a servlet to handle the login process.
a. In the login project, create a new servlet as in step 2 of practice 4-1.
b. Select login as the package name and name the class LoginServlet.
c. Select the doGet() and doPost() methods in the Servlet Wizard. This
ensures that the skeleton codes of both the methods are generated as in
Practice 4-1.
d. Click Next to leave the servlet parameters empty.
e. This servlet contains an HTML form that references the doPost() method. As
before, the URL pattern for this servlet matches the virtual path in the action
tag of the doGet() method. Create a mapping for this servlet as
/loginservlet.
f. Click Finish and you have created LoginServlet.java, with skeleton code
for the doGet() and doPost() methods.
2. Modify the doPost() method.
a. Copy the doPost() method from FirstServlet.java and paste it into
the doPost() method of LoginServlet.java. This ensures that the login
process remains the same, whereas the URL being called to log in changes.
b. Right-click inside the code editor and select Make to compile
LoginServlet.java.
3. Modify the doGet() method to create the form that is used in login.html.
a. Create a variable to store the servlets Uniform Resource Identifier (URI) from
the request.getRequestURI() method.
b. Copy the contents of login.html and paste into the doGet() method of
LoginServlet.java, just below the line PrintWriter
out=response.getWriter();. Remove the out.println statement
containing "The servlet has received a GET"
c. Modify the HTML code so that it is wrapped in out.println statements. This
also involves eliminating quotes from the HTML and adding escape characters
where necessary. Specify the variable you created in step 3a for the value of the
action tag. For example, the first four lines of the statements should be:
out.println("<html>");
out.println("<head><title>Login to Order
Entry</title>");
out.println("<link rel=stylesheet
href=\"css/oracle.css\" media=\"screen\"/></head>");
out.println("<body>" + "<form method=\"post\" " +
"action=" + <yourservleturivariable> + ">"
d. Continue to concatenate statements and eliminate extraneous quotes until the
HTML is formatted properly in the servlet.

Oracle10g: Build J2EE Applications 4-34

Practice 4-2 (continued)


4. Run LoginServlet.java to test the functionality.
a. Right-click LoginServlet.java and select Run.
b. Enter a name (ignore the Customer Id field), and click Login.
c. The name that you enter should be welcomed by the doPost() method of the
servlet.

Oracle10g: Build J2EE Applications 4-35

Practice 4-3
In this practice, you deploy the application that you built in the previous practices.
1. First, create a connection to your Oracle Application Server 10g instance.
a. Click the Connections tab in the Application Navigator. Right-click Application
Server and select New Application Server Connection.
b. Name the connection OracleAS10g and specify Oracle Application Server 10g
as the connection type. Click Next.
c. Provide welcome1 as the password for the ias_admin user and click Next.
d. Accept the default host name and port and specify the ORACLE_HOME directory
for the Oracle Application Server 10g install, E:\oraas10g, and click Next.
e. Click Next and in the following page, click Test Connection. When the status
message indicates success, click Finish.
2. Create a deployment profile for the application.
a. Right-click the login project and select New.
b. Select Deployment Profiles within the General category and create a WAR file
deployment profile for this project.
c. Name the deployment profile login and click OK.
d. Specify the J2EE Web Context Root as /practice04, accept all other default
settings, and click OK.
3. Deploy the application.
a. Right-click the deployment profile and deploy to the OracleAS10g connection
that you created in step 1.
b. When you see the text Deployment Finished in the message window, the
application is deployed.
c. Access the application by using the following URL:
http://localhost/practice04/loginservlet

d. Navigate to E:\oraas10g \j2ee\home\config and view the contents of


default-web-site.xml in WordPad. This is where the application that you
deployed is specified.

Oracle10g: Build J2EE Applications 4-36

Accessing the Database with Servlets

Copyright 2004, Oracle. All rights reserved.

Objectives

After completing this lesson, you should be able to do


the following:
Load and register a JDBC driver
Connect to an Oracle database by using data
sources
Navigate in a ResultSet
Use PreparedStatement

5-2

Create a pool of connections

Copyright 2004, Oracle. All rights reserved.

Objectives
This lesson focuses on accessing the database by using Java Database Connectivity (JDBC)
from a servlet. This method is recommended when J2EE applications do not use EJBs or
when the functionality of the servlet is not complex. Note that JSPs can also access a
database in a similar manner to that of servlets. JSPs are discussed later in the course.

Oracle10g: Build J2EE Applications 5-2

Review of JDBC

5-3

JDBC is a standard interface for connecting to


relational databases from Java.
The JDBC classes and interfaces are in the
java.sql package.

Copyright 2004, Oracle. All rights reserved.

Review of JDBC
The java.sql package contains a set of interfaces that specify the JDBC API. This
package is a core part of Java and is supported by JDeveloper. Database vendors implement
these interfaces in different ways, but the JDBC API itself is standard. Oracle provides four
drivers: a thin-client driver, an Oracle Call Interface driver for the middle tier, a Java
Transaction Serviceenabled driver for applications that span multiple databases, and a
server-based driver in the Oracle database.
By using JDBC, you can write code that:
Connects to one or more data servers
Obtains metadata from the data server
Executes any SQL statement
Obtains a ResultSet object so that you can navigate through query results

Oracle10g: Build J2EE Applications 5-3

Querying in JDBC

Connect

Query

Process results

Close

5-4

import java.sql.*;
DriverManager.registerDriver()
Connection conn =
DriverManager.getConnection(
"jdbc:oracle:thin
Statement stmt =
conn.createStatement ();
ResultSet rset =
stmt.executeQuery (
"select * from EMPLOYEES");
while (rset.next ())
System.out.println(
rset.getString (2));
rset.close();
stmt.close();
conn.close();

Copyright 2004, Oracle. All rights reserved.

Querying a Database with JDBC


The slide shows the four main steps in querying a database with JDBC.
1. JDBC drivers must register themselves with the driver manager. Use the
registerDriver() method of the DriverManager class. A Connection
object is obtained by using the getConnection() method as shown. You must
pass the username and the password to authenticate yourself, and you must also pass
the JDBC URL that dictates the type of JDBC driver that you are using.
2. A Statement object is obtained only after you have a Connection object, after
which you can invoke the executeQuery() method for SELECT statements or the
executeUpdate() method for INSERT, UPDATE, DELETE, and DDL statements.
JDBC also provides the PreparedStatement object for precompiled SQL
statements. When you declare a Statement object and initialize it by using the
createStatement() method, you implement the Statement interface that is
supplied by the driver you are using.
3. The slide shows an executeQuery() method on the Statement object, which
returns a ResultSet containing the results of your query. A ResultSet maintains
a cursor pointing to its current row of data. Use next() to step through the
ResultSet row by row, and use getString(), getInt(), and other methods,
to assign each value to a Java variable.
4. The Result Set, Statement, and Connection should then be closed.
Oracle10g: Build J2EE Applications 5-4

JDBC and Servlets

There are three ways to use JDBC in a servlet:


Register the JDBC driver within the servlet by hard
coding the driver name in either the servlet or in a
properties file.
Use the JDBC driver from the data-sources.xml
file that is provided with Oracle Application Server
10g.
Use a properties file to store connection details.

In all cases, optimize the connection:


Initialize the database connection in the servlets
init() method (or retrieve from a pool).
Close the database connection in the destroy()
method (or return to a pool).

5-5

Copyright 2004, Oracle. All rights reserved.

JDBC and Servlets


When you use JDBC, you can establish connections in the init() method of the servlet.
Therefore, when you start a Web server, it already has a connection to a database, enabling
fast database access.
Closing Connection and ResultSet Objects
ResultSet objects that were obtained from the execution of a query are automatically
closed if they were not previously explicitly closed. Explicitly close a ResultSet by
calling close() after you have finished using it.
Closing a connection involves calling the close() method of the Connection object
that represents the database connection that you would like to close.

Oracle10g: Build J2EE Applications 5-5

Synchronizing Shared Resources

Reuse PreparedStatement objects.


Sharing Statement objects may not be
thread safe.
Use a synchronized block.
PreparedStatement ps =

synchronized (ps) {
ps.clearParameters();
ps.setInt(1,3);
ps.setDouble(2, 3.14);
ps.executeUpdate();
}

5-6

Copyright 2004, Oracle. All rights reserved.

Synchronizing Shared Resources


You can use the PreparedStatement class to improve performance of the statement by
embodying the PreparedStatement objects as local variables in the doGet() method
of your servlet. However, all instance variables are available for multiple requests,
potentially causing conflicts. The PreparedStatement objects consist of several
method invocations (unlike normal Statement objects). Therefore, you must place these
invocations in a synchronized block, as shown in the slide. You should close a
Statement or PreparedStatement object when you are done using it.
Note that Oracle Application Server 10g Containers for J2EE (OC4J) supports statement
caching, where the same statement does not have to be parsed each time servlet executes it
on behalf of different users. To use statement caching, use the PreparedStatement or
CallableStatement objects.

Oracle10g: Build J2EE Applications 5-6

Transaction Handling

Initialize Connection in the servlets init() method.

Problems with transactions:


The Connection object in the servlets init()
method is shared.
The commit() method depends on the Connection
object.

Solutions for transactions:


Create a new Connection object.
Use the synchronized keyword.
Use the SingleThreadModel interface.
Use session tracking.

5-7

Copyright 2004, Oracle. All rights reserved.

Transaction Handling
If your application has transactional elements, such as committed updates, then the strategy
of having a preestablished connection to a database is a problem. This is because the handle
to this Connection object is available to multiple threads corresponding to multiple client
invocations. The slide shows four possible solutions.
Create a new Connection object every time a servlet is invoked, and close the
connection every time. In general, this solution is acceptable only in a few cases, such
as in debugging situations. Connection Pooling for this option is discussed later in this
lesson.
Create a Connection object in the init() method, but serialize the use of this
object by using the synchronized keyword. If there are few concurrent client
accesses to the Web server, then this may be an acceptable solution.
Implement the SingleThreadModel interface. When a servlet implements this
interface, the servlet engine is alerted not to allow multiple threads for the doGet()
method in this servlet object. If multiple requests are made at the same time to the Web
server, the servlet engine instantiates a new servlet object. The servlet engine is free to
spawn multiple instances beforehand. Therefore, this solution is acceptable if there is
an expected limit to the number of concurrent accesses to this servlet (for example, the
number of students in a class).
Oracle10g: Build J2EE Applications 5-7

Transaction Handling (continued)


Use session tracking. Session tracking is covered later in the course. The idea is to
track the identity of the client who is making a request. This solution does not ensure
better performance than the previous solution, but it does ensure accuracy. It also
allows requests to span multiple HTTP requests from the same client. Session tracking
can be used in conjunction with any other solution.
Note: Transactions can also be handled by using transaction services that are available when
using EJBs in OC4J. This is discussed in detail later in the course.

Oracle10g: Build J2EE Applications 5-8

Connection Pooling

Pooled Connection objects are used and released by


servlet instances. A connection pool performs the
following tasks:
Preallocates database connections
Manages available connections
Allocates new connections
Closes connections that are no longer in use

5-9

Copyright 2004, Oracle. All rights reserved.

Connection Pooling
The most elegant solution is to implement connection pooling, in which a pool of
(preinstantiated) Connection objects are awarded to different requests. When a client is
finished with the request, it is returned to the connection pool. This solution resembles the
SingleThreadModel solution with prespawned connections, except that the amount of
connection pool objects that are instantiated is dynamic and controlled by a program (which
can be adaptive).
Connection pools have a low-water mark (the minimum number of Connection objects
that must always be present, whether in use or not) and a high-water mark (maximum
number of active connections). They are useful only if connections are created relatively
frequently and released soon after use.

Oracle10g: Build J2EE Applications 5-9

Data Sources

Data sources provide logical mappings of


databases:
Developer uses the logical representation of a
database.
Deployer maps to the physical data sources.

J2EE applications use published DataSource


objects by:
Looking up the published name via Java Naming
and Directory Interface (JNDI).
Using JDBC Connection methods to connect to the
database.

5-10

Data sources are published in the JNDI tree.


Data sources come in different varieties.
Copyright 2004, Oracle. All rights reserved.

What Are Data Sources?


A data source is a Java object that has the properties and methods that are specified by the
javax.sql.DataSource interface. Data sources are factories that return JDBC
connections. J2EE applications use JNDI to look up DataSource objects that can be
bound into an external JNDI namespace. Data sources have been introduced with JDBC 2.0,
and are the preferred way for connecting a J2EE application to a data server, over the earlier
JDBC DriverManager class. Because data sources have logical names, applications that
use them are more portable.

Oracle10g: Build J2EE Applications 5-10

Data Source Definition

Global data sources are defined in the


OC4J_HOME/config/data-sources.xml file.
You specify each data source by using an XML tag.
Attributes specify values for the data source.

Application-specific data sources: Use the <datasources> tag in the application.xml file.
OC4J_HOME/applications
myapp
application.xml

Points to
data-sources.xml

5-11

Copyright 2004, Oracle. All rights reserved.

Data Source Definition


As stated earlier, data sources are objects that are used for connecting to a database. You can
set up each data source to contain connection information for the database. In addition, you
can create special types of DataSource objects to provide the following functionality:
Connection pooling: Mapping pools of JDBC connections to the database for increased
scalability
JTA: Cooperate with Java Transaction API (JTA) to support container-managed
transactions for EJBs
There is one global configuration file (OC4J_HOME/config/data-sources.xml)
that establishes data sources at the OC4J server level. OC4J parses this file when it starts,
instantiates the data source objects, and binds them into the server JNDI namespace. Thus,
as seen in the lesson titled "Creating the Web Tier: Servlets", if you add a new data source
specification to this file, then you must restart the OC4J server to make the new data source
available for lookup.
Each application also has a separate JNDI namespace. The web.xml and orionweb.xml files contain entries that can be used in mapping application JNDI names to data
sources. The XML definition for each data source includes a JDBC connection string, and
optionally a database account. After deployment, the application accesses the data sources at
run time through a JNDI lookup.
Oracle10g: Build J2EE Applications 5-11

data-sources.xml: Example

<data-source
class="com.evermind.sql.DriverManagerDataSource"
connection-driver="oracle.jdbc.driver.OracleDriver"
name="OracleDS"
location="jdbc/OracleCoreDS"
xa-location="jdbc/xa/OracleDS"
ejb-location="jdbc/OracleDS"
min-connections="5"
max-connections="25"
username="oe"
password="oe"
url="jdbc:oracle:thin:@<host>:<port>:<SID>"
/>

5-12

Copyright 2004, Oracle. All rights reserved.

data-sources.xml: Example
In the example, the attributes of the data-source tag are defined as follows:
class defines the DataSource class that is to be used.
connection-driver defines the JDBC driver for this data source.
name is used to identify this data source. The default is the value of location.
location defines the logical name for the data source. It returns a DataSource
class as specified in the class attribute.
xa-location is a mandatory attribute if ejb-location is present. This defines
the logical name for the XA-enabled data source.
ejb-location is the logical name for the entity bean data source. This is the JNDI
name that should be used for looking up data sources for any J2EE component.
min-connections controls the minimum size of the connection pool. The default
value is zero.
max-connections controls the maximum size of the connection pool.
url indicates the JDBC connection URL, and optionally the username and password.
OC4J provides a wrapper for DataSource objects that returns an appropriate
DataSource object for the requested data source location.
Note that the pooled-location tag defines the JNDI location of a pooled-connection
data source.
Oracle10g: Build J2EE Applications 5-12

Using Data Sources

To use a defined data source in a servlet:


1. Use the lookup method of the
javax.naming.Context class to retrieve the
named data source class.
2. Create the connection.
try {
Context ic = new InitialContext();
DataSource ds =
(DataSource)ic.lookup("jdbc/OracleDS");
Connection conn = ds.getConnection();
} catch (SQLException se) { }
catch (NamingException ne) { }

5-13

Copyright 2004, Oracle. All rights reserved.

Using Data Sources


To establish the connection to a named data source in data-sources.xml, use the
Context.lookup() method of the javax.naming package. Next, create the
connection. By using this connection, JDBC code can now be included in the servlet as
usual. If the data source does not provide a username and password, then
ds.getConnection (String user, String pwd) can be used to obtain a
connection.
JDeveloper automatically creates data source references in the data-sources.xml file
based on the database connections you create within the integrated development
environment (IDE). For example, if a connection named Connection1 is created in
JDeveloper, then the ejb-location attribute is set to jdbc/Connection1DS.

Oracle10g: Build J2EE Applications 5-13

Summary

In this lesson, you should have learned how to:


Create a servlet to connect to the database by
using JDBC
Load and register a JDBC driver
Connect to an Oracle database by using data
sources
Navigate in a ResultSet
Use PreparedStatement

5-14

Improve database performance by using


connection pooling

Copyright 2004, Oracle. All rights reserved.

Oracle10g: Build J2EE Applications 5-14

Practice 5-1: Overview

This practice covers the following topics:


Connecting to the database by using JDBC
Retrieving database information and formatting it
for output in a servlet

5-15

Copyright 2004, Oracle. All rights reserved.

Oracle10g: Build J2EE Applications 5-15

Practice 5-1
The purpose of this practice is to create a servlet that interacts with a database by using
JDBC. The customer number and name provided in LoginServlet.java is validated in
the CUSTOMERS table of the database, and the customer is shown a list of his or her existing
orders. In JDeveloper, open the practice05.jws workspace.
1. Create the connection to use as the data source for the servlet.
a. Select File > New and select Connections from the General category.
b. Select Database connection and click OK.
c. Name the connection oe and specify an Oracle JDBC connection type.
d. The username is orann (as indicated by your instructor) and the password is
oracle. The password should be deployed at run time.
e. Enter the host, port, and SID as indicated by your instructor.
f. Test the connection and click Finish to close the wizard.
g. You are now able to look up this data source reference by using its <ejblocation> name, jdbc/oeDS.
2. Modify LoginServlet.java to include the new functionality.
a. Double-click the verifylogin project and navigate to the Libraries tab to add
the Oracle JDBC library to your project.
b. Open LoginServlet.java in the verifylogin project.
c. Import the javax.naming (for the resource lookup), javax.sql (for the
DataSource class), java.sql (for the Connection class), and
oracle.jdbc packages to the LoginServlet.
d. Create instance variables for the Connection (as conn), the DataSource
(as ds), and the PreparedStatement (as ps) objects.
e. In a try/catch block of the init() method, use the lookup method of the
Context class to retrieve the data source that you created in step 1.
f. Catch a NamingException if the name is not found.
g. In the try block, initialize the connection object. Catch a SQLException.
h. Also in the try block, create a PreparedStatement object from the
Connection object that is stored in the PreparedStatement object
declared in step 2.d. The query string should select all columns from the
ORDERS table for all orders with the CUSTOMER_ID equal to a bind variable
parameter.
i. Create the destroy() method to close the connection and prepared statement
objects that you created in a try/catch block. Catch a SQLException.
3. Create the functionality to validate the provided name and ID.
a. Create a new synchronized boolean method in the servlet to verify the customer
information. This method accepts the connection, the customer ID, and the
customer name as arguments, and throws a SQLException.
b. Create a method variable to initialize the customer ID.
c. Create an instance of the Statement object.

Oracle10g: Build J2EE Applications 5-16

Practice 5-1 (continued)


d. Create a variable to store the query for this method. The query should select the
customer_id and cust_last_name from the CUSTOMERS table, where
the customer_id and cust_last_name match those that are provided as
arguments to the method.
e. Use the executeQuery() method of the Statement object that you created
in step d. Assign this value to a ResultSet variable.
f. While iterating through ResultSet, retrieve the customer ID.
g. Close the ResultSet and return true if the customer ID is not null or an
empty string. Otherwise, return false.
4. Create the functionality to query the database for the customers existing orders.
a. Create a new synchronized method to get the orders for a customer. This method
accepts the Connection and the customer ID as arguments, and throws a
SQLException.
b. Declare one method variable of type String. Initialize the variable to a string
with a length of zero ("").
c. Use the setString() method of the PreparedStatement object to pass
the value of the method argument to the query statement created in step 2h.
d. Execute the query from the PreparedStatement object, and store the results
in a ResultSet object.
e. By using a while loop, loop through all records in the ResultSet object. As
you iterate through each row, fetch the column values and save them into three
string variables named orderId, orderStatus, and orderTotal.
f. In the while loop, add the following code by replacing
yourStringVariableName with the name that you chose in step b.:
yourStringVariableName += "<tr><td>" + orderId +
"</td><td>" + orderStatus + "</td><td>" + orderTotal +
"</td></tr><p>";

Note that you are appending the variables to the String object that you
declared in the first step, and formatting the data in a table.
g. Close your ResultSet object outside the while loop.
h. Return yourStringVariableName. Note that this represents a string of
HTML output, including a list of all the orders placed by a given customer.

Oracle10g: Build J2EE Applications 5-17

Practice 5-1 (continued)


5. Modify the doPost() method to call the new methods.
a. Create an instance variable to retrieve the customer ID from the request
object.
b. Delete the if/else block for checking if a customer name was entered.
c. If the return of the method you created in step 4 is true, then include the return
value from the method that you created in step 5, formatted in an HTML table.
Pass the Connection object and customer ID variable to this method. If the
return value is false, then alert the customer that the login is invalid.
d. Catch a SQLException.
6. Compile to test and run the application from LoginServlet.java. Note that not
all customers have current orders in the database. Valid customer IDs and names that
have orders are listed below:
101

Welles

102

Pacino

103

Taylor

104

Sutherland

105

MacGraw

106

Hannah

107

Cruise

108

Mason

109

Cage

116

Martin

117

Edwards

118

Mahoney

119

Hasan

120

Higgins

121

Sen

122

Daltrey

123

Brown

Oracle10g: Build J2EE Applications 5-18

Using Advanced Techniques in Servlets

Copyright 2004, Oracle. All rights reserved.

Objectives

After completing this lesson, you should be able to do


the following:
Use a cookie in a servlet
Send HTTP headers to the client
Use servlet filters
Define event listeners

6-2

Copyright 2004, Oracle. All rights reserved.

Objectives
This lesson discusses additional topics in creating a servlet.

Oracle10g: Build J2EE Applications 6-2

Overview

Request
getCookies()
getHeader()

Response
Client Web
browser

Servlet

setHeader()
addCookie()

Error handling
6-3

Copyright 2004, Oracle. All rights reserved.

Overview
The request and response objects provide methods for sending and retrieving data such as
parameters (as seen in the lesson titled Creating the Web Tier: Servlets), cookies for
obtaining state information, and headers for setting status codes and redirecting the user.
This lesson covers the use of these methods, as well as the techniques for handling errors.

Oracle10g: Build J2EE Applications 6-3

HTTP Headers

6-4

Headers are HTTP details that are passed between


the browser and the server.
They can be response or request headers.
The getHeader() method of
HttpServletRequest retrieves the string value of
the header.
The setHeader() method of
HttpServletResponse sends a header to the
browser.

Copyright 2004, Oracle. All rights reserved.

HTTP Headers
The HTTP request and response headers manipulate the HTTP connection between the
browser and the server. For example, in the previous lessons, setContentType was used
to set the content type header for the browser. Note that because headers can change the
content of the response, they need to be set before the output is generated.

Oracle10g: Build J2EE Applications 6-4

Request Headers

Additional request headers include the following:

6-5

Accept

Specifies MIME types that the browser


supports

AcceptLanguage

Specifies the browsers preferred language

Cookie

Returns cookies to servers that previously


sent them to the browser

Referer

Indicates the URL of the referring Web page,


for tracking users

User-Agent

Identifies the browser that is making the


request, for checking browser features

Copyright 2004, Oracle. All rights reserved.

Request Headers
Retrieving the value of request headers is helpful for designing servlets that cater to browser
preferences. For instance, if a servlet is written to produce content in more than one
language, request.getHeader("Accept-Language") could be used to verify a
standard language code (en-us, da, and so on). Thus, the response could be modified
according to the browser settings, without having to ask the user for a form value or other
parameter. The following is a complete list of request headers:
Accept
Accept-Charset
Accept-Encoding
Accept-Language
Authorization
Cache-Control
Connection
Content-Length
Content-Type
Cookie
Expect
From
Host
If-Match
If-Modified-Since
If-None-Match
If-Range
If-UnmodifiedSince
Pragma
Proxy-Authorization Range
Referer(misspelled
Upgrade
User-Agent
due to HTTP author
Via
Warning
error)
Oracle10g: Build J2EE Applications 6-5

Sending a Response

There are three aspects to sending a response:


Sending HTTP headers
Sending a status code (an integer denoting the
nature of response)
Sending multimedia content

6-6

Copyright 2004, Oracle. All rights reserved.

Sending a Response
A servlet must also send data back to the browser. There are three aspects to this, as shown
in this slide. These aspects are explained in detail in the following slides.

Oracle10g: Build J2EE Applications 6-6

Response Headers

The HttpServletResponse class is used to send


headers.
You have seen an example of setting header
information: setContentType("text/html");.
Other headers are set by using the setHeader()
method.
Do not confuse HTTP headers with the HEAD tag in
HTML pages.

6-7

Copyright 2004, Oracle. All rights reserved.

Response Headers
The following table shows some standard HTTP response headers. Common headers have
shortcut methods, such as setContentType, setContentLength, addCookie, and
sendRedirect.
Header

Usage

Location

Specifies a new location of a document, usually used with the


SC_MOVED_TEMPORARILY and
SC_MOVED_PERMANENTLY status codes

Content-Encoding

Is used to encode the response body. Example values are xgzip and x-compress.

Cache-Control

Specifies any special treatment that a caching system should


give to this page. Example values are no-cache and maxage=(time in seconds).

Oracle10g: Build J2EE Applications 6-7

Setting Status Codes

If a servlet does not specify a status code, then


the Web server sends the default status code
(200).
You can explicitly set a status code by using the
setStatus() method.

Example:
int pageVersion =
Integer.parseInt(req.getParameter("pageVersion"));
if (pageVersion >= currentVersion){
response.setStatus(response.SC_NO_CONTENT);
}else{
//Send original page
}

6-8

Copyright 2004, Oracle. All rights reserved.

Setting Status Codes


The setStatus(int StatusCode) method in the HttpServletResponse object
is used to set status codes. The default code is 200, which the end user never sees.
Paradoxically, a code that the user often sees is the infamous 404 code, Resource not
found. Two shortcut methods exist for setStatus: sendError (int code,
String message) and sendRedirect(String URL), which generates a 302
response with a location header for the new URL.
Mnemonic Constant

Code

Default
Message

Meaning

SC_OK

200

OK

The clients request was successful, and


the servers response contains the
requested data.

SC_NO_CONTENT

204

No Content

The clients request was successful, but


there was no new response data.

SC_MOVED_TEMPORARILY

302

Temporary
Move

The requested resource has temporarily


moved to another location, but future
references should use the original URL.

Oracle10g: Build J2EE Applications 6-8

Example

Assume that the randomSite() method generates


a Web site randomly.
For example, http://www233.oracle.com

Requests to www.oracle.com can be sent to this


site to provide load balancing.

public void doGet(


HttpServletRequest req,HttpServletResponse res)
throws IOException, ServletException{
String tempSite = this.randomSite();
// implementation not shown
res.setStatus(res.SC_MOVED_TEMPORARILY);
res.setHeader("Location", tempSite);
}

6-9

Copyright 2004, Oracle. All rights reserved.

Example
The slide shows an example of a servlet sending HTTP headers back to the client. For the
purpose of this example, the browser sends a request to www.oracle.com. The servlet
receiving this request dispatches the browser to a new site for the purposes of load
balancing.
The first servlet generates a random site that is capable of serving the same request. In this
example, it is www233.oracle.com.
It sets the status code to SC_MOVED_TEMPORARILY.
It supplies the new location by sending the Location HTTP header.

Oracle10g: Build J2EE Applications 6-9

Sending Multimedia Content

6-10

Multimedia content usually contains binary


response data.
Use the getOutputStream() method instead of
the getWriter() method if you want to send
binary data, such as images.
Use the setContentType() method with the
image/gif MIME type to send a GIF-encoded
image.
Use other MIME types to send other types of
multimedia content.

Copyright 2004, Oracle. All rights reserved.

Sending Multimedia Content


To build multimedia content, you must create the image window, draw the image, and then
send the image in the specified content type to the output stream. To send the image to the
output stream, use the javax.imagio package and convert a java.awt.Image to a
java.awt.image.BufferedImage, as in the following example:
import javax.servlet.*; import javax.servlet.http.*;
import java.awt.*; import java.awt.image.*;
import java.io.*; import javax.imageio.*;
public class ImageServlet extends HttpServlet {
public void doGet(HttpServletRequest req,HttpServletResponse
res) throws ServletException,IOException
{
res.setContentType("image/jpg");

Oracle10g: Build J2EE Applications 6-10

Sending Multimedia Content (continued)


OutputStream out=res.getOutputStream();
Frame frame=null;
Graphics g=null;
try
{
//Step 1: Create the frame and window.
frame=new Frame();
frame.addNotify();
//Step 2: Draw the Image.
Image image=frame.createImage(400,60);
g=image.getGraphics();
g.setFont(new Font("Serif",Font.ITALIC,48));
g.setColor(Color.red);
g.drawString("Hello Class!!!",10,50);
BufferedImage bImg = new
BufferedImage(400,60,BufferedImage.TYPE_INT_RGB);
g = bImg.getGraphics();
g.drawImage(image,0,0,null);
ImageIO.write(bImg,"jpg",out);
}

finally
{
//clean up resources
if(g!=null) g.dispose();
if(frame!=null) frame.removeNotify();
}

}
}

Oracle10g: Build J2EE Applications 6-11

Cookies

A cookie is a name or value pair sent by a servlet


to a browser in the header.
Cookies are persistent (the information sent is
stored on the client, to be retrieved later).
Cookies are often used to obtain state information,
such as a username or preference.

6-12

Copyright 2004, Oracle. All rights reserved.

Cookies
The following table describes the methods that are available for use with cookies and their
purposes:
get/setMaxAge

This method controls the cookie expiration time in seconds. The


default value is negative, which indicates that the cookie will last only
until the user closes the browser. Setting the value to zero (0) instructs
the browser to delete the cookie.

get/setName

This method gets or sets the name of the cookie.

get/setPath

This method gets or sets the path to which the cookie applies. Default
is to return the cookie only to the URLs that are in or below the
directory containing the page that sent the cookie.

get/setValue

getValue() looks up the value that is associated with the cookie.


setValue() specifies the value.

get/setDomain

This method controls the domain for which the cookie is applied. The
browser will only return cookies to the exact host name that sent them.
Use setDomain() to return cookies to other hosts within the same
domain.
Oracle10g: Build J2EE Applications 6-12

Setting Cookies

Use the Cookie() constructor to create a new


cookie.
Use the addCookie() method in the
HttpServletResponse class to add and send the
cookie to a browser.
Cookie userCookie = new Cookie ("user", "fred");
userCookie.setMaxAge(60*60); //one hour
response.addCookie(userCookie);

6-13

Copyright 2004, Oracle. All rights reserved.

Setting Cookies
The Cookie constructor takes two strings: name and value. Note that if a user has a
browser that does not support cookies, or if the user has disabled cookies in his or her
browser, then you need to use URL rewriting, hidden form fields or session tracking to keep
track of visitors to your site. These topics are covered in a later lesson. Additionally, because
cookies are not encrypted when sent, retrieved, or stored, they should not be used for
sensitive information such as passwords.

Oracle10g: Build J2EE Applications 6-13

Retrieving Cookies

Use the getCookies() method to fetch an array of


Cookie objects.
Cookie[] cookies = request.getCookies();
if (cookies != null) {
String readValue;
for (int i = 0; i < cookies.length; i++)
readValue = cookies[i].getValue();

6-14

Copyright 2004, Oracle. All rights reserved.

Retrieving Cookies
The code in the slide shows how to read the cookie object from the browser. To use the
cookie object rather than just read the value, use the getCookie() method.

Oracle10g: Build J2EE Applications 6-14

About State Preservation

6-15

Usually, the servlet engine instantiates the servlet


only once.
Any number of requests can be handled by the
same instance of the servlet class.
Values of any instance variable in the class persist
between HTTP requests from multiple browsers.
Values of variables in the doGet() or doPost()
method do not persist between multiple browser
requests.

Copyright 2004, Oracle. All rights reserved.

About State Preservation


As discussed in the lesson titled "Creating the Web Tier: Servlets", the Servlet object is
instantiated only once (unless the servlet implements the SingleThreadModel interface.
Any number of requests can be handled by different threads at the same time to process
multiple requests. The next slide shows how to use instance variables.
Instance variables in your servlet class persist between invocations. This makes sense, given
that the object is instantiated only once. Local variables in the doGet() and doPost()
methods do not persist.

Oracle10g: Build J2EE Applications 6-15

State Preservation: Example


public class StateServlet extends HttpServlet {
int counter = 0; //persistent variable
public void doGet(HttpServletRequest req,
HttpServletResponse res) throws IOException,
ServletException{
res.setContentType("text/html");
PrintWriter out = res.getWriter();
String name = req.getParameter("firstName");
// name is transient variable
out.println ("<html><body>");
out.println ("Hello: " + name);
out.println ("Hit count is: " + ++counter);
out.println ("</body></html>");
}}
6-16

Copyright 2004, Oracle. All rights reserved.

State Preservation: Example


The example in this slide demonstrates how states can be preserved by using the ideas in the
previous slide. If a request is made to this servlet, then it stores the name of the user in the
name instance variable of String type, after the firstName parameter is available.
Next, the value of the counter instance variable is incremented and displayed. Though the
code in the slide shows how to preserve state, it is not thread safe. The synchronize
keyword should be used to ensure simultaneous requests do not have access to the same
counter instance variable. Though it is usually okay for users to receive the same value for a
counter variable, there are occasions where this is clearly not desirable (for example, when
creating user IDs). Later lessons cover more sophisticated ways of preserving states.

Oracle10g: Build J2EE Applications 6-16

ServletContext

The ServletContext interface defines the servlet


within the Web application.
Methods in ServletContext allow for retrieving
the MIME type of a file, dispatching requests to
other servlets, or writing to a log file.

6-17

Copyright 2004, Oracle. All rights reserved.

ServletContext
The following table provides some of the methods of ServletContext and their uses:
Method

Purpose

getContext(String)

Returns the ServletContext object for the specified


URL

getMimeType(String)

Returns the MIME type of the specified file as


determined by the configuration of the servlet
container, or as specified in the web.xml file

getRequestDispatcher(String)

Returns a RequestDispatcher object that acts as a


wrapper for the resource located at the given path.
RequestDispatcher is used to forward or include
the request or response.

getServerInfo()

Returns the name and version of the servlet container

getServletContextName()

Returns the name of the corresponding Web application


as specified in the deployment descriptor for this Web
application by the display-name element

Oracle10g: Build J2EE Applications 6-17

RequestDispatcher

To forward the request to another servlet or JSP,


use the RequestDispatcher interface:
getServletContext().getRequestDispatcher(String
url).

RequestDispatcher contains two methods:


forward() and include().
Use the forward() method to transfer control to
the associated URL.

These methods take HttpServletRequest and


HttpServletResponse as arguments.

6-18

Copyright 2004, Oracle. All rights reserved.

RequestDispatcher
You have seen that a user can be redirected to another resource by using
sendRedirect(). However, this does not automatically preserve the request data.
Instead, you can use the RequestDispatcher interface, passing in the URL for the new
resource. Use the forward() method of RequestDispatcher to completely transfer
control to the associated URL.
For example, if a user accesses a login form of an application and does not have an account,
the request could be forwarded to an application page for the user to complete. The
include() method is used to get an output of the content of the associated URL, after
which control is returned to the servlet. Note that for both the forward() and
include() methods, POST requests cannot be forwarded to static HTML pages, because
forwarded requests use the same request method as the original request. This can be avoided
by renaming the HTML document to a .jsp extension that can handle the POST request.
JavaServer Pages (JSP) is covered in detail later in this course.

Oracle10g: Build J2EE Applications 6-18

RequestDispatcher: Example

public void doPost(HttpServletRequest request,


HttpServletResponse response) throws
ServletException, IOException
{
String name = request.getParameter("firstName");
if (name == null){
String url = "/loginerror.jsp";
RequestDispatcher dispatcher =
getServletContext().getRequestDispatcher(url);
dispatcher.forward(request, response);
else {out.println ("Hello: " + name) ;}
}

6-19

Copyright 2004, Oracle. All rights reserved.

RequestDispatcher: Example
By using the StateServlet example seen in the section State Preservation: Example
earlier in this lesson, assume that the user does not enter a name in the HTML field. You
may then want to display an HTML form with details about appropriate values. To forward
to a static HTML page, use a RequestDispatcher. The slide shows how
RequestDispatcher is obtained by calling the getRequestDispatcher()
method of ServletContext. The RequestDispatcher can then forward or include
the content to a static HTML page, a JSP, or to another servlet.

Oracle10g: Build J2EE Applications 6-19

Servlet Filters

Filters dynamically change the content or header of a


request or response. A filter is used to:
Intercept a request before a servlet is called
Modify the request, response, and header values
Optionally, customize the response

6-20

Copyright 2004, Oracle. All rights reserved.

Servlet Filters
Servlet filters are a new feature of the Servlet 2.3 API, and can be used to intercept and
modify a servlets response. They can be configured to be invoked when one or many
servlets are called. This enables the programmer to modify production servlet functions
without changing existing code. Note that filters work with servlets and JSPs, but are not
servlets themselves, because they do not actually create a response. Instead, they pass the
response to the calling servlet. Filters can be used for several reasons, including
authenticating user identity, tracking users of an application, and compressing data.
JDeveloper contains wizards for creating filters.

Oracle10g: Build J2EE Applications 6-20

Using Filters

The javax.servlet.Filter interface is implemented


to use a filter, and contains three methods:
void init(FilterConfig)
void doFilter(ServletRequest,
ServletResponse, FilterChain)
void destroy()

6-21

Copyright 2004, Oracle. All rights reserved.

Using Filters
You must implement the javax.servlet.Filter interface and define the
init(FilterConfig), destroy(), and doFilter() methods to use a filter. The
init() method is called once to initialize the filter. Pass the FilterConfig object to
init() to pass the initialization parameters. The doFilter() method is then called for
each request that is specified to use the filter. This method is responsible for actions such as
examining request and response headers and customizing the response as necessary.
FilterChain can be used to call multiple filters in succession. If there are no filters
defined or if the current filter is the last filter in the chain, then the target servlet is called.
The server calls the destroy() method to discontinue the use of the filter.

Oracle10g: Build J2EE Applications 6-21

doFilter() Method

The doFilter() method:

6-22

Examines the request header


Modifies request headers by wrapping the
request object
Modifies the response by wrapping the response
object
Invokes the next filter in the filter chain

Copyright 2004, Oracle. All rights reserved.

doFilter() Method
Use the doFilter() method to modify the request headers, the response, and to
optionally invoke the next filter in the filter chain. The request and response objects are
wrapped in the filter class by implementing HttpServletRequest or
HttpServletResponse. The next entity (a filter or a servlet) is invoked by calling the
doFilter() method on the FilterChain object, passing in the request and response
that it was called with, or wrapped versions that it may have created. The filters are called in
the same order that they are listed in the web.xml file. Note that if the current filter is the
last filter in the filter chain, then the filter invokes the servlet that called the filter.

Oracle10g: Build J2EE Applications 6-22

Using Filters

import javax.servlet.*; import javax.servlet.Filter;


import java.io.*;
public class HelloFilter implements Filter {
private FilterConfig filterConfig;
public void init(FilterConfig filterConfig){
System.out.println("Filter Initialized");
}
public void doFilter (ServletRequest request,
ServletResponse response, FilterChain chain) throws
IOException, ServletException {
System.out.println("Hello from Filter");
chain.doFilter(request, response);
}
public void destroy(){}
}
6-23

Copyright 2004, Oracle. All rights reserved.

Using Filters
In this example, the Filter interface is implemented, and the init(), doFilter(),
and destroy() methods are created to display a message when the filter is initialized. Just
before passing the request and response objects, a Hello from Filter message will be
displayed in the console.

Oracle10g: Build J2EE Applications 6-23

Configuring Filters

To use a servlet filter, the web.xml deployment


descriptor is modified to include the <filter> tag:
<filter>
<filter-name>HelloFilter</filter-name>
<filter-class>filterpackage.HelloFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>HelloFilter</filter-name>
<servlet-name>StateServlet</servlet-name>
</filter-mapping>

6-24

Copyright 2004, Oracle. All rights reserved.

Configuring Filters
The web.xml file is used to configure a filter for use. In the example given in the slide, the
filter class, HelloFilter, intercepts the request when StateServlet is accessed. A
filter can also be configured to run whenever any request (static or dynamic) is made to the
Web application:
<filter-mapping>
<filter-name>HelloFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

Initialization parameters can be specified for a filter by using the <init-params>


element.

Oracle10g: Build J2EE Applications 6-24

Application Lifecycle Events

6-25

Lifecycle Events are a new feature of the Servlet


2.3 API.
Event listeners are used to check for state
changes.
There are two types of events: ServletContext
and HttpSession.
Event listeners can be notified when objects are
initialized, destroyed, or when their attributes
change.

Copyright 2004, Oracle. All rights reserved.

Application Lifecycle Events


The application lifecycle events feature provides notification to listening objects when a
change in the ServletContext or HttpSession is identified. For example, an event
to create a pool of database connections could be called whenever the first
ServletContext of a Web application is created. There are four listeners available:
javax.servlet.ServletContextListener
javax.servlet.ServletContextAttributeListener
javax.servlet.http.HttpSessionListener
javax.servlet.http.HttpSessionAttributeListener
Note that JDeveloper contains wizards for creating servlet listeners.

Oracle10g: Build J2EE Applications 6-25

ServletContext Events

Implement one or more ServletContext listener


interfaces to respond to ServletContext events. The
following methods are invoked when a
ServletContext event occurs:
contextInitialized()
contextDestroyed()
attributeAdded()
attributeRemoved()
attributeReplaced()

6-26

Copyright 2004, Oracle. All rights reserved.

ServletContext Events
The following table describes the types of methods that are invoked for each type of
ServletContext event:

Events

Methods

ServletContext is
created or is shutting
down.

contextInitialized()or
contextDestroyed() methods of the
ServletContextListener class

An attribute has been


added, removed, or
replaced.

attributeAdded(),
attributeRemoved(), or
attributeReplaced() methods of the
ServletContextAttributeListener
class

Oracle10g: Build J2EE Applications 6-26

HttpSession Events

Implement one or more HttpSession listener


interfaces to respond to HttpSession events. The
following methods are invoked when an HttpSession
event occurs:
sessionCreated()
sessionDestroyed()
attributeAdded()
attributeRemoved()
attributeReplaced()

6-27

Copyright 2004, Oracle. All rights reserved.

HttpSession Events
Sessions are a way to maintain a continuous connection within a Web application, and are
covered in depth later in the course. For now, just note that the following methods are
available for tracking session events:
Events

Methods

An HttpSession has
been activated or is
about to be destroyed.

sessionCreated() or
sessionDestroyed() methods of the
HttpSessionListener class

An attribute has been


added, removed, or
replaced.

attributeAdded(),
attributeRemoved(), or
attributeReplaced() methods of the
HttpSessionAttributeListener
class

Oracle10g: Build J2EE Applications 6-27

Example of an Event Listener

public class ConnectionManager implements


ServletContextListener {
public void
contextInitialized(ServletContextEvent
event) {
Connection conn = // create connection
event.getServletContext().setAttribute("conn",
conn);
}

6-28

Copyright 2004, Oracle. All rights reserved.

Example of an Event Listener


The slide shows an example event listener to ensure that a database connection is available
for every new servlet context. To use this listener, add the following to the web.xml file:
<web-app>
<listener>
<listener-class>ConnectionManager</listener-class>
</listener>
<servlet>

</servlet>
</web-app>

Note that the listener attribute must directly precede the servlet element in the
web.xml file.

Oracle10g: Build J2EE Applications 6-28

Error Handling

Java prevents a servlet from unintentionally or


maliciously damaging the servlet engine.
The Servlet API allows:
Logging of errors
Sending HTTP status codes to the client

In the doGet() method, Java requires that any


method that generates any exceptions must be
handled explicitly.
You can let the servlet engine handle only
IOException and ServletException, and not
any other exceptions (for example,
InterruptedException).

6-29

Copyright 2004, Oracle. All rights reserved.

Error Handling
As in any program, error handling is very important in a servlet. For example, errors can
occur if:
The client sends malformed data to the servlet
A resource made available by the operating system becomes unavailable or corrupt
When an error occurs, you should limit the damage to the server and inform the Web
browser appropriately. The following example illustrates how you could manipulate the
response status line in a servlet, by using the previously referenced StateServlet:
String name = request.getParameter("firstName");
if ((name.equals("") {
reportError (response, "Missing Name Parameter");
return; }
private void reportError(HttpServletResponse response,
String errmessage) throws IOException {
response.sendError (response.SC_NOT_FOUND, errmessage);
}

Oracle10g: Build J2EE Applications 6-29

Summary

In this lesson, you should have learned how to:


Send headers and other content to the client
Use filters to modify servlet response
Handle state preservation
Handle errors that might arise during the
execution of your servlet

6-30

Copyright 2004, Oracle. All rights reserved.

Oracle10g: Build J2EE Applications 6-30

Practices 6-1 and 6-2: Overview

These practices cover the following topics:


Creating a servlet that uses cookies
Using servlet filters to manipulate headers

6-31

Copyright 2004, Oracle. All rights reserved.

Oracle10g: Build J2EE Applications 6-31

Practice 6-1
The purpose of this practice is to use cookies within multiple servlet instances. You modify
the LoginServlet.java file that you created in practice 5. This servlet uses a cookie to
store the users name and retrieve that value when the user accesses the servlet. Open the
practice06.jws workspace and navigate to the newlogin project. Open
LoginServlet.java in the code editor.
1. Add code to the doPost() method of LoginServlet.java servlet to create a
cookie.
a. Create a new Cookie object named LoginCookie. The cookie value will be
the variable that holds the custName value.
b. Set the cookies maximum age to two minutes.
c. Add the cookie to the response object to send it to the browser.
2. Retrieve the cookie from the browser. Add the following code to the doGet()
method of LoginServlet.java:
a. Create a variable to store the value of the cookie.
b. Use the getCookies() method to fetch the array of Cookie objects. Then,
verify whether the request returned any cookies.
c. If so, use iteration to loop through the array of cookies. For each iteration, test to
see if the cookies name is LoginCookie. If so, retrieve the cookie value into
the variable that you created in step 2.a. and break out of the loop.
d. Test whether the cookie was found. If not, display the form that is already created
in the doGet() method. If it is found, add code to welcome the user back to the
Order Entry application by using the value of the cookie for personalization.
e. Compile LoginServlet.java.
3. Test and run the application.
a. Run LoginServlet.java. You should see the form that was created in the
previous practice. Enter a valid name and ID in the fields (refer to practice 5 for
valid name and ID entries) and click Login.
b. You should see the orders displayed for the customer as in the previous practice.
However, the name is now stored as a cookie for two minutes.
c. Run LoginServlet.java the second time to test whether the cookie is being
correctly set. You should be welcomed back to the application.
d. To ensure that your cookie is expiring correctly, wait for two minutes and then
run LoginServlet.java. You should see the form as in step a.

Oracle10g: Build J2EE Applications 6-32

Practice 6-2
The purpose of this practice is to redirect a user by sending a header to the response.
Suppose that the contract between your company and customer number 104 is currently
being reviewed, and as the developer, you have been instructed to temporarily block this
customer from entering the Order Entry application. You can do this by modifying the
servlet code to check for this customer and redirect him or her to an appropriate error
message. However, this would mean modifying the servlet itself. Therefore, to incorporate
this business rule, use a servlet filter.
1. Select File > New > Web Tier > Servlets and create a new Servlet Filter in the
newlogin project. Name the filter and the class LoginFilter, and ensure the
package name is newlogin. Map this filter to every servlet in the URL pattern.
2. Use the Properties class of the java.util package to create an instance
variable named blockUser.
a. Create an instance variable of type java.util.Properties. Note that you
will need to import this package.
b. Use blockUser.setProperty to define the business rule that you are
creating: the name property with a value of Sutherland.
c. Additionally, create an instance variable to store the value of
javax.servlet.ServletContext. Note that you must import this
package.
3. Modify the init() method.
a. Set the context for this method as
filterConfig.getServletContext(); and write to the context log
that the filter has been initialized. Use filterConfig.getFilterName()
to retrieve the name of the filter.
4. Modify the doFilter() method to check for the supplied customer name.
a. Loop through the enumeration returned from the keys() method of
blockUser and look for the String value of this variable. Use the
hasMoreElements() method of java.util.Enumeration to
increment in the loop.
b. Retrieve the custName parameter from the request object, and set it to a
temporary String variable.
c. Verify whether the value of the variable created in the previous step matches the
value that is retrieved from the enumeration.
d. If the values match, send an error message by using
javax.servlet.http.HttpServletResponse to the browser,
indicating that the service is unavailable. Additionally, include a message in the
error to indicate that the value specified has been temporarily rejected. Send this
error message text to the context log.
e. Finally, pass the doFilter() method down the filter chain.
5. Compile the filter and test by running LoginServlet, and by supplying a customer
number of 104 and a name of Sutherland. The filter should modify the response
so that a service_unavailable error is sent in the response.

Oracle10g: Build J2EE Applications 6-33

Maintaining State in J2EE Applications

Copyright 2004, Oracle. All rights reserved.

Objectives

After completing this lesson, you should be able to do


the following:
Maintain persistent activity from clients by using a
browser
Use the HttpSession object

7-2

Describe state preservation

Copyright 2004, Oracle. All rights reserved.

Objectives
Although the HTTP protocol is stateless, servlets allow your application to remember
previous visitors and the data that they have created in the past. This lesson shows you how
to achieve this capability.

Oracle10g: Build J2EE Applications 7-2

Overview

First request
Chris
Servlet
Second request
Chris

First request
Michelle
7-3

Copyright 2004, Oracle. All rights reserved.

Overview
The standard HTTP server is stateless, and cannot distinguish whether two requests come
from the same client. You may want to know if the same client has accessed your servlet
before. This question is more complex than it may seem:
If Chris accesses your servlet from a Netscape browser and an Internet Explorer
browser at the same time, then should the servlet consider the two requests to be from
the same client?
If Michelle accesses your servlet today, and again a month later from the same
browser, then should the servlet consider the two requests to originate from the same
client? Assume that the browser has not been shut down in this period.

Oracle10g: Build J2EE Applications 7-3

Session Basics

7-4

The HTTP protocol is stateless.


The session mechanism guarantees that the
object that serves the client knows which client
has made a request.
User requests from the same browser are
considered to be from the same client.

Copyright 2004, Oracle. All rights reserved.

Session Basics
Two requests originating from the same browser within a short period of time are considered
to be from the same client. When considering sessions, think about the shopping cart
scenario of many online applications. Requests from different browsers are considered to be
from different clients (as in the previous slide, with requests coming from Chris and
Michelle).

Oracle10g: Build J2EE Applications 7-4

Session Basics

Options for identifying the client: Cookies, URL


rewriting, hidden fields, HttpSession

Result: A unique identity assigned to every client


Options for implementing sessions on the server:
Single-threaded model (not scalable)
HttpSession with a multithreaded server
(Each thread uses the unique identity to process the
request.)

7-5

Copyright 2004, Oracle. All rights reserved.

Session Basics (continued)


A Web server can identify a client by using mechanisms, such as cookies, and by assigning
that client a unique object identity number. This number may expire after some time.
However, clients can disable cookies on their browsers. When you use URL rewriting, you
must always append the client-specific data to the URL, and the server must complete
expensive processing. Hidden fields are useful, but they work only if every page in your
application is dynamically generated.
One way to make sure that a servlet does not overwrite the data provided by different clients
is to create a new servlet instance for every unique object identity number. For instance, the
servlet engine could force you to declare your servlet to be a SingleThreadModel
servlet if you want unique sessions.
However, this method is not scalable. An alternative approach is to associate a unique
HttpSession object with every HttpServletRequest object, but allow multiple
threads to go through the body of the service() method.

Oracle10g: Build J2EE Applications 7-5

Threading

Multithreaded model

Single-threaded model

Client 1
Servlet instance 1

Client 1

Servlet instance 2

Client 2

Client 2
Both clients using
unique sessions, but
sharing the same
servlet instance

7-6

Both clients using


unique sessions and
unique instances

Copyright 2004, Oracle. All rights reserved.

Oracle10g: Build J2EE Applications 7-6

URL Rewriting

URL rewriting:
Every URL that is accessed by the client is rewritten
so that it has the session ID.
Use the encodeURL() method to re-create the path
dynamically.

7-7

URL rewriting is used when a client turns off


cookie support in the browser.

Copyright 2004, Oracle. All rights reserved.

URL Rewriting
Use response.encodeURL() when sending a URL from your site to the client. The
browser header information can then be retrieved by using the request object. If you are
using sendRedirect, then a corresponding method called encodeRedirectURL
exists for this purpose. For instance:
String originalURL = someURL;
String encodedURL = response.encodeRedirectURL(originalURL);
Response.sendRedirect(encodedURL);

Oracle10g: Build J2EE Applications 7-7

HttpSession

The unique identity for the client is an


HttpSession object.
The object is created by using the getSession()
method of the HttpRequest object.
HttpSession session = req.getSession(true);

Any servlet that responds to a client request can


create this object.
An object can be potentially shared across several
servlets. (Every servlet within an application can
identify with this client.)

7-8

Copyright 2004, Oracle. All rights reserved.

HttpSession
The HttpSession class is an interface. The object is obtained by using the
getSession() method in the HttpServletRequest object. This is done by
extracting a userID from a cookie or attached URL data, and then by using that ID as a key
into a table of previously created session objects. However, all this is done automatically for
you, and all you need to do is create a new session (if there is no existing session) by using
the code that is listed in the slide. If you pass false to the getSession() method, it will
return null if there is no existing session.
The servlet specification states that HttpSession objects can be shared by different
servlets in a servlet engine. Therefore, HttpSession objects must be synchronized by
the implementation. For example:
HttpSession session = request.getSession(true);
ShoppingCart cart =
(ShoppingCart)session.getAttribute(session.getId());
if (cart == null) {
cart = new ShoppingCart();
session.setAttribute(session.getId(), cart); }

Oracle10g: Build J2EE Applications 7-8

Session Objects

With session objects, you can:


Put items into the object (values persist across
multiple invocations from the same client)
Access items from the object
Obtain the session identity
Find out when the session was last accessed

Items put in a session object can:


Implement the Serializable interface
Be relocated to a different server
Persist across servlet crashes

7-9

Copyright 2004, Oracle. All rights reserved.

Session Objects
The table below describes the methods in the HttpSession class and their meanings:
getLastAccessedTime()

A long object denoting when the session


was last accessed by the client.

getId()

A string denoting the unique identity of a


client.

setAttribute(String name,
Object value)

Places an object with the name alias in the


HttpSession object. (You must make
sure that the name is unique across all
possible servlets in the engine.)

getAttribute(String name)

Retrieves the previously stored value from


the session object.

isNew()

A Boolean method that returns false if


the session existed previously for the
client, and true otherwise.

Oracle10g: Build J2EE Applications 7-9

Session-Based Page Counter

public void doGet() {


response.setContentType("text/html");
PrintWriter out = response.getWriter();
HttpSession session = request.getSession(true);
String sessionid = session.getId();
Integer sessionCount =
(Integer)session.getAttribute("sessionCount");
if (sessionCount == null) {
sessionCount = new Integer(0);
} else { sessionCount =
new Integer(sessionCount.intValue() + 1);
}
session.setAttribute("sessionCount", sessionCount);
out.println("<p>Number of requests for the session with
the id of " + "<b>" + sessionid + "</b> is: " +
sessionCount);
}

7-10

Copyright 2004, Oracle. All rights reserved.

Session-Based Page Counter


Compare this example with the one you saw earlier in the lesson titled Using Advanced
Techniques in Servlets. In this example, obtaining the correct number of hits made to your
servlet during a session is guaranteed (as opposed to during the lifetime of the servlet).

Oracle10g: Build J2EE Applications 7-10

Session Life Cycle

A session can expire automatically, or you can


explicitly invalidate a session.
The HttpSession object gets invalidated when a
session expires.
Date dayAgo = new Date(
System.currentTimeMillis() - 24*60*60*1000);
Date hourAgo = new Date() // an hour ago
Date created = new Date(
session.getCreationTime());
Date accessed = new Date()
if (created.before(dayAgo)||
accessed.before(hourAgo)) {
session.invalidate(); session = //create new
}

7-11

Copyright 2004, Oracle. All rights reserved.

Session Life Cycle


The example in this slide invalidates a session if it is too old. A session is considered old
in this example if it either has not been accessed for a long time (an hour) or was created a
long time (a day) ago. In this case, the servlet creates a new session after invalidating the old
one.
A session becomes invalid automatically based on settings in the Web server. Refer to the
Web server documentation for information about how to set the session invalidation time.
You can also use the getMaxInactiveInterval (int seconds) method to set
the duration (in seconds) for which an unused session should be kept active before being
invalidated. This timeout is maintained on the server, in contrast to the cookie expiration
time, which is sent to the client.

Oracle10g: Build J2EE Applications 7-11

Session Tracking in OC4J

J2EE server vendors handle session tracking in


different ways.
Oracle Application Server 10g Containers for J2EE
(OC4J):
Uses cookies as the default method for session
tracking (can be disabled by a user or within the
application deployment descriptor)
Does not support auto-encoding, where session IDs
are automatically encoded into the URL by the
container (an expensive process)
Causes a session to expire in 20 minutes by default
(modified in the deployment descriptor)

7-12

Copyright 2004, Oracle. All rights reserved.

Session Tracking in OC4J


OC4J first attempts to accomplish session tracking through cookies. If the cookies are
disabled, then the sessions can be maintained by using only the encodeURL() and
encodeRedirectURL() methods. Cookies can be disabled for an application by adding
the following line to global-web-application.xml or orion-web.xml:
<session-tracking cookies="disabled"> </session-tracking>

OC4J does not support the nonstandard and expensive method of encoding the session ID
into a URL.
Sessions last for 20 minutes by default. To change this, modify the web.xml file as
follows:
<session-config>
<session-timeout>5</session-timeout>
</session-config>

This changes the session timeout to five minutes. A value of 0 (zero) or less specifies that a
session never gets timed out.

Oracle10g: Build J2EE Applications 7-12

Sessions and Events


When a servlet stores an object in a session or
removes an object from a session, the session checks
whether that object implements the
HttpSessionBindingListener interface. If it does,
then the servlet notifies the object that it has been
either:
Bound to the session (by calling the objects
valueBound() method, which is a good place for
initializing client-specific resources)
Or
Unbound from a session (by calling the objects
valueUnbound() method, which is a good place
for releasing resources)
7-13

Copyright 2004, Oracle. All rights reserved.

Sessions and Events


When an application stores an object in a session by using setAttribute(), or removes
an object from a session by using removeAttribute(), the session checks whether the
object implements the HttpSessionBindingListener interface. If it does, then the
servlet notifies the object that it has been bound to, or unbound from, the session.
Notifications are sent after the binding methods are completed.
Note that for sessions that are invalidated or expire, unbound notifications are sent when the
session has been invalidated or has expired. For instance, you can create a connection in the
valueBound() method, and close it in the valueUnbound() method, after the users
session has expired.

Oracle10g: Build J2EE Applications 7-13

Sessions and Events

An object is bound to a session after the object is


passed into the session.setAttribute()
method.
An object is unbound from a session:
After the object is removed by using the
session.removeAttribute() method
When a session is invalidated

7-14

Copyright 2004, Oracle. All rights reserved.

Sessions and Events (continued)


The removeValue() and removeAttribute() methods trigger the
valueUnbound() method when implementing the
HttpSessionBindingListener. Note that removeAttribute() is used to
remove a value without replacing it, whereas setAttribute() replaces any previous
value. To explicitly end a session, use the sessions invalidate() method.

Oracle10g: Build J2EE Applications 7-14

Sessions and Events

To use the event mechanism, you must perform the


following steps:
1. Create a class that implements the
HttpSessionBindingListener interface.
2. Instantiate the class.
3. Insert the instantiated object into the
HttpSession object by using the
setAttribute() method.

7-15

Copyright 2004, Oracle. All rights reserved.

Oracle10g: Build J2EE Applications 7-15

Sessions and Events

Example:
public class EventObject
implements HttpSessionBindingListener {
public void valueBound(
HttpSessionBindingEvent event) {
// connect to the database using this client
sess = event.getSession()//which session?
// get values from this session object to
// identify client information
}
public void valueUnbound(
HttpSessionBindingEvent event) {
// release resources
}
}

7-16

Copyright 2004, Oracle. All rights reserved.

Sessions and Events (continued)


In this example, the HttpSessionBindingListener interface is implemented.
Therefore, the valueBound() method of the HttpSession object (which in this case is
event) will be called immediately after setAttribute() is called on that object.
Similarly, the valueUnbound() method will be called for the event object when the
session becomes inactive.

Oracle10g: Build J2EE Applications 7-16

Creating Distributable Applications

Applications are deployed as distributable by


specifying the <distributable/> tag in the web.xml
file. These applications should be developed to run in
a distributed servlet container (such as OC4J) as
follows:
Because the ServletContext attributes exist
locally in one Java virtual machine (JVM), the
information that must be shared between servlets
should be placed in a session, a database, or an
EJB.
HttpSession objects must implement the
Serializable interface to be sent between JVMs.

7-17

Copyright 2004, Oracle. All rights reserved.

Creating Distributable Applications


A distributable application is one that uses multiple JVMs or clusters to scale properly.
These applications should be written with the assumption that information stored in one
JVM may not be available in another. Further, because the requests from one client can be
received by any of the running JVMs, the session objects must be consistent. To maintain
this, the container replicates the state of each session. This means that your session attributes
must implement the Serializable interface, to be sent between JVMs.

Oracle10g: Build J2EE Applications 7-17

Summary

In this lesson, you should have learned how to:


Instantiate the HttpSession object
Use the HttpSession object
Implement the HttpSessionBindingListener
interface

7-18

Copyright 2004, Oracle. All rights reserved.

Oracle10g: Build J2EE Applications 7-18

Practice 7-1: Overview

This practice covers the following topics:


Creating an HttpSession object
Tracking an order based on the HttpSession
object

7-19

Copyright 2004, Oracle. All rights reserved.

Oracle10g: Build J2EE Applications 7-19

Practice 7-1
In this practice, you create a shopping cart application to track a customers orders in the
Order Entry application. You create a link to the LoginServlet that displays the
products. Each product can then be added to a shopping cart by passing in the productID
and name of the selected product. You create a class to store the products that are selected
for each session, and display them by using a servlet. Open the practice07.jws
workspace and select orderproducts.
1. Create a servlet to display the products that are available for order.
a. Create a new servlet named ProductsServlet in the orderproducts
package. Generate a doGet() method for this servlet and use the default
mappings.
b. Import the javax.naming.*, javax.sql.*, java.sql.*, and
oracle.jdbc.* packages.
c. Create instance variables for the Connection (as conn) and DataSource
(as ds).
d. Create a new method in ProductsServlet.java to retrieve the
PRODUCT_ID, PRODUCT_NAME, and PRODUCT_DESCRIPTION from the
PRODUCTS view, ordering by the CATEGORY_ID. You must use coding similar
to that used in the init() and verifyCustomer() methods of
LoginServlet.java.
e. Loop through the result set and retrieve the values of the columns into variables.
f. Set the return value for this method by creating a table to store the variables that
are returned in step 1d in a table format. Include an href link at the end of each
row that points to showcartservlet, and allows the customer to add this
product to his or her shopping cart. You create this servlet later in the practice.
Close the result set object and return the variable name.
Hint: Include two parameters in the URL, using the variables you created in the
previous step:
<yourreturnvaluename> += "<tr><td>" + var1 + "</td><td>" +
var2 + "</td><td>" + "<a href=\"showcartservlet" +
"?param1=" + var1 + "&param2=" + var2 + "\"/> + Add to
Shopping Cart" + "</a></td></tr><p>";
g. Modify the doGet() method to call the method that you have created in a
try/catch block. Make sure to create table headings for the product name and
description.
2. Create a link from LoginServlet to ProductsServlet.
a. Below the code for displaying orders for a customer (in the doPost() method),
insert an href link to point to the ProductsServlet. You can use the URLpattern mapping name that is generated for you, described in the web.xml file.
Note that the cookie functionality created in the last practice has been removed to
prevent any confusion.
3. Create a ShoppingCart class to store the selected products in a Hashtable.
a. Create a new class file by selecting Java Class from the Simple Files category
(within the General category). Name the class ShoppingCart and click OK to
accept the default package and attributes.
b. Import the java.util.* package because you will be using a Hashtable
from that package.
Oracle10g: Build J2EE Applications 7-20

Practice 7-1 (continued)


c. Declare two instance variables in the class definition: items and
numberOfItems. Declare items as a Hashtable and numberOfItems
as type int, initializing to null and zero, respectively.
d. In the class constructor, initialize items as a new Hashtable object.
e. Create a method named add(). This method should return void and pass in two
arguments, prodid and name, both strings.
f. Add code to this method to store the prodid and name arguments in the
Hashtable object that you created in step 3d, and increment the
numberOfItems variable.
g. Create a second method named getNumberOfItems(). This method should
return numberOfItems.
h. Create a third method named getItems(). This method should return an
enumeration of elements in the items hashtable.
i. Compile ShoppingCart.java.
4. The next step is to create a servlet to display the products in the users shopping cart.
a. Create a new servlet and name it ShowCartServlet. Change the package
name to orderproducts and create servlet mappings as in previous practices.
b. Add code to the doGet() method to create a new session object if one does not
already exist.
c. Next, retrieve the users shopping cart as cart from the session object. Use the
getId() method of the session to find the unique identifier of the session.
d. If the user does not have an existing shopping cart, create a new one by passing
in the sessions unique identifier and cart object.
e. Create two variables to retrieve the prodid and name parameters from the
request object.
f. Add these values to the cart object by calling the add() method of the
ShoppingCart class and passing in the prodid and name arguments.
g. Create an int variable to retrieve the number of items that are ordered from the
ShoppingCart class.
h. Add HTML to display the number of items in the users shopping cart, and create
a table to display the elements in the cart. Note that the getItems() method
returns a java.util.Enumeration of items in the Hashtable. You need
to import this package. Use the hasMoreElements() method to verify items
in the getItems() method. Remove the skeleton HTML code.
i. Compile ShowCartServlet.java.
5. Save and compile the project, and test the application by running
LoginServlet.java.

Oracle10g: Build J2EE Applications 7-21

Creating the Web Tier: JavaServer Pages

Copyright 2004, Oracle. All rights reserved.

Objectives

After completing this lesson, you should be able to do


the following:
Compare servlets and JavaServer Pages (JSP)
Build a simple JSP
Describe the JSP life cycle
List the basic JSP elements
Develop JSPs with declarations, expressions, and
scriptlets
List implicit objects
Use JavaBeans with JSP

8-2

Copyright 2004, Oracle. All rights reserved.

Objectives
This lesson discusses JavaServer Pages (JSP). You learn how to differentiate between
servlets and JSPs. You learn about the life cycle of a JSP, and also the various elements in a
JSP. You should be able to develop simple JSPs with declarations, expressions, and
scriptlets, and learn how to use JavaBeans with JSP. You also learn how Oracle JDeveloper
10g can be used to develop JSPs.

Oracle10g: Build J2EE Applications 8-2

JavaServer Pages
Connects to

Request

JSP
Database
Client
Generates

Dynamic content

Response

8-3

EJB

Copyright 2004, Oracle. All rights reserved.

JavaServer Pages
The idea behind servlets and JavaServer Pages technology is to separate the presentation
logic and business logic and, therefore, have thin clients. JSPs are based on Java servlet
technology and are an extension of servlets. JSPs can generate dynamic content just like
servlets; however, a JSP has its own advantages.
The advantage of the JSP model is that Web designers need not be familiar with the Java
programming language to create JSPs. Programmers can provide JavaBeans and custom tags
to Web designers who are familiar with HTML. In this model, there are well-defined job
roles for Web page designers and application programmers.
Given that JSP builds on servlets, the focus of JSP is on improving the programmers
productivity. JSP leverages the benefits of component technologies and, therefore, simplifies
the task of the programmer.
The graphic in the slide shows that a client invokes a JSP with a URL. Note that JSPs
function by using the request/response model, like servlets. Depending on the request from
the client, the JSP connects to a database, or calls an Enterprise JavaBean (EJB), which in
turn can connect to a database. The JSP then creates dynamic content by using the output
from the database or an EJB, and returns it to the client.

Oracle10g: Build J2EE Applications 8-3

Comparing Servlets and JSPs

Servlets:
Are Java programs
with embedded
HTML
Generate dynamic
content
Do not separate
static and dynamic
content

8-4

JavaServer Pages:
Are HTML pages
with embedded Java
code or they can be
pure XML
Generate dynamic
content
Separate static and
dynamic content

Copyright 2004, Oracle. All rights reserved.

Comparing Servlets and JSPs


A JSP is an HTML page with embedded Java code. JSPs can also be pure Extensible
Markup Language (XML). A JSP takes an HTML page, adds a few tags, and automatically
generates dynamic content. A servlet also generates dynamic content, but it is not an HTML
page. A servlet is a Java program with embedded HTML code. Because a servlet is a Java
program, the programmer must take care of the syntax and semantics while developing a
servlet. The servlet must be compiled before it is executed.
Though you must know Java programming language and the API well before you can
develop a servlet, you need not be an expert in Java to develop a JSP. A Web page designer
can develop a JSP, because JSPs mainly contain HTML/XML tags and additional JSP tags
containing the Java code.
In servlets, most of the Java code is written in the service method. However, in JSPs, the
Java code is embedded in JSP tags. This enables separation of the static and dynamic
content in JSP. All the static content is in the HTML tags, and the dynamic content (Java
code) is in the JSP tags.
Because a servlet is a Java program, the .class file must be created before it can be
invoked. A JSP is automatically compiled into a servlet when it is invoked for the first time.
You need not explicitly compile the source. However, if you are using integrated
development environment (IDE) to develop JSPs, the JSPs are automatically compiled when
you run them.
Oracle10g: Build J2EE Applications 8-4

Invoking JSPs

HTML

Invoke
JSP

Servlet

JSP
8-5

Copyright 2004, Oracle. All rights reserved.

Invoking JSPs
You can invoke a JSP in different ways, depending on the needs of your application:
Invoking a JSP with a URL: You can invoke a JSP directly with the URL
http://host:port/context-root/main.jsp.
In the URL:
- host is the name/IP address of the machine where JSP is running
- port is the port number on which the server is running
- context-root is the name with which the document is mapped to a client
- main.jsp is the name of the JSP file
You invoke a JSP directly with the URL if a home page or login page is designed with
JSP. You can also use it for testing purposes.
Invoking a JSP from an HTML page, a servlet, or a JSP: In a practical scenario, the
first page is designed as a controller servlet, which invokes a JSP depending on user
inputs. You can also invoke a JSP from another JSP.

Oracle10g: Build J2EE Applications 8-5

The Date JSP


<%@ page contentType="text/html;charset=WINDOWS-1252"%>
<html> <head>
<meta http-equiv="Content-Type" content="text/html;
charset=WINDOWS-1252">
<title> Show Date </title>
</head>
<body>
<h2> The current time is: </h2>
<p> <%= new java.util.Date() %> </p>
</body>
</html>

8-6

Copyright 2004, Oracle. All rights reserved.

The Date JSP


The slide shows the JSP code for displaying the current time and date, and the result of
invoking the JSP. Note that the code mainly contains HTML tags. The Java code that is
highlighted in the slide displays the date and time dynamically. The content in the HTML
tags form the static part of this page.
JSP is primarily component-centric and not page-centric. The page-centric model is easy to
learn and allows rapid development. However, people eventually realized that this is not the
way to build large, scalable Web applications. The logic that is written for the scripted
environments is locked inside pages. Presentation logic is mixed with business and data
logic, making application maintenance difficult as programmers attempted to modify the
look and feel of an application without breaking the tightly coupled business logic. As Web
application complexity increased, the limitations of the page-centric model became obvious.
At the same time that people were looking for better ways to build Web applications,
components were being actively developed in the client/server world. Java and Windows
application developers were using JavaBeans and ActiveX, respectively.
JSP is primarily a component-centric platform. Components can be shared across JSPs, and
both non-Java developers and Java developers can use them.

Oracle10g: Build J2EE Applications 8-6

The Date Servlet

...
public void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException,
IOException
{
response.setContentType(CONTENT_TYPE);
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head><title>Show Date
</title></head><body><h2>The current time
is:</h2><p>");
out.println(new java.util.Date());
out.println("</body></html>");
out.close();
}
...

8-7

Copyright 2004, Oracle. All rights reserved.

The Date Servlet


You have already seen Date.jsp. Consider writing a servlet instead of JSP to display
date. The code in the slide shows the doGet() method of the date servlet. Observe that all
the HTML tags (highlighted in the slide) and their data are passed to the println()
method as a java.lang.String. This is a simple servlet that displays the date, but still
includes many println statements. It is too cumbersome to design a complex page, which
includes both static and dynamic content.
Note that a single println statement can replace all the println statements in the
servlet:
out.println("<html><head><title>Show
Date</title></head><body><h2>The current time
is:</h2><p>"+ new java.util.Date()+ "</body></html>");

However, if you split the HTML tags with different println statements, it is much easier
to revisit or debug the servlet.

Oracle10g: Build J2EE Applications 8-7

Automated JSP Features

A JSP is automatically converted into a servlet the


first time it is invoked:
Java source files are generated.
Java class files are generated.
The Java Just-In-Time compiler can be used.

A JSP can contain extensible components:


Tags: Libraries such as OC4J JSP (OJSP) or
custom-developed tags.
JavaBeans (Beans are reused and their properties
are automatically introspected.)

8-8

Copyright 2004, Oracle. All rights reserved.

Automated JSP Features


Unlike servlets, you need not compile the JSPs. When you invoke a JSP for the first time,
the JSP is automatically converted into a servlet. The dynamic content (Java code) in the
JSP is put into the _jspService method of the servlet and the static content remains
untouched. Therefore, the first time that a JSP is invoked, your response time is likely to be
slow. With subsequent requests, however, you obtain the full benefits of the servlet
technology.

Oracle10g: Build J2EE Applications 8-8

JSP Life Cycle


J2EE container

First
time

OC4J

http://host/date.jsp

Yes
1
Create servlet
date.java

No

Compile servlet
date.class

Servlet life cycle

8-9

Copyright 2004, Oracle. All rights reserved.

JSP Life Cycle


When the Web server receives a request, the server deciphers the request to determine if the
request is for a JSP. The JSP engine verifies whether the corresponding servlet class exists.
If the servlet does not exist, then this is the first time the JSP has been requested. Thus, the
JSP life cycle is traversed as follows:
1. The JSP is translated into a servlet. During the translation phase, each tag in the JSP is
handled differently, because some of the tags provide instructions for the container and
some are used to create dynamic content.
2. After the translation is done, the servlet source file is compiled and a servlet class file
is generated.
3. The server then executes the servlet by following the life cycle of the servlet.
If the servlet already exists, then the servlet is executed as mentioned in step 3.

Oracle10g: Build J2EE Applications 8-9

Basic JSP Elements

A JSP contains three main elements:


Text elements
Directives
Scripting elements
Declarations
Expressions
Scriptlets

8-10

Copyright 2004, Oracle. All rights reserved.

Basic JSP Elements


Text elements: Text elements represent the static portion of the page and are formatted
through standard HTML or XML.
Directives: These elements provide instructions to the JSP at run time. The JSP container
processes the instructions that are provided in the directives while compiling the JSP.
Scripting elements: These elements represent the dynamic portion of the page. They
contain Java code. They are used to perform computation and to generate dynamic content.
They include tags called scriptlets, expressions, and declarations. The code in these scripting
elements are put in the _jspService method, which in turn is called by the service
method of the servlet when the JSP is translated to a servlet.

Oracle10g: Build J2EE Applications 8-10

Declarations

Are used to define methods or variables


Begin with the sequence <%!
End with the sequence %>

Are inserted into the body of the servlet class


during translation
Are used in conjunction with expressions or
scriptlets

<%! private int i=3; %>


<%! private String a="Hello", b=" World"; %>

8-11

Copyright 2004, Oracle. All rights reserved.

Declarations
As the name indicates, the JSP declarations are used to declare the methods or variables.
This is inserted into the main body of the servlet class outside the _jspService method.
The example in the slide shows how to declare an integer variable and string variables.
Observe that these variables are declared as well as initialized in the declaration. It is
mandatory to terminate a declaration with a semicolon before closing it with %>. Note that
declaring a variable does not write anything to the output.
The variables declared in this manner are static by default. As previously discussed, the JSP
file is translated and compiled into a servlet class. When multiple clients request the same
servlet, multiple threads are created to handle the requests. However, they operate on the
same instance of the servlet if the servlet does not implement SingleThreadModel.
Each thread calls the service method of the same instance, and this instance has a single
variable. Therefore, any changes made to the variable by one thread are reflected in the
other threads. This is as good as modifying a static variable.

Oracle10g: Build J2EE Applications 8-11

Expressions

Begin with the sequence <%=

Contain Java expressions that are evaluated and


inserted into the servlets output
End with the sequence %>

Do not end with a semicolon


<%= i+1 %>
1
<%= a + b %>
<%= new java.util.Date() %>

8-12

Copyright 2004, Oracle. All rights reserved.

Expressions
Expressions are used to insert values directly into the output. The expression is evaluated
first and the result is converted to a string. For every expression in the JSP, a print
statement is inserted in the _jspService method. Therefore, the resultant string is then
written to the output. The expressions are evaluated at run time.
1. Variable i is declared and initialized to 3 (in the previous slide). Therefore, this
expression prints the value 4. Similarly, a is initialized to Hello and b is initialized
to World. The expression a + b prints Hello World. This is same as
<%= "Hello" + " World" %>.
2. This expression prints the current time and date.
The slide shows three expressions. The corresponding translated code that is put in the
_jspService method, is as follows:
out.print(i+1);
out.print(new java.util.Date());
out.print("Hello" + " World");

Oracle10g: Build J2EE Applications 8-12

Scriptlets

Begin with the sequence <%

Contain a block of Java code that is executed


every time a request is made
End with the sequence %>

<% if (i<3)
out.print("i<3");
if (i==3)
out.print("i==3");
else
out.print("i>3");
%>

8-13

Copyright 2004, Oracle. All rights reserved.

Scriptlets
Scriptlets enable you to write blocks of Java code inside the JSP. This code is executed
every time the JSP is invoked. The code inside the scriptlet is inserted exactly as it is written
into the _jspService method. A scriptlet can contain any valid Java code. Any errors in
the scripting elements are thrown during translation time or compilation time.
The slide shows an example for scriptlet. You can alternatively write the code shown below:
<%if (i<3) %>
i<3
<%if (i==3) %>
i==3
<%else %>
i>3
In this code, whatever is not enclosed within the scriplet is treated as HTML code and gets
converted to print statements during translation. Therefore, you need not enter the print
statements repeatedly.
In the example shown in the slide, the out variable, which has not been declared so far, is
being used. The following slide discusses this variable.

Oracle10g: Build J2EE Applications 8-13

Implicit Objects

There are eight implicit objects, also known as


predefined variables, in JSP:
application
request
config
response
pageContext
session
page
out

8-14

Copyright 2004, Oracle. All rights reserved.

Implicit Objects
In JSP, implicit objects are provided. You can use these predefined variables without
explicitly declaring them. Implicit objects are created by the container, and contain
information related to a particular request, page, or session.
request: This variable is the HttpServletRequest object that is associated with the
request. You can access the request parameters, such as request type, HTTP headers, and so
on, with this variable.
response: This variable is the HttpServletResponse object that is associated with
the response to the client.
session: This variable is the HttpSession object that is associated with the request.
Sessions are created automatically; you can also disable the sessions if you do not want to
associate a session with each client.
out: This variable is the PrintWriter object that is used to send the output to the client.

Oracle10g: Build J2EE Applications 8-14

Implicit Objects (continued)


application: Servlets and JSPs store persistent data in the ServletContext
object. The application variable is the ServletContext object.
config: This variable is used to store the ServletConfig object for the page.
pageContext: The pageContext object is used to give a single point of access to page
attributes.
page: The page object is a synonym for this. It is useful if the JSP is not scripted in
Java.

Oracle10g: Build J2EE Applications 8-15

Example

8-16

Copyright 2004, Oracle. All rights reserved.

Example
You have learned about declarations, expressions, and scriptlets. This slide shows the result
of putting them all together. The code for the example is as follows:
<%@ page contentType="text/html;charset=windows-1252"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;
charset=windows-1252">
<title> Declaration Expression and Scriptlet </title>
</head>
<body bgcolor="pink">
<h3> Declarations </h3>
<b> Declare i </b> &lt%! private int i=3; %&gt <%! private
int i=3; %><br>
<b> Declare Strings a and b </b>&lt%! private String
a="Hello", b=" World"; %&gt <%!
private String a="Hello", b=" World"; %>

Oracle10g: Build J2EE Applications 8-16

Example (continued)
<h3> Expressions </h3>
&lt%= i+1 %&gt <b> output </b> <%= i+1 %> <br>
&lt%= a + b %&gt<b> output </b><%= a + b %>
<h3> Scriptlet </h3> &lt% if (i<3) <br>
out.print("i<3"); <br> if (i==3) <br>
out.print("i==3"); <br> else <br>
out.print("i>3"); %&gt <b> output </b> <% if
(i<3)out.print("i<3"); if (i==3)
out.print("i==3"); else out.print("i>3"); %> </body>
</html>

Oracle10g: Build J2EE Applications 8-17

Directives

Are used to set global values such as class


declaration, method implementations, and so on
Begin with the sequence <%@
End with the sequence %>

Are of the following types:


page
include
taglib

8-18

Copyright 2004, Oracle. All rights reserved.

Directives
JSP directives contain messages to the JSP container. They are used to set global values. All
the directives have the scope of the JSP that contains the directives.
The page directive: The page directive is used to define important attributes for a JSP.
You can include a page directive any number of times in a JSP. You learn about the
various attributes of the page directive later in this lesson.
The include directive: This directive is used to include files in the current JSP. The file
output occurs at the location of the directive in the JSP file. Whatever file you include is
interpreted when the JSP is translated into a servlet. Typically, you use the include
directive to include files that rarely change (such as a navigation bar). For example:
<%@ include file=/navigation.jsp %>
You cannot include another dynamic page with the include directive.
The URL that is specified for the file is interpreted relative to the path of the JSP page.
The taglib directive: This directive is used to specify custom markup tags.

Oracle10g: Build J2EE Applications 8-18

include: Example

8-19

Copyright 2004, Oracle. All rights reserved.

include: Example
The slide shows the result of including an HTML page in a JSP. The include directive is
used to include the file, and the file attribute is used to hold the path of the file. The
HTML file is included as follows:
<HTML><HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html;
charset=windows-1252"/>
<TITLE>untitled</TITLE>
</HEAD><BODY >
<b><font color="red" size="3" >CONTENT FROM INCLUDED FILE
</font> </b>
</BODY>
</HTML>

The JSP code that is used to include the file is as follows:


...
<body>
<b>Including the content from a file here, using the &lt%@
include file=" " %> tag </b>
<br><%@ include file="includefile.html" %>
</body> ...
Oracle10g: Build J2EE Applications 8-19

page Directive

You can define the following attributes by using the


page directive:
extends
import
info
contentType
errorPage
isThreadSafe
isErrorPage
session
language
buffer
autoflush

8-20

Copyright 2004, Oracle. All rights reserved.

page Directive
The page directive can specify several attributes for the JSP:

import: This attribute takes a list of packages or classes, separated by commas, that
must be imported by the servlet class created for a JSP.

contentType: This attribute sets the Multipurpose Internet Mail Extensions


(MIME) type for the response of the JSP. The default is text/html.

isThreadSafe: If this attribute is set to false, then the client requests are queued
for processing because the generated servlet implements SingleThreadModel.
The default value is true.

session: If this attribute value is false, a clients request is not associated with a
session. The default value for a session attribute is true.

buffer: The buffer attribute can take a size in KB or the value none for the
amount of data that is to be buffered before the page is sent to the client. The default is
8 KB.

autoFlush: If the autoFlush attribute is set to false, a run-time exception is


raised to indicate buffer overflow. The default value is true, in which case the buffer
to the client is flushed automatically when it is full.

Oracle10g: Build J2EE Applications 8-20

page directive (continued)

extends: The extends attribute is used to specify the class name that the
generated servlet class must extend.
info: This attribute is used to define a string that can be retrieved from the generated
servlet by using the getServletInfo() method.
iserrorPage: This attribute is used to specify whether or not the JSP is an error
page. If it is an error page, then the implicit variable exception is available. This
page can be invoked by another JSP when an unchecked run-time exception is thrown.
errorPage: This attribute defines the URL to another JSP, which is an error page
that is invoked when an unchecked run-time exception is thrown.
language: This attribute defines the scripting language that is to be used in JSP.

Oracle10g: Build J2EE Applications 8-21

JSP and JavaBeans

package lesson08;
import java.lang.*;
import java.util.*;
public class LuckyNumberBean {
private int luckyNum;
public LuckyNumberBean() {
luckyNum = (int) (1000 * Math.random());
}
public int getLuckyNum() {
return luckyNum;
}
public void setLuckyNum(int luckyNum) {
this.luckyNum = luckyNum;
}
}

8-22

Copyright 2004, Oracle. All rights reserved.

JSP and JavaBeans


It has already been mentioned that JSP is component-centric. You can use reusable
components, such as JavaBeans, in a JSP. JSP provides tags to use JavaBeans. In simple
applications, a JSP includes the presentation logic as well as the business logic. The Date
JSP is an example of such a page. When there is more code involved, it is important to
separate business logic and presentation logic. You can use JavaBeans to implement the
business logic and return data to the JSP, which in turn formats the data and displays it in the
browser. The following are the benefits of using JavaBeans in JSP pages:
JavaBeans are reusable components. Therefore, different applications can use these
components.
Using JavaBeans results in the separation of business logic and presentation logic.
The slide shows an example of JavaBeans. According to the JavaBean specification, a
JavaBean should:
Have a zero argument constructor
Have no public instance variables
Have accessor methods to set/get a value for instance variables
The example shown in the slide has a zero argument constructor. The LuckyNumberBean
has a luckyNum property. getLuckyNum() and setLuckyNum(int ) are the
accessor and mutator methods, respectively, for the luckyNum property.
Oracle10g: Build J2EE Applications 8-22

Using JavaBeans with JSP

Accessing JavaBeans with the <jsp:useBean> tag:


<jsp:useBean id="myBean" scope="session"
class="lesson08.LuckyNumberBean" />

8-23

Copyright 2004, Oracle. All rights reserved.

Using JavaBeans with JSP


Actions are specific tags that affect the run-time behavior of the JSP and affect the response.
Observe that these tags are in XML format. The action tags in JSP are:

<jsp:useBean>

<jsp:setProperty>

<jsp:getProperty>

<jsp:include>

<jsp:forward>

<jsp:plugin>

<jsp:param>
<jsp:useBean>, <jsp:setProperty>, and <jsp:getProperty> tags are the
action tags that are used with JavaBeans. The code given in the slide is used to instantiate an
object of the LuckyNumberBean class, and bind it to the myBean variable. The
<jsp:useBean> tag hides the Java syntax and makes it easier to associate request
parameters with Java objects. You can also share the objects among multiple requests.
The attributes of the <jsp:useBean> tag are:

id: This attribute is used to specify a name for the object of the class.

Oracle10g: Build J2EE Applications 8-23

Using JavaBeans with JSP (continued)

scope: This attribute defines the scope of the object. You learn more about this
attribute in the following slide.
<jsp:include>: This tag includes a file (usually .html or .jsp) in a JSP at request
time.
<jsp:include page="{relativeURL | <%= expression %>}" />

<jsp:forward>: This tag is used to send a request to a file. A JSP file can use this tag to
forward the client request to an HTML file, a JSP file, or a servlet for processing.
For example:
<jsp:forward page="{ relativeURL | <%= expression %> } />

<jsp:plugin>: This tag downloads a Java plug-in to the client Web browser to
execute an applet or bean:
<jsp:plugin type=" bean| applet " code=" classFileName "
codebase="classFileDirectoryName" [ name=" instanceName "
][ archive="URIToArchive, ..." ][ align=" bottom |top|
middle|left| right" ][ height=" displayPixels " ]
[ width="displayPixels " ][ hspace=" leftRightPixels " ]
[ vspace=" topBottomPixels "][ jreversion="
JREVersionNumber | 1.1 " ] [ nspluginurl="URLToPlugin " ]
[ iepluginurl=" URLToPlugin "] >[ <jsp: params> [ <jsp:
param name=" parameterName " value=" parameterValue " />
]+ </ jsp: params> ][ <jsp: fallback> text message for
user </ jsp: fallback> ]</ jsp: plugin>

<jsp:param>: This tag is used with <jsp:plugin> to specify values for the applet
parameters.

Oracle10g: Build J2EE Applications 8-24

scope Attribute of <jsp:useBean> Tag


Client
Request

Response
Request

Response

Forward

Page 1

Page 2

Page 3

page scope

page scope

page scope

request scope

request scope

session scope
8-25

Copyright 2004, Oracle. All rights reserved.

scope Attribute of the <jsp:useBean> Tag


The scope attribute determines the life of the bean object depending on the context to
which it is bound. The scope attribute can have the following values:

page: This is the default value. The bean object is placed in the pageContext
object and the servlet code can access it by calling the getAttributes() method
on the predefined pageContext variable.

request: The bean object is placed in the ServletRequest object. Use the
request object to include the bean from any JSP that is processing the same request
(until the JSP sends a response to the client, or forwards the request to another file).
You can use the request object to access the bean.

session: The bean object is stored in the HttpSession object that is associated
with the client. It can be retrieved by using the getSession() method.

application: The bean object is stored in the shared ServletContext. The


ServletContext is shared by all servlets in the same Web application. You can
use the getAttribute() method to retrieve values from ServletContext.

Oracle10g: Build J2EE Applications 8-25

Accessing and Setting Bean Property

Accessing bean property:


<jsp:getProperty name="myBean"
property=luckyNum" />

Setting bean property:


<jsp:setProperty name="myBean"
property=luckyNum" value="10" />

8-26

Copyright 2004, Oracle. All rights reserved.

Accessing and Setting Bean Property


Accessing Bean Property
The <jsp:getProperty> action is used to access bean property as shown in the slide.
The value of the name attribute should match the value of the id that is given in the
<jsp:useBean> tag. The property attribute identifies the property of the bean that is
being accessed. You can also use the following code to retrieve the bean property:
<%= myBean.getLuckyNum() %>
You can use this when you are using loops, conditional statements, and so on.
Setting Bean Property
The <jsp:setProperty> action is used to set the bean property. The value of the name
attribute should be the name of the bean instance that is defined by the <jsp:useBean>
tag. The property attribute holds the name of the property that is being changed, and the
value attribute holds the new value for the property.

Oracle10g: Build J2EE Applications 8-26

Accessing and Setting Bean Property (continued)


The property in a bean can be set:
From request parameters
From expressions
From a specified string
Example:
<jsp:setProperty name="myBean" property="luckyNum"
value='<%= Integer.parseInt(request.getParameter("num"))
%>' />

Oracle10g: Build J2EE Applications 8-27

JSP XML Document

Contains <jsp:root> as its root element

Includes only XML syntax and does not include


the traditional JSP tags
Can be processed directly by the JSP container
Can be used with XML development tools

8-28

Copyright 2004, Oracle. All rights reserved.

JSP XML Document


Traditional JSP tags cannot be used within an XML document. JSP 1.1 defines JSP syntax
that is compatible with XML. For example, the XML syntax for a traditional declaration tag
is: <%! %>, is <jsp:declaration> </jsp:declaration>.
In JSP1.1, a JSP can contain both traditional syntax and XML syntax. However, JSP1.2 does
not allow intermixing of these tags in a page. A JSP that contains the XML syntax is called a
JSP XML document or a JSP document. A JSP document is well formed and contains only
the XML syntax. <jsp:root> is the root element of this document. The three important
goals of the root element are:
Establishing the document as a JSP XML document, so that the JSP container can
process it
Identifying the namespaces for the XML syntax and custom tag libraries through the
xmlns attribute
Specifying a JSP version number

Oracle10g: Build J2EE Applications 8-28

Traditional Syntax Versus XML Syntax

Traditional:
No root element

XML:

page directive
<%@ page %>

Declaration tag
<%!
%>
Expression tag
<%= expression %>
Scriptlet
<%
%>

8-29

<jsp:root> is the root


element
<jsp:directive.
page
/>
<jsp:declaration>
</jsp:declaration>
<jsp:expression>
</jsp:expression>
<jsp:scriptlet>
</jsp:scriptlet>

Copyright 2004, Oracle. All rights reserved.

Traditional Syntax Versus XML Syntax


The slide shows the XML syntax for some of the traditional tags described in this lesson.
You have already learned that <jsp:root> is the root element of a JSP document. You
now see how to use the XML syntax in a JSP document.
<jsp:root xmlns:jsp=http://.....
xmlns:temp=http://...
version=1.2 >
body elements
</jsp:root>

The page Directive and include Directive


<jsp:directive.page language= import=
<jsp:directive.include file= />

/>

Declaration Tag
<jsp:declaration>
public void setCount(int i) { if(i &lt; 10) count=i;}
</jsp:declaration>

Expression Tag
<jsp:expression> (user==null)? :user </jsp:expression>

Oracle10g: Build J2EE Applications 8-29

Traditional Syntax Versus XML Syntax (continued)


Scriptlet
<jsp:scriptlet>
if (request.getParameter(name).equals( ))
{........}
</jsp:scriptlet>

The JSP action tags, such as <jsp:useBean>, <jsp:forward>, and so on, are XML
compatible.
Text Element
When a JSP container encounters the text element, <jsp:text>, it passes the contents to
the current JSP out object. The code <jsp:text> Hello World </jsp:text>
displays Hello World when you run the JSP document.
JSP XML View
In JSP1.2, the JSP document can be directly processed by a JSP container. The container
creates an XML version, called XML view, of the parsing result. This XML view is the
mapping of a JSP (either a traditional page or a JSP XML document) into an XML
document that describes it. The XML view can be used by validator classes to validate a
page.

Oracle10g: Build J2EE Applications 8-30

JDeveloper and JSPs

Use the JSP Wizard in JDeveloper to create JSPs


containing skeleton code.
The structure pane helps to ensure that the JSP
and HTML tags are properly formatted.
Tag Insight automatically inserts end tags after
starting a scriptlet.
JSP code is automatically created and recompiled.
JDeveloper increases productivity while
debugging JSPs:
Automatically includes source Java files such as
your JavaBean source
Enables you to set breakpoints and watch
expressions in JSPs

8-31

Copyright 2004, Oracle. All rights reserved.

JDeveloper and JSPs


JDeveloper gives you many tools for simplifying your JSP development.
The JSP Wizard creates a JSP that contains skeleton code.
The Structure Pane and Tag Insight features help you develop syntactically correct
JSPs.
When you launch your JSP, the code is re-created when needed, and recompiled.
The integrated debugger enables you to systematically run the JSP that you have
written, while viewing the generated servlet code and any JavaBeans.

Oracle10g: Build J2EE Applications 8-31

Creating JSPs Visually

8-32

Copyright 2004, Oracle. All rights reserved.

Creating JSPs Visually


JDeveloper 10g provides a visual editor for creating JSPs and HTML. This makes
development much easier because you drag items from the component palette to the visual
editor, and the elements are rendered appropriately. HTML tables are quickly created and
modified, and text can be modified much like an HTML authoring tool. Additionally,
rendering styles from CSS style sheets is supported, and you can drag images from the file
system to the visual editor. The design and source views are synchronized so that a change
in one editor is immediately propagated to the other.

Oracle10g: Build J2EE Applications 8-32

JSP Tag Insight

8-33

Copyright 2004, Oracle. All rights reserved.

JSP Tag Insight


When using the code editor, you need not remember complicated syntax and another
language because the Tag Insight feature is provided to aid development. In this example,
the developer entered <jsp:, and the tag insight selection list appeared with all valid tags.

Oracle10g: Build J2EE Applications 8-33

Summary

In this lesson, you should have learned how to:


Differentiate between servlets and JSPs
Build a simple JSP
Describe the JSP life cycle
Use JSP elements and implicit objects
Develop JSPs with declarations, expressions, and
scriptlets
Use JavaBeans with JSP

8-34

Copyright 2004, Oracle. All rights reserved.

Summary
In this lesson, you should have learned about the various elements of a JSP. You should also
have learned how to use Oracle JDeveloper 10g to build JSPs.

Oracle10g: Build J2EE Applications 8-34

Practices 8-1, 8-2, and 8-3: Overview

These practices cover the following topics:


Creating a JSP that counts the occurrence of each
character in a given string
Using JavaBean to calculate an equal discount on
the total amount of purchase
Creating a JSP that displays product_id,
product_name, and price in the form of a table

8-35

Copyright 2004, Oracle. All rights reserved.

Oracle10g: Build J2EE Applications 8-35

Practice 8-1
The purpose of this practice is to familiarize you with expressions and scriptlets that you
have learned in the lesson. You generate a simple HTML form that displays a text field and
a Submit button. Name this form Form.html. Develop a Charcounter.jsp file that
counts the occurrence of each character in a string. The HTML form should invoke the
Charcounter.jsp file when the string is entered in the text field, and the Submit button
is clicked. The JSP should obtain the string and count the occurrence of each character and
display the characters. Open the practice08.jws workspace and navigate to the
countchars project.
1. Generate the Charcounter.jsp file:
a. Right-click countchars and select New. Expand the Web Tier node under
Categories.
b. Select JavaServer Pages under Web Tier and select JSP Page from Items. Click
OK.
c. Enter Charcounter.jsp in the File Name field. Click OK. You see the JSP
file in the Web Content folder.
2. Edit the Charcounter.jsp file:
a. Select the CSS category from the Component Palette, and drag the Oracle style
sheet to the page.
b. Switch to the Source view and change the title to Character Counter.
c. Add code to declare the following variables (use the scriptlet tag):
- A string (inputString) to hold the input parameter
- A character array (inputArray) to hold the characters of the string
- An integer (len) to hold the length of input string
- An integer array (count) and a character array (c), both with sizes equal to
the length of the string
- An integer (lastpos)
- A Boolean variable (done) initialized to false
d. Add code to count the occurrences of each character in the string and display it.
Use the scriptlet tag to code the logic.
Note: You can implement the logic to count the occurrences of characters in
different ways. The solution provided for this practice is only one way of doing
it.

Oracle10g: Build J2EE Applications 8-36

Practice 8-1 (continued)


3. Open Form.html in the visual editor:
a. Select HTML from the Component Palette and insert tags to create a form that
displays a text box with a name attribute of "input", and a Submit button.
b. Select the form in the visual editor and change the value of the action attribute in
the Property Inspector to Charcounter.jsp.
4. Test and run the application:
a. Run the Form.html file: Right-click Form.html in the System Navigator
and select Run.
b. Enter a string in the text field and press [Enter] or click the Submit button.
5. Sample Input/Output
- Input: STATISTICS
- Output: S 3
T 3
A 1
I 2
C 1

Oracle10g: Build J2EE Applications 8-37

Practice 8-2
The purpose of this practice is to use JavaBeans in JSPs. You develop a JavaBean,
DiscountBean.java, which calculates equal discount on the total amount of purchase
and returns the new price. You also design a JSP, CallDiscountBean.jsp, which uses
the JavaBean. The total amount of purchase (original price) is passed with the URL to the
JSP. The JSP then invokes the bean method, which calculates the price after discount by
passing the price, and displays the price after discount. Navigate to the discountbean
project in practice08.jws.
1. Open DiscountBean.java in the code editor:
a. Add code to declare three instance variables: discount, price, and
priceAfterDiscount of double type. Initialize discount to 10.5.
b. Implement the set() method for price. Optionally, you can also implement
the get() method.
c. Implement the get() method for priceAfterDiscount. Write code to
calculate the price depending on the value of discount and return the new
price.
2. Open the CallDiscountBean.jsp file in the editor. Look for comments and
insert the tags as instructed, using either the design or source view:
a. Insert an expression to get the price from the URL.
b. Declare a string called price with the declaration tag and write a scriptlet to get
the value of parameter price from the URL and assign it to the string price.
c. Insert a useBean tag to instantiate the DiscountBean class.
d. Insert a JSP expression to display the price.
e. Insert the setProperty tag to set the value of price.
f. Insert the getProperty tag to get the price after discount.
3. Test and run the application:
a. Run CallDiscountBean.jsp: Right-click CallDiscountBean.jsp in
the System Navigator and select Run.
b. You see java.lang.NullPointerException because you have not
passed any parameter. Note the target URL for this JSP and append the following
to the URL in the browser to invoke the JSP:
?price=1000

4. Sample Input/Output:
a. Input: <target-url>?price=1000.
For example: http://localhost:8988/practice08discountbean-context-root/
CallDiscountBean.jsp?price=1000
b. Output:
USING A JAVABEAN TO CALCULATE PRICE AFTER DISCOUNT FOR
A PURCHASE OF $1000
price before discount: 1000$
price after discount: 895.0$

Oracle10g: Build J2EE Applications 8-38

Practice 8-3
The purpose of this practice is to create a JSP that interacts with a database by using JDBC.
You design a JSP to display PRODUCT_NAME and LIST_PRICE from the
PRODUCT_INFORMATION table. The information about the products is displayed in the
form of a table. The Java class ProductInfo is responsible for retrieving the data from
the database and returning the productnames and listprice in the form of vectors.
This class contains get() methods to retrieve the vector. The product.jsp file invokes
the get() method to obtain the details and display them in the form of a table. Navigate to
the product project in practice08.jws.
Note: Use the oe database connection that you created in Practice 5-1.
1. Set up the project to use this connection (optional):
a. Right-click the web.xml file in product.jpr and select Properties.
b. Select Resource Environment References and click Add to add this connection to
the project as a data source.
c. Name the environment reference jdbc/oeDS and specify the type as
javax.sql.DataSource.
d. You are now able to look up this data source reference by using jdbc/oeDS.
2. To add the Oracle JDBC library to the project, double-click the product project and
navigate to the Libraries tab under the Development node. Add the Oracle JDBC
library to the Selected Libraries for the project.
3. Open ProductInfo.java in the code editor:
a. Import the java.sql, javax.sql, javax.naming, and java.util
packages.
b. Declare the following private variables:
Vector productnames and listprice
ResultSet rs and Statement st
c. Implement an establishConnection() method with no parameters, and
void as return type. This method should establish the JDBC connection to the oe
schema with the data source oeDS that you created in practice 5.
Start a try block. Create a Context object.
Look for the data source jdbc/oeDS and create an instance of data source, ds.
Create a connection object by invoking the getConnection()method on the
ds data source object. Create the statement object with this connection. Close the
try block. The operations can throw SQLException or
NamingException. Provide catch blocks for SQLException and
NamingException.

Oracle10g: Build J2EE Applications 8-39

Practice 8-3 (continued)


d. Implement a private method getData() with no arguments, and void as the
return type. Initialize productnames and listprice declared earlier.
Start a try block. Use the Statement object created in the
establishConnection() method to execute a query. This query should
select product_name, and list_price from the
PRODUCT_INFORMATION table where product_status is orderable and
list_price is not null. Populate the productnames Vector with the
product_name in the Resultset, and listprice Vector with
list_price in the result set. Close the try block. Provide a catch block to
catch a generic exception.
e. Invoke the methods establishConnection()and getData()in the
constructor.
f. Implement the getProductnames()method, which returns Vector
productnames.
g. Implement the getListprice()method, which returns Vector
listprice.
4. Open Product.jsp:
a. Include page directive to import the product package, which contains the
ProductInfo class. Also, import the java.util package.
b. Include a scriptlet tag to do the following:
Instantiate the ProductInfo class.
Declare two variables, productnames and listprice, of Vector type.
Invoke the getProductnames()and getListprice()methods of the
ProductInfo class to populate productnames and listprice
respectively. Enumerate through the Vector elements and add the elements as
rows to the table.
5. Test and run the application: Right-click Product.jsp and select Run.

Oracle10g: Build J2EE Applications 8-40

Modularizing JavaServer Pages


Development with Tags

Copyright 2004, Oracle. All rights reserved.

Objectives

After completing this lesson, you should be able to do


the following:
Define a custom tag
Use custom tags in a JavaServer Page (JSP)
Use the customizable Component Palette for JSP
Develop a JSP using the JSP Standard Tag Library
(JSTL)

9-2

Copyright 2004, Oracle. All rights reserved.

Objectives
This lesson discusses the use of custom tags in JSPs.

Oracle10g: Build J2EE Applications 9-2

Custom Tags

Custom tags are developed in Java and defined


and used with XML syntax.
Tags are used in a JSP to reduce or constrain the
amount of Java scriptlets in the page.
Tags are useful for defining custom actions such
as:
Accessing a database
Defining recurring tasks
Sending e-mail

9-3

Collections of tags are grouped into JAR files


called Tag Libraries.

Copyright 2004, Oracle. All rights reserved.

Custom Tags
Custom tags are a feature of JSP 1.1 and later versions. Custom tags enable you to create
your own tags for use in JSP applications. Tags provide encapsulation of complex behaviors
much like JavaBeans, but they can also manipulate JSP content. This is useful because JSPs
can often have a large amount of scriptlet code to maintain, and can eventually lose their
reusability. Custom tags are useful because they have simpler syntax than scriptlets and are
reusable. Therefore, they can be developed by Java programmers and used in JSPs by Web
application developers using XML syntax.
Similar to HTML tags, there are custom tags without a body:
<tagName attribute1="value1" attribute2="value2" />

There are also tags that have matching end tags and, therefore, include a body:
<tagName attribute1="value1" attribute2="value2" >
tag body
</tagName>

Note that both types of tags may have attributes to customize the behavior of the tags.

Oracle10g: Build J2EE Applications 9-3

Custom Tag Library Components

Custom Tag Libraries contain:


One or more tag handler class files
May contain additional supporting classes

A tag library descriptor (taglib.tld)


XML formatted

To use a tag in a JSP, perform the following:


1. Invoke the tag library by using the
<jsp:taglib/> directive.
2. Call the tag in the content of the JSP.
3. Include the location of the taglib.tld file in the
web.xml file.

9-4

Copyright 2004, Oracle. All rights reserved.

Custom Tag Library Components


Custom Tag Libraries contain two main components: one or more tag handler classes (Java
class files) and a tag library descriptor (an XML file). The tag handler class defines the
custom tag itself. The tag library descriptor contains the metadata about the tag, the tag
name, the tag location, and the tag attributes. To use a tag in a JSP, the Web developer
invokes the tag library by using a special JSP directive, taglib. This directive points to the
location of the tag library descriptor, or .tld file. Tags contained within that library are
available for use by specifying the name of the class. Additionally, existing tags can be
added to a library by defining them in an existing .tld file. Tag libraries should be
declared in a <taglib> element in the web.xml file for a JSP application, as follows:
<taglib>
<taglib-uri>/webapp/mytaglib</taglib-uri>
<taglib-location>/WEB-INF/taglib.tld</taglib-location>
</taglib>

Oracle10g: Build J2EE Applications 9-4

Tag Handler: Example


import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
import java.io.*;
public class HelloWorldTag extends TagSupport {
public int doStartTag() {
try {
JspWriter out = pageContext.getOut();
out.print("Hello from Custom Tag!!!");
}
catch(IOException io) {
System.out.println("Error in TagMessage: " + io);
}
return(SKIP_BODY);
}
public int doEndTag() {
return (SKIP_PAGE);
}
}

9-5

Copyright 2004, Oracle. All rights reserved.

Tag Handler: Example


The HelloWorldTag tag handler contains the doStartTag() and doEndTag()
methods. The doStartTag() method returns SKIP_BODY because the tag has no body.
The doEndTag() method returns SKIP_PAGE because you do not want to evaluate the
rest of the page. If the tag has a body, doStartTag() returns EVAL_BODY_INCLUDE. If
the rest of the page needs to be evaluated, doEndTag() returns EVAL_PAGE. More
information about the doStartTag() and doEndTag() methods is available at:
http://java.sun.com/products/jsp/taglibraries.html.
Note that the JSPWriter for this tag is obtained from the JSP pageContext. Request,
response, and session information can also be obtained from the JSP pageContext.

Oracle10g: Build J2EE Applications 9-5

Tag Library Descriptors

A tag library descriptor (.tld) is an XML document


that describes one or more tags and their attributes. It
contains the following elements:
<tlibversion> The tag librarys version
<jspversion>

The JSP specification version for the library

<shortname>

A default name for the library

<uri>

Identifies the tag library location

<info>

Documentation regarding the library

<tagclass>

Specifies the class for the individual tag

<bodycontent> Set to empty, tagdependent, or JSP

9-6

Copyright 2004, Oracle. All rights reserved.

Tag Library Descriptors


The tag library descriptor for HelloWorldTag is listed below. Note that the
bodycontent element can have three values, empty (indicating that the tag has no
body), tagdependent (the body of the tag is handled by the tag itself), or JSP,
(indicating that the JSP container should evaluate the body of the tag). Additionally, many
tags can be defined in one .tld file.
<taglib xmlns = "http://java.sun.com/j2ee/dtds/webjsptaglibrary_1_1.dtd">
<tlibversion>1.0</tlibversion>
<jspversion>1.1</jspversion>
<shortname>mytags</shortname>
<tag>
<name>hellotag</name>
<tagclass>HelloWorldTag</tagclass>
<bodycontent>empty</bodycontent>
</tag>
</taglib>

Oracle10g: Build J2EE Applications 9-6

Using a Custom Tag

<html>
<head>
<%@ taglib uri="webapp/taglib.tld"
prefix="mytags" %>
</head>
<body>
<h2>The following output is from the
HelloWorldTag:</h2>
<p>
<mytags:hellotag/>
</p>
</body>
</html>

9-7

Copyright 2004, Oracle. All rights reserved.

Using a Custom Tag


Use the taglib directive to specify that a JSP will use a tag that is defined in a tag library
(.tld) before any custom tag is called. The uri attribute refers to the location (relative or
absolute) of the tag library descriptor. The prefix attribute specifies the tag library that is
to be used in the JSP. This typically corresponds to the value of the shortname element in
the descriptor, but can be any valid string. The example in the slide declares that the tags
described in taglib.tld will be used in this JSP. The tag is then called by using
<mytags:hellotag>. This indicates that the tag named hellotag will be called from
the taglib.tld library. Note that this tag does not contain attributes.

Oracle10g: Build J2EE Applications 9-7

Tags with Attributes

Tags with attributes should include the get() and


set() methods for each attribute in the tag handler.

The tag library descriptor defines each attribute.


Supporting classes can validate attributes.
<tag> <name>hellotag</name>
<tagclass>HelloWorldTag</tagclass>
<bodycontent>empty</bodycontent>
<attribute>
<name>custName</name>
<required> true</required>
<rtexprvalue>true</rtexprvalue>
</attribute> </tag>

9-8

Copyright 2004, Oracle. All rights reserved.

Tags with Attributes


To create a tag that contains attributes, the tag handler uses the
pageContext.setAttribute(name, value) and
pageContext.getAttribute(name) methods to create and set the value of the
expression.
The descriptor gives the attribute a name, specifies if the attribute is required, and indicates
whether the value can be determined at run time (usually via a JSP expression). The attribute
could be set in the JSP by using the following syntax:
<mytags:hellotag custName="<%=custName%>" />
To validate the value of attributes, a supporting class called a TagExtraInfo class is
created for the tag handler. The isValid() method can be used to check the attribute
values at the time of page translation. More information about the isValid() method and
the use of TagExtraInfo classes is available at:
http://java.sun.com/products/jsp/taglibraries.html.

Oracle10g: Build J2EE Applications 9-8

Creating a Custom Tag in JDeveloper

To create a custom tag and a tag library in JDeveloper,


perform the following:
1. Create a tag library descriptor from the JavaServer
Pages category.
2. Right-click the .tld file in System Navigator and
select Add Tag to create a tag handler.
3. Right-click the .java file in System Navigator and
select Add Attribute or Add Scripting Variable
as necessary.
4. Add the tag library to the component palette.

9-9

Copyright 2004, Oracle. All rights reserved.

Creating a Custom Tag in JDeveloper


To create a new custom tag and library in JDeveloper, first create the tag library descriptor.
Next, right-click the .tld file in System Navigator and select Add Tag. This invokes a
wizard that creates the skeleton code for a tag handler, and automatically adds it to the
.tld file. The tag handler can then be modified as necessary, and attributes and scripting
variables can be automatically added to the code (and defined in the .tld file) by rightclicking the tag handler in System Navigator. Finally, the tag library can be added to the
JDeveloper IDE to aid in using the tag library in JSPs. Tag libraries are contained in
JDeveloper in the customizable component palette.

Oracle10g: Build J2EE Applications 9-9

Tag Libraries in JDeveloper

9-10

Tag libraries are viewed in JDeveloper by using


the component palette.
Select View > Component Palette to enable the
palette in the integrated development environment
(IDE).

Copyright 2004, Oracle. All rights reserved.

Tag Libraries in JDeveloper


To use custom tags in JSP applications, Oracle JDeveloper 10g provides a customizable
component palette. By selecting View > Component Palette while working in a JSP, the
palette will display valid JSP tags. Additionally, you can add custom tag libraries to the
component palette by registering them in JDeveloper. You can then use these tags by
placing your cursor at the insertion point in the JSP and by clicking the tag that you want to
use in the palette. Note that you can add any tag libraries to the component palette, whether
custom-made by you, downloaded, or purchased, as long as they are contained in a .jar
file.

Oracle10g: Build J2EE Applications 9-10

Registering Tag Libraries

To add a tag library to the component palette, perform


the following:
1. Select Tools > Configure Palette.
2. Add a new palette page.
3. Name the page for display.

9-11

Copyright 2004, Oracle. All rights reserved.

Registering Tag Libraries


Custom tag libraries can be added to the component palette in the Palette Properties dialog
box. First, you must create a new page for the custom tags. This step is shown below.

Oracle10g: Build J2EE Applications 9-11

Registering Tag Libraries

4. Select Tools > Manage Libraries.


5. Add the JAR and TLD files to the list of JSP Tag
Libraries.

9-12

Copyright 2004, Oracle. All rights reserved.

Registering Tag Libraries (continued)


To add a tag library, create a new reference to the JAR file by selecting Manage Libraries
from the Tools menu. Specify the JAR file and the .tld file. Click Yes to add the
components, then specify the page you previously created.

Oracle10g: Build J2EE Applications 9-12

Registering Tag Libraries

9-13

Copyright 2004, Oracle. All rights reserved.

Registering Tag Libraries (continued)


The slide shows the component palette after the library named taglib is installed on the
Demo Tags page. These tags can now be used in a JSP by placing the cursor at the desired
point of insertion and by selecting the tag in the component palette. If there are any
attributes for the tag, then a dialog box for entering attribute values is displayed as shown:

Oracle10g: Build J2EE Applications 9-13

Using Tag Insight

9-14

Copyright 2004, Oracle. All rights reserved.

Using Tag Insight


Tag insight is a feature of JDeveloper that enables you to enter the prefix of a custom tag
and view all available tags for that library. Tag insight becomes available for a tag library
after it is registered in JDeveloper. This enables you to select the tag that you want to use
from a list. Additionally, tag attributes are displayed in a list after the tag has been selected.
The slide above displays the tag insight list when <taglib: is entered into a JSP.
Attributes for the tag are introspected from the .tld file, and available from tag insight as
well.

Oracle10g: Build J2EE Applications 9-14

JSP Standard Tag Library (JSTL)

The JSP Standard Tag Library (JSTL) was developed


under the Java Community Process. It provides a
common and standard set of custom tags for:
Iteration, conditional processing, and expression
language support
Parsing and transforming XML documents
Formatting and parsing strings, dates, and
currencies for internationalization
Database access and data manipulation

9-15

Copyright 2004, Oracle. All rights reserved.

JSP Standard Tag Library (JSTL)


The following four tag libraries are included in JSTL:
1. Core: Tags for iteration and conditional processing, including expression language
support
2. XML: Parsing and transforming tags for use with XML documents
3. SQL: Tags for accessing and manipulating table data
4. i18N: Provides tags for formatting and parsing data for internationalization

Oracle10g: Build J2EE Applications 9-15

Core Tag Library


The Core library of JSTL is used for typical JSP
actions.
Reduces the need for scriptlet tags in a JSP
Contains four types of tags:
Generic (sets variables and display results of
expressions)
Conditional (makes blocks of code dependent on
some criteria)
Iteration (repeats actions on blocks of code)
URL-related (creates URLs for linking or redirection)

Use the prefix "c" in the taglib directive:


<%@ taglib uri="http://java.sun.com/jstl/core"
prefix="c" %>
9-16

Copyright 2004, Oracle. All rights reserved.

Core Tag Library


The Core library of JSTL is used for typical JSP actions. Its purpose is to reduce the need
for scriptlet tags in a JSP, which make JSPs difficult to read and maintain. Each of the four
types of Core tags have several tags for use in JSPs, listed on the following page.

Oracle10g: Build J2EE Applications 9-16

Core Tag Library (continued)

Generic

<c:out>

Displays the result of an expression, string, or the


evaluation to the current JspWriter object

<c:set>

Sets a variable in a page and, optionally, sets the scope of


the variable

<c:remove>

Removes a scoped variable

<c:catch>

Catches a java.lang.Throwable exception thrown


by any nested actions

<c:if>

Evaluates the body content if the expression specified is


true

<c:choose>

Provides the context for conditional execution

<c:when>

Is nested in <c:choose>, and evaluates the body content


if the expression specified is true

<c:otherwi
se>

Is nested in <c:choose>, and evaluates the body content


if none of the tests in the <c:when> blocks are true. It
must be listed after all <c:when> tags.

<c:forEach
>

Repeats the action in the body content through a


collection's elements

<c:forToke
ns>

Repeats the action in the body content through tokens

<c:import>

Includes the content of the URL that is specified in the JSP

<c:redirec
t>

Redirects the client

<c:url>

Builds a URL by using the correct rewriting principles

<c:param>

Is nested inside <c:import>, <c:redirect>, or


<c:url>, and adds request parameters to the URL

Conditional

Iteration

URLrelated

Oracle10g: Build J2EE Applications 9-17

Utilizing Core Tags

Use the <c:out> and <c:set> tags within your


JSP to display and create variables. The value
attribute defines what will be displayed or created
as a variable:
<c:out value="Hello World" />
<c:set var="name" value="${param.username}"
scope="session" />
Welcome <c:out value="${name}"
default="guest" />

9-18

The value attribute of the <c:set> tag uses


Expression Language (EL).

Copyright 2004, Oracle. All rights reserved.

Utilizing Core Tags


In this example, the <c:out> tag displays a string. The <c:set> tag is used to create a
variable by using the username request parameter. The user is welcomed by using the
name variable. If there is no value for the username request parameter, then the value of
name will be null. Therefore, the default attribute of <c:out> is used to display the
text guest if the username request parameter is null.
Other tags:
Use the <c:remove> tag to remove a variable from the page:
<c:remove var="name" />
The <c:catch> tag is used to declare uniform error handling in a JSP. This tag can work
in conjunction with the errorPage and isErrorPage directives. For example, not
every error needs to be handled by the defined error page. Thus, the <c:catch> tag can be
used to design user-friendly error messages

Oracle10g: Build J2EE Applications 9-18

Expression Language

JSTL tags can contain Expression Language (EL)


within attributes. Expression Language:
Is a simpler way of writing an expression in JSPs
Accesses object properties and collection
elements using dot notation
Has access to implicit objects
Uses a dollar sign and braces to create an
expression: ${expression}
<c:set var="name" value="${param.username}"
scope="session" />
Welcome <c:out value="${name}"
default="guest" />
9-19

Copyright 2004, Oracle. All rights reserved.

Expression Language
Expression Language (EL) is an alternative to expressions. EL uses a dollar sign and braces
to create an expression. There are several benefits of using ${expr} over <%=expr%>:
1. If the value of the expression is null, it evaluates to an empty string. This is most
beneficial for eliminating null pointer exceptions when users do not enter parameter
values correctly.
2. Object properties, collection elements, and JavaBean properties are easy to reference
by using the dot notation.
3. Several implicit objects are available for easy access to JSP objects, including:
pageContext

pageScope

requestScope

sessionScope

applicationScope

param

paramValues

header

headerValues

cookie

Oracle10g: Build J2EE Applications 9-19

Using Iteration Tags

Use iteration tags to iterate over blocks of code:

<table>
<tr>
<c:forEach var="allparams" items="${param}" >
<c:out value="${allparams.key}" />
</c:forEach><tr>
<table>

9-20

Copyright 2004, Oracle. All rights reserved.

Using Iteration Tags


There are two tags for iterating in the JSTL Core Library: <c:forEach> and
<c:forTokens>. You can use <c:forEach> to iterate over objects in a collection, or
to iterate a fixed number of times, as shown in the slide. Use the <c:forTokens> tag to
iterate over a collection, specifying the delimiter. For example, the code below iterates over
a comma-delimited string to display the output:
<table>
<tr>
<c:forTokens items="7,14,15,26,42" delims=","
var="luckyNumber"> <c:out value="${luckyNumber}" />
</c:forTokens><tr>
<table>

Oracle10g: Build J2EE Applications 9-20

Using the URL Tags

The following three tags exist for working with URLs:


<c:import>: Accesses resources by specifying a
URL. It is preferred over the <jsp:include>
directive, because <c:import> can:
Access URLs that exist outside the same context as
the current pages Web application context
Access a relative URL with a foreign Web
application context
Include FTP resources

9-21

<c:url>: Handles encoding and rewriting of URLs


<c:redirect>: Redirects the client request

Copyright 2004, Oracle. All rights reserved.

Using the URL Tags


You can use the <c:import> tag to access the resources by specifying a URL. This
provides greater flexibility than the <jsp:include> directive. Specify the URL in the
url attribute of the <c:import> tag:
<c:import url="http://www.oracle.com" />
<c:import url="/copyright.html" />
<c:import url="/copyright.html" context="/anotherwebapp" />
Using the <c:url> tag makes it easier to handle encoding and rewriting of URLs. This tag
takes a value, variable, context, and optional scope attribute. Additionally,
parameters can be appended to the URL by using the <c:param> tag. For example:
<c:url value="http://companyname.com/login" var="loginUrl" >
<c:param name="username" value="${param.name}" />
</c:url>
<a href ='<c:out value="${loginUrl}"/>'> Log In</a>

Oracle10g: Build J2EE Applications 9-21

Using the URL Tags (continued)


Additionally, the <c:redirect> tag can be used to redirect the clients request, and can
include URL parameters:
<c:redirect value="/processlogin >
<c:param name="username" value="${param.name}" />
<c:param name="password" value="${param.pw}" />
</c:redirect>

Oracle10g: Build J2EE Applications 9-22

XML Tag Library

The XML tag library is used to parse and transform


XML documents.
XML tags in JSTL conform to XPath syntax.
XML tags include <x:out>, <x:set>, and other
tags similar to the core tag library, in addition to:
<x:parse> : Parses a specified XML document
<x:transform> : Creates a formatted page from an
XML source document by using an XSLT stylesheet
<x:param> : Sets transformation parameters
(nested in <x:transform>)

Use the prefix "x" in the taglib directive:


<%@ taglib uri="http://java.sun.com/jstl/xml"
prefix="x" %>
9-23

Copyright 2004, Oracle. All rights reserved.

XML Tag Library


The XML tag library in JSTL is useful for working with XML documents. The library
conforms to the XPath syntax. This means that you can easily reference hierarchical
information within an XML document in the XML tags. In addition to the iterative and
conditional tag types, similar to the core tag library, the XML tag library contains the
<x:parse>, <x:transform> and <x:param> tags for parsing and transforming XML
documents. To use the xml tags in a JSP, include the taglib directive in the JSP as
follows:
<%@ taglib uri="http://java.sun.com/jstl/xml" prefix="x" %>
The following is an example of parsing an XML document that is located at
http://www.oracle.com/xmlfile.xml, retrieving data from the file, and outputting values
using an XPath expression:
<c:import url="http://www.oracle.com/xmlfile.xml" var="xml"/>
<x:parse source="${xml}" var="doc"/>
<x:out select="$doc/description"/>

Oracle10g: Build J2EE Applications 9-23

SQL Tag Library

The SQL Tag Library contains tags for testing


database applications.
Only used for prototyping or low-volume
applications
Use the prefix sql in the taglib directive:
<%@ taglib uri="http://java.sun.com/jstl/sql"
prefix="sql" %>

9-24

Copyright 2004, Oracle. All rights reserved.

SQL Tag Library


Many JSP developers wanted an easier way to create database connections and to insert and
update records. JSTL is one of the tag libraries that has attempted to answer this
requirement. However, JSTLs SQL tag libraries do not provide connection pooling.
Therefore, JSTL SQL tags should be used for low-volume database applications or for
prototyping, but other database access elements should be used for large-scale applications.
There are six tags in the SQL tag library:
<sql:setDataSource>

Creates a connection to the specified data source

<sql:query>

Queries the database by using the statement in the body of


the tag

<sql:update>

Inserts, updates, or deletes by using the statement in the


body of the tag

<sql:param> and
<sql:dateParam>

Sets the value for ? style parameters within


<sql:query> or <sql:update>

<sql:transaction>

Allows the content of a nested <sql:query> or


<sql:update> statement to be rolled back if errors occur

Oracle10g: Build J2EE Applications 9-24

Accessing a Database with SQL Tags

To access a database from the SQL tags, you can


either:
Reference a defined J2EE data source by name in
the <sql:query> or <sql:update> tags
Or
Create a data source by using a
<sql:setDataSource> tag:
<sql:setDataSource
driver="oracle.jdbc.driver.OracleDriver"
url="jdbc:oracle:thin:@localhost:1521:ORCL"
user="oe" password="oe" var="myDS" />

9-25

Copyright 2004, Oracle. All rights reserved.

Accessing a Database with SQL Tags


If a data source is not already defined in the J2EE container, then you can create it by using
the <sql:setDataSource> tag, as shown in the slide. This example uses the driver
and url attributes to find the database, and the user and password attributes to connect
to the database. The var attribute creates a variable for this data source to be used in the
datasource attribute of the <sql:update>, <sql:query>, and
<sql:transaction> tags.
To specify isolation for a SQL transaction, use the <sql:transaction> tag. This tag
has two attributes: dataSource and isolation. The dataSource attribute value
may be either a DataSource object or a string that contains a relative path to a Java
Naming and Directory Interface (JNDI) resource. The following values are valid for the
isolation attribute: read_committed, read_uncommitted, repeatable_read, serializable.
If the <sql:transaction> tag is used, then the <sql:query> or <sql:update>
tag is nested in the body of the <sql:transaction> tag. In this way, if one or more of
the <sql:update> or <sql:query> actions fail, then the entire transaction is rolled
back.

Oracle10g: Build J2EE Applications 9-25

Querying Using SQL Tags

<sql:query datasource="jdbc/oeCoreDS"
var="customers" maxRows="10">
SELECT * FROM customers
</sql:query>
<table>
<c:forEach var="row"
items="${customers.rowsByIndex}">
<tr><c:forEach var="column" items="${row}">
<td><c:out value="${column}"/></td>
</c:forEach>
</tr>
</c:forEach>
</table>

9-26

Copyright 2004, Oracle. All rights reserved.

Querying Using SQL Tags


After you have created a data source, you can easily query data by using the
<sql:query> tag. The example in the slide would return a result set containing the first
10 customers from the data source named oeCoreDS. The <sql:query> tag outputs
the result of the query to an object that implements the
javax.servlet.jsp.jstl.sql.Result interface. This interface enables you to
navigate the result set by using the getRows(), getRowsByIndex(),
getColumnNames(), getRowCount()methods, and the Boolean method
isLimitedByMaxRows(). The Result interface methods make it possible to retrieve
<sql:query> result sets by using expression language, as shown. The <c:forEach>
tag of the core tag library is used to iterate through the rows. The <c:out> tag is used to
display each column of each row, formatted within an HTML table.

Oracle10g: Build J2EE Applications 9-26

Inserting, Updating, and Deleting Data

Use the <sql:update> tag to insert, update, or delete


data. For example:

<sql:update var="rows">
UPDATE customers SET account_mgr_id=147
WHERE account_mgr_id=149
</sql:update>
<c:out value="${rows}"/> Rows Updated.

9-27

Copyright 2004, Oracle. All rights reserved.

Inserting, Updating, and Deleting Data


The <sql:update> tag accepts four attributes:

sql: The command that you want to execute (This may also be included in the body
of the tag.)

dataSource: The javax.sql.DataSource or String JNDI location

var: A variable to store the number of rows that are affected by the update

scope: The scope of the var attribute


The SQL JSTL tags support parameterized queries with two additional tags:
<sql:param> and <sql:dateParam>. Nest these tags in a <sql:update> tag or a
<sql:query> tag to pass in the value of a parameter. The question marks [?] in your
statement will be replaced with the value of the value attribute in the order in which they
are specified. For example:
<sql:query> SELECT * FROM customers WHERE account_mgr_id=?
AND credit_limit=?
<sql:param value="${managerId}" />
<sql:param value="${creditLimit}" />
</sql:query>
Oracle10g: Build J2EE Applications 9-27

Formatting Tags

Formatting Tags are used to specify how numbers,


dates, and times, should be formatted and parsed in a
locale-sensitive manner.
It is also called "i18n" tags.
Use either java.util.ResourceBundle
or java.util.Locale to format data.
Use the prefix fmt in the taglib directive:
<%@ taglib uri="http://java.sun.com/jstl/fmt"
prefix="fmt" %>

9-28

Copyright 2004, Oracle. All rights reserved.

Formatting Tags
The i18N tags, or formatting tags as they are more informally known, are used to
specify that various data elements in a JSP page, such as numbers, dates, and times, be
formatted and parsed in a locale-sensitive manner. The format tags in JSTL use either
java.util.ResourceBundle or java.util.Locale to format data.
There are several tags in the Format library, including:
<fmt:formatNumber>: Formats a numeric value to the specified number, currency, or
percentage, or to a specified locale
<fmt:parseNumber>: Parses the specified number, currency, or percentage that are
formatted in a customized manner
<fmt:formatDate>: Formats a date and time to the specified or locale-sensitive
arrangement
<fmt:parseDate>: Parses the specified date or time that were formatted in a customized
manner
<fmt:setTimeZone>: Creates a variable containing the specified time zone
<fmt:parseTimeZone>: Parses the specified time zone

Oracle10g: Build J2EE Applications 9-28

Internationalization Concepts

There are three main considerations for


internationalizing an application:
Locale (geographical or political region)
Resource bundle (set of paired messages and
keys)
Basename (identifier for a resource bundle)

9-29

Copyright 2004, Oracle. All rights reserved.

Internationalization Concepts
A locale is a geographical or a political region. It is defined by a two-letter language code
and a two-letter country code, such as en-US.
A resource bundle is a set of paired messages and keys. The key specifies the name of the
message, and the message is the text. A resource bundle is used by referring to a basename.
The basename identifies a set of paired messages and keys based on the type of message.
For instance a login basename could contain two resource bundles for the welcome key:
Hello for English and Bonjour for French.

Oracle10g: Build J2EE Applications 9-29

Internationalizing Strings

To look up a message in a resource bundle, using


the current locale, specify the key attribute in the
<fmt:message> tag:
<fmt:message key="Hello" />

Alternatively, specify the basename to use with


the <fmt:bundle> tag:
<fmt:bundle basename="login">
<fmt:message key="Hello" />
</fmt:bundle>

9-30

Copyright 2004, Oracle. All rights reserved.

Internationalizing Strings
To look up a message in a resource bundle, specify the key attribute in the
<fmt:message> tag. This uses the current locale to display the message from the
appropriate resource bundle. Additionally, a <fmt:param> tag is available for supplying
parameters in the body of a <fmt:message> tag.
Alternatively, specify the basename to use with the <fmt:bundle> tag, as shown in the
slide. The login basename will look for the Hello key and display the string using the
current locale set in the browser. However, a locale can be specified for an application by
using <fmt:setLocale>. For example:
<fmt:setLocale value="en_US" />
To retrieve the URL parameters from a browser that does not specify an encoding of the
standard ISO-8859-1, use the <fmt:requestEncoding> tag. This tag accepts a value
attribute to set the requests character encoding.

Oracle10g: Build J2EE Applications 9-30

Formatting Numbers and Dates

There are several formatting tags for working with


numbers and dates, including:
<fmt:formatNumber>: Specify how a
percentage, currency, or number should appear
using patterns and locales
<fmt:formatDate>: Specify how a date and/or
time should appear using patterns, locales, and
time zones
<fmt:formatNumber type="percent"
value=".547" pattern="#.###" />

9-31

Copyright 2004, Oracle. All rights reserved.

Formatting Numbers and Dates


The <fmt:formatNumber> tag accepts several attributes to specify how a number
should appear. The value can be output as a percentage, currency, or number, depending
on the value of the type attribute. In this example, the output would be 55%:
<fmt:formatNumber type="percent" value=".547" />
By default, the type attribute is number. If the value attribute is missing, then the
value is taken from the body content of the tag. In this way, dynamic values can be
formatted. Additionally, the value of the formatted number is output unless the var
attribute is specified. The pattern attribute takes precedence over the type attribute.
Thus, the code example shown in the slide would output .547.
Note: The pattern attribute value should follow the syntax that is specified in the
java.text.DecimalFormat class.
When formatting currencies (type attribute set to currency), the default Locale is
used to format the number.

Oracle10g: Build J2EE Applications 9-31

Formatting Numbers and Dates (continued)


Date and time can be formatted by using the formatDate tag. This tag accepts several
attributes, shown below:
Attribute

Purpose

value

The date or time to be formatted

Type

Specifies whether the time, date, or both portions of the provided


date value are to be formatted

Datesytle

The formatting style for dates, provided in the syntax defined in the
java.text.DateFormat class

Timestyle

The formatting style for times, provided in the syntax defined in the
java.text.DateFormat class

Pattern

A custom format for dates and times

Timezone

A String or java.util.TimeZone in which to format the


provided time

Var

The name of the variable where the formatted date will be stored

page

The scope of the variable

The current date can be formatted by using a Java bean, as follows:


<jsp:useBean id="now" class="java.util.Date" />
<fmt:formatDate value="${now}" />
This formats the current date as a date type, using the current locale. If a locale is not
defined, then the date will be formatted using java.util.Date.toString().
When formatting time information by using the <fmt:formatDate> tag, the time zone
that is to be used is determined as follows:
1. Use the time zone from the actions timeZone attribute.
2. If the timeZone attribute is not specified, then use the time zone from the body of
the <fmt:timeZone> action, if present.
3. Use the time zone that is given by the
javax.servlet.jsp.jstl.fmt.timeZone configuration setting.
4. Use the JSP containers time zone.
The <fmt:timeZone> tag contains one attribute, value. Specify this attribute by using
a string that is supported by java.util.TimeZone (such as America/Los_Angeles),
or a time zone ID (such as GMT-8). Additionally, you can specify a time zone for a page,
request, application, or session by using <fmt:setTimeZone>.

Oracle10g: Build J2EE Applications 9-32

Formatting Numbers and Dates

To reverse the formatting that is executed by the


format tags, use the following tags:
<fmt:parseNumber>: Parses a number into a
currency, percent, or number
<fmt:parseDate>: Parses a date in a customized
or a locale-specific manner
Specify the way the date string should be formatted
by using the pattern or parseLocale attributes.

9-33

Copyright 2004, Oracle. All rights reserved.

Formatting Numbers and Dates (continued)


To reverse the formatting that is executed by the <fmt:formatNumber> and
<fmt:formatDate> tags, use the <fmt:parseNumber> and <fmt:parseDate>
tags, respectively. The <fmt:parseNumber> tag accepts currency, percent, or number
for the type attribute so that the number (specified in either the body of the tag or in the
value attribute) can be parsed accordingly. For example, to parse a number that was
formatted by using:
<fmt:formatNumber value="29.999" type="currency"
pattern="#,#00.00" var="num" />
use the following:
<fmt:parseNumber value="${num}" type="number" />
Additionally, this tag can be used to parse a number in a format that is specified for the
locale by using the parseLocale attribute.
The parseDate tag parses the number that is specified in either the value attribute or in
the body of the tag in a customized or a locale-specific manner. You can specify the way the
date string should be formatted by using the pattern or parseLocale attributes.
Oracle10g: Build J2EE Applications 9-33

Transforming XML Documents

XML uses XSLT stylesheets to transform data. You can


accomplish the same by using the <x:transform>
tag:

<c:import url="Customers.xml" var="xml"/>


<c:import url="customerDisplay.xsl"
var="MyStyleSheet" />
<x:transform xml="${xml}"
xslt="${MyStylesheet}" />

9-34

Copyright 2004, Oracle. All rights reserved.

Transforming XML Documents


XML uses XSLT stylesheets to transform data. You can accomplish the same by using the
<x:transform> tag. Import the XML file for transformation in the same way that you
would for <x:parse>, using a <c:import> tag, as shown in the slide. In this example,
the <xml:transform> tag applies a transformation to the Customers.xml file by
using the customerDisplay stylesheet. The result of this transformation will be
displayed in the JSP. However, it is possible to capture the result in an object that is
specified in the result attribute, or save it to a variable.
To set transformation parameters, such as additional styles, use the <x:param> tag. This
tag accepts two attributes, name and value. To use this tag, nest it within the body of an
<x:transform> tag, as follows:
<c:import url="Customers.xml" var="xml" />
<c:import url="customerDisplay.xsl" var="MyStyleSheet" />
<x:transform xml="${xml}" xslt="${MyStylesheet}" >
<x:param name="match" value="${customerName}" />
</x:transform>

Oracle10g: Build J2EE Applications 9-34

JSTL in JDeveloper

9-35

JDeveloper includes all four


libraries of the JSP Standard Tag
Libraries in the Component
Palette.

The Design editor resolves the


output of the tag, as with any
other JSP element.

Copyright 2004, Oracle. All rights reserved.

JSTL in JDeveloper
In JDeveloper 10g, you do not need to add JSTL to the Component Palette. Rather, the four
JSTL libraries are included and can be accessed by selecting JSTL Core, JSTL FMT (the
internationalization tags), JSTL SQL, or JSTL XML from the Component Palette drop-down
list. Drag a tag to either the Design or the Source editor to add it to the JSP.

Oracle10g: Build J2EE Applications 9-35

Summary

In this lesson, you should have learned how to:


Develop custom tags for use in JSP applications
Add custom tag libraries to the Component Palette
Use the JSTL custom tag libraries in JSP
applications

9-36

Copyright 2004, Oracle. All rights reserved.

Oracle10g: Build J2EE Applications 9-36

Practice 9-1: Overview

This practice covers creating a JSP that uses the JSTL


custom tag library.

9-37

Copyright 2004, Oracle. All rights reserved.

Oracle10g: Build J2EE Applications 9-37

Practice 9-1
The purpose of this practice is to use the Core JSTL tags in a JSP. Open the
practice09.jws workspace in JDeveloper.
1. Create a form that asks a user to log in.
a. Select the JSTL project and create a new JSP. Name the JSP Login.jsp.
b. Select the HTML category from the Component Palette and create a form
containing a Submit button that submits to LoginSubmit.jsp.
c. Within the form, create two text input fields named username and password.
Hint: Use the Property Inspector to change the name attributes of the text fields.
d. Create labels for the username and password fields and, optionally, add a style
sheet to the page.
2. Use the Core JSTL tags to create a JSP that welcomes the user.
a. Create a new JSP named LoginSubmit.jsp in the JSTL project.
b. Select the JSTL Core category from the Component Palette. Drag the set tag
to the page and set the value property in the Property Inspector to the
username request parameter. Name the variable un.
c. Welcome the user by name using the <c:out> tag to return the value of the un
variable. If the name is null, welcome the default user as a guest.
d. Run Login.jsp to test.
3. Next, redirect the user to a URL depending on the username that the user has entered.
a. Create a c:choose block in LoginSubmit.jsp.
b. If the name supplied is Larry, redirect the user to http://www.oracle.com.
c. If the name supplied is Scott, redirect the user to http://java.sun.com.
d. Otherwise, advise the user that the username provided is incorrect. Create a URL
variable for Login.jsp and supply an href link to the user labeled Try
Again.
Hint: Create the tags by using the tag dialog that appears when you drag a tag to
the JSP from the Component Palette, then modify the generated code in the
source code editor.
e. Run Login.jsp to test.

Oracle10g: Build J2EE Applications 9-38

Practice 9-2
The purpose of this practice is to use the SQL and Formatting JSTL tags in a JSP. You will
query the Products table and display the list price of the products according to a userselected format.
1. Create a JSP that converts currencies.
a. Create a new JSP in the JSTL project named Products.jsp. At the top of the
page, insert an HTML form and add the text Convert To:.
b. Create three option buttons with values GBP, Yen, and Dollar. The name of these
buttons should be Currency. Supply the labels of the option buttons as UK
Pounds, Yen, and US Dollars.
c. Create a Submit button and submit the form to this page.
Hint: Use the HTML tag library in the Component Palette for creating the form,
option buttons, and submit buttons. Set the value of the buttons in the Property
Inspector.
d. Beneath the form, use the JSTL SQL tags to select the PRODUCT_ID,
PRODUCT_NAME, and LIST_PRICE from the PRODUCTS table where a
LIST_PRICE exists. Select only the first 25 rows, using the defined
jdbc/oeDS data source, and name the return variable prodresult.
e. Create a 1 row by 3 column table.
f. Within the table, create a <c:forEach> tag to repeat a table row for each row
of prodresult returned. Name the returned row variable prodrow.
Hint: Create the <c:forEach> tag and then drag it between the <table>
and <tr> elements using the Structure Pane.
g. In the table, output the value of the PRODUCT_ID and PRODUCT_NAME using a
<c:out> tag.
h. Switch to the code editor and just before the third <td> element, create a JSTL
variable named Price for the returned LIST_PRICE.
2. Now create the functionality for converting the price to the specified currency.
a. Create conditional tags to test the Currency parameter for GBP or Yen and
create a <c:otherwise> tag for the Dollar.
b. Within the <c:when> tags, use the setLocale and formatNumber tags to
format the variable you created in step 1.h. Use en_GB as the Locale for Pounds,
and ja_JP as the Locale for Yen. Multiply the variable by the currency rate (for
example, .5437 and 106.034, respectively). Name the variable convertedPrice
and set the formatType attribute to currency.
c. Otherwise, the user must have selected dollars. Use a third formatNumber tag
to return the value of the Price variable to the convertedPrice variable.
d. Within the last table cell, output the value of the convertedPrice variable.
e. Run Products.jsp to test.

Oracle10g: Build J2EE Applications 9-39

Communicating in J2EE

Copyright 2004, Oracle. All rights reserved.

Objectives

After completing this lesson, you should be able to do


the following:
Describe Remote Method Invocation (RMI)
Define the role of RMI in Java 2, Enterprise Edition
(J2EE) applications
Describe Java Naming and Directory Interface
(JNDI)
Define the role of JNDI in J2EE applications
Write code to look up a Java object by a JNDI
name

10-2

Copyright 2004, Oracle. All rights reserved.

Objectives
This lesson describes the architecture and the APIs that are used for some communication
techniques in J2EE environments and examines their usage from client applications.
JNDI names are influenced by the configuration of various elements in the environment,
such as variables, EJB references, and data sources. In a J2EE environment, these elements
are specified in application deployment descriptors or property files.

Oracle10g: Build J2EE Applications 10-2

Overview of RMI
Remote Method Invocation (RMI) is a framework for
executing distributed objects in Java. RMI has the
following characteristics:
It uses RPC-like communication mechanisms.
It is designed for client applications to invoke
remote object methods, as easily as calling local
methods.
It comprises the following components:

10-3

Remote interface
Implementation class
Server application/class
Client application/class
Stub (proxy) and skeleton classes
Copyright 2004, Oracle. All rights reserved.

Introduction to RMI
An RMI client application uses a standard remote procedure call (RPC) mechanism to
communicate with remote objects. The mechanism involves the use of stubs and skeletons.
RMI applications comprise a client that communicates with a remote server object via a
user-defined remote interface. The server object is instantiated from the implementation
class in the context of a server application.
A stub acts as the clients representative for the remote object, often called a proxy. The
client invokes a method on the local stub that in turn executes the appropriate method call on
the remote object. An RMI stub class implements the same remote interface that is used by
the remote object. The remote object may have a skeleton class. The skeleton manages the
dispatching of a client call (via the client stub) to the actual remote implementation object.
In JDK 1.2 and later, an additional stub protocol is introduced that eliminates the need for
skeletons, and generic code carries out the tasks that are performed by skeletons in JDK1.1.
Stubs and skeletons are generated by running the rmic compiler on the compiled
implementation class. For example:
rmic RMIClassImpl
The rmic command produces two class files: RMIClassImpl_Stub.class for the
stub and RMIClassImpl_Skel.class for the skeleton.
Oracle10g: Build J2EE Applications 10-3

Role of RMI in J2EE

Distributed components or objects in J2EE are


implemented as Enterprise JavaBeans (EJB).
Oracle Application Server 10g Containers for J2EE
(OC4J) uses a custom form of the RMI wire
protocol known as ORMI. The J2EE 1.3
specification requires support for the RMI-IIOP
protocol as the type of communication used
between the client and server object.
EJBs have a remote interface and implementation
classes, which conform to RMI semantics:
They implement a remote interface.
Methods throw the java.rmi.RemoteException.
Object parameters or return values must be
serializable.

10-4

Copyright 2004, Oracle. All rights reserved.

Role of RMI in J2EE


Remote objects execute in a different Java virtual machine (JVM) from the client
application. The J2EE distributed object architecture and protocols are modeled on RMI in
such a way that a remote object appears as if it is local to the client. In RMI, the server
object is an instance of the remote interface running on a server. In a J2EE container, an EJB
instance is the equivalent of the RMI server object. Client interaction with an EJB instance
is mediated through the stub and skeleton classes that are generated for the EJB component.
The EJB component and its skeleton classes reside on the remote (middle) tier, while the
stub class resides with the client software.
RMI is a wire-level protocol that supports other protocols, such as HTTP, and defaults to a
protocol called Java Remote Messaging Protocol (JRMP). The OC4J stub and skeleton layer
uses a modified wire-level protocol called ORMI. OC4J supports the RMI over IIOP (RMIIIOP) protocol as required by J2EE 1.3 specifications. Common Object Request Broker
Architecture (CORBA) and Microsoft Distributed Component Object Model (DCOM) are
other distributed technology implementations that use their own wire-level protocols.
Much like an RMI server object, an EJB provides a remote interface that describes how to
invoke the EJB methods. Methods could throw java.rmi.RemoteException. Objects
must conform to Java serialization rules to be passed as parameters to, or returned from, a
remote object method.
Oracle10g: Build J2EE Applications 10-4

Communication in a J2EE Environment

J2EE server
Naming

1
3

Creation

4 Client

5
Interface

Marshaled data
Skeleton

Stub
Local call

Marshaled data
7

6
Interface

Network protocol
(Java RMI)

10-5

Server
object

Copyright 2004, Oracle. All rights reserved.

Communicating in a J2EE Distributed Object Environment


The diagram in the slide shows how the distributed object communication occurs from the
time the client requests access to a method on the remote object until the clients request is
served.
Distributed systems provide transparent communication between objects that reside on
different nodes.
1. The client requests an appropriate remote server object from the J2EE server.
2. A new server object (which implements the required interface) is created, or an
existing server object is allocated to the client. Usually an interface object (a skeleton)
is generated to intercept and forward the requests that come from the remote client.
3. On the client side, a special interface object (stub) is instantiated. This stub exposes the
same interface that the server object implements. The stub knows the details of how to
access the remote skeleton and the server.
4. The client makes local calls to the stub that represents the server object.

Oracle10g: Build J2EE Applications 10-5

Communicating in a J2EE Distributed Object Environment (continued)


5. The stub marshals the methods and parameters that are requested by the client, and
transfers the marshaled data over the network to the waiting skeleton.
6. The skeleton can intercept the client calls; perform authentication, access control, and
transaction handling; and manage the persistent state of the object. The skeleton then
invokes the appropriate method in the server implementation.
7. The results of the call or run-time exceptions, if any, are passed back by the skeleton to
the caller through the stub.
The association between a client and the server object remains in effect until the client either
directly or indirectly frees the server object. During that period, the client can make several
calls.

Oracle10g: Build J2EE Applications 10-6

How Clients Locate a Distributed


Component
In J2EE, a distributed component is bound to a name
when deployed.
The server object run-time environment provides a
naming service to help locate an object by a name:
In RMI, the RMI registry performs this task.
In J2EE, the container typically provides this
service.

10-7

Clients use the Java Naming and Directory


Interface (JNDI) API to locate a remote object by a
name.

Copyright 2004, Oracle. All rights reserved.

How a Client Locates a Distributed Component


The RMI clients use an RMI-specific URL string that is prefixed with rmi (using JRMP
protocol, by default) to locate a remote RMI server object by a name. The URL string
specifies the location of the RMI registry and the name of the remote object. The RMI
application server class instantiates the RMI server object and binds the remote
implementation object to a name in the RMI registry. In this scenario, the RMI registry
provides the service for registering the implementation object with a name, and for the client
to look up the remote object by a name in the registry. In this case, the binding of the
implementation object to a name is done at run time, and the lookup string is RMI protocol
dependent.
The J2EE implementation was designed to overcome the run-time binding and to free the
developer from a specific naming service and protocol. This was achieved by using the
JNDI specification. A J2EE container implements the naming and directory service
conforming to JNDI specifications. The binding of a name to the server object or component
is done (when the server component is deployed) by using deployment descriptors. The
client application uses the JNDI APIs to locate (or look up) a remote object by a JNDI name.
The JNDI URL pattern depends on the type of JNDI that the service provider uses to
implement the naming and directory service.
Subsequent slides in this lesson discuss JNDI in detail.
Oracle10g: Build J2EE Applications 10-7

Java Naming and Directory


Interface (JNDI)
What is JNDI?
JNDI is a standard API that provides access to the
directory and naming functionality.
The JNDI Service Provider Interface (SPI)
implementation provides the mapping between the
naming servers and the JNDI APIs.
JNDI API
Client
JNDI SPI
RMI registry

COS Naming LDAP

Name and directory services


10-8

Copyright 2004, Oracle. All rights reserved.

Java Naming and Directory Interface (JNDI)


Java Naming and Directory Interface (JNDI) is a standard interface to a naming and
directory service. J2EE applications use the following two parts of JNDI to find other
distributed objects:
An application-level interface that is used by application programs to access a naming
and directory service.
A service provider interface to attach a provider of a naming and directory service.
By using these parts and portable programming principles, client applications can access any
directory service.
Applications use JNDI to obtain naming contexts that enable the applications to locate and
retrieve objects such as data sources, local and remote EJBs, Java Message Services (JMS),
and so on. Objects in a JNDI namespace can be managed by different directory and naming
services. For example, a JNDI service provider can be implemented by using a file system,
or by using a Lightweight Directory Access Protocol (LDAP) service, such as Oracle
Internet Directory (OID), an RMI registry, or the CORBA Object Naming services in the
form of COS Naming, and so on. Similar to Java Database Connectivity (JDBC), JNDI
provides different drivers for various service providers.
OC4J provides a complete JNDI 1.2 implementation, with the JNDI service provider
implemented in memory in the container.
Oracle10g: Build J2EE Applications 10-8

J2EE Container and JNDI Interface

10-9

The container implements the J2EE environment


and makes the services and resources available
through a JNDI interface.
The JNDI service obtains names from the
Extensible Markup Language (XML) files and holds
them in memory.
JNDI allows developers to write application code
that is independent of vendor-specific underlying
protocols, connections, and other resources.
The JNDI interface provides a common naming
convention to access J2EE resources.

Copyright 2004, Oracle. All rights reserved.

J2EE Container and JNDI Interface


The J2EE container provides services, such as transaction services, naming services, and so
on, as discussed earlier in this course. These services reside in a framework in the container.
This framework exposes the interfaces that are to be used by the client application code and
enterprise beans. In the case of EJB, the interfaces enable the developer to write the code for
a bean without using vendor-specific references to underlying protocols, connections, and
other resources.
The container implements the environment and makes the services and resources available
through the JNDI interface. For example, data sources represent databases, and JMS service
names can be specified as JNDI names.
The JNDI interface provides a common naming convention to access the resources that are
provided by the container. The names in the naming convention are used in the bean class
and the deployment descriptor.

Oracle10g: Build J2EE Applications 10-9

Naming Service

A naming service allows clients or objects to locate


each other in a network by:
Storing objects published against their names,
known as binding a name to an object
Maintaining a mapping of logical names to actual
names of hierarchical objects
Using a directory service with a hierarchical
structure to maintain logical names for its data
Examples: Java Naming and Directory Interface (JNDI),
RMI registry, Lightweight Directory Access Protocol
(LDAP), CORBA naming service (COS Naming)

10-10

Copyright 2004, Oracle. All rights reserved.

Naming Service
An Object Naming Service is the principal mechanism for objects or clients to locate other
objects on the network. Names are humanly recognizable values that identify an object. The
naming service enables the creation and mapping of these names to object references.
A name-to-object association is called name binding. In the case of EJBs, the server
performs the binding of the beans home interface in the JNDI namespace.
Naming services can be used for literally mapping any type of object or resource with names
such as files, database objects, remote objects, and so on. EJB specifications require that the
bean home interfaces be published and made available to the clients through JNDI.
It is the responsibility of the server and container provider that the beans deployed in the
server are made available to different clients through a JNDI service.
A directory service usually has a hierarchical structure of data, and you use the naming
service to create logical names and map them to the naming server. For example, the
directory service of a file system contains a hierarchical structure of folders, subfolders, and
the files in the folders.
Examples of naming services are RMI registry, LDAP, and CORBA Naming Service (COS
Naming).
Oracle10g: Build J2EE Applications 10-10

JNDI Terminology
JNDI client

Initial context

ormi://host/AppCtx
Namespace

Context
env

jdbc
Atomic
names

Sub-context

OracleDS oeCoreDS

ejb

Employee

Cart

Binding
Objects

java:comp/env/jdbc/OracleDS
10-11

Compound name

Copyright 2004, Oracle. All rights reserved.

JNDI Terminology
Namespace: The set of all names in the naming server. The names in the namespace must
be unique. For example, in a directory structure, each file and subdirectory in a particular
level have unique names.
Initial context: The root directory object in the namespace that refers to the starting point of
the name hierarchy from which a client can start navigation. The client obtains this root
directory by creating a new InitialContext object. Relative to the initial context, a
client can look up another object using its compound name.
Compound name: Formed by concatenating the names of each context object along the
hierarchical path to the target atomic name for an object published in the JNDI namespace.
The slide shows env, jdbc, and ejb as context objects, where jdbc and ejb are
subcontexts below env.
Atomic name: A unique indivisible part of a name, such as env, jdbc, and OracleDS
Binding: The process of associating an object with a name in the naming and directory
service
URL: A composite name spanning more than one context or namespace, which is used to
uniquely identify an object in a composite namespace

Oracle10g: Build J2EE Applications 10-11

Main JNDI Class and Interface

The javax.naming.InitialContext class:


Is used to obtain the initial context for JNDI lookup
operations
Returns a reference to the object implementing the
java.naming.Context interface

The javax.naming.Context interface:


Provides methods to bind names to objects
Provides methods to create subcontexts
Provides methods to navigate the JNDI name
hierarchy
Looks up an object by a name that is relative to the
initial context or a subcontext

10-12

Copyright 2004, Oracle. All rights reserved.

Main JNDI Class and Interface


Context: Context is an interface in the javax.naming package. The very first JNDI
call to code is the one that gets a Context object. The first context object that you get is
called the initial context and is bound to the root naming context of the namespace. A
context can contain a subcontext and objects. An object implementing the Context
interface contains a number of methods that the EJB application developer can use. The
client uses the lookup() method on the context to look up a home object. The names in
the namespace are bound to specific objects.
URL: URL enables you to use JNDI requests to start up services and sessions and to access
components published in the database. Just as a Web document can be located by using a
unique URL, an object published in JNDI can be located by using a unique URL.
When you use JNDI in your client or server object implementations, be sure to include the
following import statements:
import javax.naming.Context; // the JNDI Context interface
import javax.naming.InitialContext;
import java.util.Hashtable; // Hashtable for the initial
// context environment

Oracle10g: Build J2EE Applications 10-12

Accessing an Object in JNDI Namespace

A client must perform the following steps to retrieve a


local object reference from the JNDI namespace:
1. Get the JNDI InitialContext object. Example:
Context ic = new InitialContext();

2. Form the URL for the bean home interface and call
the lookup() method to get the reference to the
local home interface object. Example:
DepartmentLocalHome home =
(DepartmentLocalHome) ic.lookup(
"java:comp/env/ejb/Dept");

10-13

lookup() returns an Object type that should be


cast to a desired type.

Copyright 2004, Oracle. All rights reserved.

Accessing an Object in JNDI Namespace


To access an object in the JNDI namespace, the client has to perform these steps:
1. Get the JNDI InitialContext object.
2. Form the URL for the bean home interface and call the lookup() method to get the
reference to the home interface object.
The code in the slide shows an example of this process. The first statement creates a new
initial context object, using the default environment. The second statement looks up an EJB
local home interface reference in the applications JNDI tree. In this case, ejb/Dept might
be the name of an entity bean that is declared in the ejb-jar.xml configuration file, in an
<ejb-local-ref> tag.
For example:
<ejb-local-ref>
<ejb-ref-name>ejb/Dept</ejb-ref-name>
<ejb-ref-type>Entity</ejb-ref-type>
<local-home>DepartmentLocalHome</local-home>
<local>DepartmentLocal</local>
</ejb-local-ref>

Oracle10g: Build J2EE Applications 10-13

Getting the JNDI InitialContext

When OC4J starts, a JNDI context is constructed


for each application deployed in the server.
An initial context obtained by the client is used to
access the subcontexts and objects.
Clients accessing objects in a remote OC4J
container typically require a set of environment
properties to obtain the InitialContext:

10-14

INITIAL_CONTEXT_FACTORY
PROVIDER_URL
SECURITY_PRINCIPAL
SECURITY_CREDENTIAL
dedicated.rmicontext
Copyright 2004, Oracle. All rights reserved.

Getting the JNDI InitialContext


When OC4J starts, a JNDI context is constructed for each application that is deployed in the
server (in server.xml). There is always at least one application for an OC4J server, the
global application, which is the default parent for each application in a server instance. Userwritten applications inherit properties from the global application. User-written applications
can override property values defined in the global application, can define new values for
properties, and can define new properties as required. In the default OC4J server, as shipped,
the global application is the default application, as defined in the server.xml file. OC4J
requires certain properties for obtaining the initial context reference.
Each JNDI lookup retrieves a connection to the server. Each subsequent JNDI lookup for
this same server uses the connection that is returned by the first JNDI lookup. That is, all
requests are forwarded over and share the same connection. The
dedicated.rmicontext JNDI property overrides this default behavior. If you set
dedicated.rmicontext to true before you retrieve an InitialContext, you
will retrieve a separate physical connection for each lookup, each with its own designated
username and password. The value of dedicated.rmicontext defaults to false.
The list of properties shown in the slide is not an exhaustive list. Refer to the Oracle
Application Server 10g Containers for J2EE Services Guide for more information.
Oracle10g: Build J2EE Applications 10-14

Getting the JNDI InitialContext

Set environment properties for initial context in:


The system properties, set either by the OC4J
server or by the application container
A jndi.properties file contained in the
application EAR file, as part of the applicationclient.jar file
An environment specified explicitly in a Hashtable

The JNDI InitialContext has two constructors:


A no-arg constructor used by local clients to
execute code in the same J2EE container
A constructor with a Hashtable argument used by
remote clients to execute code in a remote J2EE
container

10-15

Copyright 2004, Oracle. All rights reserved.

Getting the JNDI InitialContext (continued)


The environment properties can be in the form of system property values that are set by
OC4J as specified in the application.xml file, in the jndi.properties file that is
contained in the application EAR file, or as environment properties defined explicitly in the
client code and passed as a Hashtable to the JNDI initial context constructor.
The JNDI InitialContext constructor has two forms:
A default no-arg form of the constructor that creates a Context object by using the
default context environment for that application, that is created by the OC4J when the
server is started. This is typically used by server-side clients such as JSPs, servlets, or
other EJBs. These server-side clients typically use local references to locate an object
being looked up as the clients are running in the same J2EE container. You can also
specify that the object not be initialized by passing (boolean lazy) to the
constructor.
The second form of the constructor accepts a Hashtable parameter that consists of
the environment properties. These properties can be defined in any one of the three
forms, as described above. This form is used by remote client applications. Therefore,
it is necessary to specify the JNDI properties. In the JNDI properties, you can specify
whether the object that is being looked up is running in a JVM or in a J2EE container
remotely from the client application.
Oracle10g: Build J2EE Applications 10-15

Initial Context Factories

There are three JNDI initial context factories:


ApplicationClientInitialContextFactory
ApplicationInitialContextFactory
RMIInitialContextFactory

10-16

An initial context factory is used to construct an


InitialContext object.

The initial context factory class name is the string


value for the INITIAL_CONTEXT_FACTORY JNDI
property.

Copyright 2004, Oracle. All rights reserved.

Initial Context Factories


The three types of context factories are provided to help a client establish a connection with
the naming service in an efficient way. This depends on where the client is, relative to the
component that it is locating.
Use ApplicationClientInitialContextFactory to construct the initial context
for a local or remote resource in a J2EE application. The client is bundled with the J2EE
application. For the client to access remote objects,
ApplicationClientInitialContextFactory reads the METAINF/application-client.xml and META-INF/orion-applicationclient.xml files in the <application_name>-client.jar file.
The client code runs in a server as part of a J2EE application, and can define a default set of
properties for JNDI use. ApplicationInitialContextFactory is set as the default
initial context factory for applications that are running in the same container as the client. In
this case, the clients can only look up references to local objects (for example, a servlet or
JSP calling an EJB in the same container).
RMIInitialContextFactory is used by a client to access the JNDI namespace when
looking up objects that are part of another remote J2EE application. It is also used for
resource references that cannot be specified in the application-client.xml file.
Oracle10g: Build J2EE Applications 10-16

lookup() Method

The lookup() method obtains a reference to the


required resource.
To reference a local resource, pass the URL with
the object name as parameter:
java:comp/env/subContext/resourceName
Examples:
java:comp/env/ejb/Dept
jdbc/oeCoreDS

Retrieve a reference to target EJB by using:


The actual bean name specified in the <ejb-name>
element or the <ejb-ref-name> element of ejbjar.xml
The logical bean name specified in the <ejb-refname> element of application-client.xml

10-17

Copyright 2004, Oracle. All rights reserved.

lookup() Method
After the client obtains the InitialContext, it should obtain a reference to the required
resource by using the lookup() method on InitialContext. The client uses the
lookup() method by passing the URL with the object name as the parameter. This
generally depends on how the resources are mapped in the naming server. Generally, the
URL to look up a local resource (in the same container) is of the following format:
java:comp/env/subContext/resourceName.
For example, the client looks up an EJB called Dept under the subcontext ejb with the
URL java:comp/env/ejb/Dept. Here, java:comp/env is the initial context, and
ejb/Dept can be the actual name of the EJB as specified in either the <ejb-name> or
the <ejb-ref-name> element of the deployment descriptor where the bean is defined. It
can also be the logical name of the bean, which is defined in the <ejb-ref-name>
element under the <ejb-ref> section in the files ejb-jar.xml, applicationclient.xml, or web.xml for an EJB, an application, or a servlet or JSP client,
respectively.
In another example, a client looking up a data source called oeCoreDS may use the URL
java:comp/env/jdbc/oeCoreDS. Here, jdbc is the subcontext name and
oeCoreDS is the resource name.
Note: The initial context for a local object always uses the URL prefix java:comp/env.
Oracle10g: Build J2EE Applications 10-17

Obtaining a Reference to a Local Resource

Using the default InitialContext:


1. Obtain InitialContext:
Context ic = new InitialContext();
2. Obtain reference to a resource using lookup():
An EJB client referencing another local EJB
Object obj =
ic.lookup("java:comp/env/ejb/Dept");
An EJB client referencing a data source
Object obj = ic.lookup("jdbc/oeCoreDS");

3. Cast reference obtained from lookup():


DepartmentLocalHome dlh =
(DepartmentLocalHome) obj;
DataSource ds = (DataSource) obj;
10-18

Copyright 2004, Oracle. All rights reserved.

Obtaining a Reference to a Local Resource


To obtain a reference to a local resource, the client first obtains the initial context. The code
in the slide shows the example by using the default no-arg constructor. The
InitialContext reference returns a Context interface type variable called ic.
The client then invokes the lookup() method of the initial context. The parameter for the
lookup() method consists of the initial context and the path to the object, as discussed in
the previous slide. The lookup() method returns a value of Object type and must be
cast to the correct class to be used as intended by the application.

Oracle10g: Build J2EE Applications 10-18

Obtaining a Reference to a
Remote Resource
Use initial context with appropriate JNDI properties:
1. Set JNDI properties for application:
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY
, ...);
2. Obtain the InitialContext:
Context ic = new InitialContext(env);
3. Obtain a reference to a resource by using
lookup():
Object obj = ic.lookup("Dept");
4. Cast the reference to the returned Object type:
DepartmentHome dh = (DepartmentHome)
PortableRemoteObject.narrow(obj,
DepartmentHome.class);
10-19

Copyright 2004, Oracle. All rights reserved.

Obtaining a Reference to a Remote Resource


If the client application is external to the container that runs the resource, then you must
obtain the initial context by using a set of JNDI properties set in a Hashtable, or a
jndi.properties file for the application. The slide shows a snippet of creating the
Hashtable. Here is a more complete example of setting environment properties:
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,
"com.evermind.server.rmi.RMIInitialContextFactory");
env.put(Context.SECURITY_PRINCIPAL, "admin");
env.put(Context.SECURITY_CREDENTIALS, "oracle");
env.put(Context.PROVIDER_URL, "ormi://localhost/Dept");

After the initial context is obtained by using the appropriate JNDI properties, you can invoke
the lookup() method to return a reference to an Object data type, as seen for local
resources. You then cast the remote reference to the appropriate type such as a remote home
interface or data source by using the PortableRemoteObject.narrow() method,
which is required for obtaining a remote reference from a client accessing over the RMIIIOP protocol.
If appropriate, the Object reference returned can be cast to a data source type by using the
javax.sql.DataSource class.
Oracle10g: Build J2EE Applications 10-19

Setting JNDI Environment Properties

Do not set JNDI properties if:


The client exists in the same application as the
target
The target exists in the parent application of the
client

Setting JNDI properties:


Supply the properties through the
jndi.properties file. The path of the file must be
in the CLASSPATH, or JAVA_HOME/lib.
Supply properties in the client code by using a
Hashtable.

10-20

Copyright 2004, Oracle. All rights reserved.

Setting JNDI Environment Properties


The JNDI environment properties can be either set in the jndi.properties file or
explicitly defined in the client code. A client that co-resides with the target EJB does not
need to supply the environment properties. The client does not need to supply the
environment properties if the parent application of the client coresides with the target EJB.
In this case, the container sets the environment properties.
The two methods are:
Using the jndi.properties file that must be located in the machines
CLASSPATH, or in the JAVA_HOME/lib directory
Explicitly coding the environment properties in the client code

Oracle10g: Build J2EE Applications 10-20

Setting JNDI Environment Properties

Using the jndi.properties file:

Factory: Initial context factory to be used


java.naming.factory.initial =
com.evermind.server.
ApplicationClientInitialContextFactory

Location: URL used to look up the objects


java.naming.provider.url =
ormi://<hostname>:23891/<application-name>

Security: Valid credentials of the client to this


container
java.naming.security.principal=<username>
java.naming.security.credentials=<password>

10-21

Copyright 2004, Oracle. All rights reserved.

Setting JNDI Environment Properties (continued)


If you are setting the JNDI properties in the jndi.properties file, then set the
properties as follows. Make sure that this file is accessible from the CLASSPATH.
Factory: Specifies the initial context factory to use when creating a new initial context
object. Different context factories are discussed later in this lesson.
java.naming.factory.initial=
com.evermind.server.ApplicationClientInitialContextFactory

Location: The URL that the application client code uses to look up objects on the server.
The ORMI default port number is 23891, which can be modified in the config/rmi.xml
file. Thus, set the URL in the jndi.properties in one of the following three ways:
java.naming.provider.url=ormi://<hostname>/<application-name> or
java.naming.provider.url=ormi://<hostname>:23891/<application-name>
or when running in the Oracle Application Server 10g server, hardcoding the port is not necessary
and you can use
java.naming.provider.url=opmn:ormi://<host>:<port>:<oc4jinstance>/
<application-name>

Oracle10g: Build J2EE Applications 10-21

Setting JNDI Environment Properties (continued)


Security: When you access EJBs in a remote container, you must pass valid credentials to
this container. Stand-alone clients define their credentials in the jndi.properties file
deployed with the clients code.
java.naming.security.principal=<username>
java.naming.security.credentials=<password>

Oracle10g: Build J2EE Applications 10-22

Setting JNDI Environment Properties

Specify the JNDI properties in the client code by:


Using jndi.properties
Declaring properties in a Hashtable and passing
them to the InitialContext constructor
Hashtable env = new Hashtable();
env.put(Context.PROVIDER_URL,
"ormi://myhost/J2EECourse");
env.put(Context.INITIAL_CONTEXT_FACTORY,
"com.evermind.server.
ApplicationClientInitialContextFactory");
env.put(Context.SECURITY_PRINCIPAL, "guest");
env.put(Context.SECURITY_CREDENTIALS, "welcome");
Context ic = new InitialContext (env);
10-23

Copyright 2004, Oracle. All rights reserved.

Setting JNDI Environment Properties (continued)


If you use the jndi.properties file approach, then the properties names are specified
as the textual representation of the first parameter for each env.put() method, shown in
the slide. The property values are the same as the second parameter values that are used in
each env.put() call listed in the slide. For example:
java.naming.security.principal=guest //Context.SECURITY_PRINCIPLE

The slide shows how to use a Hashtable variable env. The property name and value
pairs are added to the Hashtable by calling the put() method. Property names are
specified by using constants defined in the javax.naming.Context class in the first
parameter of the put() method with its corresponding value specified in the second
argument.
PROVIDER_URL shows a typical example of a URL for a JNDI resource name. The
absence of the port number implies that the default ORMI port number of 23891 is assumed.
INITIAL_CONTEXT_FACTORY, as used by most client applications, is specified as
ApplicationClientInitialContextFactory.
SECURITY_PRINCIPAL and SECURITY_CREDENTIALS indicate the username and
password of the client requesting the initial context. The Hashtable variable env is then
passed as a parameter to the InitialContext constructor.
Oracle10g: Build J2EE Applications 10-23

Using RMI over HTTP Tunneling

OC4J supports tunneling of RMI over HTTP or HTTP-S.


Allows clients to communicate with remote
objects through a firewall
Makes the connection appear as if it is stateful
Clients use RMI over HTTP in JNDI requests by
prefixing PROVIDER_URL with http: as in the
following example:
Hashtable env = new Hashtable();
env.put(Context.PROVIDER_URL,
"http:ormi://<host>:<port>/Application");

10-24

Port used is the HTTP server port (by default 80)

Copyright 2004, Oracle. All rights reserved.

Using RMI over HTTP Tunneling


OC4J supports the ability to tunnel RMI over HTTP and HTTP-S protocols. You can use
RMI over HTTP/HTTP-S tunneling for Java-based clients when they must communicate
with OC4J over the HTTP protocol.
Typically, HTTP tunneling simulates a stateful socket connection between a Java client and
OC4J and tunnels this socket connection through an HTTP port in a security firewall.
HTTP is a stateless protocol, but OC4J provides the tunneling functionality to make the
connection appear to be a stateful RMI connection.
If you are using RMI over HTTP tunneling, a client can make requests and accept replies
from a server, but the server cannot initiate a communication with the client. This means
that a continuous two-way connection is not possible.
The OC4J HTTP tunneling simulates an RMI connection over the HTTP protocol,
overcoming these limitations.
An advantage of HTTP tunneling is that different J2EE components can be deployed on a
single physical tier to optimize performance, or on separate physical tiers for better
accessibility. Deploying components on separate tiers can make use of architectural
redundancy designed for managing connection rerouting and high availability, in the event
of failure.
Oracle10g: Build J2EE Applications 10-24

Using Environment References with JNDI

An environment reference is:


A static element accessible to applications at run
time
Defined as:
An environment variable
A resource manager (JDBC data source, JMS
services, or a URL)
An EJB reference (logical name for the EJB)

Bound in JNDI namespace at deployment time


Defined in the J2EE deployment descriptors
Mapped through OC4J-specific descriptor

10-25

Referenced by using the JNDI lookup() method


of an InitialContext
Copyright 2004, Oracle. All rights reserved.

Configuring Environment References


Independent software vendors (ISVs) typically develop EJBs that are independent of the
EJB container. To distance the bean implementation from the container specifics, you can
create environment elements that map to one of the following:
Environment variables that can be used by more than one application
EJB references
Resource managers
These environment elements are static and cannot be changed by the bean. The elements are
given logical names when defined in the J2EE deployment descriptor. Using a logical name
enables the bean developer to refer to existing variables, EJBs, and a JDBC data source
without specifying the actual name. The logical names are then associated to the actual
names within the OC4J-specific deployment descriptor. When the bean is deployed, these
elements are bound in the JNDI registry and are accessible by the client during run time.
One advantage of this is that the deployer can set different values to the same element
through the container-specific tool and deploy the bean with these different values.
The client accesses these environment elements by using the lookup() method of the
InitialContext, as discussed in the next slide.

Oracle10g: Build J2EE Applications 10-25

Configuring Environment Variables

Environment variables are defined in the <enventry> section of the deployment descriptor (DD).
One entry for each variable; case-sensitive
Types can be the following classes: String, Integer,
Boolean, Double, Byte, Short, Long, or Float
<env-entry>

Deployment Descriptor

<env-entry-name>minBalance</env-entry-name>
<env-entry-type>java.lang.Integer</env-entry-type>
<env-entry-value>500</env-entry-value>
</env-entry>
InitialContext ic = new InitialContext();

Client

Integer minBal = (Integer)


ic.lookup("java:comp/env/minBalance");
10-26

Copyright 2004, Oracle. All rights reserved.

Configuring Environment Variables


Environment variables are defined in an <env-entry> element of the J2EE deployment
descriptor (DD) files, that is, web.xml or ejb-jar.xml. There is one environment entry
for each variable accessed in the client code. The name of the environment variable is
defined in <env-entry-name>, the type is defined in <env-entry-type>, and its
initial value is defined in <env-entry-value>. The example in the slide declares one
environment variable for minBalance.
<env-entry>
<env-entry-name>minBalance</env-entry-name>
<env-entry-type>java.lang.Integer</env-entry-type>
<env-entry-value>500</env-entry-value>
</env-entry>

The data types specified in the <env-entry-type> element can be one of the following
Java classes: String, Integer, Boolean, Double, Byte, Short, Long, or Float.
The client accesses the environment variables through the InitialContext, as follows:
InitialContext ic = new InitialContext();
Integer min = (Integer)ic.lookup("java:comp/env/minBalance");

To retrieve the environment variable values, prefix each environment element with the base
location of java:comp/env/, at which the container stores the environment variable.
Oracle10g: Build J2EE Applications 10-26

Configuring Environment Variables

The J2EE name can be mapped to a different value


in the OC4J-specific deployment descriptor (DD).
The OC4J-specific DD overrides the value in the
J2EE deployment descriptor.
J2EE DD

<env-entry>
<env-entry-name>minBalance</env-entry-name>

<env-entry-type>java.lang.Integer</env-entry-type>
<env-entry-value>500</env-entry-value>
</env-entry>
<env-entry-mapping

OC4J DD

name="minBalance">300
</env-entry-mapping>

10-27

Copyright 2004, Oracle. All rights reserved.

Configuring Environment Variables (continued)


If you want the value of the environment variable to be defined in the OC4J-specific
deployment descriptor, you can map <env-entry-name> to the <env-entrymapping> element in the OC4J-specific deployment descriptor.
Note: The value specified in the orion-ejb-jar.xml file overrides any value that may
be specified in the ejb-jar.xml file. The type specified in the EJB deployment
descriptor stays the same.
The minBalance environment variable is defined as 300 in the OC4J-specific
deployment descriptor, as shown in the code in the slide.

Oracle10g: Build J2EE Applications 10-27

Specifying an EJB Reference

Specify an EJB reference by using an <ejb-ref>


element in a J2EE client application deployment
descriptor:
<ejb-ref>
<ejb-ref-name>Employee</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<home>businesstier.EmployeeHome</home>
<remote> businesstier.Employee</remote>
</ejb-ref>

10-28

A logical name in an <ejb-ref-name> element must


be mapped to a JNDI name in an <ejb-name>
element of an EJB deployment descriptor.
The server side receives the JNDI name and resolves
it in its JNDI tree.
Copyright 2004, Oracle. All rights reserved.

Specifying an EJB Reference


You can specify a reference to a local or remote EJB in the <ejb-ref> element of a J2EE
client applications deployment descriptor (for example, in applicationclient.xml, ejb-jar.xml, or web.xml). Choose the XML file based on the
location of the client with respect to the target EJB.
Note: The slide shows an example of a reference to a remote EJB because you defined the
<home> and <remote> elements of the bean in the <ejb-ref> element. If the EJB
reference is for a local component (that is, in the same container), then you specify the
names of the local interfaces in the <local-home> and <local> elements inside the
<ejb-ref> section.
The value specified for <ejb-ref-name> can be:
The actual JNDI name of the target EJB, as found in the <ejb-name> element of the
EJB deployment descriptor (ejb-jar.xml)
A logical name used by the application client in the JNDI lookup request
If <ejb-ref-name> used is a logical name, then it must be mapped to an actual JNDI
name found in the <ejb-name> element of the target EJB.

Oracle10g: Build J2EE Applications 10-28

Configuring EJB References

The <ejb-ref> element of a client J2EE


deployment descriptor can provide:
The actual name of the bean in <ejb-ref-name>
A logical name of the bean in <ejb-ref-name> and
the actual name in <ejb-link>
The logical name of the bean in <ejb-ref-name>,
to be mapped to the actual name of the bean in the
<ejb-ref-mapping> element in the OC4J-specific
deployment descriptor

Other elements of the EJB reference are:


Type: Session or entity bean
Home/LocalHome: Qualified home interface name
Remote/Local: Qualified remote/local interface
name

10-29

Copyright 2004, Oracle. All rights reserved.

Configuring EJB References


If an EJB client invokes another EJB, the deployment descriptor for the client uses a
reference to locate the other bean. The following examples show how a client specifies an
EJB reference by using the actual JNDI name or logical name of the referenced bean.
The examples assume that the referenced EJB is a session bean defined in the EJB
deployment descriptor (ejb-jar.xml) as follows:
<session> ...
<ejb-name>Employee</ejb-name>
<home>businesstiersoln.EmployeeHome</home>
<remote>businesstiersoln.Employee</remote>
<ejb-class>businesstiersoln.impl.EmployeeBean</ejb-class>
...
</session>

Specify the actual JNDI name of the bean in the <ejb-ref-name> element:
<ejb-ref>
<ejb-ref-name>Employee</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<home>businesstier.EmployeeHome</home>
<remote>businesstier.Employee/remote>
</ejb-ref>
Oracle10g: Build J2EE Applications 10-29

Configuring EJB References (continued)


Specify a logical name in the <ejb-ref-name> element, and the actual name in the
<ejb-link> element:
<ejb-ref>
<ejb-ref-name>ejb/MyEmployee</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<home>businesstier.EmployeeHome</home>
<remote>businesstier.Employee/remote>
<ejb-link>Employee</ejb-link>
</ejb-ref>

The <ejb-link> element provides the mapping of the logical name used in a JNDI
lookup request to the target bean.
Provide a logical name in the <ejb-ref-name> element, which is mapped to the actual
name with a <ejb-ref-mapping> element:
<ejb-ref>
<ejb-ref-name>ejb/MyEmployee</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<home>businesstier.EmployeeHome</home>
<remote>businesstier.Employee/remote>
</ejb-ref>

This reference alone is incomplete without mapping the logical name to the actual bean
name. The mapping can be achieved by using either the <ejb-link> element in the same
deployment descriptor, as shown in the example before this, or by specifying the mapping of
the logical name to the actual name in the applications OC4J-specific deployment descriptor
as follows:
<ejb-ref-mapping
name="ejb/MyEmployee"
location="Employee"/>

In the <ejb-ref-mapping> element of the client applications OC4J-specific


deployment descriptor:
The name attribute identifies the logical name used in the client application lookup
request and specifies the <ejb-ref-name> element of the J2EE deployment
descriptor.
The location attribute identifies the actual JNDI name of the target bean specified
in the <ejb-name> element of the EJB deployment descriptor (ejb-jar.xml).

Oracle10g: Build J2EE Applications 10-30

Configuring Data Source References

10-31

Create an environment reference to each data


source that is used by a client through a JNDI
reference.
These references can be used only by the J2EE
application that defines these data sources.
The JNDI name is defined in the ejb-location
attribute of a <data-source> element in the
data-sources.xml file.
The J2EE deployment descriptor can use either
the JNDI name or a logical name.
A logical name must be mapped to the JNDI name
in the OC4J-specific deployment descriptor.
Copyright 2004, Oracle. All rights reserved.

Configuring Data Source References


You can access a database through JDBC either by using the traditional method or by
creating an environment reference element for a JDBC data source. To create an
environment reference element for your JDBC data source, the following steps are
necessary:
1. Define the JNDI name for each data source in the OC4J or the application-specific
data-sources.xml file.
2. Write the client code to use the JNDI name specified in the data sources file, or use a
logical name that must be specified in the <res-ref-name> element in the J2EE
deployment descriptor (either the web.xml file for a servlet or JSP, or the ejbjar.xml file for an EJB).
3. If the client application uses a logical JNDI name, as specified in the <res-refname> element of the J2EE applications deployment descriptor, then this logical
name should be mapped to the actual JNDI name specified in the ejb-location
attribute for the data source found in a data-sources.xml file. The mapping of
the logical name to the actual JNDI name is done in the OC4J-specific deployment
descriptor (that is, the orion-web.xml file for a servlet or JSP, and the orionejb-jar.xml file for an EJB).

Oracle10g: Build J2EE Applications 10-31

Configuring Data Source References


1. Define in data-sources.xml.
<data-sources>
<data-source
class="com.evermind.sql.DriverManagerDataSource"
name="OracleDS"
location="jdbc/OracleCoreDS" ...
ejb-location="jdbc/OracleDS" ... />
</data-sources>
2. Reference in J2EE Deployment Descriptor.
<resource-ref>
<res-ref-name>jdbc/oeCoreDB</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Application</res-auth>
<resource-ref>

JNDI Name

3. Map in OC4J-specific deployment descriptor.


<resource-ref-mapping
Logical Name
name="jdbc/oeCoreDB"
location= "jdbc/OracleDS" />
10-32

Copyright 2004, Oracle. All rights reserved.

Configuring Data Source References (continued)


The code examples in the slide indicate how the target JNDI name and the logical names for
a data source are defined.
1. The data-sources.xml file defines the JNDI name value jdbc/OracleDS in
the ejb-location attribute of the <data-source> element.
2. In the J2EE deployment descriptor (web.xml/ejb-jar-xml), the reference
indicates that the value jdbc/oeCoreDB in the <res-ref-name> element is the
logical JNDI name that the client application uses to look up the data source.
3. The OC4J-specific deployment descriptor (orion-web.xml/orion-ejbjar.xml) is used to map the logical name used in J2EE deployment descriptor to the
actual JNDI name for the data source defined in the data-sources.xml file.
Note: Although JNDI names are specified in the location, xa-location, and ejblocation attributes of the <data-source> element, it is recommended that you use or
map to the name specified in the ejb-location attribute. The configuration in the slide
supports a client application that uses the logical JNDI name defined in the <res-refname> element of the J2EE deployment descriptor. For example:
InitialContext ic = new InitialContext();
javax.sql.DataSource ds =
(javax.sql.DataSource)ic.lookup("java:comp/env/jdbc/oeCoreDB");

Oracle10g: Build J2EE Applications 10-32

Summary

In this lesson, you should have learned how to:


Describe Remote Method Invocation (RMI)
Recognize the role of RMI in a J2EE environment
Explain the concepts of JNDI
Access an EJB or a data source object by using
JNDI techniques
Configure the JNDI names and environment
properties, such as environment variables, EJB
references, and data sources

10-33

Copyright 2004, Oracle. All rights reserved.

Summary
The slide summarizes the key points covered in this lesson. RMI is not specified as a part of
the J2EE specification. However, RMI mechanisms and java.rmi interfaces and classes
are used by J2EE components. The RMI communications architecture is used as the basis
for communication between J2EE client and server components such as Enterprise
JavaBeans. The JNDI services provided by J2EE-compliant implementations provide a
standard way for clients to locate, look up, and communicate with distributed objects in a
J2EE environment.

Oracle10g: Build J2EE Applications 10-33

Practice 10-1: Overview

This practice covers the following topics:


Creating a JSP Java client to connect to and
invoke a remote Hello World EJB (the EJB is
provided) by using the ORMI protocol
Creating a stand-alone client to obtain a reference
to an EJB and JDBC data source

10-34

Copyright 2004, Oracle. All rights reserved.

Oracle10g: Build J2EE Applications 10-34

Practice 10-1
The aim of this practice is to write the code to perform JNDI lookup of an EJB and data
source object. To formulate an appropriate JNDI lookup request, you need to know only the
name of the EJB and how to call a method, which is similar to calling a method by using an
object reference in any Java application.
In JDeveloper, open the workspace practice10ske.jws in the practice10ske
directory and expand the usingjndi.jpr project. The project contains a HelloWorld
stateless session EJB and its deployment descriptor.
1. Enable the HelloWorldLocal.jsp application to invoke the greeting()
method of the HelloWorld session bean. The JSP and the session bean execute in
the same embedded OC4J container.
a. Open the HelloWorldLocal.jsp file and in the first scriptlet create an
initial context object and assign it to a Context variable called context.
b. Which package name is required in the import statement to compile this line of
code?
c. Now modify the string parameter value in the context.lookup() method to
be the name of the EJB.
Hint: Open the ejb-jar.xml file for the EJB and find the <ejb-name>
element.
d. Save your changes, compile the JSP, and correct any syntax errors.
e. Expand the usingjndi.impl package, and right-click the HelloWorld
node to run the HelloWorld EJB component in the embedded OC4J container.
f. Run HelloWorldLocal.jsp and observe the results in the generated HTML
page. The HTML page should contain the following text: Result from the
HelloWorld greeting() method is: Hello World (from Stateless Session
EJB).
2. Create a stand-alone Java class, with a main() method to invoke the
HelloWorldEJB in the embedded OC4J container.
a. Right-click the usingjndi project, select New, and then click Simple Files and
create a new Java class called HelloWorldClient, making sure that the
Generate Main Method check box is selected.
b. In the default constructor, copy the code from the scriptlet of the
HelloWorldLocal.jsp into the body of a try block, with Exception
class being caught in the catch block.
Hint: Make sure that you import the javax.naming package and any others
that may be required in your class, and call the exception object
printStackTrace() method in the catch block.
c. In the last line of the try block, enter the following code to print the return
value of the greetings() method of the EJB:
System.out.println(helloWorld.greetings());

d. Right-click HelloWorldClient.java, and select Run from the menu.


e. You are expected to get an error. Can you explain the error?
Hint: Check the first line of the error message displayed.

Oracle10g: Build J2EE Applications 10-35

Practice 10-1 (continued)


f. Modify the HelloWorldClient application to create a
java.util.Hashtable with JNDI properties set to the following values:
Context.INITIAL_CONTEXT_FACTORY set to the string
"com.evermind.server.rmi.RMIInitialContextFactory"
Context.SECURITY_PRINCIPAL set to "admin"
Context.SECURITY_CREDENTIALS set to "welcome"
Context.PROVIDER_URL set to
"ormi://localhost:23891/current-workspace-app"
Hints: Remember to add an import statement for the
java.util.Hashtable. Make sure that the port number in
PROVIDER_URL is the same as the RMI port number printed in the Embedded
OC4J Container tab window in the Log Message window.
g. Modify the HelloWorldClient application to provide the Hashtable
object as a parameter to the constructor when creating the InitialContext.
h. Right-click HelloWorldClient.java and select Run. The Log window
should show the bean message.
3. Open the UseDataSource.java file and write the JNDI code to obtain a data
source object from an OC4J server. You must run the HelloWorld EJB application
to start the embedded OC4J container.
a. In the try block of the UseDataSource() constructor, create a new
InitialContext with the same JNDI properties used in the
HelloWorldLocal.jsp application.
Hints: Use a Hashtable parameter with the InitialContext constructor,
or copy the jndi.properties file located in your
E:\JDeveloper\jdev\mywork\practice10ske directory to your
E:\JDeveloper\jdev\mywork\practice10ske\usingjdni\clas
ses directory, and use the no-arg constructor of the InitialContext.
You may need to edit the port number in the java.naming.provider.url
property of the jndi.property file.
b. Use the context object to create a javax.sql.DataSource object by
looking up the JNDI name of jdbc/oeDS.
c. Create a java.sql.Connection using the data source object by calling the
getConnection(), or the getConnection(user, pass) with your
database username and password.
d. Call the listDepartments() method using the JDBC connection object that
you opened from the data source to verify that your JNDI lookup works.
e. Compile the code and eliminate any syntax errors.

Oracle10g: Build J2EE Applications 10-36

Practice 10-1 (continued)


f. Run the HelloWorld EJB to launch the OC4J container.
g. Run the UseDataSource application. The application should display a list of
department ID and names in the JDeveloper Log window.
Optionally, if you have time, then you can perform the following:
4. Alter the client applications to work with the HelloWorld EJB deployed to Oracle
Application Server 10g.
a. Right-click HelloWorldEJB.deploy and select Deploy to
OracleAS10g, or select Deploy to EAR file and deploy the resulting
EAR file by using the Oracle Enterprise Manager Web interface.
b. Modify HelloWorldClient.java and UseDataSource.java to work
with Oracle Application Server 10g.
c. Run HelloWorldClient.java. You should see the EJB message Hello
World (from Stateless Session EJB) displayed in the Log Message
window.
d. In HelloWorldClient.java, alter the code that executes the lookup()
method by passing the return value of the context.lookup() method to the
first parameter of the javax.rmi.PortableRemoteObject.narrow()
method.
Hint: PortableRemoteObject.narrow() requires
HelloWorldHome.class as a second parameter and an import
javax.rmi.PortableRemoteObject statement.
e. Run the HelloWorldClient.java application again, and it should yield the
same result as before. In the client code, you use
PortableRemoteObject.narrow()to resolve the remote object reference
obtained from the a JNDI lookup request into its target object type.
5. Modify HelloWorldClient.java or UseDataSource.java to use RMI over
HTTP tunneling.
Hint: Prefix PROVIDER_URL with http:.

Oracle10g: Build J2EE Applications 10-37

Creating the Business Tier:


Enterprise JavaBeans

Copyright 2004, Oracle. All rights reserved.

Objectives

After completing this lesson, you should be able to do


the following:
Define an Enterprise JavaBean
Describe the Enterprise JavaBeans (EJB)
architecture
Describe the types of EJBs and when they
are used
Explain EJB interfaces
Define the steps to deploy an EJB to Oracle
Application Server 10g

11-2

Copyright 2004, Oracle. All rights reserved.

Objectives
This lesson introduces Enterprise JavaBeans and how to create them in Oracle JDeveloper
10g.

Oracle10g: Build J2EE Applications 11-2

Enterprise JavaBeans (EJB)

Enterprise JavaBeans are portable components,


which:
Enable faster application development
Allow reuse of business components
Encapsulate business logic that can be invoked
by clients
Execute in a container that provides services such
as support for transactions, persistence, and
access control for the beans

11-3

Copyright 2004, Oracle. All rights reserved.

Enterprise JavaBeans
EJBs have the following features:
EJBs reduce the burden on the developer, because the details of transaction support,
security, remote object access, and many other complicated and error-prone issues are
provided transparently to the developer by the EJB server and container.
EJBs support a standard set of interfaces.
EJBs consist of methods that encapsulate business logic. For example, an EJB may
have business logic that contains a method to update the customer data in a database. A
variety of remote and local clients can invoke this method.
The container vendor provides the services that are required to make EJBs work.
Because all vendors support the same standard set of EJB interfaces, any EJB should
be able to execute in any EJB container. This complies with the write once, run
anywhere concept of Java. Oracle provides an EJB container in Oracle Application
Server 10g Containers for J2EE (OC4J).

Oracle10g: Build J2EE Applications 11-3

When to Use EJBs

When developing a J2EE application, decide whether


to use EJBs based on the following requirements:
The applications are complex and would benefit
from the system-level services that are provided
by an EJB container.
The applications must be portable and scalable.
The applications must be accessed by different
types of clients.

11-4

Copyright 2004, Oracle. All rights reserved.

When to Use EJBs


When you develop a J2EE application, use the following requirements to decide whether to
use EJB APIs or another technology:
The applications are complex and would benefit from the system-level services that are
provided by an EJB container. You might not be able to determine which API to use
for the application, based only on complexity. However, if data integrity is maintained
by using transactions, you can use an EJB container to manage these transactions.
The applications must be portable and scalable. You might need to distribute your
applications across various platforms and make them available to multiple clients. EJB
applications provide location transparency.
The applications may be accessed by different types of clients. One of the benefits of
EJB applications is that the clients requiring access to these applications need only a
few lines of code to locate and access them. Clients can be servlets, JSPs, applets,
stand-alone applications, or other local or remote server-side Java applications.

Oracle10g: Build J2EE Applications 11-4

Types of EJBs

11-5

EJB Type

Purpose

Session Beans

Performs a task for a client

Entity Beans

Represents a business object


that exists in a database

Message-Driven Beans

Receives asynchronous Java


Message Service (JMS)
messages

Copyright 2004, Oracle. All rights reserved.

Types of EJBs
Session Bean
A session bean implements one or more business tasks. A session bean can contain methods
that query and update data in a relational table. Session beans are often used to implement
services. For example, an application developer can implement one or several session beans
that retrieve and update inventory data in a database.
Entity Bean
An entity bean is a complex business entity. An entity bean models a business entity or
multiple actions within a business process. Entity beans are often used to facilitate the
business services that involve data and computations on that data. For example, an
application developer might implement an entity bean to retrieve and perform computation
on items in a purchase order. Your entity bean can manage multiple, dependent, and
persistent objects while performing its necessary tasks. An entity bean is an object that
manages persistent data, performs complex business logic, potentially uses several
dependent Java objects, and can be uniquely identified by a primary key.

Oracle10g: Build J2EE Applications 11-5

Types of EJBs (continued)


Message-Driven Bean
Message-driven beans (MDBs) provide an easier method to implement asynchronous
communication than by using straight Java Message Services (JMS). MDBs were created to
receive asynchronous JMS messages. The container handles most of the setup processes that
are required for JMS queues and topics. It sends all the messages to the interested MDB. An
MDB allows J2EE applications to send asynchronous messages that can then be processed
by the application.

Oracle10g: Build J2EE Applications 11-6

Session Beans
Session beans invoke methods for a single client.
There are two types of session beans:
Stateless Session Beans (SLSBs)
Conversation that spans a single method call
Single request business processes that do not
maintain client-specific state

Stateful Session Beans (SFSBs)


Conversation with one client that may invoke many
methods
Business processes that span multiple method
requests, thus maintaining state
EJB container
Pool of SLSBs

11-7

EJB container
SFSBs

Client 1

Client 1

Client 2

Client 2

Copyright 2004, Oracle. All rights reserved.

Session Beans
Session beans represent verbs in the business process such as process order. Session beans
are classified based on the maintenance of the conversation state:
Stateless session beans: Stateless session beans do not have an internal state. They do
not keep track of the information that is passed from one method call to another. Thus,
each invocation of a stateless business method is independent of its previous
invocation; for example, calculating taxes or shipping charges. When a method to
calculate taxes is invoked with a certain taxable value, the tax value is calculated and
returned to the calling method, without the necessity to store the callers internal state
for future invocation. Because they do not maintain state, these beans are simple to
manage for the container. When the client requests a stateless bean instance, it may
receive an instance from the pool of stateless session bean instances that are
maintained by the container. Because stateless session beans can be shared, the
container can maintain a lesser number of instances to serve a large number of clients.

Oracle10g: Build J2EE Applications 11-7

Session Beans (continued)


Stateful session beans: A stateful session bean maintains a conversational state across
method invocations; for example, an online shopping cart of a customer. When the
customer starts online shopping, the customers details are retrieved from the database.
The same details are available for the other methods that are invoked when the
customer adds or removes items from the cart, places the order, and so on. Yet, stateful
session beans are transient because the state does not survive session termination,
system crash, or network failure. When a client requests a stateful session bean
instance, that client is assigned one stateful instance, and the state of the bean is
maintained for that client.

Oracle10g: Build J2EE Applications 11-8

Entity Beans
Entity beans represent a business object in the
database. They are:
Sharable across multiple clients
Uniquely identifiable through a primary key
Persistentthe state survives an EJB server crash
There are two types of persistence in entity EJBs:
Container-managed persistence (CMP) beans:
The state of the bean is maintained by the
container.
The bean developer specifies the persistent fields.

Bean-managed persistence (BMP) beans:


The state of the bean is maintained by the bean
itself.
The bean developer writes the logic to manage
persistence by using Java Database Connectivity
(JDBC).

11-9

Copyright 2004, Oracle. All rights reserved.

Entity Beans
An entity bean represents persistent data from the database. For example, an entity bean can
represent a row in a customer table, or an employee record in an employee table.
Entity beans are sharable across multiple clients. For example, an employee entity bean can
be used by various clients to calculate the annual salary of an employee or to update the
employee address.
Each entity bean instance is uniquely identified through its primary key.
An EJB server crash can result in the rollback of a transaction but does not destroy the entity
bean because the entity bean is a representation of permanent data from the database. The
same entity bean can be restored by reading from the persistent storage.
Specific fields of the entity bean object can be made persistent. Thus, based on their
persistence mechanisms, entity beans can be classified as follows:
Container-managed persistence (CMP) beans: The container reads the information
of the persistent fields from the deployment descriptor and automatically manages the
persistence. The bean developer does not need to code the persistent logic because the
container performs all the functions that are necessary to save, load, and locate the
persistent data.
Bean-managed persistence (BMP) beans: The bean developer must write the logic to
save, load, and locate the persistent data of the entity bean by using a persistence API
such as JDBC.
Oracle10g: Build J2EE Applications 11-9

Message-Driven Beans

Provide a facility for asynchronous


communication
Exist within a pool, and receive and process
incoming messages from a JMS queue or topic
Are invoked by the container to handle each
incoming message from the queue or topic
Are similar to stateless session beans
JMS queue

EJB container

Clients
Pool of MDBs

11-10

Copyright 2004, Oracle. All rights reserved.

Message-Driven Beans
Message-driven beans provide an easier method to implement asynchronous communication
than by using straight Java Message Service (JMS). MDBs were created to receive
asynchronous JMS messages from JMS queues or topics. The container handles most of the
setup processes required for JMS queues and topics. It sends all messages to the interested
MDB. The container invokes a bean from the queue or topic to handle each incoming
message from the queue or topic. No object invokes an MDB directly: all invocation for an
MDB comes from the container. After the container invokes the MDB, it can invoke other
EJBs or Java objects to continue the request. MDBs are responsible for coordinating tasks
that involve other session or entity beans.
An MDB is similar to a stateless session bean because it does not save conversational state
and is used for handling multiple incoming requests. However, instead of handling direct
requests from a client, MDBs handle requests that are placed in a queue. The diagram in the
slide demonstrates this by showing how clients place requests on a queue. The container
takes the requests from the queue and gives the request to an MDB in its pool.

Oracle10g: Build J2EE Applications 11-10

EJB Architecture
EJB server
EJB container
Home/local
home
interface

Home/
local home
object

EJB client
Remote/
local
interface

Deployment
descriptor

11-11

EJB
Class

Remote/
local
object

Database

Enterprise Services
Naming, Transaction, Security,
Messaging

Copyright 2004, Oracle. All rights reserved.

EJB Architecture
The diagram in the slide shows the major components (classes, interfaces, and services) in
the EJB architecture. A basic EJB architecture consists of the following major components:
The EJB server provides the server-side framework and services to the components.
An EJB container isolates the beans from the specifics of the server, hosts the beans,
and maintains their life cycles. They also provide services such as naming (Java
Naming and Directory Interface [JNDI]), security, and transaction (Java Transaction
Service [JTS]) control.
The EJB classes are beans themselves. They are the business components of the
application, and contain the implementation of the business and life-cycle methods.
Home/local home interfaces and home/local home objects are object factories. Using
them, the client can create, get a reference to, or destroy instances of beans.
Remote/local interface and remote/local objects mediate a clients request to access
business methods on the EJBs. The remote/local interface is generally referred to as
the component interface. The component interface defines the services that the bean
provides to the client program.
EJB clients are the applications that access the business methods of the EJB through
the EJB container.
The deployment descriptor is an XML file that describes how the EJB should be
installed (deployed) into the server/container.
Oracle10g: Build J2EE Applications 11-11

EJB Server

Manages the EJB container


Provides a deployment and execution platform for
EJB components
Provides system services to containers that in
turn provide services to beans:
Transaction services
JNDI naming services

11-12

Can provide vendor-specific features such as


connection pooling

Copyright 2004, Oracle. All rights reserved.

EJB Server
The EJB server provides a deployment platform and an organized environment to support
the execution of applications that are developed by using EJBs and other related
components. It provides services to the containers, which in turn provide services to the
bean. The EJB server manages and coordinates the allocation of resources to the
applications.
The EJB server makes EJB containers that are running within the server visible to the
outside world. The server provides JNDI-accessible naming services, secure socket layer
(SSL) support, transaction management services, and so on. All the bean home objects that
are hosted by the containers in the server are published in this server-provided naming
service. The clients look for the home interface by using the JNDI service.
The EJB server is responsible for communicating with the network, handling protocol
issues, and providing a place for the EJBs to execute.
EJBs are based conceptually on the Java Remote Method Invocation (RMI) model. For
example, remote object access and parameter passing for EJBs follow the RMI specification.
The EJB specification does not prescribe the transport protocol. The Oracle Application
Server 10g EJB server uses ORMI for its transport protocol.

Oracle10g: Build J2EE Applications 11-12

EJB Container

Manages the life cycle of the enterprise beans


Isolates the enterprise beans from direct access
by client applications
Makes required services available to the EJB
classes through well-defined interfaces
EJB container
Home/local
home
interface

home/local
home
object

Remote/
local
interface

remote/
local
object

Client

11-13

EJB
class

Container
generated

Copyright 2004, Oracle. All rights reserved.

EJB Container
The EJB container supplies the run-time environment for a deployed EJB. Containers ensure
that the EJBs are deployed properly and present an interface between the bean and the
server. All the service requests that the bean makes from its infrastructure are directed to the
container, which in turn delegates them to the server. A container manages the entire life
cycle of the beanthat is, its creation, destruction, passivation, and activation. The
container also manages remote access to the bean, security, transaction, distribution, and
other infrastructure issues. It performs all these functions with the help of the server. The
container generates the home object and remote object.
The EJB container also provides a naming context for the object. A particular class of an
enterprise bean is assigned to one EJB container. When a client application invokes a remote
method on an enterprise bean, the container verifies the invocation to ensure that the
persistence, transactions, and security are applied properly to every operation that a client
performs on the bean.

Oracle10g: Build J2EE Applications 11-13

Services Provided by the EJB Container

11-14

Life-cycle management
Bean instance pooling
Client state management
Database connection pooling
Declarative transaction management
Security
Persistence

Copyright 2004, Oracle. All rights reserved.

Services Provided by the EJB Container


The container manages the life cycle of the deployed EJB by creating, instantiating,
activating, passivating, and removing the bean instances as appropriate.
When a client requests a bean that is not already in the pool, the container creates a new
instance of the bean. If an instance is already there in the pool, the container retrieves an
instance of the bean from the pool (activates the bean) and assigns it to the client. Similarly,
when a client releases the bean, the container returns the bean to the pool (passivates the
bean). The container also removes the unused bean instances from the pool.
When a client requests an instance of a bean, the container may record the state of the client.
When the client requests the same bean after some time, the recorded state is copied into an
available instance from the pool and then allocated to the client. When the state is
maintained in this manner, the client cannot see any difference in the instances that are being
allocated.
When the server starts up, it pools a set of database connections. These connections can be
shared by many clients, and this increases the scalability of the applications.

Oracle10g: Build J2EE Applications 11-14

Services Provided by the EJB Container (continued)


The application developer can leave the transaction management to the container by
declaring the methods or specific operations that need to be transaction-managed in the
deployment descriptor. The container then manages the operations such as rolling back or
committing a transaction.
Similar to transaction management, the application developer can declare the users, roles,
and access privileges in the deployment descriptor. The container then provides security to
the application by verifying the clients privileges to various components of the application.
The application developer may request that the persistence of the data be managed by the
container. This is known as container-managed persistence (CMP).

Oracle10g: Build J2EE Applications 11-15

EJB Client
An EJB client is a stand-alone application, servlet,
JSP, or another EJB that accesses the bean.
It can be a:
Local client:
Resides within the same Java virtual machine (JVM)
as the bean
Passes arguments by reference to the bean
Interacts with the EJB through methods defined in
the local interface

Remote client:
Is location independent
Passes arguments by value to the bean
Interacts with the EJB through methods defined in
the remote interface

11-16

Copyright 2004, Oracle. All rights reserved.

EJB Client
An EJB client is the application that accesses the bean. Although it does not necessarily
reside on the client tier, a client can be a stand-alone application, JSP, servlet, or another
EJB.
The client accesses the methods on the bean class through the EJB container. The container
generates a proxy for the bean, called the remote or local object. The client obtains reference
to this object through the home interface. When the client invokes a business method on the
bean, the remote or local object receives the request, delegates it to the corresponding bean
instance, and returns the results to the client.
Because a local client must run in the same JVM as the EJB, there is less overhead in
looking up the bean instance. The client accesses the methods of an EJB through the local
home and local interfaces of the bean. The client passes arguments to the bean by passing
the location of the argument to the bean.
A remote client accesses the methods of an EJB through the home and remote interfaces of
the bean. The client may reside in a different JVM or on a different machine than the EJB.
However, there is overhead involved in looking up the bean instance to access the bean
methods. Additionally, the client passes arguments to the bean methods by value. That is, an
argument in a remote call is a copy of an object. The bean processes the argument at the
copied location. The disadvantage in this method is that if the size of the argument is large,
there can be considerable overhead in copying the argument to a different location.
Oracle10g: Build J2EE Applications 11-16

EJB Interfaces and Classes

Interfaces:
Remote interface/Local interface
Home interface/Local home interface

Classes:
Bean class
Primary key class (entity beans)

11-17

Copyright 2004, Oracle. All rights reserved.

EJB Interfaces and Classes


The EJB interfaces are classified as the following types:
A remote interface that defines a beans business methods that are accessible by
remote clients
A local interface that defines business methods that are accessible by local clients
residing in the same JVM as the bean
A home interface that defines life cycles of a bean that are accessible by remote clients
A local home interface that defines life-cycle methods for local clients
These interfaces are used only by session and entity beans. The message-driven beans do not
use these interfaces because the message-driven beans are not accessible by clients through
any method calls. Because an EJB can have both remote and local clients, it may have all
the four interfaces (mentioned above) defined on it.
An EJB class is:
A bean class that actually implements the beans business methods
A primary key class that uniquely identifies each entity bean. A primary key class is
not mandatory if a Java primitive type is used to identify an entity bean. In this case,
the deployment descriptor of the bean declares a unique field of the bean as its primary
key.
Note: Remote and local interfaces are generally referred to as the component interfaces.
Oracle10g: Build J2EE Applications 11-17

Remote Interface and Remote Object

Remote interface:
Extends the javax.ejb.EJBObject interface that
extends the java.rmi.Remote interface
Describes the client view of an EJB
Declares the business methods that are accessible
to remote clients

EJB object:
Is a container-generated implementation of a
remote interface
Is a reference object that a client receives
Delegates the method calls to a bean class after
doing some infrastructure work

11-18

The remote interface and remote object are used


by session and entity beans.
Copyright 2004, Oracle. All rights reserved.

EJB Remote Interface and Remote Object


The bean developer writes a remote interface for each EJB in the application. The remote
interface declares the business methods that the bean contains. Each method in the bean to
which a remote client has access must be specified in the remote interface. Private methods
in the bean are not specified in the remote interface. The signature for each method in the
remote interface must match the signature in the bean implementation. (PL/SQL developers
recognize that the remote interface is much like a package specification, and the remote
interface implementation is similar to the package body. However, the remote interface does
not declare public variables. It declares only the methods that are implemented by the bean.)
The remote interface must be public, and it must extend javax.ejb.EJBObject.
All the methods in the remote interface are declared as throwing the
java.rmi.RemoteException exception. This is the usual mechanism for notifying
the client of run-time errors in the bean. However, the bean container can throw other
exceptions, such as SQLException. Any exception can be thrown to the client as long as
it is serializable. Run-time exceptions are transferred back to the client as remote run-time
exceptions. The remote object is generated by the container.

Oracle10g: Build J2EE Applications 11-18

Home Interface and Home Object

Home interface:
Extends the javax.ejb.EJBHome interface that
extends the java.rmi.Remote interface
Contains the life-cycle methods for creating,
removing, and locating the instances of a bean
class
Contains home methods
Are accessed by remote clients

Home object:
Is a container-generated implementation of the
home interface
Uses callback methods on a bean class to perform
its functions

11-19

Copyright 2004, Oracle. All rights reserved.

Home Interface and Home Object


The home interface defines the life-cycle methods to create, destroy, and find a bean
instance. When a client needs to create a bean instance, it does so through the home
interface. The client uses one of the create() methods specified by the home interface.
The client uses this home interface to obtain a reference to the beans remote interface. A
create() method can take parameters that are passed in from the client when the bean is
created.
For each create() method in the home interface, there must be a corresponding
ejbCreate() method specified in the bean class with the same signature. For the
remove() method in the home interface, there must be an ejbRemove() method in the
bean class. The home interface contains find methods for entity beans. A find method is a
method that starts with the findBy keyword. When a client invokes the create()
method on the home interface, the container interposes whatever services are required at that
point, and then calls the corresponding ejbCreate() method in the bean itself. The home
object is generated by the container. The client looks up the reference of the published home
object to create instances of the bean. The home interface uses the callback methods that
allow the container to notify the bean of events in its life cycle.

Oracle10g: Build J2EE Applications 11-19

Local Interface and Local Home Interface

Local interface:
Extends the javax.ejb.EJBLocalObject interface
Declares the business methods of the bean that are
accessible by a local client
Improves performance because the bean resides in
the same JVM, and parameters are passed by
reference

Local home interface:


Extends the javax.ejb.EJBLocalHome interface
Defines the life-cycle methods that are accessible
by local clients

11-20

These interfaces are used by session and entity


beans.
They enable relationships between entity beans.
Copyright 2004, Oracle. All rights reserved.

EJB Local Interface and Local Home Interface


The local interface defines business methods that are accessible by local clients. The local
interface extends the javax.ejb.EJBLocalObject interface. Local interface methods
never throw the RemoteException exception.
The local home interface defines life-cycle methods that are accessible by local clients. The
local home interface extends the EJBLocalHome interface.
In addition to the fact that the business methods never throw the RemoteException
exception, the business methods of beans that implement the local interface receive
arguments by reference instead of by value.
Because the client and the bean are in the same JVM, and because the values are passed by
reference, there is less overhead in locating and accessing the bean from the client. This
improves performance.
Relationship between entity beans is possible only through local interfaces that are defined
on the beans. Relationship between the entity beans is discussed later in this course.

Oracle10g: Build J2EE Applications 11-20

EJB Bean Class

A bean class extends


javax.ejb.EnterpriseBean.

A session/entity bean class:


Implements javax.ejb.SessionBean /
javax.ejb.EntityBean
Implements business/life-cycle methods
Contains methods to support container callbacks
Contains methods to set and unset the context of
the bean

A message-driven bean class:


Implements javax.ejb.MessageDrivenBean
Must implement the MessageListener interface
Contains business logic in the onMessage()
method

11-21

Copyright 2004, Oracle. All rights reserved.

EJB Bean Class


Enterprise JavaBean is a Java class that defines the business methods and implements some
interfaces and methods to conform to the requirements of the specification. Business
methods are methods that represent the business tasks that a bean has to perform. These
methods are:
Methods to support home interface functions: For each create() method specified
by the home interface, the bean class must specify an ejbCreate() and an
ejbPostCreate() method with the same signature.
Methods to support container callbacks: Callback methods allow the container to
notify the bean of the events in its life cycle. The container informs the bean class
when it is about to activate the bean, persist its state to the database, end a transaction,
remove the bean from memory, and so on. This allows the bean class to restore or
close any resources as required.
Methods that perform business tasks: A bean class must implement each of the
business methods that is described in the remote/local interface of the bean.
Methods that set and unset the session and entity context: After it is set, the context
can be used later to access the methods of the bean.
For an MDB, as discussed earlier, there are no component interfaces. An MDB has a bean
class only and it contains the business logic in its onMessage() method.
The bean class is discussed in detail when each bean type is discussed later in this course.
Oracle10g: Build J2EE Applications 11-21

The EJB Deployment Process


Home interface
Remote interface
Bean class
Other classes

Deployment
descriptor

Developers
responsibility
Component deployers
responsibility
Jar
command/
tool

EJB
JAR

Deployment
tools/
commands

Deployed EJB in the


Server

JNDI

11-22

Copyright 2004, Oracle. All rights reserved.

The EJB Deployment Process


The EJB deployment process consists of the following steps:
The EJB developer creates a JAR file containing the beans and their accompanying
classes, including the home and remote interfaces and any classes that are dependent
on the bean. This is known as the EJB JAR file.
Each EJB JAR file has an EJB deployment descriptor, named ejb-jar.xml.
If you are deploying your EJB to Oracle Application Server 10g, then create an Oraclespecific deployment descriptor, named orion-ejb-jar.xml.
Deploy the EJB by using a command-line tool such as Oracle Enterprise Manager, or
Oracle JDeveloper 10g. These tools:
- Read the deployment descriptor and the bean JAR file
- Map the logical names that are defined in the EJB deployment descriptor to
existing JNDI names and database tables
- Load the bean classes into the EJB server
- Publish the home interface of the bean
The client application developer can then access the methods of the bean that are
provided with the remote interface name of the bean and the name of the published
beans.
Oracle10g: Build J2EE Applications 11-22

ejb-jar.xml File
<ejb-jar>
<enterprise-beans>
<session>|<entity>|<message-driven>
<description>Say Hello</description>
<display-name>HelloWorld</display-name>
<ejb-name>HelloWorld</ejb-name>
<home>lesson11.HelloWorldHome</home>
<remote>lesson11.HelloWorld</remote>
<ejb-class>lesson11.impl.HelloWorldBean</ejb-class>
</session>|</entity>|</message-driven>
</enterprise-beans>
<assembly-descriptor>
<security-role> </security-role>
<method-permission> </method-permission>
<container-transaction> </container-transaction>
</assembly-descriptor>
</ejb-jar>

11-23

Copyright 2004, Oracle. All rights reserved.

ejb-jar.xml File
The code in the slide shows major elements of an EJB deployment descriptor.
The tag <ejb-jar> indicates the beginning of the document. (The version and Document
Type Definition (DTD) for this XML file should be included before the beginning tag.) The
body of the deployment descriptor is enclosed within the <ejb-jar> and </ejb-jar>
tags.
Between the <enterprise-beans> and </enterprise-beans> tags, you declare
the details for the beans that are contained in this JAR file. The information described within
these tags contains the type of the bean, the names of the home and remote interfaces, and
the bean class. The details of the session beans are described with a <session> element,
those of entity beans with an <entity> element, and those of MDBs with a <messagedriven> element. Additionally, elements that are specific to individual EJB types are
contained within the bean descriptor. For example, a session bean should have a
<session-type> element, and an entity bean should have a <primary-key> element.
In the <assembly-descriptor> section, the security roles that are used to access the
beans and transaction attributes for the application are defined. Note that all the beans within
this JAR file share security and transactional declarations.
The details of the above elements are discussed in detail later in the course.
Oracle10g: Build J2EE Applications 11-23

orion-ejb-jar.xml File

Oracle Application Server 10g uses the orion-ejbjar.xml file for deployment. This file:

11-24

Specifies run-time attributes of the bean for


deployment to the container
Enables customization of the run-time behavior of
enterprise beans

Copyright 2004, Oracle. All rights reserved.

orion-ejb-jar.xml File
The orion-ejb-jar.xml file is the deployment descriptor for EJBs that are deployed to
Oracle Application Server 10g. It is used for customizing and specifying the dependencies of
the beans on the environment, such as resources and security, relationships between beans,
lists of parameters for controlling pooling, session timeout, interoperability, and concurrency
modes. The orion-ejb-jar.xml file is processed by OC4J at deployment. Note that
the ejb-jar.xml file is used for all J2EE containers. The orion-ejb-jar.xml is
specifically used by the OC4J server for EJB configuration within the OC4J container. Other
vendors have their own deployment descriptors, many of which can be created in
JDeveloper, although orion-ejb-jar.xml is created by default.

Oracle10g: Build J2EE Applications 11-24

Creating an EJB in JDeveloper

11-25

Copyright 2004, Oracle. All rights reserved.

Creating an EJB in JDeveloper


To create a new EJB in JDeveloper, select File > New > Business Tier > Enterprise
JavaBeans. You can choose the type of bean to create from the list of items.

Oracle10g: Build J2EE Applications 11-25

Using the EJB Wizard

11-26

Copyright 2004, Oracle. All rights reserved.

Using the EJB Wizard


After selecting the type of bean to create, enter the name of the EJB and the details of the
bean, depending on the type of bean that you selected.

Oracle10g: Build J2EE Applications 11-26

Using the EJB Wizard

11-27

Copyright 2004, Oracle. All rights reserved.

Using the EJB Wizard (continued)


You can easily create home and remote/local interfaces by using the wizard. After you click
Finish to generate the bean, JDeveloper creates the following files for you:

ejb-jar.xml: The deployment descriptor for this EJB module, based on the
parameters you gave when using the wizard

MySessionEJB: The EJB module containing all the components of the bean
- MySessionEJB.java: Contains the skeleton code for the remote interface
- MySessionEJBBean.java: Contains the skeleton code for the class,
including ejbCreate(), ejbRemove(), and so on
- MySessionEJBHome.java: Contains the skeleton code for the home
interface

orion-ejb-jar.xml: The deployment descriptor for Oracle Application Server


10g

Oracle10g: Build J2EE Applications 11-27

Adding Methods to the Bean

To add methods to the bean, right-click and select Go


To Bean Class:

11-28

Copyright 2004, Oracle. All rights reserved.

Adding Methods to the Bean


When you select the Class Editor as shown in the slide above, you can add methods to the
bean by using the Add button, as shown in the following screenshot:

Oracle10g: Build J2EE Applications 11-28

Deploying to Oracle Application Server


10g from JDeveloper

11-29

Copyright 2004, Oracle. All rights reserved.

Deploying to Oracle Application Server 10g from JDeveloper


As stated previously, you can use a command-line tool, such as Oracle Enterprise Manager,
or JDeveloper, to deploy EJBs. To deploy from JDeveloper, right-click the ejb-jar.xml
file and select Create EJB JAR Deployment Profile. This creates a .deploy file, which
contains the details of the deployment. After creating the .deploy file, you can right-click
the file and select Deploy to OracleAS10g, where OracleAS10g is the name of your
application server connection.

Oracle10g: Build J2EE Applications 11-29

Summary

In this lesson, you should have learned how to:


Define an EJB
Describe the EJB architecture
Describe the types of EJBs and when they are
used
Explain EJB interfaces
Define the steps to deploy an EJB to Oracle
Application Server 10g

11-30

Copyright 2004, Oracle. All rights reserved.

Summary
There are three types of EJBs:
Session beans: Process business logic. They can access data from the database by using
direct JDBC calls, or by using an entity bean.
Entity beans: Represent data in the database and also the methods to manipulate that
data. Each row of the data in a data object is represented by one entity bean.
Message-driven beans: Are developed to enable asynchronous messaging with JMS
The EJB architecture contains:
A server and container that are responsible for managing the life cycle of the EJBs and
for providing the system services. Deployment tools such as JDeveloper are used to
publish the beans on the EJB server.
A client application that invokes methods on the bean
A home interface that contains methods to create, find, and get metadata from the EJB
A remote interface that describes the methods that a client application can invoke on
the EJB
The bean class itself that contains the methods to process business logic
Deployment descriptors that contain the properties of the bean that are used by the
container during the deployment process
Oracle10g: Build J2EE Applications 11-30

Practice 11-1: Overview

This practice covers the following topics:


Creating an EJB in JDeveloper
Testing an EJB

11-31

Copyright 2004, Oracle. All rights reserved.

Practice 11-1: Overview


In this practice, you observe the classes, interfaces, and deployment descriptor for a given
EJB.

Oracle10g: Build J2EE Applications 11-31

Practice 11-1
The purpose of this practice is to reinforce the concepts of EJBs by creating a simple session
bean in JDeveloper, testing it, and deploying it.
1. Create a new EJB.
a. Navigate to the EJB project in the practice11ske.jws workspace. Rightclick the EJB project and select New.
b. From the Business Tier category, select Enterprise JavaBeans and select Session
Bean from the items list.
c. Select EJB 2.0 to create a session bean that complies with the 2.0 specification.
d. Accept the defaults for the name, session, and transaction types, and click Next.
e. Accept the defaults for the bean class and source directory, and click Next.
f. Accept the default to include the remote interfaces for the bean.
g. Click Finish to generate the EJB.
2. Add a field to the EJB that you have created.
a. Right-click the bean class that is generated for you and select "Go to Bean
Class."
b. Click the Class tab to open the class editor.
c. Click the Fields tab and add a String field named hello to the EJB.
d. Accept all the other field defaults and click OK.
e. Click the Source tab to view the code that is generated for you.
f. Select the bean in the System Navigator and double click the remote interface in
the Structure Pane.
g. Create a declaration in the remote interface for the setHello() and
getHello() methods. These methods should throw a
java.rmi.RemoteException exception.
3. Test the EJB.
a. Right-click the session bean that you created and choose Run. This starts the
embedded OC4J server and deploys the EJB. After the message Oracle
Application Server Containers for J2EE 10g initialized appears, the bean is
running and you can access it with a client.
b. Right-click your session bean and select New Sample Java Client.
c. In the Sample EJB Java Client Details dialog box, select the option to connect to
the embedded OC4J server and click OK.
d. A new client file is created for you. View the code in the editor to see how the
client accesses the EJB that you created in step 1.
e. Uncomment the setHello() method and set the value to any String value.
f. Call getHello() and print it to the console.

Oracle10g: Build J2EE Applications 11-32

Practice 11-1 (continued)


g. If the code was not added for you, obtain access to the InitialContext
object by copying and pasting the following code into the
getInitialContext() method:
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,
"com.evermind.server.rmi.RMIInitialContextFactory");
env.put(Context.SECURITY_PRINCIPAL, "admin");
env.put(Context.SECURITY_CREDENTIALS, "welcome");
env.put(Context.PROVIDER_URL,
"ormi://localhost:23891/current-workspace-app");
return new InitialContext(env);
h. Finally, run the client by right-clicking the client and selecting Run
<yourclientname>. You should see the output in the EJB.jpr message
window containing your String value.

Oracle10g: Build J2EE Applications 11-33

Implementing Business Tasks with


Session EJBs

Copyright 2004, Oracle. All rights reserved.

Objectives

After completing this lesson, you should be able to do


the following:
Describe session beans
Differentiate stateless session beans from stateful
session beans
Develop a home interface, a remote interface, and
a bean class for session beans
Develop a client application to invoke the
business methods

12-2

Copyright 2004, Oracle. All rights reserved.

Objectives
This lesson introduces session beans and different types of session beans. You learn the
difference between stateless session beans and stateful session beans. You develop a
stateless session bean and a client application to invoke the stateless session bean.

Oracle10g: Build J2EE Applications 12-2

Session Beans

A session bean:
Implements business processes
Is short-lived and has the lifetime of a clients
session
Does not survive server, machine, or network
crashes
Is not saved in permanent storage
Implements the javax.ejb.SessionBean
interface

12-3

Copyright 2004, Oracle. All rights reserved.

Session Beans
You have learned about the different interfaces and the bean class that constitute Enterprise
JavaBeans (EJB). You have also learned that there are three types of enterprise beans:
session beans, entity beans, and message-driven beans (MDB). You now learn about session
beans.
A session bean implements one or more business processes. A session bean can perform any
business process. For example, it can retrieve and update inventory data in a database. Note
that the session bean can retrieve or update the data but it does not represent the persistent
data. That is, a session bean is not directly associated with a row of a table.
Session beans are short-lived. Their life cycles are dependent on the clients session. When
there is a request for a session bean, the container instantiates the session bean and
associates one instance of this bean to the client. The EJB container uses management
methods for creating and destroying session beans.
Session beans are transient because they do not survive a server crash or a network failure.
If, after a crash, you instantiate a bean that had previously existed, then the state of the
previous instance is not restored. However, stateful session beans can survive crashes if they
are clustered.

Oracle10g: Build J2EE Applications 12-3

Session Beans (continued)


Session beans are nonpersistent. They are in-memory objects that live and die with their
environments. Session beans are not saved to permanent storage.
All session beans must implement the javax.ejb.SessionBean interface, which in
turn extends the generic javax.ejb.EnterpriseBean interface. This interface must
be implemented because it provides the management methods that are used by the EJB
container to manage the life cycle of the session beans.

Oracle10g: Build J2EE Applications 12-4

javax.ejb.SessionBean Interface

The SessionBean interface contains the following


callback methods:
setSessionContext(SessionContext ctx)
ejbActivate()
ejbPassivate()
ejbRemove()

12-5

Copyright 2004, Oracle. All rights reserved.

javax.ejb.SessionBean Interface
Callback methods: A session enterprise bean class must implement the SessionBean
interface. This interface defines the methods that the container calls on the bean at various
stages to manage the bean life cycle and state. These methods are called callback methods.
The bean class must implement all the methods that are defined in the SessionBean
interface, or at least provide empty implementations. The client never directly accesses these
methods.
setSessionContext(SessionContext ctx): Enterprise beans are assigned a
context object when they are first created. Session beans are assigned a SessionContext
object. The beans save this context object for later processing. A bean uses its session
context to interact with the container regarding the security and transaction management.
The setSessionContext(SessionContext ctx)method takes this session
context as its parameter and is invoked in the beginning of the life cycle of a bean. This
method is invoked each time a session bean is created. The container calls
setSessionContext()on the bean instance when the client calls create()on the
home interface. Beans that manage their own transactions can use the session context to get
the transaction context. Session beans have session contexts that the container maintains and
makes available to the beans. The bean can use the methods in the session context to make
callback requests to the container.
Oracle10g: Build J2EE Applications 12-5

javax.ejb.SessionBean Interface (continued)


ejbActivate(): The container invokes this method immediately after it returns a bean
instance from secondary storage (passivated state) to the main memory. The container
notifies the bean about activation before calling this method. The bean class can open any
closed resources at this stage.
ejbPassivate(): Instances of the beans that are no longer required can be moved to
temporary storage, such as a file system or database, by the container, thus releasing some of
the resources that the beans were using. This process is known as passivation. Passivating
the beans allows the container to efficiently manage the pool of beans in a cache. Just before
passivating the bean, the container uses this callback method to inform the bean that it is
going to be passivated. The implementation of this method in the bean class must have the
logic to release the resources that it might be holding. For example, the bean may close its
open files, database or network connections, open cursor objects, and so on.
ejbRemove(): A container invokes this method before it is about to remove the session
bean instance. This happens when the client invokes the home objects remove() method
or when a container decides to terminate the session object after timeout. The container calls
this method on the bean before destroying the bean reference. This gives the bean instance a
chance to release some resources that it may be holding or to make some database updates
before it is destroyed. Note that the container may never call this method even if this method
is implemented. This can happen under circumstances such as container crashes, exceptions,
and so on.
The ejbRemove() method is a no-argument method that must be implemented by all the
beans. There is only one ejbRemove() method per bean.

Oracle10g: Build J2EE Applications 12-6

Types of Session Beans

There are two types of session beans:


Stateless session bean: A stateless session bean
does not maintain the state for a client.
Stateful session bean: A stateful session bean
maintains the state for a client, and the instance
variable represents the state of a unique client.

12-7

Copyright 2004, Oracle. All rights reserved.

Types of Session Beans


What is a conversation in terms of enterprise beans?
A conversation is an interaction between a client and a bean. This interaction is nothing but
the method calls between the client and the bean. Session beans are classified into stateless
session beans and stateful session beans depending upon their conversational state.
Stateless session bean: A stateless session bean does not maintain the conversational state
for a particular client. When a client invokes a method of stateless bean, the variables that
hold the state have some value. But these values persist only until the called method is
executed. When the client invokes another method of the stateless bean within the same
instance, the previous state of the instance is not maintained. After each method invocation,
a stateless session bean clears itself of all information pertaining to past invocation. Stateless
session beans are employed for business services that are not connected to any specific
client, such as generic currency calculations, mortgage rate calculations, and so on.

Oracle10g: Build J2EE Applications 12-7

Types of Session Beans (continued)


Stateful session bean: A stateful session bean maintains the conversational state for a
particular client. It maintains the state of the client across method invocations and
transactions. Thus, there is one instance of a stateful session bean created for each client.
The container guarantees that no other client request is ever handled by the same stateful
session bean instance. The stateful session bean can also span across client sessions, because
the life of a stateful session beans handle is not bound to client sessions. Although stateful
session beans maintain the state of a client, the information does not survive system crashes.
However, clustered stateful session beans in OC4J can survive crashes.

Oracle10g: Build J2EE Applications 12-8

When to Use Session Beans

The state of the bean need not be persistent.


Use stateless session beans when:
The state need not be maintained for a client
A general task must be performed
Data is fetched only from a database, and data
manipulation is not necessary

Use stateful session beans when:


Interaction between bean and client must be
maintained across method calls and transactions
A bean works on logic based on entity beans that
represent persistent data

12-9

Copyright 2004, Oracle. All rights reserved.

When to Use Session Beans


Session beans model business processes or tasks and interactions; for example, a session
bean can be used to process an order by calculating discounted prices. Session beans are
generally represented by verbs.
A stateful session bean can work on logic based on the data represented by the entity bean. If
a bean is used to calculate discounted prices, then an entity bean can represent the prices of
products. The session bean can get the data by invoking methods of an entity bean and
applying the necessary business logic.
Session beans do not store persistent states. When the state of the bean need not be persistent
or when the state must be available for only a short period of time, you can use session
beans.
You can use a stateless session bean in the following situations:
When the bean state need not be associated with a specific client
When a general task must be performed, such as sending an e-mail when the order has
been processed
When you need to fetch read-only data from a database, such as to display the video
rentals that are available in a week

Oracle10g: Build J2EE Applications 12-9

When to Use Session Beans (continued)


You can use a stateful session bean in the following situations:
When the bean state must be associated with interaction from a specific client between
method invocations, such as in an online shopping cart
When the bean must manage the logic by using data retrieved from the database, using
the entity beans. For example, an online shopping cart might need to retrieve product
information, customer information, and so on, to complete the processing for a
particular customer. The information about products and customers may be obtained
through entity beans representing the persistent data.

Oracle10g: Build J2EE Applications 12-10

Life Cycle of a Stateless Session Bean

Does not
exist

Container invokes
class.newInstance,
setSessionContext(sessCtx),
and ejbCreate().

Container invokes
ejbRemove() .

Ready

12-11

Copyright 2004, Oracle. All rights reserved.

Life Cycle of a Stateless Session Bean


You have learned that stateless session beans do not hold any state for a client. Therefore, all
instances of the same stateless session bean class are equivalent and indistinguishable to a
client. Any stateless session bean instance can service any client request. These beans are
easily reused by multiple clients.
Taking advantage of the fact that stateless session beans do not maintain conversational
state, EJB containers pool stateless session bean instances before the clients connect. When
a client calls a method, the container retrieves one instance from the pool to service the
client. This instance is returned to the pool when the clients request is served. This enables
the container to dynamically assign bean instances to different clients. The slide shows the
life cycle of a stateless session bean.
The container verifies whether there are instances of a stateless session bean. If there are no
instances or fewer instances than needed, it invokes the newInstance()method on the
bean class to create an instance. Then the container invokes the
setSessionContext(SessionContext)and ejbCreate()methods on the bean
instance. Now a client can invoke methods on this instance. The container can invoke the
ejbRemove() method to remove the instance from the pool and free the resources.

Oracle10g: Build J2EE Applications 12-11

Home Interface for Stateless


Session Beans
import javax.ejb.EJBHome;
import java.rmi.RemoteException;
import javax.ejb.CreateException;
public interface StatelessejbHome extends
EJBHome
{
Statelessejb create() throws RemoteException,
CreateException;
}

12-12

Copyright 2004, Oracle. All rights reserved.

Home Interface for Stateless Session Beans


You have already learned that home interfaces define methods for creating, destroying, and
finding EJB objects. The home interface acts as the factory for EJB. Note that the home
interface StatelessejbHome contains a single create()method that does not take
any argument. Stateless session beans do not hold any state for a client between method
invocations. Therefore, it does not make sense to provide overloaded formscreate()
methods with different argument listof the create() method. The create() method
throws a javax.rmi.RemoteException exception, because the home object is a
Remote Method Invocation (RMI) remote object. The EJBHome interface extends the
javax.rmi.Remote interface. All methods of objects extending the
javax.rmi.Remote interface must throw the RemoteException exception.
You can have remote home interfaces or local home interfaces. A remote client accesses a
bean through the beans remote home interface. When you define a local component
interface, you define a local home interface. A local home interface extends the
javax.ejb.EJBLocalHome interface. Although a bean can have both the remote and
the local interfaces, it is common to provide either of the interfaces, but not both.

Oracle10g: Build J2EE Applications 12-12

Home Interface for Stateless Session Beans (continued)


A local client accesses a bean through the beans local home interface. A local client is
collocated in the same Java virtual machine (JVM) with the bean that it is accessing.
If you define local interfaces, then they can be used only in the same application. You have
faster access to the beans because RMI calls are avoided. If you define remote interfaces,
then they can be used with both local and remote applications. The access is slower
compared with beans with local interfaces, because RMI calls are required.

Oracle10g: Build J2EE Applications 12-13

Remote Interface for Stateless


Session Beans
import javax.ejb.EJBObject;
import java.rmi.*;
public interface Statelessejb extends
EJBObject
{
public String incrementValue() throws
RemoteException;
public int getValue()throws RemoteException;
}

12-14

Copyright 2004, Oracle. All rights reserved.

Remote Interface for Stateless Session Beans


Clients access the entity object through component interface reference. Component
interfaces can be remote or local interfaces. Component interfaces define business methods
that are accessible by the client. They may also define the get() and set()methods to
get and set bean attributes.
A remote interface is the component interface that is accessed by remote clients. A remote
interface extends the javax.ejb.EJBObject interface. Methods that are declared in
the remote interface should throw the RemoteException exception.
The local interface is the component interface that is accessed by local clients. A local
interface extends the javax.ejb.EJBLocalObject interface. Methods in the local
interface must not throw the RemoteException exception.
The slide shows a remote interface, which contains the business methods that are
implemented in the bean. Though the bean class implements these methods, the bean class
does not implement the remote interface. The container implements the remote interface and
this implementation is the EJB object that is responsible for delegating the clients request to
the beans. The remote interface shown in the slide has two business methods:
incrementValue() and getValue(). These methods are implemented in the bean
class.
Oracle10g: Build J2EE Applications 12-14

The Session Bean Class

The class must be defined as public, must not be


final, and must not be abstract.
The class must implement ejbCreate() methods:
There must be an ejbCreate() method for each
create() method of the home interface.
The signatures of the two methods mentioned
above should match.
The return type of the ejbCreate() method
should be void.
Remote or create exceptions need not be thrown.

12-15

The class can optionally implement the


SessionSynchronization interface.
Copyright 2004, Oracle. All rights reserved.

The Session Bean Class


The bean class must be public and must not be final or abstract.
ejbCreate(): The container invokes this method immediately before it creates the bean.
Stateless session beans must not do anything in this method. Stateful session beans can
initiate state in this method. The create() method is used to initialize the state of a bean.
Because there is no state maintained, stateless session beans implement a no-argument
create()method.
Session beans are initialized through the ejbCreate() method. Because the
ejbCreate() method is not part of the SessionBean interface, it must be provided by
the bean developer.
There must be one ejbCreate() method corresponding to each create() method
of the home interface. Signatures of these two methods must match. Stateless session
beans contain only one ejbCreate() method, which cannot contain any parameters,
because stateless session beans do not store their states.
When the client calls a create() method of the home interface, the parameters, if
any, are passed by the container to the corresponding ejbCreate() method of the
bean class. This ejbCreate() method of the bean class performs any initialization
that is required for the bean.
Oracle10g: Build J2EE Applications 12-15

The Session Bean Class (continued)


The return type of the ejbCreate() method must be void. Even though the
create() method of the home interface returns an object that implements the remote
interface, the actual creation of this object is the responsibility of the container.
The ejbCreate() method need not throw the remote and create exceptions because
the container may throw these exceptions. If any application-specific exceptions are to
be thrown for this method, then those exceptions must also be thrown in the
corresponding create() method.
A session bean should implement the SessionSynchronization interface if it needs
to synchronize its state before and after the start and completion of a transaction. The
SessionSynchronization interface allows a session bean instance to be notified by
its container of transaction boundaries.
The methods of this interface notify the bean instance when a new transaction has started,
when a transaction is about to be committed, and when a transaction is complete. These
methods help the bean instance to read data from a database and cache the data in its
instance fields or write cached data to the database. After the transaction is complete, the
bean instance can discern whether the transaction has been committed or rolled back.

Oracle10g: Build J2EE Applications 12-16

The Session Bean Class:


Business Methods

12-17

The bean class may define zero or more methods


to process the business logic.
The business methods that are to be accessed by
the client applications must be public.
The business methods must not be declared as
final or static.
The business methods that are to be accessed by
clients must be exposed through the component
interface.
The method arguments and return types must be
legal types for RMI.
Application-specific exceptions can be thrown.
Copyright 2004, Oracle. All rights reserved.

The Session Bean Class: Business Methods


The bean class may provide zero or more business methods that contain the business logic.
All the business methods of the bean class that need to be accessed by the client applications
must be exposed through the component interface with the same signature. These methods
must be public.
The container delegates all the business method calls to the bean instance, after performing
some preliminary tasks such as security checks and transaction demarcation. The business
methods can throw any application-specific exception. These exceptions are passed as such
to the client, invoking the method.

Oracle10g: Build J2EE Applications 12-17

Bean Class for the Stateless


Session Bean
...
public class StatelessejbBean implements SessionBean
{
int value =0;
public void ejbCreate() { }
public void ejbActivate() { }
public void ejbPassivate(){ }
public void ejbRemove() { }
public void setSessionContext(SessionContext ctx) { }
public String incrementValue() {
value++;
return " value incremented by 1";
}
public int getValue()
{
return value;
}
}

12-18

Copyright 2004, Oracle. All rights reserved.

Bean Class for the Stateless Session Bean


The bean class contains all the container callback methods. These methods are invoked by
the container to manage the life cycle of the beans. You can include several ejbCreate()
methods corresponding to the create() method in the home interface. The bean class
must have at least one ejbCreate() method. The slide shows the bean class for a
stateless session bean. It contains a single instance variable called value, which is
initialized to 0. It also contains the ejbCreate() method and the implementation of the
business methods.

Oracle10g: Build J2EE Applications 12-18

Deployment Descriptor

<?xml version = '1.0' encoding = 'windows-1252'?>


<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD
Enterprise JavaBeans 2.0//EN" "http://java.sun.com/dtd/ejbjar_2_0.dtd">
<ejb-jar>
<enterprise-beans>
<session>
<description>Session Bean ( Stateless ) </description>
<display-name>statelessejb</display-name>
<ejb-name>Statelessejb</ejb-name>
<home>StatelessejbHome</home>
<remote>Statelessejb</remote>
<ejb-class>StatelessejbBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
</session>
</enterprise-beans>
</ejb-jar>

12-19

Copyright 2004, Oracle. All rights reserved.

Deployment Descriptor
The code in the slide is an example of a deployment descriptor written in Extensible Markup
Language (XML) for the stateless session bean StatelessejbBean.
The <ejb-jar> tag is the root element that is defined for a deployment descriptor. The
body of the deployment descriptor is enclosed within the <ejb-jar> and </ejb-jar>
tags.
Between the <enterprise-beans> and </enterprise-beans> tags, you declare
the definition of the beans that are contained in this JAR file. In the above example, the code
between the <session> and </session> tags indicates that the JAR file contains a
session bean. Within these tags, there are tags for:
Optional description of the bean.
Mandatory logical name of the bean that is used by the container while diverting the
clients method calls to the appropriate bean on the server (Statelessejb).
Mandatory home interface, remote interface, and bean class names.
Mandatory session-type indicating that the bean is a stateless session bean. If the
bean is a stateful bean, then the session-type is stateful.
Mandatory transaction-type (applicable only to session beans), indicating
whether the transaction is managed by the container or by the bean.
Oracle10g: Build J2EE Applications 12-19

Client Application
To access methods on the bean instance, an EJB
client must perform the following operations:
Obtain access to the naming service (Java Naming
and Directory Interface [JNDI]) where the beans
home interface is published
Authenticate itself with the naming service
interface
Obtain a reference to the beans home interface
from the naming service by using the beans URL
Invoke the create() method on the home
interface
Invoke business methods

12-20

Copyright 2004, Oracle. All rights reserved.

Client Application
An EJB client cannot access an EJB method directly. It must obtain a bean reference by
using the create() method of a beans home interface, and then invoke the business
methods on the bean reference that have been obtained.
To use the create() method of a beans home interface, the client must first obtain the
reference to the home interface of the bean. When a bean is deployed in a server or
container, the server or container publishes the home interface of the bean in a publicly
available JNDI service. The create() method creates an instance of the bean in the server
and returns its reference to the client. The clients can obtain the reference to the bean home
interface by looking for it in the JNDI.
JNDI consists of several published objects that are arranged in a hierarchical manner. You
must know the URL of the object that you want to locate.

Oracle10g: Build J2EE Applications 12-20

Client Application for Stateless


Session Beans
...
public class StatelessejbClient
{
public static void main(String [] args)
{
StatelessejbClient statelessejbClient = new
StatelessejbClient();
try
{Context context = getInitialContext();
StatelessejbHome statelessejbHome =
(StatelessejbHome)PortableRemoteObject.narrow
(context.lookup("Statelessejb"),
StatelessejbHome.class);
//create 3 instances
Statelessejb obj[] = new Statelessejb[3];
for (int i=0;i<3;i++)
{ obj[i]= statelessejbHome.create(); }
...

12-21

Copyright 2004, Oracle. All rights reserved.

Client Application for Stateless Session Beans


The code in the slide shows a part of the client for a stateless session bean. The client
application imports classes in the javax.naming package that are necessary to create the
contexts and environment parameters for the JNDI naming service. Context is an interface
in the javax.naming package. All EJB clients that use JNDI methods to look up and
activate the remote or local objects must import this interface.
The first JNDI call to code is the one that gets a context object. The first context object that
you get is called the InitialContext and is bound to the root naming context of the
JNDI namespace. EJB home interfaces are published in the EJB server, arranged in a file
systemlike hierarchy. You get the root naming context by creating a new JNDI
InitialContext, as shown in the slide.
To find the Statlessejb home object in the context path, you use the lookup method.
The result of the lookup is cast to obtain the home interface by using the
javax.rmi.PortableRemoteObject.narrow method.

Oracle10g: Build J2EE Applications 12-21

Client Application for Stateless Session Beans (continued)


The lookup() method to obtain remote reference returns an Object type. The EJB 1.0
specification uses Java RMI type arguments and return types, assuming that the client and
server are Java applications. Because the clients can be written in any programming
language, in the EJB 2.0 specification, Java RMI-IIOP (Java RMI over IIOP) is the required
programming model to follow Common Object Request Broker Architecture (CORBA)
standards. Internet Inter-ORB Protocol (IIOP) requires the returned remote references from
any method to be narrowed to a specific type that can be used by any protocol that accesses
the bean. This can be implemented by using the
javax.rmi.PortableRemoteObject.narrow method. The narrow()method
takes two parameters: the remote reference to be narrowed and the type it to which it should
be narrowed. This method returns a stub that implements the specified remote reference,
which can then be cast to the required remote interface type. In the previous example, the
lookup() method returns an Object type homeObject for remote reference of
Statelessejb. This reference homeObject is then narrowed to
StatelessejbHome class and cast to the StatelessejbHome interface type.
You explicitly narrow the reference by using the narrow() method, only when a method
returns a general remote reference such as EJB home or EJB object. In this case, you must
narrow and cast the returned type to a more specific remote interface type, as shown in the
above example.
You do not explicitly narrow a remote reference if a method returns a specific remote
interface type.
You obtain reference to the home interface and remote interface and narrow the objects to
the EJB home and remote interfaces.

Oracle10g: Build J2EE Applications 12-22

Client Application for Stateless


Session Beans
...
// Invoke the business methods with each of the
// instances created to observe the state of each
// instance
for (int i=0;i<3;i++)
{
System.out.println("Value before increment for
object" + i + " "+ obj[i].getValue());
System.out.println( "Calling incrementValue with
object" + i+" " +obj[i].incrementValue());
System.out.println("Calling getValue with
object" + i+" " +obj[i].getValue()+"\n");
}
for (int i=0;i<3;i++)
{ obj[i].remove(); }
...

12-23

Copyright 2004, Oracle. All rights reserved.

Client Application for Stateless Session Beans (continued)


The code in the slide is the continuation of the client application for a stateless session bean.
The client code creates three instances and invokes the incrementValue() and
getValue() methods with each instance. Recollect that the variable value is initialized
to zero in the bean class.
The output of the client application is as follows:
Value before increment for object0 0
Calling incrementValue with object0
value incremented by 1
Calling getValue with object0 1
Value before increment for object1 1
Calling incrementValue with object1
value incremented by 1
Calling getValue with object1 2
Value before increment for object2 2
Calling incrementValue with object2
value incremented by 1
Calling getValue with object2 3
Oracle10g: Build J2EE Applications 12-23

Client Application for Stateless Session Beans (continued)


Initially the value is zero (initialized in the bean class). When object[0] calls the
incrementValue() method, the value is incremented to 1. When the method is invoked
with object[1], the container has not created another instance of the session bean. The
same bean is used to serve this client. Therefore, the value is incremented to 2, and so on.
The instance variable cannot be reinitialized to zero, because the create() method of a
stateless session bean does not take a parameter such as the create() method of a stateful
session bean.

Oracle10g: Build J2EE Applications 12-24

Life Cycle of a Stateful Session Bean

Does not
exist

setSessionContext(sessCtx),
and ejbCreate()

Container invokes
ejbRemove()

ejbPassivate()

Passivated
instances

Ready

ejbActivate()

12-25

Copyright 2004, Oracle. All rights reserved.

Life Cycle of a Stateful Session Bean


The client initiates the life cycle of the stateful session bean by invoking the create()
method. The EJB container instantiates the bean and calls the setSessionContext()
and ejbCreate() methods of the session bean. The client can now invoke business
methods on the session bean instance. When the objects are in the pool, the EJB container
can passivate the bean by moving it from memory to secondary storage. The container
invokes the ejbPassivate() method just before passivating the instance. If a client
invokes a business method on the bean while it is in the passive stage, the EJB container
activates the bean. It calls the ejbActivate()method.
To remove the bean instance, the container invokes the ejbRemove() method and the
bean instance is ready for garbage collection.

Oracle10g: Build J2EE Applications 12-25

Home Interface for Stateful Session Bean

import javax.ejb.EJBHome;
import java.rmi.RemoteException;
import javax.ejb.CreateException;
public interface StatefulejbHome extends
EJBHome
{
Statefulejb create(int x) throws
RemoteException, CreateException;
}

12-26

Copyright 2004, Oracle. All rights reserved.

Home Interface for Stateful Session Bean


This is the same example that was used to demonstrate the stateless session bean. The home
interface contains the create() method as in the case of a stateless session bean.
However, the difference is that the create() method of a stateful session bean can take
parameters. The create() method shown in the slide takes an integer as parameter to
initialize the value of the value variable.
The remote interface for the stateful session bean is the same as that for a stateless session
bean. The bean class for the stateful session bean implements the business methods as in a
stateless session bean. However, the implementation of the ejbCreate()method in the
bean class is as follows:
public void ejbCreate(int x)
{
value=x;
}

Oracle10g: Build J2EE Applications 12-26

Client Application for Stateful


Session Bean
...
Statefulejb obj[]= new Statefulejb[3];
for (int i=0;i<3;i++)
{ obj[i]= StatefulejbHome.create(0); }
for (int i=0;i<3;i++)
{
System.out.println("Value before increment for
object" + i + " "+ obj[i].getValue());
System.out.println( "Calling incrementValue with
object" + i+" " +obj[i].incrementValue());
System.out.println("Calling getValue with
object" + i+" " +obj[i].getValue()+"\n");
}
for (int i=0;i<3;i++)
{ obj[i].remove(); }
...

12-27

Copyright 2004, Oracle. All rights reserved.

Client Application for Stateful Session Bean


The slide shows a part of the client application that is used to invoke the business methods
of the bean. The bean instances are created by passing a value 0 in the create() method.
Therefore, the value for the variable value is initialized to zero. The following output is
displayed when you run the client application:
Value before increment for object0 0
Calling incrementValue with object0
value incremented by 1
Calling getValue with object0 1
Value before increment for object1 0
Calling incrementValue with object1
value incremented by 1
Calling getValue with object1 1
Value before increment for object2 0
Calling incrementValue with object2
value incremented by 1
Calling getValue with object2 1

Note that for all instances, the value variable is 0 and then incremented to 1, unlike in
stateless session beans.
Oracle10g: Build J2EE Applications 12-27

Summary

In this lesson, you should have learned how to:


Describe session beans
Differentiate stateless session beans from stateful
session beans
Develop a stateless session bean
Develop a client application to invoke a stateless
session bean

12-28

Copyright 2004, Oracle. All rights reserved.

Summary
In this lesson, you should have learned about session beans and the types of session beans.
You should have also learned to develop a stateless session bean and invoke it with a client
application.

Oracle10g: Build J2EE Applications 12-28

Practices 12-1 and 12-2: Overview

These practices cover the following topics:


Creating a session bean to validate a card
Creating a session bean to display the
first_name, last_name, email, and
department_name of an employee whose
employee_id is provided

12-29

Copyright 2004, Oracle. All rights reserved.

Oracle10g: Build J2EE Applications 12-29

Practice 12-1
The purpose of this practice is to create a stateless session bean that validates the entry made
for the customer card number. The bean should contain a business method that takes the
customer card number in the form of a string and validates the card. Note that this practice
does not validate the card number against the database. A card number can be alphanumeric.
A card is valid if:
The length of the number is nine characters.
It starts with AN, BN, CN, or LN
The last character is A
The rest of the characters are numbers and not letters
The workspace for this practice is practice12oneske.jws. Open the
validatecard project. This project contains the necessary skeleton files for this
practice.
1. Expand the validatecard node, select the ValidateCard EJB, and doubleclick ValidateCard.java in the Structure Pane to open it in the code editor. This
is the remote interface.
a. Import the java.rmi package.
b. Declare a method called validate(), which takes a string as parameter and
returns a string. This method should throw a RemoteException exception.
2. Add code to the bean class. Open ValidateCardBean.java in the code editor.
Implement the validate()method that is declared in the remote interface. This
method should verify that the card is valid. The conditions for the validity of the card
are given above.
3. Generate a sample Java client. Right-click the ValidateCard bean in the navigator
and select New Sample Java Client. Select Connect to OC4J Embedded in JDeveloper
if you are testing your EJB with the embedded OC4J, otherwise select Connect to
Remote Application Server. Click OK.
4. Invoke the validate()business method from the client application
ValidateCardClient.java:
Add code to the try block of the main()method to invoke the validate()
method. Invoke the method twice: once with a valid card number and once with an
invalid card number.
5. Test and run the application:
a. Right-click ValidateCard bean and select Make (optional).
b. Right-click ValidateCard bean and select Run.
c. Right-click the client application and select Run.

Oracle10g: Build J2EE Applications 12-30

Practice 12-1 (continued)


6. Sample Input/Output:
If the following lines are added to the client application:
System.out.println("Passing a valid customer card number
BN349672A ");
System.out.println(validateCard.validate("BN349672A"));
System.out.println("Passing an invalid customer card
number BN3496723A");
System.out.println(validateCard.validate("BN3496723A"));

The output is:


Passing a valid customer card number BN349672A
THANKYOU FOR PROVIDING YOUR CUSTOMER CARD NUMBER
Passing an invalid customer card number BN3496723A
Ensure that you enter right number of characters

Note: This is only a sample input/output. The error messages may be different
depending on your implementation.

Oracle10g: Build J2EE Applications 12-31

Practice 12-2
The purpose of this practice is to create a stateless session bean that interacts with the
database by using JDBC. So far you have used the oe schema for the practices. In this
practice, you create a connection to the hr schema and create the data source reference to it.
The bean should contain a business method that takes the employee_id and retrieves
first_name, last_name, email, and department_name from the EMPLOYEES
table and the DEPARTMENTS table. The business method returns an instance of
EmployeeDetails class. This instance has variables to hold the first name, last name, email, and department name of the employee.
Note: The EMPLOYEES table has many fields, some of them are first_name,
last_name, and email. However, the EMPLOYEES table does not contain the
department_name. The DEPARTMENTS table has department_name, and the
common field in both the EMPLOYEES and DEPARTMENTS table is department_id.
Therefore, you can join the two tables to obtain the department_name. For the
description of each of these tables, refer to Appendix B.
The workspace for this practice is practice12twoske.jws. Open the
employeedetails project and expand the employeedetails node. The Employee
bean contains the skeleton files that are required to implement the session bean.
1. Create the connection to use as the data source for the session bean:
a. In the Connection Navigator, right-click Database and select New Database
Connection. You see the Connection Wizard. Click Next.
b. Provide hr for Connection Name and select Oracle (JDBC) as Connection Type.
Click Next.
c. Provide the username and password as oraxx/oracle (as provided by your
instructor). Click Next.
d. Specify the Host Name, JDBC port, and SID, as indicated by your instructor.
Click Next.
e. Test the connection by clicking the Test Connection button. Click Finish.
2. Edit the EmployeeDetails.java file in the code editor:
a. Import java.io package.
b. Declare four string variables: fname, lname, email, and deptname.
c. Provide a constructor that takes parameters to initialize all four instance
variables.
d. Override the toString() method to provide a string representation of the
object.
3. Modify the remote interface:
a. Navigate to Employee.java and open it in the code editor.
b. Import the java.rmi package.
c. Declare a getDetails() method that takes an integer as argument and returns
an EmployeeDetails object. This method should throw the
RemoteException exception.

Oracle10g: Build J2EE Applications 12-32

Practice 12-2 (continued)


4. Modify the bean class:
a. Open the EmployeeBean.java file in the code editor.
b. Import the packages java.sql, javax.naming, javax.sql, and
employeedetails (contains the EmployeeDetails class).
c. Declare the following instance variables: Connection variable conn,
Statement variable st, and ResultSet variable rs.
5. Implement an establishConnection() method that returns a Connection
object as follows:
a. Declare variable ds of type DataSource.
b. Start a try block, and get the initial context and lookup for the data source
jdbc/hrDS. This code can throw a NamingException exception.
c. Get the connection by invoking the getConnection() method on the data
source. This can throw a SQLException exception. You can have two catch
blocks, or you can catch the generic exception.
d. Close the try block and add catch blocks.
e. Return the connection.
6. Implement the getDetails() method as follows:
a. It should take an integer as argument, which is the employee_id of an
employee, and return an instance of EmployeeDetails class.
b. Create a variable emp of type EmployeeDetails.
c. Start a try block. Call the establishConnection() method to initialize
the Connection object conn. Create a Statement with this object.
d. Execute the query to retrieve employee first_name, last_name, and
email from the EMPLOYEES table and department_name from the
DEPARTMENTS table.
e. Create an instance called EmployeeDetails class with first_name,
last_name, email, and department_name as parameters.
f. Close the try block and catch generic exception.
g. Return EmployeeDetails object emp.
7. Edit the client application EmployeeClient.java in the code editor. Invoke the
getDetails()business method:
a. Add code to the try block of the main() method to invoke the
getDetails() method.
8. Test and run the application:
a. Right-click Employee bean and select Make (optional).
b. Right-click Employee bean and select Run.
c. Right-click the client application and select Run.
9. Sample Input/Output:
If the following line is added to the client application:
System.out.println(employee.getDetails(119));
The output is:
Karen Colmenares KCOLMENA Purchasing

Oracle10g: Build J2EE Applications 12-33

Das könnte Ihnen auch gefallen