Professional Documents
Culture Documents
Version: J2EE/HANDOUT/0605/2.0
Date: 14-06-05
TABLE OF CONTENTS
Introduction .........................................................................................................................5
Multi-tiered Architecture......................................................................................................6
Client Tier..........................................................................................................................7
Web Tier ...........................................................................................................................8
Business Tier.....................................................................................................................8
EIS Tier.............................................................................................................................8
J2EE API...........................................................................................................................8
Enterprise Java Beans ..................................................................................................... 12
Session ...........................................................................................................................12
Entity...............................................................................................................................14
SUMMARY ......................................................................................................................16
Chapter 2: HTML ................................................................................................................ 17
Learning Objectives.......................................................................................................... 17
Introduction......................................................................................................................17
Create first HTML document .............................................................................................19
Elements of HTML ........................................................................................................... 20
Create Hyperlinks............................................................................................................. 21
Creating a mail to link....................................................................................................... 22
Create Images ................................................................................................................. 22
The Alt Attribute ............................................................................................................... 22
Create Lists .....................................................................................................................23
Create Forms...................................................................................................................25
Create Form Elements ..................................................................................................... 25
Create Tables .................................................................................................................. 27
Create the HTML <FONT> tag and CSS............................................................................ 28
SUMMARY ......................................................................................................................30
Chapter 3: Servlets ............................................................................................................ 31
Learning Objectives.......................................................................................................... 31
Introduction......................................................................................................................31
Servlet architecture .......................................................................................................... 32
Servlet Request & Response Model .................................................................................. 32
Using the HttpServletRequest and HttpServletResponse Object.......................................... 33
Writing a simple Servlet.................................................................................................... 34
Complex Example............................................................................................................ 35
Servlet life cycle............................................................................................................... 36
Web.xml configuration ...................................................................................................... 37
Servlet scope objects ....................................................................................................... 38
Session ...........................................................................................................................40
Carrying forward a Request ..............................................................................................42
Form-Servlet Integration ................................................................................................... 45
SUMMARY ......................................................................................................................47
Chapter 4: JSP...................................................................................................................48
Learning Objectives.......................................................................................................... 48
Introduction......................................................................................................................48
Learning the Basic Syntax ................................................................................................51
JSP Syntax Elements. ...................................................................................................... 52
Predefined Variables ........................................................................................................ 57
THE JSP PAGE LIFE CYCLE ...........................................................................................58
UNDERSTANDING JSP................................................................................................... 60
JAVABEANS: A BRIEF OVERVIEW.................................................................................. 65
WEBSITES.................................................................................................................... 141
BOOKS ......................................................................................................................... 141
STUDENT NOTES: ........................................................................................................... 142
Introduction
Target Audience
The module is specifically aimed at Entry Level Trainee Programmers.
Module Objectives
The module seeks to achieve the following objectives:
q Explain the various utilities and its functions
q Familiarize with data set and system related utilities
q Implement the utilities for basic operations
Pre-requisite
The module requires a prior knowledge of the following applications in a student:
q Programming in Cobol or any other mainframe language
q MVS operating system
Learning Objectives
After completing this chapter, you will be able to:
q Understand Multi-tired Architecture
q Know about J2EE API
q Understand about session and entity
Introduction
J2EE stands for Java 2 Enterprise Edition. It is a specification provided by Sun Microsystems
for server side development in Java that is deployable in distributed environments. The latest
available version is J2EE version 1.4.
One unified specification of J2EE has helped to create applications that are vendor
independent. There are several application servers currently available in the market on which
a server side Java application can run. IBM Websphere, BEA Weblogic, Sun Java System
Application Server, Oracle 9i etc are most common examples. All these servers are J2EE
compliant servers as the vendors for these servers (IBM, BEA, Sun, Oracle) have made the
servers as J2EE compatible. Due to this, an application developed with J2EE compliance ad
running on one server can run on another server that supports J2EE, without any change (at
least in theory).
Multi-tiered Architecture
Before delving deeper into J2EE, it would be ideal to understand the multi-tier architecture
and how J2EE aligns to these tiers. The block diagram (Diagram 1) shows the schematic
representation of the multi-tier application. The left side shows the multi-tier representations
and the right side shows the equivalent J2EE layers.
Intranet or
Internet
Intranet
Diagram 1
Client Tier
Client tier resides on one side of the network and the servers reside on the other. It is
represented by the sum total of all the client machines that are accessing the server where
the application is running. A program might be running on the client side that executes the
operations of the client tier. A browser is an ideal example of such an application. The client
tier can be further classified into the following:-
Thin client
A thin client has minimal processing logic. It depends completely on the server to do the
processing. An ideal thin client will just pass on events to the server requesting for data and
renders the data that is sent while the server responds. Examples of thin client are HTML,
XML, Javascript, etc running on a browser.
Thick client
A thick client will involve some processing at the client side. The server is contacted for data
retrieval. Number crunching, calculations, data manipulations etc will happen on the client
side. For a client, this may provide faster response than a thin client because the server is
contacted less frequently as compared to thin client.
Out of the two, a thin client is always preferred. Thin client model encourages the server to do
all the processing. This makes the application more maintainable and load balanced. If the
processing logic has to change, a thick client will have to under go change for every client
machine in the tier. But in thin client, the change is centralized and in the server. Also, a client
machine may not be well equipped to handle operations that require lot of processor capacity.
But this can be easily managed at server side as servers are usually installed with more
capable processors and memory. Also load balancing is possible at server side where
multiple servers can be added to distribute the load.
Web Tier
J2EE web components are either servlets or pages created using JSP technology (JSP
pages). Servlets are Java programming language classes that dynamically process requests
and construct responses. JSP pages are text-based documents that execute as servlets but
allow a more natural approach to creating static content.
Static HTML pages and applets are bundled with web components during application
assembly but are not considered web components by the J2EE specification. Server-side
utility classes can also be bundled with web components and, like HTML pages, are not
considered web components.
Business Tier
This includes the business code, which is logic that solves or meets the needs of a particular
business domain such as banking, retail, or finance, is handled by enterprise beans running in
the business tier.
EIS Tier
The enterprise information system tier handles EIS software and includes enterprise
infrastructure systems such as enterprise resource planning (ERP), mainframe transaction
processing, database systems, and other legacy information systems. For example, J2EE
application components might need access to enterprise information systems for database
connectivity.
J2EE API
The J2EE platform supports the multi-tier architecture by supporting a wide range of APIs that
will provide for the functionalities of the various tiers of the distributed system.
There are three kinds of enterprise beans: session beans, entity beans, and message-driven
beans. Enterprise beans often interact with databases. One of the benefits of entity beans is
that you do not have to write any SQL code or use the JDBC API (see JDBC API) directly to
perform database access operations; the EJB container handles this for you. However, if you
override the default container-managed persistence for any reason, you will need to use the
JDBC API. Also, if you choose to have a session bean access the database, you must use
the JDBC API.
JavaMail API
J2EE applications use the JavaMail API to send email notifications. The JavaMail API has two
parts: an application-level interface used by the application components to send mail, and a
service provider interface. The J2EE platform includes JavaMail with a service provider that
allows application components to send Internet mail.
JavaBeans Activation Framework
The JavaBeans Activation Framework (JAF) is included because JavaMail uses it. JAF
provides standard services to determine the type of an arbitrary piece of data, encapsulate
access to it, discover the operations available on it, and create the appropriate JavaBeans
component to perform those operations.
JAXP also provides namespace support, which lets you work with schemas that might
otherwise have naming conflicts. Designed to be flexible, JAXP lets you use any XML-
compliant parser or XSL processor from within your application and supports the W3C
©Copyright 2004, Cognizant Academy, All Rights Reserved 9
J2EE
schema. You can find information on the W3C schema at this URL:
http://www.w3.org/XML/Schema.
JAX-RPC relies on the HTTP transport protocol. Taking that a step further, JAX-RPC lets you
create service applications that combine HTTP with a Java technology version of the Secure
Socket Layer (SSL) and Transport Layer Security (TLS) protocols to establish basic or mutual
authentication. SSL and TLS ensure message integrity by providing data encryption with
client and server authentication capabilities.
Authentication is a measured way to verify whether a party is eligible and able to access
certain information as a way to protect against the fraudulent use of a system or the
fraudulent transmission of information. Information transported across the Internet is
especially vulnerable to being intercepted and misused, so it's very important to configure a
JAX-RPC web service to protect data in transit.
Additionally, businesses can submit material to be shared and search for material that others
have submitted. Standards groups have developed schemas for particular kinds of XML
documents; two businesses might, for example, agree to use the schema for their industry's
standard purchase order form. Because the schema is stored in a standard business registry,
both parties can use JAXR to access it.
JDBC API
The JDBC API lets you invoke SQL commands from Java programing language methods.
You use the JDBC API in an enterprise bean when you override the default container-
managed persistence or have a session bean access the database. With container-managed
persistence, database access operations are handled by the container, and your enterprise
bean implementation contains no JDBC code or SQL commands. You can also use the JDBC
API from a servlet or a JSP page to access the database directly without going through an
enterprise bean.
The JDBC API has two parts: an application-level interface used by the application
components to access a database, and a service provider interface to attach a JDBC driver to
the J2EE platform.
A J2EE component locates its environment naming context using JNDI interfaces. A
component creates a javax.naming.InitialContext object and looks up the environment naming
context in InitialContext under the name java:comp/env. A component's naming environment
is stored directly in the environment naming context or in any of its direct or indirect
subcontexts.
A J2EE component can access named system-provided and user-defined objects. The
names of system-provided objects, such as JTA UserTransaction objects, are stored in the
environment naming context, java:comp/env. The J2EE platform allows a component to name
user-defined objects, such as enterprise beans, environment entries, JDBC DataSource
objects, and message connections. An object should be named within a subcontext of the
naming environment according to the type of the object. For example, enterprise beans are
named within the subcontext java:comp/env/ejb, and JDBC DataSource references in the
subcontext java:comp/env/jdbc.
Because JNDI is independent of any specific implementation, applications can use JNDI to
access multiple naming and directory services, including existing naming and directory
services such as LDAP, NDS, DNS, and NIS. This allows J2EE applications to coexist with
legacy applications and systems.
Session
A session bean represents a single client inside the Application Server. To access an
application that is deployed on the server, the client invokes the session bean's methods. The
session bean performs work for its client, shielding the client from complexity by executing
business tasks inside the server.
As its name suggests, a session bean is similar to an interactive session. A session bean is
not shared; it can have only one client, in the same way that an interactive session can have
only one user. Like an interactive session, a session bean is not persistent. (That is, its data is
not saved to a database.) When the client terminates, its session bean appears to terminate
and is no longer associated with the client.
Stateless session
A stateless session bean does not maintain a conversational state for the client. When a
client invokes the method of a stateless bean, the bean's instance variables may contain a
state, but only for the duration of the invocation. When the method is finished, the state is no
longer retained. Except during method invocation, all instances of a stateless bean are
equivalent, allowing the EJB container to assign an instance to any client.
Because stateless session beans can support multiple clients, they can offer better scalability
for applications that require large numbers of clients. Typically, an application requires fewer
stateless session beans than stateful session beans to support the same number of clients.
At times, the EJB container may write a stateful session bean to secondary storage. However,
stateless session beans are never written to secondary storage. Therefore, stateless beans
may offer better performance than stateful beans.
A stateless session bean can implement a web service, but other types of enterprise beans
cannot.
Stateful session
The state of an object consists of the values of its instance variables. In a stateful session
bean, the instance variables represent the state of a unique client-bean session. Because the
client interacts with its bean, this state is often called the conversational state.
The state is retained for the duration of the client-bean session. If the client removes the bean
or terminates, the session ends and the state disappears. This transient nature of the state is
not a problem, however, because when the conversation between the client and the bean
ends there is no need to retain the state.
When to use
In general, you should use a session bean if the following circumstances hold:
q At any given time, only one client has access to the bean instance.
q The state of the bean is not persistent, existing only for a short period (perhaps a
few hours).
q The bean implements a web service.
Stateful session beans are appropriate if any of the following conditions are true:
q The bean's state represents the interaction between the bean and a specific
client.
q The bean needs to hold information about the client across method invocations.
q The bean mediates between the client and the other components of the
application, presenting a simplified view to the client.
q Behind the scenes, the bean manages the work flow of several enterprise beans.
To improve performance, you might choose a stateless session bean if it has any of these
traits:
q The bean's state has no data for a specific client.
q In a single method invocation, the bean performs a generic task for all clients. For
example, you might use a stateless session bean to send an email that confirms
an online order.
q The bean fetches from a database a set of read-only data that is often used by
clients.
There are two types of persistence for entity beans: bean-managed and container-managed.
With bean-managed persistence, the entity bean code that you write contains the calls that
access the database. If your bean has container-managed persistence, the EJB container
automatically generates the necessary database access calls. The code that you write for the
entity bean does not include these calls.
Primary key
Each entity bean has a unique object identifier. A customer entity bean, for example, might be
identified by a customer number. The unique identifier, or primary key, enables the client to
locate a particular entity bean.
Relationships
Like a table in a relational database, an entity bean may be related to other entity beans. You
implement relationships differently for entity beans with bean-managed persistence than
those with container-managed persistence. With bean-managed persistence, the code that
you write implements the relationships. But with container-managed persistence, the EJB
container takes care of the relationships for you. For this reason, relationships in entity beans
with container-managed persistence are often referred to as container-managed
relationships.
When to use
The entity bean can be used under the following situations:-
q The bean represents a business entity and not a procedure. For example,
CreditCardBean would be an entity bean, but CreditCardVerifierBean would be a
session bean.
q The bean's state must be persistent. If the bean instance terminates or if the
Application Server is shut down, the bean's state still exists in persistent storage
(a database).
Message driven
A message-driven bean is an enterprise bean that allows J2EE applications to process
messages asynchronously. It normally acts as a JMS message listener, which is similar to an
event listener except that it receives JMS messages instead of events. The messages can be
sent by any J2EE component--an application client, another enterprise bean, or a web
component--or by a JMS application or system that does not use J2EE technology. Message-
driven beans can process either JMS messages or other kinds of messages.
The most visible difference between message-driven beans and session and entity beans is
that clients do not access message-driven beans through interfaces. Unlike a session or
entity bean, a message-driven bean has only a bean class.
When to use
Session beans and entity beans allow you to send JMS messages and to receive them
synchronously, but not asynchronously. To avoid tying up server resources, you may prefer
not to use blocking synchronous receives in a server-side component. To receive messages
asynchronously, use a message-driven bean.
The java:comp/env name is bound to the environment naming context of this client
component.
SUMMARY
After completing this chapter, you will have learned:
q Understand Multi-tired Architecture
q Know about J2EE API
q Understand about session and entity
Chapter 2: HTML
Learning Objectives
After completing this chapter, you will able to:
q Create HTML Pages yourself
Introduction
What is the World Wide Web?
The World Wide Web (Web) is a network of information resources. The Web relies on three
mechanisms to make these resources readily available to the widest possible audience:
1. A uniform naming scheme for locating resources on the Web (e.g., URIs).
2. Protocols, for access to named resources over the Web (e.g., HTTP).
3. Hypertext, for easy navigation among resources (e.g., HTML).
Introduction to URIs
Every resource available on the Web -- HTML document, image, video clip, program, etc. --
has an address that may be encoded by a Universal Resource Identifier, or "URI".
Consider the URI that designates the W3C Technical Reports page:
http://www.w3.org/TR
This URI may be read as follows: There is a document available via the HTTP protocol (see
[RFC2616]), residing on the machine www.w3.org, accessible via the path "/TR". Other
schemes you may see in HTML documents include "mailto" for email and "ftp" for FTP.
Here is another example of a URI. This one refers to a user's mailbox:
To publish information for global distribution, one needs a universally understood language, a
kind of publishing mother tongue that all computers may potentially understand. The
publishing language used by the World Wide Web is HTML (from HyperText Markup
Language).
Fragment identifiers
Some URIs refers to a location within a resource. This kind of URI ends with "#" followed by
an anchor identifier (called the fragment identifier). For instance, here is a URI pointing to an
anchor named section_2:
http://somesite.com/html/top.html#section_2
Relative URIs
A relative URI doesn't contain any naming scheme information. Its path generally refers to a
resource on the same machine as the current document. Relative URIs may contain relative
path components (e.g., ".." means one level up in the hierarchy defined by the path), and may
contain fragment Identifiers.
Relative URIs are resolved to full URI using a base URI. As an example of relative URI
resolution, assume we have the base URI
http://www.acme.com/support/intro.html
<A href="suppliers.html">Suppliers</A>
http://www.acme.com/support/suppliers.html,
Application of URIs
In HTML, URIs are used to:
q Link to another document or resource
q Link to an external style sheet or script
q Include an image, object, or applet in a page
q Create an image map.
q Submit a form.
q Create a frame document.
q Cite an external reference.
q Refer to metadata conventions describing a document.
Contents
The content inside the html is mainly divided into two parts
head – Contains the information about the document
Body – Contains that are to be displayed in the browser
First HTML should at least have this
<html>
<head>
<title>page title</title>
</head>
<body>
Every HTML document is required by the HTML standard to have a title. The title should
instantly tell the reader what the document is about.
The above forms the basic skeleton for a HTML file. The file should be saved as htm or html.
HTML tags are not case sensitive; <b> means the same as <B>. But, the World Wide Web
Consortium (W3C) recommends lowercase tags in their HTML 4 recommendation, and
XHTML (the next generation HTML) demands lowercase tags.
Elements of HTML
Create HTML and text
Comments can be added with the <!—tag.
<!-- This is a comment -->
Headings are defined with the <h1> to <h6> tags. <h1> defines the largest heading. <h6>
defines the smallest heading.
<h1>This is a heading</h1>
HTML automatically adds an extra blank line before and after a heading.
HTML display will not insert line breaks or paragraph breaks on its own – they have to be
inserted using tags in the HTML file. <br> would insert a line break. The <br> tag is used
when you want to end a line, but don't want to start a new paragraph. Paragraph elements
are defined by the p tag. <p> ( Text goes here) </p>.
HTML automatically adds an extra blank line before and after a paragraph. Some text
formatting tags :
<b>This text is bold</b><br>
<pre>This is
preformatted text.
It preserves both spaces
and line breaks.
</pre>
The <a> tag is used to create an anchor to link from, the href attribute is used to address the
document to link to, and the words between the open and close of the anchor tag will be
displayed as a hyperlink.
This anchor defines a link to the Cognizant website:
<a href="http://www.cognizant.com/">Visit us at the
Cognizant website!</a>
The Target Attribute With the target attribute, we can define where the linked document will
be opened. The line below will open the document in a new browser window:
<a href="http://www.cognizant.com/" target="_blank">
Visit us at the Cognizant website!</a>
A hyperlink to the Contact Us Section from WITHIN the file "html. " will look like this:
<a href="#Contact">Contact Us!</a>
A trailing slash should always be added to subfolder references. If we link like this:
href="http://www.cognizant.com/html"
Two HTTP requests to the server will be generated, because the server will add a slash to the
address and create a new request like this:
href= http://www.cognizant.com/html/
Named anchors are often used to create "table of contents" at the beginning of a large
document. Each chapter within the document is given a named anchor, and links to each of
these anchors are put at the top of the document. If a browser cannot find a named anchor
that has been specified, it goes to the top of the document. No error occurs.
This will generate a hyperlink that will directly open an email client with Hello Again as the
Subject. This is another, more complicated mailto link:
<a href="mailto:someone@cognizant.com?cc=someoneelse
@cognizant.com&bcc=andsomeoneelse2@cognizant.com&subj
ect=Customer%20Complaint&body=I%20wish%20to%20registe
r%20a%20product%20complaint.">Send mail!</a>
Create Images
In HTML, images are defined with the <img> tag.
The <img> tag is empty, which means that it contains attributes only and it has no closing tag.
To display an image on a page, we need to use the src attribute. Src stands for "source". The
value of the src attribute is the URL of the image we want to display on ther page. The syntax
of defining an image:
<img src="url">
The URL points to the location where the image is stored. An image named "vertical.gif"
located in the directory "images" on "www.cognizant.com" has the URL:
http://www.cognizant.com/images/vertical.gif.
The browser puts the image where the image tag occurs in the document. If an image tag is
put between two paragraphs, the browser shows the first paragraph, then the image, and then
the second paragraph.
The "alt" attribute tells the reader what he or she is missing on a page if the browser can't
load images. The browser will then display the alternate text instead of the image. It is a good
practice to include the "alt" attribute for each image on a page, to improve the display and
usefulness of the document for people who have text-only browsers.
Best Practice
Loading images take time, so images must be used sparingly. Wherever possible, we must
use thumbnails that then open up into bigger images when clicked on.
<body background="background.jpg">
Both gif and jpg files can be used as HTML backgrounds. If the image is smaller than the
page, the image will repeat itself.
3. Aligning an Image
<img src ="/images/xhtml.gif" align="bottom"
width="100" height="50">
OR
<img src ="/images/xhtml.gif" align="middle"
width="100" height="50">
Create Lists
Unordered Lists
An unordered list is a list of items. The list items are marked with bullets. An unordered list
starts with the <ul> tag. Each list item starts with the <li> tag.
<ul>
<li>Operating Systems</li>
<li>Client Server</li>
</ul>
Inside a list item we can put paragraphs, line breaks, images, links, other lists, etc.
Ordered Lists
An ordered list is a numbered list of items. The list items are marked with numbers. An
ordered list starts with the <ol> tag. Each list item starts with the <li> tag.
<ol>
<li> Operating Systems </li>
<li> Client Server </li>
</ol>
Definition Lists
A definition list is not a list of items. This is a list of terms and explanation of the terms also
called a glossary list.
A definition list starts with the <dl> tag. Each definition-list term starts with the <dt> tag. Each
definition-list definition starts with the <dd> tag.
<dl>
<dt>Operating systems</dt>
<dd>Duration: 8 hours Coverage: Operating System
concepts and Basics</dd>
<dt>Client Server</dt>
<dd>Duration : 8 hours Coverage: Evolution upto n
tier systems</dd>
</dl>
Inside a definition-list definition (the <dd> tag) we can put paragraphs, line breaks, images,
links, other lists, etc.
Different Lists:
For a list numbered as A, B, C
<h4>Letters list:</h4>
<ol type="A">
<li>Tim Berners Lee</li>
<li>Judy Brewer</li>
<li>Steve Bratt </li>
<li>Daniel Dardailler</li>
</ol>
Create Forms
A form is an area that contains form elements. Form elements are elements that allow the
user to enter information (like text fields, textarea, fields, drop-down menus, radio buttons,
checkboxes, etc.) in a form. Forms are typically used for registration of new users, providing
payment details , answering surveys, submitting feedback etc on websites. Forms are an
important part of website interaction and enhance visitor experience.
If some characters are typed in the text field above, and "Submit" button clicked, input will be
sent to a page called " Search_Input_Form1.asp ". That page will show the received input or
process it in some way.
Text Fields
Text fields are used when you want the user to type letters, numbers, etc. in a form.
<form>
First name:
<input type="text" name="firstname">
<br>
Last name:
<input type="text" name="lastname">
</form>
The form itself will not be visible. The default number of characters is 20 and can be set by
the attribute “size”.
Radio Buttons
Radio Buttons are used when the user has to select one of a limited number of choices
(Mutually Exclusive Options).
<form>
<input type="radio" name="sex" value="male"> Male
<br>
<input type="radio" name="sex" value="female"> Female
</form>
Textarea
A text area is a like a text box but can be scollable and has a wrap option.
<textarea rows = “10” columns = “30”>
A textarea is like a scrollable text box and upto 255
characters can be displayed
</textarea>
Create Tables
Tables are a good way of displaying text in cells or to align text on a page as HTML is
equipped to control text inherently. Table attributes are:
q Align
q bgcolor
q border
q bordercolor
q cellpadding
q cellspacing
q height
q width
Sometimes, a table may not be symmetric and need some columns or rows to be merged .
This is achieved by the <td colspan = “some number”> or <td rowspan = “some number”>
attribute.
The table in the page below was generated by the following HTML:
Cascading Style Sheets (CSS) is a simple mechanism for adding style (e.g. fonts, colors,
spacing) to Web documents. Setting the color of the text and the background: This can be
done by using the STYLE element to set style properties for the document's tags:
<style type="text/css">
body { color: black; background: white; }
</style>
The text between the <style> and </style> is written in special notation for style rules. Each
rule starts with a tag name followed by a list of style properties bracketed by { and }. In this
example, the rule matches the body tag. The body tag provides the basis for setting the
overall look and feel of the Web page.
Each style property starts with the property's name, then a colon and lastly the value for this
property. When there is more than one style property in the list, you need to use a semicolon
between each of them to delimit one property from the next. In this example, there are two
properties - "color" which sets the color of the text, and "background" which sets the color of
the page background. Colors can be given as names or as numerical values, for instance
rgb(255,204, 204) which is light pink. The 3 numbers correspond to red, green and blue
respectively in the range 0 to 255. But as a best practice, we should use a hexadecimal
notation, where the same color can also be written as #FFCCCC.
Note that the style element must be placed in the document's head along with the title
element. It shouldn't be placed within the body.
If the same styles are to be used for several Web pages it is worth considering using a
separate style sheet which can then be linked from each page. This can be done as as
follows:
The LINK tag should be placed in the document's head. The rel attribute must be set to the
value "stylesheet" to allow the browser to recognize that the href attribute gives the Web
address (URL) for the style sheet.
Font styles
The most common styles are to place text in italic or bold. Most browsers render the em tag in
italic and the strong tag in bold. Let's assume that we want em to appear in bold italic and
strong in bold uppercase :
h2 { text-transform: lowercase; }
In this example, important headings would preferably be shown in Garamond, failing that in
Times New Roman, and if that is unavailable in the browsers default serif font. Paragraph text
would appear in Verdana or if that is unavailable in the browser's default sans-serif font. The
legibility of different fonts generally depends more on the height of lower case letters than on
the font size itself. Fonts like Verdana are much more legible than ones like "Times New
Roman".
This example has three style rules. One for the body, one for h1 (used for the most important
headings) and one for the rest of the headings (h2, h3, h4, h5 and h6). The margins for the
headings are additive to the margins for the body. Negative values are used to move the start
of the headings to the left of the margin set for the body.
SUMMARY
q HTML is Hypertext Markup Language – the language on which the WWW and the
Internet are based on.
q HTML is all about display of text and does not possess programming capabilities
q The HTML standards are set by W3C and the standard is moving towards a
hybrid of XML and HTML called XHTML
q HTML consists of tags, attributes with name value pairs and can be understood
by browsers.
q Most tags are a pair – starting tag and closing tag
q Cascading stylesheets are now a standard for defining look and feel of HTML
pages
Chapter 3: Servlets
Learning Objectives
After completing this chapter, you will be able to:
q Understand Servlet Architecture
q Know Servlet lifecycle and how to write Servlet
q Know Web.xml Configuration
q Understand Servlet scope and Session
Introduction
Servlets are Java technology’s answer to Common Gateway Interface (CGI) programming.
They are programs that run on a Web server, acting as a middle layer between a request
coming from a Web browser or other HTTP client and databases or applications on the HTTP
server. Their job is to:
q Read any data sent by the user. This data is usually entered in a form on a
Webpage, but could also come from a Java applet or a custom HTTP client
program.
q Look up any other information about the request that is embedded in the HTTP
request. This information includes details about browser capabilities, cookies, the
host name of the requesting client, and so forth.
q Generate the results. This process may require talking to a database, executing
an RMI or CORBA call, invoking a legacy application, or computing the response
directly.
q Format the results inside a document. In most cases, this involves embedding the
information inside an HTML page.
q Set the appropriate HTTP response parameters. This means telling the browser
what type of document is being returned (e.g., HTML), setting cookies and
caching parameters, and other such tasks.
q Send the document back to the client. This document may be sent in text format
(HTML), binary format (GIF images), or even in a compressed format like gzip
that is layered on top of some other underlying format.
Returning pre-built documents can satisfy many client requests, and the server would handle
these requests without invoking servlets. In many cases, however, a static result is not
sufficient, and a page needs to be generated for each request. There are a number of
reasons why Web pages need to be built on the fly like this:
q The Web page is based on data submitted by the user. For instance, the results
page from search engines and order-confirmation pages at on-line stores are
specific to particular user requests. The Web page is derived from data that
changes frequently. For example, a weather report or news headlines page might
build the page dynamically, perhaps returning a previously built page if it is still up
to date.
q The Web page uses information from corporate databases or other server-side
sources.For example, an e-commerce site could use a servlet to build a Web
page that lists the current price and availability of each item that is for sale.
q In principle, servlets are not restricted to Web or application servers that handle
HTTP requests, but can be used for other types of servers as well. For example,
servlets could be embedded in mail or FTP servers to extend their functionality.
Servlet architecture
The featured component created with the servlet API is the servlet itself. A servlet is an
object that extends either the javax.servlet.GenericServlet class or the
javax.servlet.http.HttpServlet class. The javax.servlet.GenericServlet class defines methods
for building generic, protocol-independent servlets. The javax.servlet.http.HttpServlet class
extends this class to provide HTTP-specific methods. The diagram in following figure
illustrates the hierarchy of a typical HTTP servlet and the relationships and functionality
exposed by the classes in the hierarchy.
Class hierarchy
As you can see, the GenericServlet class defines generic server-side operations; the
HttpServlet extends this to define HTTP-specific operations; and application-specific servlets
extend this to provide application-specific operations. We will be referring to servlets created
for the HTTP environment throughout this article.
server dispatches a request to a servlet, it invokes the servlet’s service () method. A generic
servlet should override its service () method to handle requests as appropriate for the servlet.
The service () method accepts two parameters: a request object and a response object. The
request object tells the servlet about the request, while the response object is used to return a
response. Figure shows how a generic servlet handles requests.
In contrast, an HTTP servlet usually does not override the service () method. Instead, it
overrides doGet () to handle GET requests and doPost () to handle POST requests. An HTTP
servlet can override either or both of these methods, depending on the type of requests it
needs to handle. The service () method of HttpServlet handles the setup and dispatching t o
all the doXXX () methods, which is why it usually should not be overridden. Figure shows how
an HTTP servlet handles GET and POST requests.
An HTTP servlet can override the doPut () and doDelete () methods to handle PUT and
DELETE requests, respectively. However, HTTP servlets generally don’t touch doHead (),
doTrace (), or doOptions (). For these, the default implementations are almost always
sufficient.
methods, and they provide a variety of methods for accessing and manipulating HTTP
headers, attributes, URL parameters, etc.
Below are some examples of the most commonly used methods of the HttpServletRequest
and HttpServletResponse classes. (The naming conventions used for the HttpServletRequest
and HttpServletResponse objects below are standard practice. If desired, object instances
can be renamed, such res and req.
q response.getWriter()
This method returns a PrintWriter object, which is used for your response to the client. Once
PrintWriter out = response.getWriter(); is used, out.println("lt;HTMLgt;"); ..
out.println("lt;/HTMLgt;"); can be used.
q request.getParameter()
This following example shows how to assign the value of a request parameter named
parName to a string named parValue using the getParameter method.
String parValue = request.getParameter("parName").
The value in parValue is the string representation of the parameter associated to parName or
is null if parName does not exist. In the case of multiple values associated with the name, the
first value is returned. To obtain all of the values in undetermined order, use the String[]
getParameterValues("parName").
q response.setContentType()
How does the client know what to do with the returned output? The Internet is used to
transport thousands of different flavors of information. The client is given a hint by setting an
attribute of the output, namely its content type. HTML has a content type of text/html, normal
text text/plain and plain binary data application/octet-stream. The list of possible attributes is
known as MIME types.
To tell the client that the output is to be treated as HTML, the following object should be used:
response.setContentType("text/html")
out.println("lt;HTMLgt;");
out.println("lt;HEADgt;lt;TITLEgt;HelloWorld
Outputlt;/TITLEgt;lt;/HEADgt;");
out.println("lt;BODYgt;");
out.println("lt;H1gt;Hello World!lt;/H1gt;");
out.println("lt;/BODYgt;");
out.println("lt;/HTMLgt;");
out.close();
}
}
Complex Example
In this example, two types of request will be served, namely the request for a simple page
with a form in it via a GET request and process the form with some simple validation via a
POST request. The methods doGet and doPost are both implemented in the code below.
By passing the servlet two parameters, errorMsg and niceMsg, the servlet will be more
flexible with the messages that are passed back to the client as a result of the validation. The
way in which the init parameters are picked up is illustrated in the init method of this example.
There is also a helper method, createForm, used to remove the form generation away from
the actual request methods. It is used by both of the request methods to generate the form.
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class FormServlet extends HttpServlet
{
private String errorMsg =
tmp = config.getInitParameter("niceMsg");
if(tmp != null) {
beNice = tmp;
}
}
public void destroy()
{
// although I don't actually need to clear anything
up here
// this is the method to do it in.
}
public void doGet(HttpServletRequest
req,HttpServletResponse resp)
throws ServletException, IOException
{
resp.setContentType("text/html");
PrintWriter out = resp.getWriter();
out.println("");
out.println("");
out.println(createForm("", "", ""));
out.println(""):
}
It’s perfectly legal for a servlet to be loaded, created, and instantiated in its own JVM, only to
be destroyed and garbage collected without handling any client requests or after handling just
one request. Why not use a constructor instead? Well, in JDK 1.0 (for which servlets were
originally written), constructors for dynamically loaded Java classes (such as servlets)
couldn’t accept arguments. So, in order to provide a new servlet any information about itself
and its environment, a server had to call a servlet’s init () method and pass along an object
those implements the ServletConfig interface. Also, Java doesn’t allow interfaces to declare
constructors. This means that the javax.servlet. Servlet interface cannot declare a constructor
that accepts a ServletConfig parameter. It has to declare another method, like init (). It’s still
possible, of course, for you to define constructors for your servlets, but in the constructor you
don’t have access to the ServletConfig object or the ability to throw a ServletException. This
ServletConfig object supplies a servlet with information about its initialization (init)
parameters. These parameters are given to the servlet itself and are not associated with any
single request. They can specify initial values, such as where a counter should begin
counting, or default values, perhaps a template to use when not specified by the request.
The server calls a servlet’s destroy () method when the servlet is about to be unloaded. In the
destroy () method, a servlet should free any resources it has acquired that will not be garbage
collected. The destroy () method also gives a servlet a chance to write out its unsaved cached
information or any persistent information that should be read during the next call to init ().
Web.xml configuration
Servlets are the pure Java solution to handle web requests. Many application will use servlets
instead of JSP and others will use servlets in conjunction with JSP. Experienced JSP
programmers use servlets in conjunction with JSP to create clearer and simpler applications.
The servlets handle Java processing: form handing, calculation and database queries. JSP
formats the results. Servlets belong in WEB-INF/classes. WEB-INF/classes is the standard
location for servlets and other Java classes
“WEB-INF/classes/test/ “ looks as
WEB-INF/classes/test/HelloServlet.java
package test;
import java.io.*;
import javax.servlet.http.*;
import javax.servlet.*;
public class HelloServlet extends HttpServlet
{
public void doGet (HttpServletRequest req,
HttpServletResponse res)
throws ServletException, IOException
{
PrintWriter out = res.getWriter();
out.println("Hello, world!");
out.close();
}
}
Configuration for the servlet is in the WEB-INF/web.xml file.
The servlet needs to be configured and it needs to be mapped to a URL. The <servlet> tag
configures the servlet. In our simple example, we just need to specify the class name for the
servlet.
The <servlet-mapping> tag specifies the URLs which will invoke the servlet. In our case, say
the /hello URL invokes the servlet. Web.xml configuration file lookslike this for our example.
WEB-INF/web.xml
<web-app xmlns="http://caucho.com/ns/resin">
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>test.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
Another example is a shopping cart servlet that loads in memory the price list along with
information about its recently connected clients. Yet another servlet may choose to cache
entire pages of output to save time if it receives the same request again. Not only do servlets
persist between requests, but also so do any threads created by servlets. This perhaps isn’t
useful for the run-of-the-mill servlet, but it opens up.
For example:
GET /intro.html HTTP/1.0
This request uses the GET method to ask for the document named intro.html, using HTTP
Version 1.0. After sending the request, the client can send optional header information to tell
the server extra information about the request, such as what software the client is running and
what content types it understands. This information doesn’t directly pertain to what was
requested, but the server in generating its response could use it. Here are some sample
request headers:
User-Agent: Mozilla/4.0 (compatible; MSIE 4.0; Windows 95)
Accept: image/gif, image/jpeg, text/*, */*
The User-Agent header provides information about the client software, while the Accept
header specifies the media (MIME) types that the client prefers to accept. After the headers,
the client sends a blank line, to indicate the end of the header section. The client can also
send additional data, if appropriate for the method being used, as it is with the POST method.
If the request doesn’t send any data, it ends with an empty line. After the client sends the
request, the server processes it and sends back a response. The first line of the response is a
status line that specifies the version of the HTTP protocol the server is using, a status code,
and a description of the status code.
For example:
HTTP/1.0 200 OK
This status line includes a status code of 200, which indicates that the request was
successful, hence the description “OK”. Another common status code is 404, with the
description “Not Found”—as you can guess, this means that the requested document was not
found. After the status line, the server sends response headers that tell the client things like
what software the server is running and the content type of the server’s response.
For example:
Date: Saturday, 23-May-98 03:25:12 GMT
Server: JavaWebServer/1.1.1
MIME-version: 1.0
Content-type: text/html
Content-length: 1029
Last-modified: Thursday, 7-May-98 12:15:35 GMT
The Server header provides information about the server software, while the Content-type
header specifies the MIME type of the data included with the response. The server sends a
blank line after the headers, to conclude the header section. If the request was successful,
the requested data is then sent as part of the response. Otherwise, the response may contain
human-readable data that explains why the server couldn’t fulfill the request.
information in the URL in this way allows the page to be book marked or emailed like any
other. Because GET requests theoretically shouldn’t need to send large amounts of
information, some servers limit the length of URLs and query strings to about 240 characters.
The POST method uses a different technique to send information to the server because in
some cases it may need to send megabytes of information. A POST request passes all its
data, of unlimited length, directly over the socket connection as part of its HTTP request body.
The exchange is invisible to the client. The URL doesn’t change at all. Consequently, POST
requests cannot be book marked or emailed or, in some cases, even reloaded. That’s by
design— information sent to the server, such as your credit card number, should be sent only
once. In practice, the use of GET and POST has strayed from the original intent. It’s common
for long parameterized requests for information to use POST instead of GET to work around
problems with overly long URLs. It’s also common for simple forms that upload information to
use GET because, well—why not, it works! Generally, this isn’t much of a problem. Just
remember that GET requests, because they can be book marked so easily, should not be
allowed to cause damage for which the client could be held responsible. In other words, GET
requests should not be used to place an order, update a database, or take an explicit client
action in any way.
Other Methods
In addition to GET and POST, there are several other lesser-used HTTP methods. There’s
the HEAD method, which is sent by a client when it wants to see only the headers of the
response, to determine the document’s size, modification time, or general availability. There’s
also PUT, to place documents directly on the server, and DELETE, to do just the opposite.
These last two aren’t widely supported due to complicated policy issues. The TRACE method
is used as a debugging aid—it returns to the client the exact contents of its request. Finally,
the OPTIONS method can be used to ask the server which methods it supports or what
options are available for a particular resource on the server.
Session
Many applications require a series of requests from a client to be associated with one
another. For example, the Duke's Bookstore application saves the state of a user's shopping
cart across requests. Web-based applications are responsible for maintaining such state,
called a session, because the HTTP protocol is stateless. To support applications that need to
maintain state, Java Servlet technology provides an API for managing sessions and allows
several mechanisms for implementing sessions.
Accessing a Session
Sessions are represented by an HttpSession object. You access a session by calling the
getSession method of a request object. This method returns the current session associated
with this request, or, if the request does not have a session, it creates one. Since getSession
may modify the response header (if cookies are the session tracking mechanism), it needs to
be called before you retrieve a PrintWriter or ServletOutputStream.
For example say, The Duke's Bookstore application stores a customer's shopping cart as a
session attribute. This allows the shopping cart to be saved between requests and also allows
cooperating servlets to access the cart. CatalogServlet adds items to the cart;
ShowCartServlet displays, deletes items from, and clears the cart; and CashierServlet
retrieves the total cost of the books in the cart.
Session Management
Since there is no way for an HTTP client to signal that it no longer needs a session, each
session has an associated timeout so that its resources can be reclaimed. The timeout period
can be accessed with a session's [get|set]MaxInactiveInterval methods. You can also set the
time-out period in deploy tool:
To ensure that an active session is not timed out, you should periodically access the session
via service methods because this resets the session's time-to-live counter.
When a particular client interaction is finished, you use the session's invalidate method to
invalidate a session on the server side and remove any session data.
In this article we will learn how to pass control from one Servlet to another using
RequestDispatcher.forward() method and how to include response from another Servlet
within the caller Servlet using RequestDispatcher.include() method.
RequestDispatcher Interface
This interface is present in the javax.servlet package and contains only following two
methods:
q forward(Servl
etRequestrequest,Servl
etResponse response)Forwards a request
to another resource on the same server. That resource can be a Servlet, JSP
page or a simple HTML page.
q i
ncl
ude(ServletRequestrequest,Servl
etResponse response)Works like a server-
side include ( SSI ) and includes the response from the given resource ( Servlet,
JSP page, HTML page ) within the caller response.
q Servl
etContext.getRequestDi
spatcher(Stri
ng resource)
q Servl
etRequest.getRequestDi
spatcher(String resource)
RequestDispatcher rd;
rd = req.getRequestDispatcher("pathToServlet");
rd.forward(req, res);
RequestDispatcher rd;
rd =
getServletContext().getRequestDispatcher("pathToServlet")
;
rd.forward(req, res);
Having learned the theory about including and forwarding response using RequestDispatcher
interface, it is time now that we build some demo application and demonstrate the use of
these methods. We will also be learning one more thing which is setting and getting attributes
from HttpServletRequest object.
TestDispatcherServlet1
package com.stardeveloper.servlets;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
res.setContentType("text/html");
PrintWriter out = res.getWriter();
out.print("<html><head><style>");
out.print("p,form{font-family:tahoma;font-
size:10pt;}");
out.print("input{width:20;height:20;}");
out.print("</style></head><body>");
// Displaying Form
out.print("<form action=\"");
out.print( req.getRequestURI() );
out.print("\" method=\"post\">");
out.print("<input type=\"hidden\" name=\"mode\" ");
out.print("value=\"forward\">");
out.print("<input type=\"submit\" value=\" \"");
out.print("> ");
out.print(" Forward to another Servlet ..");
out.print("</form>");
out.print("<form action=\"");
out.print( req.getRequestURI() );
out.print("</body></html>");
out.close();
}
// Forwarding to Servlet2
req.getRequestDispatcher(forwardTo).forward(req, res);
}
req.getRequestDispatcher(includeIn).include(req, res);
}
}
}
Explanation
Our Servlet above extends HttpServlet class and overrides doGet() a n d doPost() methods.
We also declare two variables forwardTo and includeIn which point to the path of the second
Servlet. For this example they both point to same Servlet.
In doGet() we display a Form to the user giving the option to either test the forward() method
or the include() method. To determine user clicked which button we provide a hidden input
field with name of 'mode' and a value of 'forward' (for forwarding) or 'include' (for
including).We handle the user response in our doPost() method and depending on the type of
button clicked we either forward the request to the second Servlet or include it's response in
the first Servlet.
We also set the attribute "mode" in the HttpServletRequest object to a value depending on
which button user clicked, which can be displayed on the next page by accessing the value
from the request object.
Form-Servlet Integration
Constructing a form is far less intimidating that it may appear at first. If you've already set up
web pages using HTML, then you'll move naturally into setting up forms, which are also
written using HTML tags embedded right in an ordinary HTML page.
Example form
These tags start and end a form (all input fields of the form are placed between these two
tags). METHOD specifies which technical protocol the web server will use to pass the form
data to the program which processes it (always set it to POST), and ACTION tells the server
exactly which program that is. Note: POST must be capitalized; otherwise the method
defaults to "GET".
In our example, the action is a program is the Yahoo Forms Processor. In this case we
configured it just say hello and echo the name you entered. Most or all of your forms in your
Yahoo account will point to http://www.yahoo.com/cgi-bin/form - the WebCom form processor,
a program which reads a configuration file you set up in your directory in which you define
how you want the form data to be formatted and routed, what to display to the user after they
submit the form, etc. (the configuration file is optional - if you don't have one the form
processor simply emails the contents of the form to you (the name and value of each field on
the form when the user submitted it)).
A web page (i.e., an HTML document) may include multiple forms; however, forms may not
be nested (you cannot create a form within a form). You must end the current form with <
/FORM > before you can start a new form.
You can pick any name for your fields, just make sure it is not one of the pre-defined Form-
parameters. These variables, when set to have values, perform certain specialized tasks. For
instance, one of the most common errors in creating forms is to have an input field ask for a
client's email address, and using the variable email to store the address in. The word 'email',
however, is one of the predefined parameters. Giving email a value tells the Forms Processor
to send the form's results to that address, which is usually not what is intended.
You also want to be careful to use only letters, numbers, and underscores in your field
names. The HTML standard allows other symbols other than letters, numbers, and
underscores to be used in a field name but the Yahoo form processor will not recognize such
field names (and it's good practice to stick with letters, numbers and underscores for
readability). TYPE defines the various types of input fields recognized in the current HTML
specification (text, radio, checkbox, password, or submit), which we'll look at a little later.
The text input type creates what user interface designers call a single line edit, an input field
which allows the user to enter and/or edit a single line of text. This is the type of field we used
in our sample form. We did not have to say TYPE=text because that is the default type, but
we could just as well have coded the field as follows with the same result:
Some other things we can do with a text input field are defining an initial value for the field,
and make it longer (or shorter):
Enter your name:
<INPUT TYPE=text NAME=your_name SIZE=50 VALUE="Joe
Schmoe" >
Note that the user could still type more than 50 characters in the above field, the browser just
scrolls the text in the window. You can also limit the length of the text input by the user by
including a MAXLENGTH=nn in the INPUT field definition.
When the user clicks the submit button, the browser collects the values of each of the input
fields (text typed by the user, etc.) and sends them to the web server identified in the ACTION
keyword of the FORM open tag (and that web server passes that data to the program
identified in the ACTION, using the METHOD specified).
You may at some point get the urge to create a form with two or more submit buttons, each of
which you'd like to perform a different task (say one to subscribe to a mailing list, and another
to unsubscribe. This is a natural inclination, but unfortunately you can't do it with the current
WWW standards. Sometimes you can simulate this behavior by having multiple forms on one
page, each with its own submit button (and perhaps nothing else). But if you associate
multiple submit buttons with the same input fields by putting them on the same form (that is,
between the same FORM tags), all the submit buttons will do exactly the same thing (namely
pass the data of that form to the program identified by the ACTION identifier).
SUMMARY
After completing this chapter, you have learned:
q Servlet Architecture
q Know Servlet lifecycle and how to write Servlet
q Know Web.xml Configuration
q Understand Servlet scope and Session
Chapter 4: JSP
Learning Objectives
After completing this chapter, you will be able to:
q Learn the basic syntax of JSP and predefined variables
q Understand JSP Page Lifecycle
q Know a brief overview of JAVABEANS
q Create your own customized tags
Introduction
In the J2EE suite of specifications that includes Servlets, JavaServer Pages (JSP), the Java
Naming and Directory Interface (JNDI), Enterprise JavaBeans (EJB), and so forth, the JSP is
a w e b -tier specification that supplements the Servlet specification and is useful in the
development of web interfaces for enterprise applications.
JSP is a technology that combines the HTML/XML markup languages and elements of the
Java programming language to return dynamic content to a web client. For this reason, it is
commonly used to handle the presentation logic of a web application, although the JSP pages
may also contain business logic.
The Java Server Pages (JSP) technology was designed to fit this need. The JSP specification
is the result of extensive industry cooperation between vendors of web servers, application
servers, transactional systems, and development tools. Sun Microsystems developed the
specification to integrate with and leverage existing expertise and tools support for the Java
programming environment, such as Java Servlets and JavaBeans. The result is a new
approach to developing web-based applications that extends powerful capabilities to page
designers using component-based application logic.
q vs. Active Server Pages (ASP). ASP is a similar technology from Microsoft. The
advantages of JSP are twofold. First, the dynamic part is written in Java, not
Visual Basic or other MS-specific language, so it is more powerful and easier to
q vs. Pure Servlets. JSP doesn't give you anything that you couldn't in principle do
with a servlet. But it is more convenient to write (and to modify!) regular HTML
than to have a zillion println statements that generate the HTML. Plus, by
separating the look from the content you can put different people on different
tasks: your Web page design experts can build the HTML, leaving places for your
servlet programmers to insert the dynamic content.
q vs. Server-Side Includes (SSI). SSI is a widely supported technology for
including externally defined pieces into a static Web page. JSP is better because
it lets you use servlets instead of a separate program to generate that dynamic
part. Besides, SSI is really only intended for simple inclusions, not for "real"
programs that use form data, make database connections, and the like.
q vs. JavaScript. JavaScript can generate HTML dynamically on the client. This is
a useful capability, but only handles situations where the dynamic information is
based on the client's environment. With the exception of cookies, HTTP and form
submission data is not available to JavaScript. And, since it runs on the client,
JavaScript can't access server-side resources like databases, catalogs, pricing
information, and the like.
q vs. Static HTML. Regular HTML, of course, cannot contain dynamic information.
JSP is so easy and convenient that it is quite feasible to augment HTML pages
that only benefit marginally by the insertion of small amounts of dynamic data.
Previously, the cost of using dynamic data would preclude its use in all but the
most valuable instances.
JSP technology speeds the development of dynamic web pages in a number of ways:
On the server, a JSP engine interprets JSP tags and scriptlets, generates content (for
TM
example, by accessing JavaBeans components, accessing a database with JDBC
technology, or including files), and sends the results back in the form of an HTML (or XML)
page to the browser. This helps authors protect proprietary code while ensuring complete
portability for any HTML-based web browser.
The JSP technology is extensible through the development of customized tag libraries. Over
time, third-party developers and others will create their own tag libraries for common
functions. This lets web page developers work with familiar tools and constructs, such as
tags, to perform sophisticated functions
The JSP technology is best described using an example. The following JSP page is very
simple; it prints the day of the month and the year, and welcomes you with either "Good
Morning" or "Good Afternoon," depending on the time of day.
<HTML>
<%@ page language=="java" imports=="com.wombat.JSP.*" %>
<H1>Welcome</H1>
<P>Today is </P>
<jsp:useBean id=="clock" class=="calendar.jspCalendar" />
<UL>
<LI>Day: <%==clock.getDayOfMonth() %>
<LI>Year: <%==clock.getYear() %>
</UL>
<% if (Calendar.getInstance().get(Calendar.AM_PM) ====
Calendar.AM) { %>
Good Morning
<% } else { %>
Good Afternoon
<% } %>
<%@ include file=="copyright.html" %>
</HTML>
example above, the first list item will be the day of the year, and the second item
the year.
q A scriptlet is a small script that performs functions not supported by tags or ties
everything together. The native scripting language for JSP 1.0 software is based
on the Java programming language. The scriptlet in the above sample
determines whether it is AM or PM and greets the user accordingly (for daytime
users, at any rate).
The example may be trivial, but the technology is not. Businesses can encapsulate critical
processing in server-side Beans, and web developers can easily access that information,
using familiar syntax and tools. Java-based scriptlets provide a flexible way to perform other
functions, without requiring extensive scripting. The page as a whole is legible and
comprehensible, making it easier to spot or prevent problems and to share work.
Expressions
Expressions act as placeholders for Java language expressions. This is an example of a JSP
expression:
<%= count; %>
The expression is evaluated each time the page is accessed, and its value is then embedded
in the output HTML. Instead of incrementing the count variable in a scriptlet, we could have
incremented it in the expression itself:
A JSP expression always starts with <%= and ends with %>. Unlike variable declarations,
expressions must not be terminated with a semicolon. Thus, the following is not valid:
<%= count; %>
We can print the value of any object or any primitive data type (int, boolean, char, etc.) to the
output stream using an expression. We can also print the value of any arithmetic or Boolean
expression or a value returned by a method call. The exam may ask you to identify valid JSP
expressions. Tables 11.2 and 11.3 contain some examples of valid and invalid JSP
expressions based on the following declarations:
Valid expressions
Invalid Expression
Directives
Directives provide general information about the JSP page to the JSP engine. There are three
types of directives: page, include, and taglib.
A page directive informs the engine about the overall properties of a JSP page. For example,
the following page directive informs the JSP engine that we will be using Java as the scripting
language in our JSP page:
<%@ page language="java" %>
An include directive tells the JSP engine to include the contents of another file (HTML, JSP,
etc.) in the current page. Here is an example of an include directive:
A directive always starts with <%@ and ends with %>. The general syntax of the three
directives is:
<%@ page attribute-list %>
<%@ include attribute-list %>
<%@ taglib attribute-list %>
In the sample tags above, attribute-list represents one or more attribute-value pairs that are
specific to the directive. Here are some important points to remember about the syntax of the
directives:
q The tag names, their attributes, and their values are all case sensitive.
q The value must be enclosed within a pair of single or double quotes.
q A pair of single quotes is equivalent to a pair of double quotes.
q There must be no space between the equals sign (=) and the value.
Declarations
Declarations declare and define variables and methods that can be used in the JSP page.1
The following is an example of a JSP declaration:
This declares a variable named count and initializes it to 0. The variable is initialized only
once when the page is first loaded by the JSP engine, and retains its value in subsequent
client requests. That is why the count variable is not reset to 0 each time we access the page.
A declaration always starts with <%! and ends with %>. It can contain any number of valid
Java declaration statements. For example, the following tag declares a variable and a method
in a single tag:
<%!
String color[] = {"red", "green", "blue"};
String getColor(int i)
{
return color[i%3];
}
%>
We can also write the above two Java declaration statements in two JSP declaration tags:
Note that since the declarations contain Java declaration statements, each variable’s
declaration statement must be terminated with a semicolon.
Scriptlets
Scriptlets are Java code fragments that are embedded in the JSP page. For example,this line
from the counter.jsp is a JSP scriptlet:
The scriptlet is executed each time the page is accessed, and the count variable is
incremented with each request.
Since scriptlets can contain any Java code, they are typically used for embedding computing
logic within a JSP page. However, we can use scriptlets for printing HTML statements, too.
The following is equivalent to the code:
Instead of writing normal HTML code directly in the page, we are using a scriptlet to achieve
the same effect. The variable out refers to an object of type javax.servlet.
jsp.JspWriter.
Actions
Actions are commands given to the JSP engine. They direct the engine to perform certain
tasks during the execution of a page. For example, the following line instructs the engine to
include the output of another JSP page, copyright.jsp, in the output of the current JSP page:
Comments
Comments do not affect the output of a JSP page in any way but are useful for documentation
purposes. The syntax of a JSP comment is:
A JSP comment always starts with <%-- and ends with --%>.
We can comment the Java code within scriptlets and declarations by using normal Java-style
comments and the HTML portions of a page by using HTML-style comments,as shown here:
<html><body>
Welcome!
<%-- JSP comment --%>
<% //Java comment %>
<!—- HTML comment -->
</body></html>
As we mentioned earlier, the exam does not cover comments, but they can be quite useful
when you’re debugging JSP pages. The JSP engine drops everything between <%-- and --
%>, so it is easy to comment out large parts of a JSP page—including nested HTML and
other JSP tags. However, remember that you cannot nest JSP comments within other JSP
comments.
Predefined Variables
To simplify code in JSP expressions and scriptlets, you are supplied with eight automatically
defined variables, sometimes called implicit objects. The available variables are request,
response, out, session, application, config, pageContext, and page. Details for each are given
below.
Request
This is the HttpServletRequest associated with the request, and lets you look at the request
parameters (via getParameter), the request type (GET, POST, HEAD, etc.), and the incoming
HTTP headers (cookies, Referer, etc.). Strictly speaking, request is allowed to be a subclass
of ServletRequest other than HttpServletRequest, if the protocol in the request is something
other than HTTP. This is almost never done in practice.
Response
This is the HttpServletResponse associated with the response to the client. Note that, since
the output stream (see out below) is buffered, it is legal to set HTTP status codes and
response headers, even though this is not permitted in regular servlets once any output has
been sent to the client.
Out
This is the PrintWriter used to send output to the client. However, in order to make the
response object useful, this is a buffered version of PrintWriter called JspWriter. Note that you
can adjust the buffer size, or even turn buffering off, through use of the buffer attribute of the
page directive.. Also note that out is used almost exclusively in scriptlets, since JSP
expressions automatically get placed in the output stream, and thus rarely need to refer to out
explicitly.
Session
This is the HttpSession object associated with the request. Recall that sessions are created
automatically, so this variable is bound even if there was no incoming session reference. The
one exception is if you use the session attribute of the page directive to turn sessions off, in
which case attempts to reference the session variable cause errors at the time the JSP page
is translated into a servlet.
Application
This is the ServletContext as obtained via getServletConfig().getContext().
Config
This is the ServletConfig object for this page.
PageContext
JSP introduced a new class called PageContext to encapsulate use of server-specific
features like higher performance JspWriters. The idea is that, if you access them through this
class rather than directly, your code will still run on "regular" servlet/JSP engines.
Page
This is simply a synonym for this, and is not very useful in Java. It was created as a
placeholder for the time when the scripting language could be something other than Java.
But an important thing to remember here is that when the JSP engine generates the Java
code for a JSP page, it also inserts the contents of the included pages into the servlet that it
generates. The set of pages that is translated into a single servlet class is called a translation
unit. Some of the JSP tags affect the whole translation unit and not just the page in which
they are declared.
q The standard action <jsp:useBean> cannot declare the same bean twice in a
single translation unit.
UNDERSTANDING JSP
We can also use multiple tags for readability. For example, the above page directive can also
be written as:
<%@ page import="java.util.* " %>
<%@ page import="java.io.* " %>
Since the order of import statements in a Java class does not matter, the order of import tags
shown here does not matter, either. A JSP engine always imports the java.lang.*,
javax.servlet.*, javax.servlet.jsp.*, and javax.servlet.http.* packages, so we do not have to
import them explicitly.
NOTE import is the only attribute of the page directive that can occur multiple times in a
translation unit. Duplicate values are ignored.
The above JSP page throws an exception if the parameter name is not supplied in the
request, but it does not catch the exception itself. Instead, with the help of the errorPage
attribute, it instructs the JSP engine to delegate the error handling to errorHandler.jsp. The
isErrorPage attribute conveys whether or not the current page can act as an error handler for
any other JSP page. The default value of the isErrorPage attribute is false. For example, the
errorHandler.jsp that we used in the previous example must explicitly set this attribute to true.
In this case, the JSP engine declares the implicit variable exception in the page’s servlet
class.
Notice that this page only extracts the information from the exception and generates a n
appropriate error message. Because it does not implement any business logic, it can be
reused for different JSP pages. In JSP 1.2, it is not necessary that the errorPage value be a
JSP page. It can also be a static file, such as an HTML page:
The value of the buffer is in kilobytes and the suffix kb is mandatory. To send the data directly
to the client without any buffering, we can specify the value as none.
The autoFlush attribute specifies whether the data in the output buffer should
be sent to the client automatically as soon as the buffer is full. The default value for autoFlush
is true. If it is set to false and the buffer is full, an exception is raised when we attempt to add
more data to the buffer. Here is the syntax for this attribute:
If isThreadSafe is set to false, the container dispatches the requests to the page one at a time
in the order they are received. This is equivalent to implementing the SingleThreadModel
interface for servlets. “Developing Thread-Safe Servlets.” In this case, only one thread will
execute the servlet code at a time, incrementing the value of count and then printing it in the
output HTML. However, note that even this is not a totally foolproof method of synchronizing
the counter. It will work when there is only one instance of the servlet serving the requests.But
if the container decides to create a pool of instances of the thread-unsafe servlet, then each
servlet instance will have its own copy of the count variable. A request to the same JSP page
will then return the count depending on which servlet instance was used from the pool. In
such cases, it is better to use a programmatic synchronization mechanism for incrementing
the count and leave the page as thread safe:
In this code, the attribute-value pair isThreadSafe=true will ensure that the servlet does not
implement SingleThreadModel; that way, only a single instance of the servlet is created. The
this keyword refers to the servlet instance, and the synchronized block on the instance will
make sure that the two operations—incrementing the count and printing its value—are
executed by a single thread at a time, thus printing a unique value of the count in the output
HTML for each request.
response.setContentType("text/html;charset=ISO-8859-1");
The pageEncoding attribute specifies the character encoding of the JSP page. The default
value is ISO-8859-1. The following line illustrates the syntax:
In the following getter and setter methods, the name of the property is color and its data type
is String:
public String getColor();
public void setColor(String);
Let’s look at a simple example of a Java class that can be used as a JavaBean in a JSP
page.
The default scope .The following declaration uses only two attributes—id and class:
<jsp:useBean id="address" class="AddressBean" />
This is similar to the previous example, except that we have not specified the scope attribute.
In this case, the page scope is used by default. Thus, this bean is available only in the JSP
page in which it is defined and only for the request for which it is created. It is equivalent to
the following code:
AddressBean address = (AddressBean)
pageContext.getAttribute("address");
if (address == null)
{
address = new AddressBean();
pageContext.setAttribute("address", address);
}
Using serialized beans In the following useBean declaration, the beanName attribute
specifies the use of a serialized bean, businessData.Address.John:
In the JSP even if the property numItems is int and the numitem is passes as a request
parameter param attribute is defined to casted to the required type and then the value is set.
Explicit conversion is not required.
Application scope:
Application-scoped objects are shared across all the components of the web application and
are accessible for the life of the application. These objects are maintained as attribute-value
pairs by an instance of the ServletContext class. In a JSP page, this instance is available in
the form of the implicit object application. Thus, to share objects at the application level, we
use the setAttribute() and getAttribute() methods of the ServletContext interface.
Session scope:
Objects in the session scope are shared across all the requests that belong to a singleuser
session and are accessible only while the client is active. These objects are maintained as
attribute-value pairs by an instance of the HttpSession class. In a JSP page, this instance is
available in the form of the implicit object session. Thus, to share objects at the session level,
we can use the session.setAttribute() and session. getAttribute() methods. In the following
example, the login.jsp page adds the user ID to the session scope so that the userProfile.jsp
page can retrieve it:
<%--
Add the userId to the session
--%>
<%
String userId = // getUserLoggedIn
session.setAttribute("userId", userId);
%>
<%--
Retrieve the userId from the session
--%>
<%
String userId = (String) session.getAttribute("userId")
//use the userId to retrieve user details.
String name = getUserNameById(userId);
%>
User Name is: <%=name%>
Request scope:
Objects in the request scope are shared across all the components that process the same
request and are accessible only while that request is being serviced. These objects are
maintained as attribute-value pairs by an implementation instance of the interface
HttpServletRequest. In a JSP page, this instance is available in the form of the implicit object
request. Thus, we can add attributes to the request in one page and forward the request to
another page. The second page can then retrieve these attributes to generate a response. In
this example, the file login.jsp creates a user object and adds it to the request, and then
forwards the request to authenticate.jsp:
<%
//Get login and password information from the request
object
//and file it in a User Object.
User user = new User();
user.setLogin(request.getParameter("login"));
user.setPassword(request.getParameter("password"));
//Set the user object in the request scope for now
request.setAttribute("user", user);
//Forward the request to authenticate.jsp
pageContext.forward("authenticate.jsp");
return;
%>
Page scope:
Objects in the page scope are accessible only in the translation unit in which they are defined.
They do not exist outside the processing of a single request within a single translation unit.
These objects are maintained as attribute-value pairs by an instance of a concrete subclass
of the abstract class PageContext. In a JSP page, this instance is available in the form of the
implicit object pageContext. ” The only way for actions (standard JSP actions and user-
defined custom tags) to share data and JavaBean objects with other actions or custom tags
appearing in the same JSP page (translation unit) and in the same request thread is to use
the pageContext implicit object and the page scope.
The point of using the second form is that the statements between the jsp:useBean start and
end tags are executed only if a new bean is created, not if an existing bean is used. This
conditional execution is convenient for setting initial bean properties for beans that are shared
by multiple pages. Since you don’t know which page will be accessed first, you don’t know
which page should contain the initialization code. No problem: they can all contain the code,
but only the page first accessed actually executes it.
<jsp:useBean id="counter"
class="coreservlets.AccessCountBean" scope="application">
<jsp:setProperty name="counter" property="firstPage"
value="Current Page Name" />
</jsp:useBean>
AccessCountBean.java
package coreservlets;
/** Simple bean to illustrate sharing beans through
* use of the scope attribute of jsp:useBean.
*/
public class AccessCountBean {
private String firstPage;
private int accessCount = 1;
public String getFirstPage() {
return(firstPage);
}
public void setFirstPage(String firstPage) {
this.firstPage = firstPage;
}
public int getAccessCount() {
return(accessCount++);
}
}
SharedCounts1.jsp
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0
Transitional//EN">
<HTML>
<HEAD>
<TITLE>Shared Access Counts: Page 1</TITLE>
<LINK REL=STYLESHEET HREF="JSP-Styles.css"
TYPE="text/css">
</HEAD>
<BODY>
<TABLE BORDER=5 ALIGN="CENTER">
<TR><TH CLASS="TITLE">
Shared Access Counts: Page 1</TABLE>
<P>
<jsp:useBean id="counter"
class="coreservlets.AccessCountBean"
scope="application">
<jsp:setProperty name="counter" property="firstPage"
value="SharedCounts1.jsp" />
</jsp:useBean>
Of SharedCounts1.jsp (this page),
<A HREF="SharedCounts2.jsp">SharedCounts2.jsp</A>, and
<A HREF="SharedCounts3.jsp">SharedCounts3.jsp</A>,
<jsp:getProperty name="counter" property="firstPage" />
was the first page accessed.
<P>
Collectively, the three pages have been accessed
<jsp:getProperty name="counter" property="accessCount" />
times.</BODY></HTML>
JAVABEANS IN SERVLETS
We know that JSP pages are converted into servlets at translation time, which means that the
beans that we use in our JSP pages are actually used from a servlet. This implies that we can
use JavaBeans from servlets, too. This section discusses the ways in which we can share
beans between JSP pages and servlets. The exam requires you to know the servlet code that
is equivalent to using beans in the different scopes: request, session, and application.
Suppose a JSP page uses three beans, each with a different scope, request, session, and
application, declared as:
<jsp:useBean id="address1" class="AddressBean" scope="request" />
<jsp:useBean id="address2" class="AddressBean" scope="session" />
<jsp:useBean id="address3" class="AddressBean" scope="application" />
Tag handler
The JSP specification defines a tag handler as a runtime, container-managed object that
evaluates custom actions during the execution of a JSP page. In practical terms, a tag
handler is a Java class that implements one of the tag interfaces— Tag, IterationTag, or
BodyTag—of the package javax.servlet.jsp.tagext. Remember that while executing a JSP file,
if the JSP engine encounters a custom tag, it calls the methods on the tag’s handler class to
do the actual work. The JSP specification defines a tag library as a collection of actions that
encapsulate some functionality to be used from within a JSP page. Typically, we would not
create just one tag to fulfill a particular requirement. Rather, we would design and develop a
set of custom tags that work together and help solve a recurring requirement. Such a set of
custom tags is called a tag library.
<docroot>/sampleLib.tld
<docroot>/myLibs/sampleLib.tld
<docroot>/WEB-INF/sampleLib.tld
<docroot>/WEB-INF/myLibs/sampleLib.tld
We usually keep the TLD file in a directory, instead of a JAR file, during the development of a
tag library. This speeds up the development and testing cycles, during which we design new
tags, add new handler classes, and modify the TLD file frequently. However, once
development is finished, we package the handler classes and the TLD file of the library as a
JAR file. This file is then deployed under the <doc-root>/web-inf/lib directory along with other
jarred classes, such as servlets and third-party tools. The JSP specification mandates that,
when deployed in a JAR file, a TLD file be placed either directly under or inside a subdirectory
of the META-INF directory. In addition, the name of the TLD file must be taglib.tld. Thus, a
JAR file containing a packaged tag library is typically structured like this:
myPackage/myTagHandler1.class
myPackage/myTagHandler2.class
myPackage/myTagHandler3.class
META-INF/taglib.tld
Exception classes
This marks the end of the processing of the tag and gives the tag handler a chance to do the
final cleanup for the tag. If anything fails during the cleanup process, the method may throw a
JspException or a subclass of JspException, such as JspTagException, to indicate the
problem. Finally, the doEndTag() method decides whether or not to continue evaluating the
rest of the JSP page. As a result, it returns one of the two integer constants defined in the Tag
interface: EVAL_PAGE or SKIP_PAGE. A return value of Tag.EVAL_PAGE indicates that the
rest of the JSP page must be evaluated and its output be included in the response, while a
return value of Tag.SKIP_PAGE indicates that the rest of the JSP page must not be
evaluated at all and that the JSP engine should return immediately from the current
_jspService() method. If this page was forwarded or included from another JSP page or a
servlet, only the current page evaluation is terminated, and if the page was included, the
processing resumes from the calling component. The tag cannot return any other value from
this method.
Order of processing in a tag handler class that implements the Tag interface.
If an error occurs during the invocation of the doAfterBody() method, it may throw a
JspException or a subclass of it, such as JspTagException, to indicate the problem. If
everything goes fine, it decides whether or not to reevaluate its body. To evaluate the body
again, it will return the integer constant EVAL_BODY_AGAIN, which is defined in the
IterationTag interface. This will cause an evaluation of the tag’s body the second time, and
after the evaluation, the JSP container will call doAfterBody() for the second time. This
process continues until doAfterBody() returns SKIP_BODY, which is defined in the Tag
interface. We cannot return any other value from this method. Finally, the doEndTag() method
is called, either because doStartTag() returns SKIP_BODY, or because doAfterBody() returns
SKIP_BODY. The purpose and functionality of the doEndTag() method in the IterationTag
interface are the same as in the Tag interface.
Order of processing in a tag handler class that implements the IterationTag interface.
This method allows the tag handler class to initialize the BodyContent object, if required,
before the actual evaluation process starts. Thus, if the initialization of Body- Content fails, the
doInitBody() method may throw a JspException or a subclass of JspException, such as
JspTagException, to indicate the problem. Since BodyTag extends IterationTag, which in turn
extends the Tag interface, BodyTag inherits all the functionality of IterationTag as well as Tag.
The container sets up the implementation handler class with appropriate references by calling
the setPageContext() and setParent() methods, passes the attribute values using the setter
methods, and calls doStartTag(). The doStartTag() method of a class that implements the
BodyTag interface returns any one of three values: EVAL_BODY_INCLUDE or SKIP_BODY
inherited from the Tag interface, or EVAL_BODY_BUFFERED, which is defined in the
BodyTag interface. The actions taken by the JSP container for the return values
EVAL_BODY_ INCLUDE and SKIP_BODY are the same as for the IterationTag interface.
STATIC INCLUSION
q Because request parameters are a property of the requests and do not make any
sense at translation time, the file attribute value cannot pass any parameters to
the included page. Thus, the value of the file attribute in the following example is
invalid:
DYNAMIC INCLUSION
In dynamic inclusion, when the JSP page is requested, it sends a request to another object,
and the output from that object is included in the requested JSP page. We use the standard
JSP actions <jsp:include> and <jsp:forward> to implement dynamic inclusion. Their syntax is
as follows:
<jsp:include page="relativeURL" flush="true" />
<jsp:forward page="relativeURL" />
The page attribute is mandatory. It must be a relative URL, and it can refer to any static or
dynamic web component, including a servlet. It can also be a request-time expression, The
flush attribute is only valid for <jsp:include> and not for <jsp:forward>. It is optional and
specifies that if the output of the current JSP page is buffered, then the buffer should be
flushed before passing the output stream to the included component. The default value for the
flush attribute is false. Functionally, the <jsp:include> and <jsp:forward> actions are
equivalent to the RequestDispatcher.include() and RequestDispatcher.forward() methods that
are used in servlets to include and forward the requests to other components.
if the output is buffered, it is first cleared, and then the request is forwarded to the other
resource. However, if the output is not buffered and/or if the response is already committed by
the forwarding resource, then a java.lang.IllegalStateException is raised when we attempt to
forward the request.
Chapter 5: XML
Learning Objective
After completing this chapter, you will be able to:
q Understand XML Grammar and Document Rules
q Understand Document type declaration
q Create well formed and valid XML’s
q Know various rules of writing XML’s
q Understand XML Parsing, DOM, SAX
Introduction
XML, or Extensible Markup Language, is a markup language that you can use to create your
own tags. It was created by the World Wide Web Consortium (W3C) to overcome the
limitations of HTML, the Hypertext Markup Language that is the basis for all Web pages. Like
HTML, XML is based on SGML -- Standard Generalized Markup.
Language. Although SGML has been used in the publishing industry for decades, its
perceived complexity intimidated many people that otherwise might have used it. XML was
designed with the Web in mind.
XML documents are made up of storage units called entities, which contain either parsed or
unparsed data. Parsed data is made up of characters, some of which form character data,
and some of which form markup. Markup encodes a description of the document's storage
layout and logical structure. XML provides a mechanism to impose constraints on the storage
layout and logical structure.
Why XML?
HTML is the most successful markup language of all time. You can view the simplest HTML
tags on virtually any device, from palmtops to mainframes, and you can even convert HTML
markup into voice and other formats with the right tools. Given the success of HTML, why did
the W3C create XML? To answer that question, take a look at this document:
<p>
<b>Mrs. Mary McGoon</b>
<br>
1401 Main Street
<br>
Anytown, NC 34829
</p>
The trouble with HTML is that it was designed with humans in mind. Even without viewing the
above HTML document in a browser, you and I can figure out that it is someone's postal
address. (Specifically, it's a postal address for someone in the United States; even if you're
not familiar with all the components of U.S. postal addresses, you could probably guess what
this represents.)
As humans, you and I have the intelligence to understand the meaning and intent of most
documents. A machine, unfortunately, can't do that. While the tags in this document tell a
browser how to display this information, the tags don't tell the browser what the information is.
You and I know it's an address, but a machine doesn't.
To render HTML, the browser merely follows the instructions in the HTML document.The
paragraph tag tells the browser to start rendering on a new line, typically with a blank line
beforehand, while the two break tags tell the browser to advance to the next line without a
blank line in between. While the browser formats the document beautifully, the machine still
doesn't know this is an address.
Consider the task of extracting the postal code from this address. Here's an (intentionally
brittle) algorithm for finding the postal code in HTML markup: If you find a paragraph with two
<br> tags, the postal code is the second word after the first comma in the second break
tag.Although this algorithm works with this example, there are any number of perfectly valid
addresses worldwide for which this simply wouldn't work. Even if you could write an algorithm
that found the postal code for any address written in HTML, there are any numbers of
paragraphs with two break tags that don't contain addresses at all. Writing an algorithm that
looks at any HTML paragraph and finds any postal codes inside it would be extremely difficult,
if not impossible. Now let's look at a sample XML document. With XML, you can assign some
meaning to the tags in the document. More importantly, it's easy for a machine to process the
information as well. You can extract the postal code from this document by simply locating the
content surrounded by the <postal-code> and </postal-code> tags, technically known as the
<postal-code> element.
<address>
<name>
<title>Mrs.</title>
<first-name>Mary</first-name>
<last-name>McGoon</last-name>
</name>
<street>1401 Main Street</street>
<city>Anytown</city>
<state>NC</state>
<postal-code>34829</postal-code>
</address>
To summarise:
XML HTML
XML Grammar
XML declarations:
Most XML documents start with an XML declaration that provides basic information about the
document to the parser. An XML declaration is recommended, but not required. If there is
one, it must be the first thing in the document. It is also called as prologue.
The declaration can contain up to three name-value pairs (many people call them attributes,
although technically they're not). The version is the version of XML used; currently this value
must be 1.0. The encoding is the character set used in this document. The ISO-8859-1
character set referenced in this declaration includes all of the characters used by most
Western European languages. If no encoding is specified, the XML parser assumes that the
characters are in the UTF-8 set, a Unicode standard that supports virtually every character
and ideograph from the world's languages.
Finally, standalone, which can be either yes or no, defines whether this document can be
processed without reading any other files. For example, if the XML document doesn't
reference any other files, you would specify standalone="yes". If the XML document
references other files that describe what the document can contain, you could specify
standalone="no". Because standalone="no" is the default, you rarely see standalone in XML
declarations.
Elements
Elements are the most common form of markup. Delimited by angle brackets, most elements
identify the nature of the content they surround. Some elements may be empty, as seen
above, in which case they have no content. If an element is not empty, it begins with a start-
tag, <element>, and ends with an end-tag, </element>.
Attributes
Attributes are name-value pairs that occur inside tags after the element name. For example,
<div class="preface"> is the div element with the attribute class having the value preface. In
XML, all attribute values must be quoted.
Entity References
In order to introduce markup into a document, some characters have been reserved to
identify the start of markup. The left angle bracket, "<", for instance, identifies the beginning of
an element start- or end-tag. In order to insert these characters into your document as
content, there must be an alternative way to represent them. In XML, entities are used to
represent these special characters. Entities are also used to refer to often repeated or varying
text and to include the content of external files.
Every entity must have a unique name. Defining your own entity names is discussed in the
section on entity declarations below. In order to use an entity, you simply reference it by
name. Entity references begin with the ampersand and end with a semicolon. For example,
the amp entity inserts a literal ampersand into a document. So the string "O'Reilly &
Associates, Inc." can be represented in an XML document as O'Reilly & Associates, Inc.
Comments
Comments begin with "<!--" and end with "-->". Comments can contain any data except the
literal string "--". You can place comments between markup anywhere in your document.
Comments are not part of the textual content of an XML document. An XML processor is not
required to pass them along to an application.
Processing Instructions
Processing instructions (PIs) are an escape hatch to provide information to an application.
Like comments, they are not textually part of the XML document, but the XML processor is
required to pass them to an application.
Processing instructions have the form: <?name pidata?>. The name, called the PI target,
identifies the PI to the application. Applications should process only the targets they recognize
and ignore all other PIs. Any data that follows the PI target is optional, it is for the application
that recognizes the target. The names used in PIs may be declared as notations in order to
formally identify them.PI names beginning with "XML" are reserved for XML standardization.
CDATA Sections
In a document, a CDATA section instructs the parser to ignore most markup characters.
Consider a source code listing in an XML document. It might contain characters that the XML
parser would ordinarily recognize as markup (< and &, for example). In order to prevent this, a
CDATA section can be used.
Between the start of the section, "<![CDATA[" and the end of the section, "]]>", all character
data is passed directly to the application.
The only string that cannot occur in a CDATA section is "]]>". Note: comments are not
recognized in a CDATA section. If present, the literal text "<!--comment-->" will be passed
directly to the application.
One of the greatest strengths of XML is that it allows you to create your own tag names. But
for any given application, it is probably not meaningful for tags to occur in a completely
arbitrary order. Consider the old joke example introduced earlier. Would this be meaningful?
<quote><oldjoke>Goodnight,
<applause/>Gracie</oldjoke></quote>
<burns><gracie>Say
<quote>goodnight</quote>, </gracie>Gracie.</burns>
It's so far outside the bounds of what we normally expect that it's nonsensical. It just doesn't
mean anything.
However, from a strictly syntactic point of view, there's nothing wrong with that XML
document. So, if the document is to have meaning, and certainly if you're writing a style sheet
to present it, there must be some constraint on the sequence and nesting of tags.
Declarations are where these constraints can be expressed .More generally, declarations
allow a document to communicate meta-information to the parser about its content. Meta-
information includes the allowed sequence and nesting of tags, attribute values and their
types and defaults, the names of external files that may be referenced and whether or not
they contain XML, the formats of some external (non-XML) data that may be included, and
entities that may be encountered. There are four kinds of declarations in XML: element
declarations, attribute list declarations, entity declarations, and notation declarations.
Element Declarations
Element declarations [Section 3.2] identify the names of elements and the nature of
their content. A typical element declaration looks like this:
This declaration identifies the element named oldjoke. Its "content model" follows the element
name. The content model defines what an element may contain. In this case, an oldjoke must
contain burns and allen and may contain applause. The commas between element names
indicate that they must occur in succession. The plus after burns indicates that it may be
repeated more than once but must occur at least once. The question mark after applause
indicates that it is optional. A name with no punctuation, such as allen, must occur exactly
once.
Declarations for burns, allen, applause and all other elements used in any content model
must also be present for an XML processor to check the validity of a document.In addition to
element names, the special symbol #PCDATA is reserved to indicate character data. The
moniker PCDATA stands for "parseable character data".Elements with both element content
and PCDATA content are said to have "mixed content".For example, the definition for burns
might be
The vertical bar indicates an "or" relationship, the asterisk indicates that the content is
optional (may occur zero or more times); therefore, by this definition, burns may contain zero
or more characters and quote tags. All content models that include PCDATA must have this
form: PCDATA must come first, all of the elements must be separated by vertical bars, and
the entire group must be optional.
Two other content models are possible: EMPTY indicates that the element has no content
(and consequently no end-tag), and ANY indicates that any content is allowed. The ANY
content model is sometimes useful during document conversion, but should be avoided at
almost any cost in a production environment because it disables all content checking in that
element.
Here is a complete set of element declarations for the example used in this article:
Attribute Declarations
Attribute declarations identify which elements may have attributes, what attributes they may
have, what values the attributes may hold, and what default value each attribute has. A typical
attribute declaration looks like this:
In this example, the oldjoke element has three attributes: name, which is an ID and is
required; label, which is a string (character data) and is not required; and status, which must
be either funny or notfunny and defaults to funny if not specified.
Each attribute in a declaration has three parts: a name, a type, and a default value.You are
free to select any name you wish, subject to some slight restrictions, but names cannot be
repeated on the same element.
ID: The value of an ID attribute must be a name. All of the ID values used in a document
must be different. IDs uniquely identify individual elements in a document. Elements can have
only a single ID attribute.
IDREF or IDREFS: An IDREF attribute's value must be the value of a single ID attribute on
some element in the document. The value of an IDREFS attribute may contain multiple
IDREF values separated by white space.
ENTITY or ENTITIES: An ENTITY attribute's value must be the name of a single entity. The
value of an ENTITIES attribute may contain multiple ENTITY values separated by white
space.
NMTOKEN or NMTOKENS : Name token attributes are a restricted form of string attribute. In
general, an NMTOKEN attribute must consist of a single word, but there are no additional
constraints on the word, it doesn't have to match another attribute or declaration. The value of
an NMTOKENS attribute may contain multiple NMTOKEN values separated by white space.
A list of names: You can specify that the value of an attribute must be taken from a specific
list of names. This is frequently called an enumerated type because each of the possible
values is explicitly enumerated in the declaration.
#IMPLIED: The attribute value is not required, and no default value is provided. If a value is
not specified, the XML processor must proceed without one.
"value": An attribute can be given any legal value as a default. The attribute value is not
required on each element in the document, but if it is not present, it will appear to be the
specified default.
#FIXED "value" : An attribute declaration may specify that an attribute has a fixed value. In
this case, the attribute is not required, but if it occurs, it must have the specified value. One
use for fixed attributes is to associate semantics with an element. A complete discussion is
beyond the scope of this article, but you can find several examples of fixed attributes in the
XLL specification.
Entity Declarations
Entity declarations allow you to associate a name with some other fragment of the document.
That construct can be a chunk of regular text, a chunk of the document type declaration, or a
reference to an external file containing either text or binary data. Here are a few typical entity
declarations:
If you begin a <i> element inside a <b> element, you have to end it there as well. If you want
the text XML to appear in italics, you need to add a second <i> element to correct the markup:
If an element contains no markup at all it is called an empty element; the HTML break (<br>)
and image (<img>) elements are two examples. In empty elements in XML documents, you
can put the closing slash in the start tag. The two break elements and the two image
elements below mean the same thing to an XML parser:
<img src="../img/c.gif"></img>
<img src="../img/c.gif" />
©Copyright 2004, Cognizant Academy, All Rights Reserved 96
J2EE
You can use either single or double quotes, just as long as you're consistent. If the value of
the attribute contains a single or double quote, you can use the other kind of quote to
surround the value (as in name="Doug's car"), or use the entities " for a double quote
and ' for a single quote. An entity is a symbol, such as ", that the XML parser
replaces with other text, such as ".
Namespaces:
XML's power comes from its flexibility, the fact that you and I and millions of other people can
define our own tags to describe our data. Remember the sample XML document for a
person's name and address? That document includes the <title> element for a person's
courtesy title, a perfectly reasonable choice for an element name. If you run an online
bookstore, you might create a <title> element for the title of a book. If you run an online
mortgage company, you might create a <title> element for the title to a piece of property. All
of those are reasonable choices, but all of them create elements with the same name. How
do you tell if a given <title> element refers to a person, a book, or a piece of property? We do
this with namespaces. To use a namespace, you define a namespace prefix and map it to a
particular string. Here's how you might define namespace prefixes for our three <title>
elements:
<?xml version="1.0"?>
<customer_summary
xmlns:addr="http://www.xyz.com/addresses/"
xmlns:books="http://www.zyx.com/books/"
xmlns:mortgage= http://www.yyz.com/title/>
... <addr:name><title>Mrs.</title> ... </addr:name>
In this example, the three namespace prefixes are addr, books, and mortgage. Notice that
defining a namespace for a particular element means that all of its child elements belong to
the same namespace. The first <title> element belongs to the addr namespace because its
parent element, <addr:Name>, does. One final point: The string in a namespace definition is
just a string.
Yes, these strings look like URLs, but they're not. You could define xmlns:addr="mike" and
that would work just as well. The only thing that's important about the namespace string is
that it's unique.
Although the DTD is pretty simple, it makes it clear what combinations of elements are legal.
An address document that has a <postal-code> element before the <state> element I sn't
legal, and neither is one that has no <last-name> element.
Symbols in DTDs
There are a few symbols used in DTDs to indicate how often (or whether) something may
appear in an XML document. Here are some examples, along with their meanings:
Defining attributes:
You can define attributes for the elements that will appear in your XML document. Using a
DTD, you can also:
Suppose that you want to change the DTD to make “state” an attribute of the <city> element.
This defines the <city> element as before, but the revised example also uses an ATTLIST
declaration to list the attributes of the element. The name city inside the attribute list tells the
parser that these attributes are defined for the <city> element.
The name state is the name of the attribute, and the keywords CDATA and #REQUIRED tell
the parser that the state attribute contains text and is required (if it's optional, CDATA
#IMPLIED will do the trick).
To define multiple attributes for an element, write the ATTLIST like this:
This example defines both state and postal-code as attributes of the <city> element.
Finally, DTDs allow you to define default values for attributes and enumerate all of the valid
values for an attribute:
The example here indicates that it only supports addresses from the states of Arizona (AZ),
California (CA), Nevada (NV), Oregon (OR), Utah (UT), and Washington (WA), and that the
default state is California. Thus, you can do a very limited form of data validation.
You can create XML documents using a plain text editor like Notepad (PC), TextEdit (Mac), or
pico (Unix). You can also use programs like Dreamweaver and Cooktop, but all that is
necessary to create the document is a text editor.
Let's say we have two types of documents we would like to wrap in XML: emails and letters.
We want to encode the emails and letters because we are creating an online repository of
archival messages within an organization or by an individual. By encoding them in XML, we
hope to encode their content once and be able to translate it to a variety of outputs, like
HTML, PDFs, or types not yet created.
Now, after declaring the XML version, we need to determine the root element for the
documents. Let's use message as the root element, since both email and letters can be
classified as messages.
Note: We created both the opening and closing tags for the message element. When creating
XML documents, it is useful to create both the opening and closing elements at the same
time. After creating the tags, you would then fill in the content. Since one of the fatal errors for
XML is forgetting to close an element, if you make the opening and closing tags each time
you create an element, you won't accidentally forget to do so.
Now that we have the XML declaration, the root element, and the child element (email), let's
determine the information we want to break out in an email. Say we want to keep information
about the sender, recipients, subject, and the body of the text. Since the information about the
sender and recipients are generally in the head of the document, let's consider them children
elements of a parent element that we will call <header>. In addition to <header>, the other
child elements of <email> will be <subject> and <text>. So our XML will look something like
this:
<?xml version="1.0" encoding="iso-8859-1"?>
<message>
<email>
<header>
<sender>me@ischool.utexas.edu</sender>
<recipient>you@ischool.utexas.edu</recipient>
</header>
<subject>Re: XML
</subject>
<text>I'm working on my XML project right now.
</text>
Now say we wanted to keep track of whether or not these messages were replies or not.
Instead of creating an additional element called <reply>, let's assign an attribute to the
elements <email> and <letter> indicating whether that document was a reply to a previous
message.
In XML, it would look something like this:
<email reply="yes">
or
<letter reply="no">
When creating XML documents, it's always useful to spend a little time thinking about what
information you want to store, as well as what relationships the elements will have. Now that
we've made some XML documents, let's talk about "well formed" XML and valid XML.
Well formed in relation to XML means that it has no syntax, spelling, punctuation, grammar
errors, etc. in its markup. These kinds of errors can cause your XML document to not parse.
Note: An XML Parser is software that reads XML documents and interprets or "parses" the
code according to the XML standard. A parser is needed to perform actions on XML. For
example, a parser would be needed to compare an XML document to a DTD.
In the next section, we will talk about some common errors that prevent an XML document
from being well formed.
When you say an XML document is valid, you're saying that the element structure and
markup of the XML document matches a defined standard of relationships, in addition to
having well formed markup. In other words, is this XML document a quality document?
One standard used to validate XML is a DTD, or Document Type Declaration, although XML
Schemas are also used.
These standards are useful when dealing with the creation of a number of XML documents for
they provide a quality control measure to ensure that all the documents meet a minimum
standard. Another benefit is that it allows for errors to be detected in the process of creating
the XML document, rather than at the end. Later, we'll create a sample DTD for our email and
letter XML documents.
Note: An important thing to remember is that when a document is valid it is also "well formed,"
but a "well formed" document is not necessarily valid. Additionally, you can create XML
documents without a DTD, but the XML document can't be considered valid without a
document type.
XML Attributes
From HTML you will remember this: <IMG SRC="computer.gif">. The SRC attribute provides
additional information about the IMG element.
In HTML (and in XML) attributes provide additional information about elements:
<img src="computer.gif">
<a href="demo.asp">
Attributes often provide information that is not a part of the data. In the example below, the file
type is irrelevant to the data, but important to the software that wants to manipulate the
element:
<file type="gif">computer.gif</file>
Note: If the attribute value itself contains double quotes it is necessary to use single quotes,
like in this example:
<person sex="female">
<firstname>Anna</firstname>
<lastname>Smith</lastname>
</person>
<person>
<sex>female</sex>
<firstname>Anna</firstname>
<lastname>Smith</lastname>
</person>
In the first example sex is an attribute. In the last, sex is a child element. Both examples
provide the same information.
There are no rules about when to use attributes, and when to use child elements. My
experience is that attributes are handy in HTML, but in XML you should try to avoid them. Use
child elements if the information feels like data.
<note date="12/11/2002">
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
<note>
<date>12/11/2002</date>
</note>
<note>
<date>
<day>12</day>
<month>11</month>
<year>2002</year>
</date>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
If you use attributes as containers for data, you end up with documents that are difficult to
read and maintain. Try to use elements to describe data. Use attributes only to provide
information that is not relevant to the data.
Don't end up like this ( if you think this looks like XML, you have not understood the point):
<messages>
<note id="p501">
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
<note id="p502">
<to>Jani</to>
<from>Tove</from>
<heading>Re: Reminder</heading>
<body>I will not!</body>
</note>
</messages>
The ID in these examples is just a counter, or a unique identifier, to identify the different notes
in the XML file, and not a part of the note data.
What I am trying to say here is that metadata (data about data) should be stored as attributes,
and that data itself should be stored as elements.
XML Parsing
Parsing an XML is to parse a stream of well-formed XML tags into an element tree, letting
you perform the common task of extracting data from XML-formatted text.
Two Most popular XML parsers developed and used over a range of domains are SAX and
DOM parsers. SAX (Simple API for XML) and DOM (Document Object Model) were both
designed to allow programmers to access their information without having to write a parser in
their programming language of choice. By keeping the information in XML 1.0 format, and by
using either SAX or DOM APIs your program is free to use whatever parser it wishes. This
can happen because parser writers must implement the SAX and DOM APIs using their
favorite programming language. SAX and DOM APIs are both available for multiple
languages (Java, C++, Perl, Python, etc.).
So both SAX and DOM were created to serve the same purpose, which is giving you access
to the information stored in XML documents using any programming language (and a parser
for that language). However, both of them take very different approaches to giving you access
to your information
DOM
DOM gives you access to the information stored in your XML document as a hierarchical
object model. DOM creates a tree of nodes (based on the structure and information in your
XML document) and you can access your information by interacting with this tree of nodes.
The textual information in your XML document gets turned into a bunch of tree nodes. Figure
below illustrates this.
SAX
SAX chooses to give you access to the information in your XML document, not as a tree of
nodes, but as a sequence of events! You ask, how is this useful? The answer is that SAX
chooses not to create a default Java object model on top of your XML document (like DOM
does). This makes SAX faster, and also necessitates the following things:
SAX can be really fast at runtime if your object model is simple. In this case, it is faster than
DOM, because it bypasses the creation of a tree based object model of your information. On
the other hand, you do have to write a SAX document handler to interpret all the SAX events
(which can be a lot of work).
What kinds of SAX events are fired by the SAX parser? These events are really very simple.
SAX will fire an event for every open tag, and every close tag. It also fires events for
#PCDATA and CDATA sections. You document handler (which is a listener for these events)
has to interpret these events in some meaningful way and create your custom object model
based on them. Your document handler will have to interpret these events and the sequence
in which these events are fired is very important. SAX also fires events for processing
instructions, DTDs, comments, etc. But the idea is still the same, your handler has to interpret
these events (and the sequence of the events) and make sense out of them.
However, if you are dealing mostly with structured data (the equivalent of serialized Java
objects in XML) DOM is not the best choice. That is when SAX might be a better fit.
If the information stored in your XML documents is machine readable (and generated) data
then SAX is the right API for giving your programs access to this information. Machine
readable and generated data include things like:
The SAX document handler you write does element to object mapping. If your information is
structured in a way that makes it easy to create this mapping you should use the SAX API.
On the other hand, if your data is much better represented as a tree then you should use
DOM.
Chapter 6: Design
Patterns
Learning Objective
After completing this chapter, you will be able to:
q Understand various design patterns like MVC, Factory, Singleton
q Know about Transfer object and Session Facade
Introduction
Design patterns are recurring solutions to software design problems you find again and again
in real-world application development. Design patterns are about design and interaction of
objects, as well as providing a communication platform concerning elegant, reusable solutions
to commonly encountered programming challenges.
The knowledge of the following patterns will help you to fit business requirements into object
models that is proven for efficiency in an enterprise application
MVC pattern
When developing an application to support a single type of client, it is sometimes beneficial to
interweave data access and business rules logic with interface-specific logic for presentation
and control. Such an approach, however, is inadequate when applied to enterprise systems
that need to support multiple types of clients. Different applications need to be developed, one
to support each type of client interface. Non-interface-specific code is duplicated in each
application, resulting in duplicate efforts in implementation (often of the copy-and-paste
variety), as well as testing and maintenance. The task of determining what to duplicate is
expensive in itself, since interface-specific and non-interface-specific code are intertwined.
The duplication efforts are inevitably imperfect. Slowly, but surely, applications that are
supposed to provide the same core functionality evolve into different systems.
The MVC architecture is applied to map the traditional input, processing, and output tasks to
the graphical user interaction model. However, it is straightforward to map these concepts into
the domain of multi-tier enterprise applications.
Model - The model represents enterprise data and the business rules that govern access to
and updates of this data. Often the model serves as a software approximation to a real-world
process, so simple real-world modeling techniques apply when defining the model.
View -The view renders the contents of a model. It accesses enterprise data through the
model and specifies how that data should be presented. It is the view's responsibility to
maintain consistency in its presentation when the model changes. This can be achieved by
using a push model, where the view registers itself with the model for change notifications, or
a pull model, where the view is responsible for calling the model when it needs to retrieve the
most current data.
Controller - The controller translates interactions with the view into actions to be performed
by the model. In a stand-alone GUI client, user interactions could be button clicks or menu
selections, whereas in a Web application, they appear as GET and POST HTTP requests.
The actions performed by the model include activating business processes or changing the
state of the model. Based on the user interactions and the outcome of the model actions, the
controller responds by selecting an appropriate view.
Singleton Pattern
This pattern ensures that a class has only one instance and provide a global point of access
to it. A singleton class is shown in the following class diagram:-
If (instance == null) {
}
return instance;
Factory Pattern
This pattern defines an interface for creating an object, but let subclasses decide which class
to instantiate. Factory Method lets a class defer instantiation to subclasses
The classes and/or objects participating in this pattern are (The class name mentioned in
bracket are examples. For example, Page is an example product):
q Product (Page) defines the interface of objects the factory method creates
q ConcreteProduct (EducationPage, ExperiencePage) implements the Product
interface
This code will fetch the EducationPage object and the client need not know the method of
creation of EducationPage. The client even need not know that the page that is returned is an
EductaionPage. In another day, if it is decided that the Report creates a ProgressPage, then
the clinet code need not change, only the createPage() in Report class need to change.
Hence the pattern is used to hide the details of creation of an object (EducationPage)
EJB technology used factory pattern in its HomeInterface. The create method is the factory
method.
Transfer/Value Object
Java 2 Platform, Enterprise Edition (J2EE) applications implement server-side business
components as session beans and entity beans. Some methods exposed by the business
components return data to the client. Often, the client invokes a business object's get
methods multiple times until it obtains all the attribute values.
Session beans represent the business services and are not shared between users. A session
bean provides coarse-grained service methods when implemented per the Session Facade
pattern.
Entity beans, on the other hand, are multiuser, transactional objects representing persistent
data. An entity bean exposes the values of attributes by providing an accessor method (also
referred to as a getter or get method) for each attribute it wishes to expose.
Every method call made to the business service object, be it an entity bean or a session
bean, is potentially remote. Thus, in an Enterprise JavaBeans (EJB) application such remote
invocations use the network layer regardless of the proximity of the client to the bean,
creating a network overhead. Enterprise bean method calls may permeate the network layers
of the system even if the client and the EJB container holding the entity bean are both running
in the same JVM, OS, or physical machine. Some vendors may implement mechanisms to
reduce this overhead by using a more direct access approach and bypassing the network.
As the usage of these remote methods increases, application performance can significantly
degrade. Therefore, using multiple calls to get methods that return single attribute values is
inefficient for obtaining data values from an enterprise bean.
The solution is to use a Transfer Object to encapsulate the business data. A single method
call is used to send and retrieve the Transfer Object. When the client requests the enterprise
bean for the business data, the enterprise bean can construct the Transfer Object, populate it
with its attribute values, and pass it by value to the client.
Clients usually require more than one value from an enterprise bean. To reduce the number
of remote calls and to avoid the associated overhead, it is best to use Transfer Objects to
transport the data from the enterprise bean to its client.
When an enterprise bean uses a Transfer Object, the client makes a single remote method
invocation to the enterprise bean to request the Transfer Object instead of numerous remote
method calls to get individual attribute values. The enterprise bean then constructs a new
Transfer Object instance, copies values into the object and returns it to the client. The client
receives the Transfer Object and can then invoke accessor (or getter) methods on the
Transfer Object to get the individual attribute values from the Transfer Object. Or, the
implementation of the Transfer Object may be such that it makes all attributes public.
Because the Transfer Object is passed by value to the client, all calls to the Transfer Object
instance are local calls instead of remote method invocations.
This class diagram that represents the Transfer Object pattern in its simplest form:-
The sequence diagram that shows the interactions for the Transfer Object pattern:-
Client
This represents the client of the enterprise bean. The client can be an end-user application,
as in the case of a rich client application that has been designed to directly access the
enterprise beans. The client can be Business Delegates (see "Business Delegate" on page
248) or a different BusinessObject.
BusinessObject
The BusinessObject represents a role in this pattern that can be fulfilled by a session bean,
an entity bean, or a Data Access Object (DAO). The BusinessObject is responsible for
creating the Transfer Object and returning it to the client upon request. The BusinessObject
may also receive data from the client in the form of a Transfer Object and use that data to
perform an update.
TransferObject
The TransferObject is an arbitrary serializable Java object referred to as a Transfer Object. A
Transfer Object class may provide a constructor that accepts all the required attributes to
create the Transfer Object. The constructor may accept all entity bean attribute values that
the Transfer Object is designed to hold. Typically, the members in the Transfer Object are
defined as public, thus eliminating the need for get and set methods. If some protection is
necessary, then the members could be defined as protected or private, and methods are
provided to get the values. By offering no methods to set the values, a Transfer Object is
protected from modification after its creation. If only a few members are allowed to be
modified to facilitate updates, then methods to set the values can be provided. Thus, the
Transfer Object creation varies depending on an application's requirements. It is a design
choice as to whether the Transfer Object's attributes are private and accessed via getters and
setters, or all the attributes are made public.
Session Façade
Enterprise beans encapsulate business logic and business data and expose their interfaces,
and thus the complexity of the distributed services, to the client tier.
Tight coupling, which leads to direct dependence between clients and business objects;
Too many method invocations between client and server, leading to network performance
problems;
A multitiered J2EE application has numerous server-side objects that are implemented as
enterprise beans. In addition, some other arbitrary objects may provide services, data, or
both. These objects are collectively referred to as business objects, since they encapsulate
business data and business logic.
J2EE applications implement business objects that provide processing services as session
beans. Coarse-grained business objects that represent an object view of persistent storage
and are shared by multiple users are usually implemented as entity beans.
Application clients need access to business objects to fulfill their responsibilities and to meet
user requirements. Clients can directly interact with these business objects because they
expose their interfaces. When you expose business objects to the client, the client must
understand and be responsible for the business data object relationships, and must be able to
handle business process flow.
However, direct interaction between the client and the business objects leads to tight coupling
between the two, and such tight coupling makes the client directly dependent on the
implementation of the business objects. Direct dependence means that the client must
represent and implement the complex interactions regarding business object lookups and
creations, and must manage the relationships between the participating business objects as
well as understand the responsibility of transaction demarcation.
Tight coupling between objects also results when objects manage their relationship within
themselves. Often, it is not clear where the relationship is managed. This leads to complex
relationships between business objects and rigidity in the application. Such lack of flexibility
makes the application less manageable when changes are required.
When accessing the enterprise beans, clients interact with remote objects. Network
performance problems may result if the client directly interacts with all the participating
business objects. When invoking enterprise beans, every client invocation is potentially a
remote method call. Each access to the business object is relatively fine-grained. As the
number of participants increases in a scenario, the number of such remote method calls
increases. As the number of remote method calls increases, the chattiness between the client
and the server-side business objects increases. This may result in network performance
degradation for the application, because the high volume of remote method calls increases
the amount of interaction across the network layer.
A problem also arises when a client interacts directly with the business objects. Since the
business objects are directly exposed to the clients, there is no unified strategy for accessing
the business objects. Without such a uniform client access strategy, the business objects are
exposed to clients and may reduce consistent usage.
q Avoid exposing the underlying business objects directly to the client to keep tight
coupling between the two tiers to a minimum.
To solve this, use a session bean as a facade to encapsulate the complexity of interactions
between the business objects participating in a workflow. The Session Facade manages the
business objects, and provides a uniform coarse-grained service access layer to clients.
The Session Facade abstracts the underlying business object interactions and provides a
service layer that exposes only the required interfaces. Thus, it hides from the client's view
the complex interactions between the participants. The Session Facade manages the
interactions between the business data and business service objects that participate in the
workflow, and it encapsulates the business logic associated with the requirements. Thus, the
session bean (representing the Session Facade) manages the relationships between
business objects. The session bean also manages the life cycle of these participants by
creating, locating (looking up), modifying, and deleting them as required by the workflow. In a
complex application, the Session Facade may delegate this lifestyle management to a
separate object. For example, to manage the lifestyle of participant session and entity beans,
the Session Facade may delegate that work to a Service Locator object.
Sample Code
Implementing the Session Façade
Consider a Professional Services Application (PSA), where the workflow related to entity
beans (such as Project, Resource) is encapsulated in ProjectResourceManagerSession,
implemented using the Session Facade pattern. The following example shows the interaction
with Resource and Project entity beans, as well as other business components, like Value List
Handlers and Transfer Object Assemblers.
package corepatterns.apps.psa.ejb;
i
mportj
ava.uti
l.*;
i
mportj
ava.rmi
.Rem oteExcepti
on;
i
mportj
avax.ej
b.*;
i
mportj
avax.nami
ng.*;
i
mportcorepatterns.apps.psa.core.*;
i
mportcorepatterns.uti
l.Servi
ceLocator;
i
mportcorepatterns.uti
l.Servi
ceLocatorException;
//Note:al
ltry/catch detai
ls notshown forbrevi
ty.
publ
ic cl
ass Proj
ectResourceM anagerSessi
on
i
mpl
ements Sessi
onBean {
pri
vate Sessi
onContextcontext;
//defaul
tcreate
publ
ic voi
d ej
bCreate()
throws CreateExcepti
on {
}
publ
ic voi
d ej
bCreate(
Stri
ng resourceI
d,Stri
ng proj
ectId,...)
throws CreateExcepti
on,ResourceExcepti
on {
try{
//l
ocate and connectto enti
ty beans
connectToEnti
ti
es(resourceId,projectI
d,...);
}cat
ch(...){
//Handle excepti
ons
}
}
connectToEnti
ti
es(resourceI
d,proj
ectId,...);
}
//pri
vate method to getHome forResource
pri
vate ResourceHom e getResourceHom e()
throws Servi
ceLocatorException {
return Servi
ceLocator. getI
nstance().getHome(
"ResourceEnti
ty",ResourceHom e.cl
ass);
}
//pri
vate method to getHome forProj
ect
pri
vate Proj
ectHome getProjectHom e()
throws Servi
ceLocatorException {
return Servi
ceLocator. getI
nstance().getHome(
"Proj
ectEnti
ty",Proj
ectHom e.cl
ass);
}
//pri
vate method to getResource enti
ty
pri
vate Resource getResourceEnti
ty(
Stri
ng resourceI
d) throws ResourceExcepti
on {
try{
ResourceHom e home = getResourceHome();
return (Resource)
home.fi
ndByPri
maryKey(resourceI
d);
}cat
ch(...){
//Handle excepti
ons
}
}
//pri
vate method to getProjectenti
ty
pri
vate Proj
ectgetProj
ectEnti
ty(Stri
ng proj
ectI
d)
throws ProjectExcepti
on {
/
/si
mil
arto getResourceEnti
ty
.
..
}
//Method to encapsul
ate workfl
ow rel
ated
//to assi
gni
ng a resource to a project.
//I
tdeal
s wi
th Proj
ectand Resource Enti
ty beans
publ
ic voi
d assi
gnResourceToProject(i
ntnum Hours)
throws PSAExcepti
on {
try{
i
f((proj
ectEnti
ty == nul
l)|
|
(resourceEnti
ty == nul
l)){
//Sessi
onFacade notconnected to enti
ti
es
throw new PSAExcepti
on(...);
}
//GetResource data
ResourceTO resourceTO =
resourceEnti
ty.getResourceData();
//GetProj
ectdata
Proj
ectTO projectTO =
proj
ectEnti
ty.getProj
ectData();
//fi
rstadd Resource to Proj
ect
proj
ectEnti
ty.addResource(resourceTO);
//Create a new Commi
tmentforthe Proj
ect
Commi
tmentTO commi
tm ent= new
Commi
tmentTO( ...);
}cat
ch(...){
//Handle excepti
ons
}
}
//Si
mil
arl
yimpl
ementotherbusi
ness methods to
//faci
li
tate vari
ous use cases/i
nteracti
ons
publ
ic voi
d unassi
gnResourceFromProj
ect()
throws PSAExcepti
on {
.
..
}
//Methods worki
ng wi
th ResourceEnti
ty
publ
ic ResourceTO getResourceData()
throws ResourceExcepti
on {
.
..
}
publ
ic voi
d updateBl
ockoutTi
m e(
Col
lecti
on bl
ockoutTi
me)
throws RemoteExcepti
on,Bl
ockoutTi
meExcepti
on {
.
..
}
publ
ic Col
lecti
on getResourceCommi
tments()
throws RemoteExcepti
on,ResourceExcepti
on {
.
..
}
//Methods worki
ng wi
th ProjectEnti
ty
publ
ic Proj
ectTO getProj
ectData()
throws ProjectExcepti
on {
.
..
}
//Update Proj
ectEnti
ty Bean
publ
ic voi
d setProj
ectData(Proj
ectTO proj
ect)
throws ProjectExcepti
on {
.
..
}
throws ProjectExcepti
on {
.
..
}
...
//Othersessi
on facade method exam pl
es
//Thi
sproxi
es a cal
lto a TransferObjectAssembl
er
//to obtai
n a composi
te TransferObject.
//See TransferObjectAssembl
erpattern
publ
ic Proj
ectCTO getProj
ectDetai
lsData()
throws PSAExcepti
on {
try{
Proj
ectTOAHom e proj
ectTOAHom e = (Proj
ectTOAHom e)
Servi
ceLocator.getI
nstance().getHome(
"Proj
ectTOA",Proj
ectTOAHome.cl
ass);
//TransferObj
ectAssembl
ersessi
on bean
Proj
ectTOA projectTOA =
proj
ectTOAHome.create(...);
return proj
ectTOA.getData(...);
}cat
ch (...){
//Handl
e /throw excepti
ons
}
}
proj
ectVLHHome.create();
return proj
ectLi
stHandler.getProjects(
start,end);
}cat
ch (...){
//Handl
e /throw excepti
ons
}
}
...
publ
ic voi
d ej
bActi
vate(){
.
..
}
publ
ic voi
d ej
bPassi
vate(){
context= nul
l;
}
publ
ic voi
d setSessi
onContext(Sessi
onContextctx){
thi
s.context= ctx;
}
publ
ic voi
d ej
bRem ove(){
.
..
}
The remote interface for the Session Facade is listed in the following example
Implementing Session Facade - Remote Interface
package corepatterns.apps.psa.ejb;
i
mportj
ava.rmi
.Rem oteExcepti
on;
i
mportj
avax.ej
b.*;
i
mportcorepatterns.apps.psa.core.*;
//Note:al
ltry/catch detai
ls notshown forbrevi
ty.
publ
ici
nterface ProjectResourceM anager
extends EJBObj
ect{
publ
ic resetEnti
ti
es(Stri
ng resourceI
d,
Stri
ng projectI
d,...)
throws RemoteExcepti
on,ResourceExcepti
on ;
publ
ic voi
d assi
gnResourceToProject(i
ntnum Hours)
throws RemoteExcepti
on,ResourceExcepti
on ;
publ
ic voi
d unassi
gnResourceFromProj
ect()
throws RemoteExcepti
on,ResourceExcepti
on ;
...
publ
ic ResourceTO getResourceData()
throws RemoteExcepti
on,ResourceExcepti
on ;
publ
ic voi
d setResourceData(ResourceTO resource)
throws RemoteExcepti
on,ResourceExcepti
on ;
publ
ic ResourceTO createNewResource(ResourceTO resource)
throws ResourceExcepti
on ;
publ
ic voi
d addBlockoutTi
me(Col
lecti
on blockoutTi
me)
throws RemoteExcepti
on,Bl
ockoutTi
meExcepti
on ;
publ
ic voi
d updateBl
ockoutTi
m e(Col
lecti
on bl
ockoutTi
m e)
throws RemoteExcepti
on,Bl
ockoutTi
meExcepti
on ;
publ
ic Col
lecti
on getResourceCommi
tments()
throws RemoteExcepti
on,ResourceExcepti
on;
publ
ic Proj
ectTO getProj
ectData()
throws RemoteExcepti
on,Proj
ectExcepti
on ;
publ
ic voi
d setProj
ectData(Proj
ectTO proj
ect)
throws RemoteExcepti
on,Proj
ectExcepti
on ;
publ
ic Proj
ectTO createNewProject(ProjectTO project)
throws RemoteExcepti
on,Proj
ectExcepti
on ;
...
publ
ic Proj
ectCTO getProj
ectDetai
lsData()
throws RemoteExcepti
on,PSAExcepti
on ;
publ
ic Col
lecti
on getProj
ectsLi
st(Date start,
Date end)throws RemoteException,PSAExcepti
on ;
...
}
The Home interface for the Session Facade is shown in the following example
Implementing Session Facade - Home Interface
package corepatterns.apps.psa.ejb;
i
mportj
avax.ej
b.EJBHome;
i
mportj
ava.rmi
.Rem oteExcepti
on;
i
mportcorepatterns.apps.psa.core.ResourceExcepti
on;
i
mportj
avax.ej
b.*;
publ
ici
nterface ProjectResourceM anagerHome
extends EJBHome {
publ
ic Proj
ectResourceM anagercreate()
throws RemoteExcepti
on,CreateExcepti
on;
publ
ic Proj
ectResourceM anagercreate(Stri
ng
resourceId,Stri
ng proj
ectId,...)
throws RemoteExcepti
on,CreateExcepti
on;
SUMMARY
After completing this chapter, you have learned:
q Various design patterns like MVC, Factory, Singleton
q Know about Transfer object and Session Facade
Learning Objective
After completing this chapter, you will be able to:
q Learn the best practices and how to use that while designing any J2EE
architecture
Introduction
As J2EE got eveloved best practices also eveloved along with its growth. A top 12 list of the
most important best practices for J2EE application development.These needs to be
considered while desiging any J2EE applications
This practice is so central to the successful adoption of J2EE that there is no competition for
the #1 slot. M o d e l-View-Controller (MVC) is fundamental to the design of good J2EE
applications. It is simply the division of labor of your programs into the following parts:
Those responsible for business logic (the Model -- often implemented using Enterprise
Java™Beans or plain old Java objects).
Those responsible for presentation of the user interface (the View -- usually implemented with
JSP and tag libraries, but sometimes with XML and XSLT).
Those responsible for application navigation (the Controller -- usually implemented with Java
Servlets or associated classes like Struts controllers).
There are a number of problems that can emerge from not following basic MVC architecture.
The most problems occur from putting too much into the View portion of the architecture.
Practices like using JSP tag libraries to perform database access, or performing application
flow control within a JSP are relatively common in small-scale applications, but these can
cause issues in later development as JSPs become progressively more difficult to maintain
and debug.
Likewise, we often see migration of view layer constructs into business logic. For instance, a
common problem is to push XML parsing technologies used in the construction of views into
the business layer. The business layer should operate on business objects -- not on a
particular data representation tied to the view.
However, just having the proper components does not make your application properly
layered. It is quite common to find applications that have all three of servlets, JSPs, and EJB
components, where the majority of the business logic is done in the servlet layer, or where
application navigation is handled in the JSP. You must be rigorous about code review and
refactoring to ensure that business logic is handled in the Model layer only, that application
navigation is solely the province of the Controller layer, and that your Views are simply
concerned with rendering model objects into appropriate HTML and Javascript.
There has been quite a shake-up in the methodology world over the past several years as
new, lightweight methods that call themselves Agile (such as SCRUM [Schwaber] and
Extreme Programming [Beck1] in Resources) become more commonplace. One of the
hallmarks of nearly all of these methods is that they advocate the use of automated testing
tools to improve programmer productivity by helping developers spend less time regression
testing, and to help them avoid bugs caused by inadequate regression testing. In fact, a
practice called Test-First Development [Beck2] takes this practice even further by advocating
that unit tests be written prior to the development of the actual code itself. However, before
you can test your code, you need to isolate it into testable fragments. A "big ball of mud" is
hard to test because it does not do a single, easily identifiable function. If each segment of
your code does several things, it is hard to test each bit for correctness.
One of the advantages of the MVC architecture (and the J2EE implementation of MVC) is that
the componentization of the elements make it possible (in fact, relatively easy) to test your
application in pieces. Therefore, you can easily write tests to separately test Entity beans,
Session beans, and JSPs outside of the rest of the code base. There are a number of
frameworks and tools for J2EE testing that make this process easier. For instance, JUnit,
which is an open-source tool developed by junit.org, and Cactus, which is an open source
project of the Apache consortium, are both quite useful for testing J2EE components.
[Hightower] discusses the use of these tools for J2EE in detail.
Despite all of the great information about deeply testing your application, we still see many
projects that believe that if they test the GUI (which may be a Web based GUI or a standalone
Java application), then they have comprehensively tested the entire application. GUI testing is
rarely enough. There are several reasons for this. First, with GUI testing, it is difficult to test
every path through the system. The GUI is only one way of affecting the system. There may
be background jobs, scripts, and various other access points that also need to be tested.
Often, however, they do not have GUIs. Secondly, testing at the GUI level is very coarse
grained. It tests at the macro level of the system how the system behaves. This means that if
problems are found, entire subsystems must be considered, making finding the bugs
identified difficult. Third, GUI testing usually cannot be done well until late in the development
cycle when the GUI is fully defined. This means that latent bugs will not be found
systematically until very late. Fourth, average developers probably do not have access to
automatic GUI testing tools. Thus, when a developer makes a change, there is no easy way
for that developer to retest the affected subsystem. This actually discourages good testing. If
the developer has access to automated code level unit tests, the developer can easily run
them to make sure the changes do not break existing function. Finally, if automated builds are
done, it is fairly easy to add an automated unit testing suite to the automated build process.
By doing this, the system can be rebuilt regularly (often nightly) and regression-tested with
little human intervention.
In addition, we must emphasize that distributed, component based development with EJBs
and Web services makes testing your individual components absolutely necessary. When
there is no "GUI" to test, you must then fall back on lower-level tests. It is best to start that
way, and spare yourself the headache of having to retrofit your process to include those tests
when the time comes to expose part of your application as a distributed component or Web
service.
In summary, by using automated unit tests, defects are found sooner, defects are easier to
find, testing can be made more systematic, and thus, overall quality is improved.
It is very easy to cause yourself grief by trying to play around at the edges of what J2EE
allows you to do. We find developers dig themselves into a hole by trying something that they
think will work "a little better" than what J2EE allows, only to find that it causes serious
problems in performance, or in migration (from vendor to vendor, or more commonly from
version to version) later. In fact, this is such an issue with migrations, that [Beaton] calls this
principle out as the primary best practice for Migration efforts.
There are several places in which not taking the most straightforward approach can definitely
cause problems. A common one today is where developers take over J2EE security through
the use of JAAS modules rather than relying on built-in spec compliant application server
mechanisms for authentication and authorization. Be very wary of going beyond the
authentication mechanisms provided by the J2EE specification. This can be a major source of
security holes and vendor compatibility problems. Likewise, rely on the authorization
mechanisms provided by the servlet and EJB specs, and where you need to go beyond them,
make sure you use the spec's APIs (such as getCallerPrincipal()) as the basis for your
implementation. This way you will be able to leverage the vendor-provided strong security
infrastructure and, where business needs require, support more complex authorization rules.
Other common problems include using persistence mechanisms that are not tied into the
J2EE spec (making transaction management difficult), relying on inappropriate J2SE facilities
like threading or singletons within your J2EE programs, and "rolling your own" solutions for
program-to-program communication instead of staying within supported mechanisms like
JCA, JMS, or Web services. Such design choices cause no end of difficulty when moving
from one J2EE compliant server to another, or even when moving to new versions of the
same server. Using elements outside of J2EE often causes subtle portability problems. The
only time you should ever deviate from a spec is when there is a clear problem that cannot be
addressed within the spec. For instance, scheduling the execution of timed business logic
was a problem prior to the introduction of EJB 2.1. In cases like this, we may recommend
using vendor-provided solutions where available (such as the Scheduler facility in
WebSphere® Application Server Enterprise), or to use third-party tools where these are not
available. In this way, maintenance and migration to later spec versions becomes the problem
of the vendor, and not your own problem.
Finally, be careful about adopting new technologies too early. Overzealously adopting a
technology before it has been integrated into the rest of the J2EE specification, or into a
vendor's product, is often a recipe for disaster. Support is critical -- if your vendor does not
directly support a particular technology proposed in a JSR but not yet accepted into J2EE,
you should probably not pursue it. After all, with rare exceptions, most of us are in the
business of solving business problems, not advancing technology for the sheer fun of it.
It is a continual source of astonishment to us how few customers we work with originally plan
to turn on WebSphere's J2EE security. In our estimate around 50% of the customers we see
initially plan to use this feature. For instance, we have worked with several major financial
institutions (banks, brokerages, and so on) that did not plan on turning security on; luckily this
problem was fixed in review prior to deployment.
Not leveraging J2EE security is a dangerous game. Assuming your application requires
security (almost all do), you are betting that your developers can build a better security
infrastructure than the one you bought from the J2EE vendor. That's not a good bet. Securing
a distributed application is extraordinarily difficult. For example, you need to control access to
EJBs using a network safe encrypted token. In our experience, most home-grown security
infrastructures are not secure; with significant weaknesses that leave production systems
terribly vulnerable. (Refer to chapter 18 of [Barcia] for more.)
Reasons cited for not using J2EE security include: fear of performance degradation, belief
that other security products like Netegrity SiteMinder handle this, or ignorance of the features
and capabilities of WebSphere Application Server security. Do not fall into these traps. In
particular, while products like SiteMinder provide excellent security features, they alone
cannot secure an entire J2EE application. They must work hand in hand with the J2EE
application server to secure all aspects of the system.
Another common reason given for not using J2EE security is that the role-based model does
not provide sufficiently granular access control to meet complex business rules. Though this
is often true, this is not a reason to avoid J2EE security. Instead, leverage the J2EE
authentication model and J2EE roles in conjunction with your specific extended rules. If a
complex business rule is needed to make a security decision, write the code to do it, basing
the decision upon the readily available and trustable J2EE authentication information (the
user's ID and roles).
Let's face it, J2EE is big. If a development team is just starting with J2EE, it is far too difficult
to try to learn it all at once. There are simply too many concepts and APIs to master. The key
to success in this environment is to take J2EE on in small, controlled steps.
This approach is best implemented through building small, vertical slices through your
application. Once a team has built its confidence by building a simple domain model and
back-end persistence mechanism (perhaps using JDBC) and thoroughly tested that model,
they can then move on to mastering front-end development with servlets and JSPs that use
that domain model. If a development team finds a need for EJBs, they could likewise start
with simple Session Facades atop Container-Managed persistence EJB components or
JDBC-based Data Access Objects (DAOs) before moving on to more sophisticated constructs
like Message-Driven beans and JMS.
This approach is nothing new, but relatively few teams actually build their skills in this way.
Instead, most teams cave in to schedule pressures by trying to build everything at once --
they attack the View layer, the Model Layer, and the Controller layer in MVC, simultaneously.
Instead, consider some of the new Agile development methods, such as Extreme
Programming (XP), that foster this kind of incremental learning and development. There is a
procedure often used in XP called ModelFirst [Wiki] that involves building the domain model
first as a mechanism for organizing and implementing your User Stories. Basically, you build
the domain model as part of the first set of User Stories you implement, and then build a UI
on top of it as a result of implementing later User Stories. This fits very well with letting a team
learn technologies one at a time, as opposed to sending them to a dozen simultaneous
classes (or letting them read a dozen books), which can be overwhelming.
Also, iterative development of each application layer fosters the application of appropriate
patterns and best practices. If you begin with the lower layers of your application and apply
patterns like Data Access Objects and Session Facades, you should not end up with domain
logic in your JSPs and other View objects.
Finally, when you do development in thin vertical slices, it makes it easier to start early in
performance testing your application. Delaying performance testing until the end of an
application development cycle is a sure recipe for disaster, as [Joines] relates.
Using a session facade is one of the best-established best practices for the use of EJB
components. In fact, the general practice is widely advocated for any distributed technology,
including CORBA, EJB, and DCOM. Basically, the lower the distribution "cross-section" of
your application, the less time will be wasted in overhead caused by multiple, repeated
network hops for small pieces of data. The way to accomplish this is to create very large-
grained facade objects that wrap logical subsystems and that can accomplish useful business
functions in a single method call. Not only will this reduce network overhead, but within EJBs,
it also critically reduces the number of database calls by creating a single transaction context
for the entire business function.
EJB local interfaces, introduced as part of the EJB 2.0 specification, provide performance
optimization for co-located EJBs. Local interfaces must be explicitly called by your application,
requiring code changes and preventing the ability to later distribute the EJB without
application changes. Because the Session Facade and the entity EJBs it wraps should be
local to each other, we recommend using local interfaces for the entity beans behind the
Session Facade. However, the implementation of the Session Facade itself, typically a
stateless session bean, should be designed for remote interfaces.
For performance optimization, a local interface can be added to the Session Facade. This
takes advantage of the fact that most of the time, in Web applications at least, your EJB client
and the EJB will be co-located within the same JVM. Alternatively, J2EE application server
configuration optimizations, such as WebSphere "No Local Copies," can be used if the
Session Facade is invoked locally. However, you must be aware these alternatives change
the semantics of the interaction from pass-by-value to pass-by-reference. This can lead to
subtle errors in your code.
To take advantage of these options, you should plan for this possibility from the start.
If you use a remote interface (as opposed to a local interface) for your Session Facade, then
you may also be able to expose that same Session Facade as a Web service in a J2EE 1.4
compliant way. (This is because JSR 109, the Web services deployment section of J2EE 1.4,
requires you to use the remote interface of a stateless session bean as the interface between
an EJB Web service and the EJB implementation.) Doing so is often desirable, since it can
increase the number of client types for your business logic.
Stateful session beans are, in our opinion, an idea whose time has come and gone. If you
think about it, a stateful session bean is exactly the same, architecturally, as a CORBA object
-- a single object instance, tied to a single server, which is dependent upon that server for its
life. If the server goes down, the object values are lost, and any clients of that bean are thus
out of luck.
J2EE application servers providing for stateful session bean failover can workaround some
issues, but stateful solutions are not as scalable as stateless ones. For example, in
WebSphere Application Server, requests for stateless session beans are load-balanced
across all of the members of a cluster where a stateless session bean has been deployed. In
contrast, J2EE application servers cannot load-balance requests to stateful beans. This
means load may be spread disproportionately across the servers in your cluster. In addition,
the use of stateful session beans pushes state to your application server which is undesirable.
It increases system complexity and complicates failure scenarios. One of the key principles of
robust distributed systems is stateless behavior whenever possible.
Therefore, we recommend that a stateless session bean approach be chosen for most
applications. Any user-specific state necessary for processing should either be passed in as
an argument to the EJB methods (and stored outside the EJB through a mechanism like the
HttpSession) or be retrieved as part of the EJB transaction from a persistent back-end store
(for instance, through the use of Entity beans). Where appropriate, this information can be
cached in memory, but beware of the potential challenges that surround keeping the cache
consistent in a distributed environment. Caching works best for read-only data.
In general, you should make sure that you plan for scalability from day one. Examine all the
assumptions in your design and see if they still hold if your application will run on more than
one server. This rule applies not only in application code in the cases outlined above, but also
to situations like MBeans and other administrative interfaces.
Using container-managed transactions (CMTs) provides two key advantages that are nearly
impossible to obtain without container support: composable units of work, and robust
transactional behavior.
If your application code explicitly begins and ends transactions (perhaps using
javax.jts.UserTransaction, or even native resource transactions), future requirements to
compose modules, perhaps as part of a refactoring, often requires changing the transaction
code. For example, if module A begins a database transaction, updates the database and
then commits the transaction, and module B does the same, consider what happens when
you try to use both from module C. Now, module C, which is performing what is a single
logical action, is actually causing two independent transactions to occur. If module B were to
fail during an operation, module A's work is still committed. This is not the desired behavior. If,
instead, module A and module B both used CMTs, module C can also start a CMT (typically
implicitly via the deployment descriptor) and the work in modules A and B will be implicitly part
of the same unit of work without any need for complex rework.
If your application needs to access multiple resources as part of the same operation, you
need 2-phase commit transactions. For example, if a message is removed from a JMS queue
and then a record is updated in a database based on that message, it is important that both
operations occur -- or that neither occurs. If the message was removed from the queue and
then the system failed without updating the database, this system is inconsistent. Serious
customer and business implications result from inconsistent states.
We occasionally see client applications trying to implement their own solutions. Perhaps the
application code will try to "undo" the queue operation if the database update fails. We do not
recommend this. The implementation is much more complex than you initially think and there
are many corner cases (imagine what happens if the application crashes in the middle of
this). Instead, use 2-phase commit transactions. If you use CMT and access to 2-phase
commit capable resources (like JMS and most databases) in a single CMT, WebSphere will
take care of the dirty work. It will make sure that the transaction is entirely done or entirely not
done, including failure cases such as a system crash, database crash, or whatever. The
implementation maintains transactional state in transaction logs. We cannot emphasize
enough the need to rely on CMT transactions if the application accesses multiple resources.
There is a common argument that we often hear for why you should choose XML and XSLT
as your presentation technology over JSP. This is that JSP "allows you to mix model a n d
view" too much, and that XML/XSLT is somehow free from this problem. Unfortunately, this is
not quite true, or at least not as black and white as it may seem. XSL and XPath are, in
reality, programming languages. In fact, XSL is Turing-complete, even though it may not
match most people's definition of a programming language in that it is rules-based and does
not have all of the control facilities that programmers may be used to.
The issue is that given this flexibility, developers will take advantage of it. While everyone
agrees that JSP makes it easy for developers to do "model-like" behaviors in the view, in fact,
it is possible to do some of the same kinds of things in XSL. While it is very difficult, if not
impossible, to do things like calling databases from XSL, we have seen some incredibly
complex XSLT stylesheets that perform difficult transformations that still amount to model
code.
However, the most basic reason why people should choose JSP as your first option for
presentation technology is simply because it is the best supported and best-understood J2EE
view technology available. Given the introduction of custom tag libraries, the JSTL, and the
new JSP 2.0 features, it is becoming increasingly easy to build JSPs that do not require any
Java code, and that cleanly separate model and view. There is significant support (including
debugging support) for JSP built into development environments like WebSphere Studio, and
many developers find developing with JSP easier than developing with XSL -- mostly due to
how JSP is procedurally based, as opposed to rules-based. While WebSphere Studio
supports XSL development, the graphical layout tools and other features supporting JSP
(especially when in the context of frameworks like JSF) make it much easier for developers to
work in a WYSIWYG way -- something that is not easily done with XSL.
The final reason to carefully consider using JSP is one of speed. Performance tests done at
IBM comparing the relative speed of XSL and JSP show that in most cases a JSP will be
several times faster at producing the same HTML output as an equivalent XSL transform,
even when compiled XSL is used. While this is often not an issue, in performance-critical
situations it can create problems.
This is not to say that you should never use XSL, however. There are certain cases where the
ability of XSL to take a single representation of a fixed set of data and render it in one of
several different ways based on different stylesheets (see [Fowler]) is the best solution for
rendering your views. However, this kind of requirement is most often the exception rather
than the rule. If you are only ever producing one HTML rendering for each page, then in most
cases, XSL is overkill, and it will cause more problems for your developers than it will solve.
10. When using HttpSessions, store only as much state as you need for the current
business transaction and no more.
Enable session persistence.
HttpSessions are great for storing information about application state. The API is easy to use
and understand. Unfortunately, developers often lose sight of the intent of the HttpSession --
to maintain temporary user state. It is not an arbitrary data cache. We have seen far too many
systems that put enormous amounts of data -- megabytes -- for each user's session. Well, if
there are 1000 logged-in users, each with a 1 MB HTTP session, that is one gigabyte or more
of memory in use just for sessions. Keep those HTTP sessions small. If you don't, your
application's performance will suffer. A good rule of thumb is something under 2K-4K. This
isn't a hard rule. 8K is still okay, but obviously slower than 2K. Just keep your eye on it and
prevent the HttpSession from becoming a dumping ground for data that "might" be used.
One common problem is using HttpSessions to cache information that is easily recreated,
should it be necessary. Since sessions are persisted, this is a very expensive decision forcing
unnecessary serialization and writing of the data. Instead, use an in memory hash table to
cache the data and just keep a key to the data in the session. This allows the data to be
recreated should the user fail over to another application server. (See [Brown2] for more.)
Speaking of session persistence, don't forget to enable it. If you do not enable session
persistence, should a server be stopped for any reason (a server failure or ordinary
maintenance), any user that is currently on that application server will lose their session. That
makes for a very unpleasant experience. They have to log in again and redo whatever they
were working on. If, instead, session persistence is enabled, WebSphere will automatically
move the user (and their session) to another application server, transparently. They won't
even know it happened. This works so well, that we have seen production systems that crash
regularly due to nasty bugs in native code (not IBM code!) yet provide adequate service.
11. In WebSphere, turn on dynamic caching and use the WebSphere servlet caching
mechanism.
The performance gains are substantial; the overhead minimal. The programming model is
unaffected.
The merits of caching to improve performance are well understood. Unfortunately, the current
J2EE specification does not include a mechanism for servlet/JSP caching. However,
WebSphere provides support for page and fragment caching through its dynamic cache
function without requiring any application changes. The cache policy is specified declaratively
and configuration is through XML deployment descriptors. Therefore, your application is
unaffected, remaining J2EE specification compliant and portable, while benefiting from the
performance optimizations provided from WebSphere's servlet and JSP caching.
The performance gains from dynamic caching of servlets and JSPs can be substantial,
depending on the application characteristics. Cox and Martin [Cox] showcase performance
benefits up to a multiplier of 10 from applying dynamic caching to an existing RDF (Resource
Description Format) site summary (RSS) servlet. Please recognize that this experiment
involved a simple servlet, and this order of magnitude improvement may not be reflective of a
more complex application mix.
For additional performance gains, the WebSphere servlet/JSP results cache is integrated with
the WebSphere plug-in ESI Fragment processor, the IBM HTTP Server Fast Response
Cache Accelerator (FRCA) and Edge Server caching capabilities. For heavy read-based
workloads, significant additional benefits are gained through leveraging these capabilities.
12. Prefer CMP Entity beans as a first-pass solution for O/R mapping due to the
programmer productivity benefits.
Optimize performance through the WebSphere framework (readahead, caching options,
isolation levels, and so on). If necessary, selectively apply patterns like Fast-Lane reader
[Marinescu] to achieve performance goals.
CMP EJB components are now widely used in many high performing applications.
WebSphere includes optimizations to enhance the performance of EJB components including
life-time in cache and read-ahead capabilities. Both of these optimizations are deployment
options, and do not require application modifications or impact portability.
Life-time in cache caches CMP state data and provides time-based invalidation. The
performance gains from life-time in cache approach Option A caching performance, while still
providing capabilities for your application to scale in a cluster. Read-ahead capabilities are
used in conjunction with container managed relationships. This feature minimizes database
interactions by optionally retrieving associated data in the same query as the parent data.
This provides performance benefits if the associated data is typically going to be accessed
with a subsequent query. [Gunther] provides detailed descriptions and details the
performance improvements possible from these features.
In addition, to fully optimize your EJB components, pay close attention when specifying the
isolation level. Use the lowest isolation level possible while still maintaining integrity of your
data. Lower isolation levels provide optimal performance and reduce the risk of database
deadlocks.
This is by far the most contentious best practice of the lot. Volumes have been written in
praise of CMP EJBs, and condemning them as well. However, the basic problem here is that
database development is hard. You need to have a fundamental knowledge of how queries
and database locks work before beginning to use any persistence solution. If you choose to
use CMP EJBs, be sure you are well-educated in their use through books such as [Brown]
and [Barcia]. There are subtle interactions in locking and contention that are difficult to
understand, but which can be mastered given enough time and effort.
SUMMARY
After completing this chapter, you have learned:
q The best practices and how to use that while designing any J2EE architecture
REFERENCES
WEBSITES
http://www.tutorgig.com/
http://www.java.sun.com/
http://www.enterprisedeveloper.com/developers
BOOKS
q EJB- mastering Enterprise Java Beans By Roman Ed
q Enterprise Java Beans By MONSON-HAEFEL RICHARD
q Enterprise Java Beans By Tom Valesky
q JAVA & XML By BRETT McLAUGHLIN
q JAVA Server Programming By AYERS DANNY ET AL
q JAVA Server Programming J2EE Ed Vol1 & Vol2 By KARL AVEDAL
STUDENT NOTES: