Professional Documents
Culture Documents
The classes and interfaces defined in the javax.servlet package are protocol independent, while
the second one, the javax.servlet.http contains classes and interfaces which are HTTP specific.
The classes and interfaces of the Java servlet AP can be divided in several categories,
namely:
servlet implementation
servlet configuration
servlet exceptions
request and responses
session tracking
servlet context
servlet collaboration
miscellaneous
11.( the Ser+'et inter"a$e
The Servlet interface is part of the javax.servlet package. t declares the following
methods:
p$%lic void init0ServletCon5ig con5ig1 throws Servlet'xceptionW
p$%lic void service0ServletReM$est reM3 ServletResponse resp1 throws
95
11 - JND
Servlet'xception3 I+'xceptionW
p$%lic void destroB01 throws Servlet'xceptionW
p$%lic ServletCon5ig getServletCon5ig01W
p$%lic String getServletIn5o01W
After instantiating the servlet, the web container calls its init01 method. The method
performs all initialization required, before the servlet processes any HTTP request. The servlet
specification insures that the init01 method is called just once for any given instance of the
servlet.
The web container calls the service01 method in response to any incoming request. This
method has two arguments, arguments which implement the ServletReM$est and
ServletResponse interfaces, respectively.
More on the servlet lifecycle, in a different section.
11.* the Generi$Ser+'et $'ass
p$%lic a%stract class -enericServlet implements
Servlet3 ServletCon5ig3 SerialiRa%le
This class provides a basic implementation of the Servlet interface. Since this class
implements the ServletCon5ig interface, as well, the developer may call ServletCon5ig
methods directly, without having to obtain a ServletCon5ig object first. All classes extending
the GenericServlet class should provide an implementation for the service01 method.
Methods specific to this class:
public void init()
public void log(String msg)
public void log(String msg, Throwable t)
11., the Htt&Ser+'et $'ass
t is very likely that the only implementation of the Servlet interface we'll ever use is one that
processes an HTTP request. The servlet AP provides such a specific class, namely the
6ttpServlet class.
public abstract class HttpServlet extends GenericServlet implements Serializable
The HttpServlet provides an HTTP specific implementation of the Servlet interface. This
abstract class specifies the following methods:
public void service(ServletRequest req, ServletResponse resp)
96
11 - JND
public void service(HttpServletRequest req, HttpServletResponse resp)
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
protected void doPost(HttpServletRequest req,
HttpServletResponse resp)
protected void doDelete(HttpServletRequest req,
HttpServletResponse resp)
protected void doOptions(HttpServletRequest req,
HttpServletResponse resp)
protected void doPut(HttpServletRequest req, HttpServletResponse resp)
protected void doTrace(HttpServletRequest req,
HttpServletResponse resp)
11.- the Ser+'etC!n"ig inter"a$e
This interface abstracts configuration information about the servlet, namely:
initialization parameters (as name-value pairs)
the name of the servlet
a ServletContext object, containing web container information
This interface specifies the following methods:
public String getnitParameter(String name)
public Enumeration getnitParameterNames()
public ServletContext getServletContext()
public String getServletName()
11.0 ser+'et eC$e&ti!ns
The Java servlet AP specifies two servlet specific exceptions:
javax.servlet.Servlet'xception
javax.servlet.navaila%le'xception
The Servlet'xception class extends java.lang.'xception and can be thrown by the
init01, service01, doXXX01 and destroB01 methods of the Servlet interface
implementations.
The navaila%le'xception indicates to the web container that the servlet instance is
unavaialble. t also extends the java.lang.'xception class.
97
11 - JND
11.4 the ser+'et 'i"e$1$'e
Generally, a servlet instance goes through the following stages:
instantiation
initialization
service
destroy
unavailable
The container creates a servlet instance as first response to an incoming (HTTP) request or at
container startup. Typically, the web container creates a single instance of the servlet, which will
service all incoming requests. f the servlet does not implement the
javax.servlet.Single!hreadModel, concurrent requests are serviced in more than one
service thread, which requires that the service01 method be thread safe.
After instantiation, the container calls the init01 method of the servlet, method which
performs the initialization of the servlet. Typically, this method contains JDBC driver loading, DB
connection opening, etc.
The web container makes sure that the init01 method of the servlet will be completed before
invoking its service01 method. Also, the servlet's destroB01 method will be called before the
servlet itself is destroyed.
11.15 the Ser+'et9e@est inter"a$e
Here are some of the methods of this interface:
p$%lic +%ject get(ttri%$te0String name1
p$%lic +%ject set(ttri%$te0String name3 +%ject attr1
p$%lic 'n$meration get(ttri%$te)ames01
p$%lic int getContentLength01
p$%lic String getContent!Bpe01
p$%lic String get7arameter0String name1
p$%lic 'n$meration get7arameter)ames01
p$%lic 'n$meration get7arameterGal$es01
p$%lic String getServer)ame01
p$%lic int getServer7ort01
p$%lic String getRemote(ddr01
p$%lic String getRemote6ost01
Most of the above methods are self explanatory. But what is the difference between a
parameter and an attribute? While the parameters of the request are part of the request itself, the
attributes of the request are attached by the web containers or by the servlets/JSPs.
There are 3 different ways for attaching and retrieving attributes. The first one is to attach
98
11 - JND
attributes to the request object. The other two use the HttpSession and ServletContext objects,
respectively. The purpose of attributes is to allow the container to provide additional data to a
servlet or JSP or to allow sending data from a servlet to another.
11.11 the Htt&Ser+'et9e@est inter"a$e
p$%lic inter5ace 6ttpServletReM$est extends ServletReM$est
This interface contains HTTP specific methods. One has to take in account the structure of an
HTTP request when overviewing the most important methods of this interface. Here are some of
them:
p$%lic Coo2ieST getCoo2ies01
p$%lic long get#ate6eader01
p$%lic String get6eader0String name1
p$%lic 'n$meration get6eaders0String name1
p$%lic 'n$meration get6eader)ames01
p$%lic String getContext7ath01
p$%lic String get7athIn5o01
p$%lic String getH$erBString01
p$%lic String getRemoteser01
11.12 the Ser+'et9es&!nse inter"a$e
This interface defines methods for constructing responses to servlet requests.
Here are the most important ones:
p$%lic Servlet+$tp$tStream get+$tp$tStream01
p$%lic 7rint/riter get/riter01
p$%lic void setContentLength0int len1
p$%lic void setContent!Bpe0String tBpe1
p$%lic void setC$55erSiRe0int siRe1
p$%lic int getC$55erSiRe01
p$%lic void 5l$shC$55er01
11.1% the Htt&Ser+'et9es&!nse inter"a$e
99
11 - JND
This interface extends the ServletResponse interface and defines methods specific for
constructing responses to HTTP requests.
Here are the most important ones:
p$%lic void addCoo2ie0Coo2ie coo2ie1
p$%lic String encodeRL0String $rl1
p$%lic void send'rror0int stat$s1
p$%lic void send'rror0int stat$s3 String message1
p$%lic void set6eader0String header)ame3 String val$e1
p$%lic void add6eader0String header)ame3 String val$e1
p$%lic void setStat$s0int stat$sCode1
11.1( the Ser+'etC!nteCt inter"a$e
A servlet context defines servlet's view of the web application and provides access to resources
common to all servlets of the web application. Each servlet context is rooted at a specific path in
the web server. The deployment of a web application involves adding an application specific
;context4 tag which associates the the name of the application with its root directory. This is
done in server's (container's) server.xml file.
The ServletContext interface abstracts the context of a web application. A reference to an
object of this type can be obtained by invoking the getServletContext01 method of the
6ttpServlet object.
p$%lic String getMIM'!Bpe0String 5ile)ame1
p$%lic String getReso$rce0String path1
p$%lic ServletContext getContext0String $rl7ath1
p$%lic String getInit7arameter0String name1
p$%lic 'n$meration getInit7arameter)ames01
p$%lic +%ject get(ttri%$te0String name1
p$%lic 'n$meration get(ttri%$te)ames01
p$%lic void set(ttri%$te0String name3 +%ject attr1
p$%lic String remove(ttri%$te0String name1
11.1* the Enr!'' ser+'et
The Enroll servlet services the request sent by the web browser when we submit the Enroll form
(file Enroll.html)
Here is its abbreviated form (topics which are DB related are postponed) of the
100
11 - JND
"EnrollServlet.java" file:
package com.bank11.ccards.servlets;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class EnrollServlet extends HttpServlet
{
public void init(ServletConfig config)
throws ServletException
{
super.init(config);
}
public void doPost(HttpServletRequest req,
HttpServletResponse resp)
throws ServletException, OException
{
resp.setContent!Bpe0Ytext/htmlL1W
7rint/riter o$t K resp.get/riter01W
// o$tp$t Bo$r page here
o$t.println0=;html4=1W
o$t.println0=;head4=1W
o$t.println0=;title4Servlet;/title4=1W
o$t.println0=;/head4=1W
o$t.println0=;%odB4=1W
o$t.println0=merge=1W
o$t.println0=;%r4=1W
o$t.println0=;/%odB4=1W
o$t.println0=;/html4=1W
o$t.close01W
V
V
101
12 - SERVLETS
12 - SE97LETS
12.1 the ser+'ets as &art !" web a&&'i$ati!ns
3a+a ser+'ets small, platform independent programs, which extend the functionality of the
web server.
Technically speaking, a servlet is a Java class that extends the GenericServlet (or, more often,
the HttpServlet) class.
The Java servlet AP provides a simple frame for building web applications on web servers.
The current Java Servlet specification (as of 10.2008) is 2.5 and is in final state. Java EE 5
SDK contains an implementation of the Java Servlet 2.5 specification.
12.2 ser+'et $!ntainers
The servlet does not communicate directly with the client, but through a web container. The
servlet lives within this container which provides an execution environment for the servlet class.
Web containers are implemented by various vendors, in most cases as part of an application
server.
12.2.1 N!n$!..er$ia' ser+'et $!ntainers
Apache Tomcat (formerly Jakarta Tomcat) is an open source web container available
under the Apache Software License.
Apache Geronimo is a full Java EE implementation by Apache.
Jetty
Jaminid contains a higher abstraction than servlets.
Enhydra
Winstone supports specification v2.4, has a focus on minimal configuration and the ability
to strip the container down to only what you need.
tjws spec 2.4, small footprint, modular design
12.2.2 $!..er$ia' ser+'et $!ntainers
BEA WebLogic Server or Weblogic Express, from BEA Systems
Borland Enterprise Server
GlassFish (open source)
Java System Application Server , from Sun Microsystems
Java System Web Server , from Sun Microsystems
JBoss (open source)
JRun , from Adobe Systems (formerly developed by Allaire Corporation)
LiteWebServer (open source)
102
12 - SERVLETS
Oracle Application Server , from Oracle Corporation
Orion Application Server , from ronFlare
Caucho's Resin Server
ServletExec , from New Atlanta Communications
WebObjects , from Apple nc.
WebSphere , from BM
12.% ser+'et &a$>ages and $'asses
The Java servlet AP consists of 2 packages, which are part of the J2 SDK, Enterprise Edition.
These packages are:
javax.servlet
javax.servlet.http
The classes and interfaces defined in the javax.servlet package are protocol independent, while
the second one, the javax.servlet.http contains classes and interfaces which are HTTP specific.
The classes and interfaces of the Java servlet AP can be divided in several categories,
namely:
servlet implementation
servlet configuration
servlet exceptions
request and responses
session tracking
servlet context
servlet collaboration
miscellaneous
12.( the Ser+'et inter"a$e
The Servlet interface is part of the javax.servlet package. t declares the following
methods:
p$%lic void init0ServletCon5ig con5ig1 throws Servlet'xceptionW
p$%lic void service0ServletReM$est reM3 ServletResponse resp1 throws
Servlet'xception3 I+'xceptionW
p$%lic void destroB01 throws Servlet'xceptionW
p$%lic ServletCon5ig getServletCon5ig01W
p$%lic String getServletIn5o01W
103
12 - SERVLETS
After instantiating the servlet, the web container calls its init01 method. The method
performs all initialization required, before the servlet processes any HTTP request. The servlet
specification insures that the init01 method is called just once for any given instance of the
servlet.
The web container calls the service01 method in response to any incoming request. This
method has two arguments, arguments which implement the ServletReM$est and
ServletResponse interfaces, respectively.
More on the servlet lifecycle, in a different section.
12.* the Generi$Ser+'et $'ass
p$%lic a%stract class -enericServlet implements
Servlet3 ServletCon5ig3 SerialiRa%le
This class provides a basic implementation of the Servlet interface. Since this class
implements the ServletCon5ig interface, as well, the developer may call ServletCon5ig
methods directly, without having to obtain a ServletCon5ig object first. All classes extending
the GenericServlet class should provide an implementation for the service01 method.
Methods specific to this class:
public void init()
public void log(String msg)
public void log(String msg, Throwable t)
12., the Htt&Ser+'et $'ass
t is very likely that the only implementation of the Servlet interface we'll ever use is one that
processes an HTTP request. The servlet AP provides such a specific class, namely the
6ttpServlet class.
public abstract class HttpServlet extends GenericServlet implements Serializable
The HttpServlet provides an HTTP specific implementation of the Servlet interface. This
abstract class specifies the following methods:
public void service(ServletRequest req, ServletResponse resp)
public void service(HttpServletRequest req, HttpServletResponse resp)
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
protected void doPost(HttpServletRequest req,
HttpServletResponse resp)
104
12 - SERVLETS
protected void doDelete(HttpServletRequest req,
HttpServletResponse resp)
protected void doOptions(HttpServletRequest req,
HttpServletResponse resp)
protected void doPut(HttpServletRequest req, HttpServletResponse resp)
protected void doTrace(HttpServletRequest req,
HttpServletResponse resp)
12.- the Ser+'etC!n"ig inter"a$e
This interface abstracts configuration information about the servlet, namely:
initialization parameters (as name-value pairs)
the name of the servlet
a ServletContext object, containing web container information
This interface specifies the following methods:
public String getnitParameter(String name)
public Enumeration getnitParameterNames()
public ServletContext getServletContext()
public String getServletName()
12.0 ser+'et eC$e&ti!ns
The Java servlet AP specifies two servlet specific exceptions:
javax.servlet.Servlet'xception
javax.servlet.navaila%le'xception
The Servlet'xception class extends java.lang.'xception and can be thrown by the
init01, service01, doXXX01 and destroB01 methods of the Servlet interface
implementations.
The navaila%le'xception indicates to the web container that the servlet instance is
unavaialble. t also extends the java.lang.'xception class.
12.4 the ser+'et 'i"e$1$'e
Generally, a servlet instance goes through the following stages:
105
12 - SERVLETS
instantiation
initialization
service
destroy
unavailable
The container creates a servlet instance as first response to an incoming (HTTP) request or at
container startup. Typically, the web container creates a single instance of the servlet, which will
service all incoming requests. f the servlet does not implement the
javax.servlet.Single!hreadModel, concurrent requests are serviced in more than one
service thread, which requires that the service01 method be thread safe.
After instantiation, the container calls the init01 method of the servlet, method which
performs the initialization of the servlet. Typically, this method contains JDBC driver loading, DB
connection opening, etc.
The web container makes sure that the init01 method of the servlet will be completed before
invoking its service01 method. Also, the servlet's destroB01 method will be called before the
servlet itself is destroyed.
12.15 the Ser+'et9e@est inter"a$e
Here are some of the methods of this interface:
p$%lic +%ject get(ttri%$te0String name1
p$%lic +%ject set(ttri%$te0String name3 +%ject attr1
p$%lic 'n$meration get(ttri%$te)ames01
p$%lic int getContentLength01
p$%lic String getContent!Bpe01
p$%lic String get7arameter0String name1
p$%lic 'n$meration get7arameter)ames01
p$%lic 'n$meration get7arameterGal$es01
p$%lic String getServer)ame01
p$%lic int getServer7ort01
p$%lic String getRemote(ddr01
p$%lic String getRemote6ost01
Most of the above methods are self explanatory. But what is the difference between a
parameter and an attribute? While the parameters of the request are part of the request itself, the
attributes of the request are attached by the web containers or by the servlets/JSPs.
There are 3 different ways for attaching and retrieving attributes. The first one is to attach
attributes to the request object. The other two use the HttpSession and ServletContext objects,
respectively. The purpose of attributes is to allow the container to provide additional data to a
servlet or JSP or to allow sending data from a servlet to another.
106
12 - SERVLETS
12.11 the Htt&Ser+'et9e@est inter"a$e
p$%lic inter5ace 6ttpServletReM$est extends ServletReM$est
This interface contains HTTP specific methods. One has to take in account the structure of an
HTTP request when overviewing the most important methods of this interface. Here are some of
them:
p$%lic Coo2ieST getCoo2ies01
p$%lic long get#ate6eader01
p$%lic String get6eader0String name1
p$%lic 'n$meration get6eaders0String name1
p$%lic 'n$meration get6eader)ames01
p$%lic String getContext7ath01
p$%lic String get7athIn5o01
p$%lic String getH$erBString01
p$%lic String getRemoteser01
12.12 the Ser+'et9es&!nse inter"a$e
This interface defines methods for constructing responses to servlet requests.
Here are the most important ones:
p$%lic Servlet+$tp$tStream get+$tp$tStream01
p$%lic 7rint/riter get/riter01
p$%lic void setContentLength0int len1
p$%lic void setContent!Bpe0String tBpe1
p$%lic void setC$55erSiRe0int siRe1
p$%lic int getC$55erSiRe01
p$%lic void 5l$shC$55er01
12.1% the Htt&Ser+'et9es&!nse inter"a$e
This interface extends the ServletResponse interface and defines methods specific for
constructing responses to HTTP requests.
Here are the most important ones:
107
12 - SERVLETS
p$%lic void addCoo2ie0Coo2ie coo2ie1
p$%lic String encodeRL0String $rl1
p$%lic void send'rror0int stat$s1
p$%lic void send'rror0int stat$s3 String message1
p$%lic void set6eader0String header)ame3 String val$e1
p$%lic void add6eader0String header)ame3 String val$e1
p$%lic void setStat$s0int stat$sCode1
12.1( the Ser+'etC!nteCt inter"a$e
A servlet context defines servlet's view of the web application and provides access to resources
common to all servlets of the web application. Each servlet context is rooted at a specific path in
the web server. The deployment of a web application involves adding an application specific
;context4 tag which associates the the name of the application with its root directory. This is
done in server's (container's) server.xml file.
The ServletContext interface abstracts the context of a web application. A reference to an
object of this type can be obtained by invoking the getServletContext01 method of the
6ttpServlet object.
p$%lic String getMIM'!Bpe0String 5ile)ame1
p$%lic String getReso$rce0String path1
p$%lic ServletContext getContext0String $rl7ath1
p$%lic String getInit7arameter0String name1
p$%lic 'n$meration getInit7arameter)ames01
p$%lic +%ject get(ttri%$te0String name1
p$%lic 'n$meration get(ttri%$te)ames01
p$%lic void set(ttri%$te0String name3 +%ject attr1
p$%lic String remove(ttri%$te0String name1
12.1* the Enr!'' ser+'et
The Enroll servlet services the request sent by the web browser when we submit the Enroll form
(file Enroll.html)
Here is its abbreviated form (topics which are DB related are postponed) of the
"EnrollServlet.java" file:
package com.bank11.ccards.servlets;
import java.io.*;
108
12 - SERVLETS
import javax.servlet.*;
import javax.servlet.http.*;
public class EnrollServlet extends HttpServlet
{
public void init(ServletConfig config)
throws ServletException
{
super.init(config);
}
public void doPost(HttpServletRequest req,
HttpServletResponse resp)
throws ServletException, OException
{
resp.setContent!Bpe0Ytext/htmlL1W
7rint/riter o$t K resp.get/riter01W
// o$tp$t Bo$r page here
o$t.println0=;html4=1W
o$t.println0=;head4=1W
o$t.println0=;title4Servlet;/title4=1W
o$t.println0=;/head4=1W
o$t.println0=;%odB4=1W
o$t.println0=merge=1W
o$t.println0=;%r4=1W
o$t.println0=;/%odB4=1W
o$t.println0=;/html4=1W
o$t.close01W
V
V
109
13 - JDBC
1% - 3DBC
1%.1 what is #db$F
JDBC stands for Java Data Base Connectivity and is the Java version of ODBC (Open Data
Base Connectivity). t offers an AP for SQL-compliant relational databases access. t abstracts
the vendor-specific details and offers support for the most common database access functions.
1%.2 #db$ dri+ers
Each database vendor offers its own version of DB access AP. A JDBC driver is a middleware
layer that translates JDBC calls into vendor specific calls. These drivers fall into four standard
categories, as recognized by the DB industry.
Type 1. 3DBC ) ODBC Bridge
The driver translates the JDBC calls into equivalent ODBC calls. Both the JDBC and the JDBC-
ODBC calls are invoked within the client application. This solution is inefficient, due to the
multiple layers of indirection involved and to the limitations imposed to the JDBC layer by the
ODBC frame.
The standard JDK includes all the classes for this bridge, namely
s$n.jd%c.od%c.Zd%c+d%c#river .
Type 2. 6art 3a+a/ 6art Nati+e Dri+er
The drivers in this category use a combination of Java implementation and vendor specific
APs for DB access. The driver translates JDBC specific calls into vendor specific AP calls. The
DB returns the result of the call to the AP, which in turn, forwards them to the JDBC driver. t is
much faster than the Type 1 drivers, because it eliminates one level of indirection.
110
13 - JDBC
Type 3. Inter.ediate Database A$$ess Ser+er
Type 3 drivers are DataBase servers which act as intermediate tier between multiple clients and
multiple Database servers. The client application sends a JDBC call through a JDBC driver to the
intermediate Database servers. These servers translate the call into a native driver call which
handles the actual DB connection. This type of drivers are implemented by several application
servers, like WebLogic (of BEA Systems) or nprise Application Server (of Borland).
Type 4. 6re 3a+a Dri+ers
These are the most efficient drivers. The JDBC AP calls are converted to direct network calls
using vendor provided protocols. All major vendors provide type 4 JDBC drivers for their
Database products.
111
13 - JDBC
For an extensive list of JDBC drivers, check the site:
http://industry.java.sun.com/products.j/jdbc/drivers .
1%.% $!nne$ting t! a database
There are two main steps in connecting to an existing database. The first one is
'!ading a database dri+er.
A database driver is specified by the driver name. Here are some examples of actual database
driver names:
com.borland.datastore.jdbc.DataStoreDriver
com.sybase.jdbc.SybDriver
com.ibm.db2.jdbc.net.DB2Driver
oracle.jdbc.driver.OracleDriver
sun.jdbc.odbc.JdbcOdbcDriver
The Java code to load the driver name is somewhat obscure, but let's take it for granted:
import java.sql.*;
import java.util.*;
try
{
Class.forName("org.gjt.mm.mysql.Driver").newnstance();
} catch (Exception e) {
// driver not found
e.printStackTrace();
}
The actual location of the database is specified by its URL (also known as connection URL).
The URL has 3 parts separated by colons, as follows:
jdbc:<subprotocol>:subname
jdbc is the &r!t!$!' name (actually, the only protocol allowed in JDBC).
the sb-&r!t!$!' is used to identify the JDBC driver, as specified by the driver vendor.
sbna.e the syntax of this field is vendor specific and allows the identification
Here are some examples of JDBC driver URLs:
jdbc:sybase:localhost:2025
112
13 - JDBC
jdbc:db2://db2.bank11.com:50002/ccards
jdbc:oracle:thin:@loclahost:1521:ORCL
The second step in connecting to an existing database is to !&en the $!nne$ti!n/ by using the
connection URL.
Here is some sample code which shows how this is done:
String connRL K =jd%c:mBsMl://localhost:339A/ccards=W
String $ser K =root=W
String passwd K =root=
Connection conn K #riverManager.getConnection0connRL3
$ser3 passwd1W
Since we just used it, let's have a better look in the next section at the #riverManager class.
1%.( the Dri+er2anager $'ass
This class belongs to the javax.sMl package and offers a common access layer on top of
different JDBC drivers. Each driver used by the application must be registered (loaded) before the
#riverManager class tries to obtain a connection.
There are 3 versions of the getConnection01 method of the #riverManager class. Here
they are:
public static Connection getConnection(String connURL)
throws SQLException
public static Connection getConnection(String connURL, String user, String passwd)
throws SQLException
public static Connection getConnection(String connURL,
java.util.Properties info) throws SQLException
While the first two forms of getConnection() are pretty straightforward, let's see an example of
how to use the last of the three forms.
7roperties prp K new 7roperties01W
prp.p$t0=a$tocommit=3 =tr$e=1W
prp.p$t0=create=3 =tr$e=1W
Connection conn K #riverManager.getConnection0connRL3 prp1W
113
13 - JDBC
1%.* the C!nne$ti!n inter"a$e
The Connection interface is part of then javax.sMl package. Once we get the hold of a
Connection object, we can use it for various purposes, but we will restrict ourselves to creating
SQL statements. The most important methods for creating statements:
Statement createStatement01 throws SHL'xception
Statement createStatement0int res$ltSet!Bpe3 int res$ltSetConc$rrencB1
throws SHL'xception
Statement createStatement0int res$ltSet!Bpe3 int res$ltSetConc$rrencB3
int res$ltSet6olda%ilitB1
7reparedStatement prepareStatement0String sMl1
throws SHL'xception
Calla%leStatement prepareCall0String sMl1
throws SHL'xception
1%., state.ent inter"a$es
The objects we encountered in the previous section, namely, Statement,
7reparedStatement and Calla%leStatement abstract regular SQL statements, prepared
statements and stored procedures, respectively.
The Statement interface has (among others) the following methods:
1. methods for executing statements:
exec$te01
exec$teH$erB01
exec$tepdate01
2. methods for batch updates:
addCatch01
exec$teCatch01
clearCatch01
3. methods for result set fetch size and direction:
set*etchSiRe01
get*etchSiRe01
set*etch#irection01
get*etch#irection01
114
13 - JDBC
4. method to get the current result set:
getRes$ltSet01
5. methods for result set concurrency and type:
getRes$ltSetConc$rrencB01
getRes$ltSet!Bpe01
6. other methods:
setH$erB!imeo$t01
getH$erB!imeo$t01
setMax*ieldSiRe01
getMax*ieldSiRe01
cancel01
getConnection01
The Statement interfaces also support the same methods for transaction support as the
Connection objects.
Objects implementing the Connection interface are mainly used for SQL queries execution.
Here is a typical example:
Statement stmt K conn.createStatement01W
String sMlString K =CR'(!' !(CL' c$stomer ...=W
stmt.exec$tepdate0sMlString1W
1%.- the 9es'tSet inter"a$e
The result of a query by a Statement object is a java.sMl.Res$ltSet object which is
available to the user and allows access to the data retrieved. The interface Res$ltSet is
implemented by driver vendors.
Methods to retrieve data:
get(sciiStream01
getCoolean01
get#ate01
getInt01
getShort01
get!imeStamp01
115
13 - JDBC
getCinarBStream01
getCBtes01
get*loat01
get+%ject01
get!ime01
getString01
getCBte01
get#o$%le01
getLong01
getCig#ecimal01
getMeta#ata01
getClo%01
get/arnings01
getClo%01
Most of these methods require the column index (which in SQL starts at 1, not at 0) or the
column name, as the argument.
The usage of these retrieval methods assumes the prior knowledge of the type and the index
(or name) of a particular column. What if we don't have this knowledge? Fortunately, all this data
about the DB schema (or metadata) can be retrieved using the Res$ltSetMeta#ata interface.
The invocation of the getMeta#ata01 method of a Res$ltSet object returns an object of
Res$ltSetMeta#ata type.
Here are the most important methods specified by the Res$ltSetMeta#ata interface:
getCatalog)ame01
get!a%le)ame01
getSchema)ame01
getCol$mnCo$nt01
getCol$mn)ame01
getCol$mnLa%el01
getCol$mn!Bpe01
getCol$mn!Bpe)ame01
getCol$mnClass)ame01
getCol$mn#isplaBSiRe01
getScale01
get7recision01
is)$lla%le01
isC$rrencB01
isSearcha%le01
isCaseSensitive01
116
13 - JDBC
isSigned01
is($toIncrement01
isRead+nlB01
is#e5initelB/rita%le01
1%.0 eCa.&'e !" data retrie+a'
// DisplayServlet.java
package com.bank11.ccards.servlets;
import java.sql.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.math.*;
import java.util.*;
public class DisplayServlet extends HttpServlet {
Connection conn;
// nitializes the servlet
public void init(ServletConfig config) throws ServletException {
super.init(config);
String driverName = "org.gjt.mm.mysql.Driver";
try {
Class.forName("org.gjt.mm.mysql.Driver");
}
catch(ClassNotFoundException e) {
e.printStackTrace();
}
String connURL="jdbc:mysql://localhost:3306/ccards";
try {
conn=DriverManager.getConnection(connURL,"root","root");
} catch (SQLException sqle) {
sqle.printStackTrace();
}
}
// Destroys the servlet.
public void destroy() {
}
117
13 - JDBC
// Processes requests for both HTTP GET and POST methods.
protected void processRequest(HttpServletRequest req, HttpServletResponse resp) throws
ServletException, java.io.OException {
String theCode = req.getParameter("CODE);
String sql = "SELECT FRST_NAME, LAST_NAME, ACCOUNT_NUM from
CUSTOMERS where CNP=+theCode+;;
try {
Statement stmt = conn.getStatement();
ResultSet rs = stmt.executeQuery(sql);
while(rs.next()) {
String firstName = rs.getString("FRST_NAME);
String lastName = rs.getString("LAST_NAME);
BigDecimal accountNum = rs.getBigDecimal("ACCOUNT_NUM);
}
} catch (SQLException sqle) {
sqle.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
resp.setContentType("text/html");
java.io.PrintWriter out = resp.getWriter();
// output your page here
out.println("<html>");
out.println("<head>");
out.println("<title>Servlet</title>");
out.println("</head>");
out.println("<body>");
...
out.println("</body>");
out.println("</html>");
out.close();
}
// Handles the HTTP GET method.
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws
ServletException, java.io.OException {
processRequest(req, resp);
}
// Handles the HTTP POST method.
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws
ServletException, java.io.OException {
processRequest(req, resp);
}
118
13 - JDBC
// Returns a short description of the servlet.
public String getServletnfo() {
return "Short description";
}
}
1%.4 the 6re&aredState.ent inter"a$e
f an SQL statement is used several times and its different forms differ only with respect to the
data they specify, a better choice is the usage of a 7reparedStatement object. Prepared
statements are parametrized and each parameter (usually, a field (column) value or name) is
represented by a question mark '?'.
The following lines of Java code give an example of how to use 7reparedStatement objects:
Statement stmt K con.createStatement01W
7reparedStatement pstmt K con.prepareStatement0=I)S'R! I)!+ c$stomer
G(L'S 0O3 O3 O1=1W
stmt.exec$tepdate0=CR'(!' !(CL' c$stomer 0id int3 5irst)ame
varchar03D1 last)ame varchar0D:11=1W
// set parameters 5or preparedStatement
pstmt.setInt083 89D81W
pstmt.setString0D3 =Gasile=1W
pstmt.setString033 =#$mitrasc$=1W
int co$nt K pstmt.exec$tepdate01W
1%.15 #db$ and s@' t1&es and their $!rres&!nding #a+a $'asses
+D,C Type Purpose '-. Type +#v# Type
ARRAY SQL array ARRAY java.sql.Array
BGNT 64 bit integer BGNT long
BNARY binary value none byte[]
BT one bit value BT boolean
BLOB binary large object BLOB java.sql.Blob
CHAR char string CHAR String
CLOB character large object CLOB java.sql.Clob
DATE day, month, year DATE java.sql.Date
DECMAL decimal value DECMAL java.math.Big
Decimal
119
13 - JDBC
+D,C Type Purpose '-. Type +#v# Type
DSTNCT distinct DSTNCT none
DOUBLE double precision DOUBLE PRECSON double
FLOAT double precision FLOAT double
NTEGER 32 bit integer NTEGER int
JAVA_OBJECT stores Java objects none Object
LONGVARBNARY variable length binary
value
none byte[]
LONGVARCHAR variable length char string none String
NULL null values NULL null
NUMERC decimal value NUMERC java.math.Big
Decimal
OTHER db specific types none Object
REAL single precision REAL float
REF
SMALLNT 16 bit integer SMALLNT short
STRUCT
TME hrs, mins, secs TME java.sql.Time
TMESTAMP date, time, nanoseconds TMESTAMP java.sql.Times
tamp
TNYNT 8 bit integer TNYNT short
VARBNARY variable length binary
value
none byte[]
VARCHAR variable length char string VARCHAR String
1%.11 3DBC Data S!r$es
n the JDBC 2.0 optional package, the #riverManager interface is replaced by the
#ataSo$rce interface as main method of obtaining DB connections.
While the #riverManager interface was used at run time to load explicitly a JDBC driver, the
new mechanism uses a centralized JND service to locate a javax.sMl.#ataSo$rce object.
This interface is, basicly, a factory for creating DB connections. t is part of the javax.sMl
package.
The #ataSo$rce interface is implemented by a driver vendors. There are three types of
implementations:
1. Basic implementation -- produces a standard Connection object
2. Connection pooling implementation -- produces a Connection object that will
automatically participate in connection pooling. This implementation works with a middle-
tier connection pooling manager.
120
13 - JDBC
3. Distributed transaction implementation -- produces a Connection object that may be
used for distributed transactions and almost always participates in connection pooling.
This implementation works with a middle-tier transaction manager and almost always with
a connection pooling manager.
Main methods:
p$%lic Connection getConnection01 throws SHL'xception
p$%lic Connection getConnection0String $ser3 String pwd1 throws
SHL'xception
A servlet example using the DataSource interface:
package com.bank11.ccards.servlets;
import java.io.*;
import java.sql.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.naming.*;
import javax.sql.*;
public class TestDataSource extends HttpServlet
{
private final static Logger log =
Logger.getLogger(TestDataSource.class.getName());
private final static String DATASOURCE_NAME = "jdbc/ccards";
private DataSource theDataSource;
public void setDataSource(DataSource dataSource)
{
theDataSource = dataSource;
}
public DataSource getDataSource()
{
return theDataSource;
}
public void init() throws ServletException
{
if (theDataSource == null) {
try {
Context env =
(Context) new nitialContext().lookup("java:comp/env");
theDataSource = (DataSource) env.lookup(DATASOURCE_NAME);
if (theDataSource == null)
121
13 - JDBC
throw new ServletException("`" + DATASOURCE_NAME +
"' is an unknown DataSource");
} catch (NamingException e) {
throw new ServletException(e);
}
}
}
public void doGet(HttpServletRequest request, HttpServletResponse
response) throws OException, ServletException
{
...
}
}
122
14 - JSP
1( - 3S6
1(.1 #a+a ser+er &ages as &art !" web a&&'i$ati!ns
A 3a+a Ser+er 6age (JSP) is a standard HTML or XML file which contains new scripting tags.
A JSP is loaded by a JSP container and is converted (to servlet code). f the JSP is modified,
the servlet code is regenerated.
The current JSP specification is JSP 2.1 and is related to the 2.5 Java Servlet specification.
The JSP specific interfaces, classes and exceptions are part of two packages, namely
javax.servlet.jsp and javax.servlet.jsp.tagext.
The javax.servlet.jsp package contains a number of classes and interfaces that describe and
define the contracts between a JSP page implementation class and the runtime environment
provided for an instance of such a class by a conforming JSP container.
The package javax.servlet.jsp defines two interfaces JspPage and HttpJspPage. The
interface HttpJspPage is the interface that a JSP processor-generated class for the HTTP protocol
must satisfy. The JspPage interface is the interface that a JSP processor-generated class must
satisfy.
The package javax.servlet.jsp.tagext contains classes and interfaces for the definition of
JavaServer Pages Tag Libraries.
1(.2 #a+a beans
A java bean is a java class which:
implements the java.io.Serializable interface
provides a no-argument constructor
for each of its properties, provides get and set methods
implements a property change mechanism
Here is a typical example of a java bean.
/*
* NewBean.java
*/
import java.beans.*;
import java.io.Serializable;
/**
* @author sm
123
14 - JSP
*/
public class NewBean extends Object implements Serializable {
public static final String PROP_SAMPLE_PROPERTY = "sampleProperty";
private String sampleProperty;
private PropertyChangeSupport propertySupport;
public NewBean() {
propertySupport = new PropertyChangeSupport(this);
}
public String getSampleProperty() {
return sampleProperty;
}
public void setSampleProperty(String value) {
String oldValue = sampleProperty;
sampleProperty = value;
propertySupport.firePropertyChange(PROP_SAMPLE_PROPERTY, oldValue,
sampleProperty);
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
propertySupport.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
propertySupport.removePropertyChangeListener(listener);
}
}
1(.% the #a+a.ser+'et.#s&.3s&6age inter"a$e
This interface has 2 methods:
p$%lic void jspInit01
p$%lic void jsp#estroB01
The javax.servlet.6ttpZsp7age interface has a single method:
124
14 - JSP
p$%lic void jspService06ttpServletReM$est reM3
6ttpServletResponse resp1 throws Servlet'xception3 I+'xception
The implementation of this method is generated by the web container never by the developer.
1(.( #s& tags
There are 3 categories of JSP tags (elements):
1. directives affect the structure of the whole jsp
2. scripting elements java code inserted in the JSP page
3. actions special tags affecting the run time behaviour of the JSP
Rules for JSP tags:
attribute values are always quoted (single or double quotes)
URLs follow the servlet conventions
if the URL does not start with / , it is interpreted relative to the position of the current JSP
1(.* #s& dire$ti+es
The JSP directives are messages sent by the Java Server Page to the JSP container. These
directives do not produce any client output and affect the whole JSP file.
The general format of a JSP directive is as follows:
;[Qdirective,name attr8K=val8= ... attrnK=valn= [4
Ther are three JSP directives: page, include and taglib.
The &age directive format:
;[Qpage attr8K=val8= ... [4
attributes:
language values: "java"
extends superclass of the generated class
import list of packages classes
session "true" or "false", the implicit session object is available
buffer buffering model for the output stream
autoflush if "true", the buffer is flushed automatically if full
125
14 - JSP
isThreadSafe "true" or "false"
isErrorPage "true" or "false"
contentType MME type of the response
info
errorPage the URL of an error page, in case of error
The in$'de directive instructs the container to include inline the content of the resource
specified by "5ile)ame". The format of this directive:
;[Qincl$de 5ileK=5ile)ame= [4
The tag'ib directive allows the usage of custom tags (tag extensions). t has the following
format:
;[Qtagli% $riK=tagLi%ri= pre5ixK=tag7re5ix= [4
where the tagPrefix indicates a name scope.
1(., s$ri&ting e'e.ents
1(.,.1 de$'arati!ns
;[< java vars and method declarations [4
Basicly, a bloc of java code used to define class-wide variables and methods in the generated
servlet.
1(.,.2 s$ri&t'ets
;[ valid java statements [4
Block of java code which is executed during request processing. n Tomcat, this code goes to
inside the service() method.
1(.,.% eC&ressi!ns
;[K java expressions to %e eval$ated [4
126
14 - JSP
A scriptlet that sends a value of a Java expression to back to the client. t is evaluated at
request processing time and the result is converted to a string which is then displayed.
1(.,.( standard a$ti!ns
Tags that affect the runtime behaviour of the JSP and the response to the client. A tag can be
embedded into a JSP page. The standard actions are detailed in the next paragraphs.
1(.- the seBean standard a$ti!n
<jsp:useBean>
Used to instantiate a Java bean or locate a bean instance. Assigns it to available name or id.
The syntax for this action is:
;jsp:$seCean idK=%ean)ame= scopeK=s)ame= %eandetails /4
where %eandetails is one of the following:
class="className"
class="className" type="typeName"
beanName="beanName" type="typeName"
type="typeName"
1(.0 the set6r!&ert1 standard a$ti!n
;jsp:set7ropertB4
Used in conjunction with the <jsp:useBean> action to set the value of the bean properties.
The syntax for this action is:
;jsp:set7ropertB nameK=%ean)ame= propertBdetails /4
where propertBdetails is one of the following:
property="*"
property="propertyName"
property="propertyName" param="parameterName"
property="propertyName" value="propertyValue"
where propertyValue is a string or a scriptlet.
127
14 - JSP
Attributes description:
name - the name of a bean instance, already defined in a <jsp:useBean>
property -
1(.4 the get6r!&ert1 standard a$ti!n
;jsp:get7ropertB4
Used to access the properties of a bean, converts them to string and displays the output to the
client.
The syntax for this action is:
;jsp:get7ropertB nameK=%ean)ame= propertBK=prop)ame= /4
Attributes description:
name - the name of a bean instance whose property is to be retrieved
property - name of the property to be retrieved
1(.15 the &ara. standard a$ti!n
;jsp:param4
Provide other tags with additional information in the form of name:value pairs. t is used in
conjunction with the <jsp:include>, <jsp:forward>, <jsp:plugin> actions.
The syntax for this action is:
;jsp:param nameK=param)ame= val$eK=paramGal$e= /4
1(.11 the in$'de standard a$ti!n
;jsp:incl$de4
Used for the inclusion of a static or dynamic resource into the current JSP page at request
processing time. An included page has access only to the JspWriter object and cannot set
headers or cookies. While the <%@include> directive is executed at compile time and has static
content, the <jsp:include> action is executed at request processing time and has static or dynamic
content.
The syntax for this action is:
128
14 - JSP
;jsp:incl$de pageK=pageRL= 5l$shK=tr$e= /4
Attributes description:
page - the URL of the page, same format as the ;[Qincl$de4 directive.
flush - only the "true" value is supported.
1(.12 the "!rward standard a$ti!n
;jsp:5orward4
Used to forward the the request to another JSP, servlet or to a static resource..
The syntax for this action is:
;jsp:5orward pageK=pageRL= /4
The action may include several <jsp:param> tags, as well. t is used mainly, when we want to
separate the application into different views, depending on request.
1(.1% the &'gin standard a$ti!n
;jsp:pl$gin4
Used in pages to generate client browser specific HTML tags (<OBJECT> or <EMBED>) that
result in download of Java plugins(if required), followed by the execution of the applet or
JavaBeans component specified by the tag.
The syntax for this action is:
;jsp:pl$gin tBpeK=%ean\applet= codeK=o%jCode= codeCaseK=o%jCodeCase=
alignK=align= archiveK=archiveList= heightK=height= hspaceK=hSpace=
jreversionK=jreGersion= nameK=component)ame= vspaceK=vSpace=
widthK=width= nspl$gin$rlK=netscapeRL= iepl$gin$rlK=I'RL=4
;jsp:params4
;jsp:param nameK=param)ame= val$eK=paramGal$e= /4
...
;/jsp:params4
;/jsp:pl$gin4
Attributes description:
name - the name of a bean instance, already defined in a ;jsp:$seCean4
129
14 - JSP
1(.1( i.&'i$it !b#e$ts
JSP provides several implicit objects, based on the servlet AP, objects which are automaticly
available.
1. re@est - represents the object that triggered the service() method invokation and has type
Htt&Ser+'et9e@est with scope re@est
2. res&!nse - represents server's response to the request, it has Htt&Ser+'et9es&!nse type and
&age scope
3. &ageC!nteCt - provides a single point of access to attributes and shared data within the page,
it has type 6ageC!nteCt with scope &age
4. sessi!n - it has Htt&Sessi!n type and sessi!n scope
5. a&&'i$ati!n - represents the servlet context, it has type Ser+'etC!nteCt and scope
a&&'i$ati!n
6. !t - it represents the buffered version of java.io.7rint/riter, writes to the output
stream to the client, it has #a+aC.ser+'et.#s&.3s&Writer type and scope &age
7. $!n"ig - it is the SevletCon5ig for the current JSP page, it is of type Ser+'etC!n"ig and has
&age scope
8. &age - it is an instance of the page's implementation of the servlet class, it has
#a+a.'ang.Ob#e$t type and scope &age
1(.1* s$!&es
1. re@est - an object with request scope is bound to the 6ttpServletReM$est object; the
object can be accessed by invoking the get(ttri%$te01 method on the implicit re@est
object; the generated servlet binds the object to 6ttpServletReM$est object using the
set(ttri%$te0String 2eB3 +%ject val$e1 method
2. sessi!n - an object with session scope is bound to the 6ttpSession object; the object can
be accessed by invoking the getGal$e01 method on the implicit sessi!n object; the
generated servlet binds the object to 6ttpSession object using the set(ttri%$te0String
2eB3 +%ject val$e1 method
3. a&&'i$ati!n - an object with application scope is bound to the ServletContext object; the
object can be accessed by invoking the get(ttri%$te01 method on the implicit a&&'i$ati!n
object; the generated servlet binds the object to the ServletContext object using the
set(ttri%$te0String 2eB3 +%ject val$e1 method
4. &age - an object with page scope is bound to the 7ageContext object; the object can be
accessed by invoking the get(ttri%$te01 method on the implicit &ageC!nteCt object; the
generated servlet binds the object to 7ageContext object using the set(ttri%$te0String
2eB3 +%ject val$e1 method
1(.1, an eCtended eCa.&'e
This example is provided by De+s&here/ a software development and consulting company.
130
14 - JSP
1(.1,.1 Data beans
Si.&'eBean is a Java bean that contains several standard properties (a String, a float, an int, a
boolean and another String), two indexed standard properties (a String[] and an int[]) and another
data bean (a SimpleSubBean). The SimpleBean class is declared public, has a no-arg constructor
and provides accessors (get & set methods) for its properties. The public constructor could have
been omitted, since the Java compiler generates one in the absence of any other constructors.
Si.&'eBean.#a+aE
pac2age com.devsphere.examples.mapping.simpleW
/XX
X Simple %ean
X/
p$%lic class SimpleCean implements java.io.SerialiRa%le U
private String stringW
private 5loat n$m%erW
private int integerW
private %oolean 5lagW
private String colorsSTW
private int listSTW
private String optionalW
private SimpleS$%Cean s$%CeanW
/XX
X )o&arg constr$ctor
X/
p$%lic SimpleCean01 U
V
/XX
X -ets the string propertB
X/
p$%lic String getString01 U
ret$rn this.stringW
V
/XX
X Sets the string propertB
X/
p$%lic void setString0String val$e1 U
this.string K val$eW
V
/XX
X -ets the n$m%er propertB
X/
p$%lic 5loat get)$m%er01 U
ret$rn this.n$m%erW
V
/XX
X Sets the n$m%er propertB
X/
p$%lic void set)$m%er05loat val$e1 U
this.n$m%er K val$eW
V
/XX
131
14 - JSP
X -ets the integer propertB
X/
p$%lic int getInteger01 U
ret$rn this.integerW
V
/XX
X Sets the integer propertB
X/
p$%lic void setInteger0int val$e1 U
this.integer K val$eW
V
/XX
X -ets the 5lag propertB
X/
p$%lic %oolean get*lag01 U
ret$rn this.5lagW
V
/XX
X Sets the 5lag propertB
X/
p$%lic void set*lag0%oolean val$e1 U
this.5lag K val$eW
V
/XX
X -ets the colors propertB
X/
p$%lic StringST getColors01 U
ret$rn this.colorsW
V
/XX
X Sets the colors propertB
X/
p$%lic void setColors0String val$esST1 U
this.colors K val$esW
V
/XX
X -ets an element o5 the colors propertB
X/
p$%lic String getColors0int index1 U
ret$rn this.colorsSindexTW
V
/XX
X Sets an element o5 the colors propertB
X/
p$%lic void setColors0int index3 String val$e1 U
this.colorsSindexT K val$eW
V
/XX
X -ets the list propertB
X/
p$%lic intST getList01 U
132
14 - JSP
ret$rn this.listW
V
/XX
X Sets the list propertB
X/
p$%lic void setList0int val$esST1 U
this.list K val$esW
V
/XX
X -ets an element o5 the list propertB
X/
p$%lic int getList0int index1 U
ret$rn this.listSindexTW
V
/XX
X Sets an element o5 the list propertB
X/
p$%lic void setList0int index3 int val$e1 U
this.listSindexT K val$eW
V
/XX
X -ets the optional propertB
X/
p$%lic String get+ptional01 U
ret$rn this.optionalW
V
/XX
X Sets the optional propertB
X/
p$%lic void set+ptional0String val$e1 U
this.optional K val$eW
V
/XX
X -ets the s$%Cean propertB
X/
p$%lic SimpleS$%Cean getS$%Cean01 U
ret$rn this.s$%CeanW
V
/XX
X Sets the s$%Cean propertB
X/
p$%lic void setS$%Cean0SimpleS$%Cean val$e1 U
this.s$%Cean K val$eW
V
V
Si.&'eSbBean contains only two standard properties (a String and a float).
Si.&'eSbBean.#a+aE
pac2age com.devsphere.examples.mapping.simpleW
133
14 - JSP
/XX
X Simple s$%&%ean
X/
p$%lic class SimpleS$%Cean implements java.io.SerialiRa%le U
private String stringW
private 5loat n$m%erW
/XX
X )o&arg constr$ctor
X/
p$%lic SimpleS$%Cean01 U
V
/XX
X -ets the string propertB
X/
p$%lic String getString01 U
ret$rn this.stringW
V
/XX
X Sets the string propertB
X/
p$%lic void setString0String val$e1 U
this.string K val$eW
V
/XX
X -ets the n$m%er propertB
X/
p$%lic 5loat get)$m%er01 U
ret$rn this.n$m%erW
V
/XX
X Sets the n$m%er propertB
X/
p$%lic void set)$m%er05loat val$e1 U
this.n$m%er K val$eW
V
V
1(.1,.2 the HT2L 8!r.
The properties of SimpleBean are mapped to the form elements of SimpleForm.html:
Name Property type Element type
string String text
number float text
integer int radio[]
134
14 - JSP
flag boolean checkbox
colors String[] checkbox[]
list int[] select
optional String text
subBean.string String text
subBean.number float text
Si.&'e8!r..ht.'E
;6!ML4
;6'(#4;!I!L'4Simple 5orm;/!I!L'4;/6'(#4
;C+#F4
;634Simple 'xample;/634
;*+RM M'!6+#K=7+S!=4
;74 String ;CR4
;I)7! !F7'K=!'X!= )(M'K=string= SIJ'K=D9=4
;74 )$m%er ;CR4
;I)7! !F7'K=!'X!= )(M'K=n$m%er= SIJ'K=D9=4
;74 Integer ;CR4
;I)7! !F7'K=R(#I+= )(M'K=integer= G(L'K=8=4+ption 8
;I)7! !F7'K=R(#I+= )(M'K=integer= G(L'K=D=4+ption D
;I)7! !F7'K=R(#I+= )(M'K=integer= G(L'K=3=4+ption 3
;74 *lag ;CR4
;I)7! !F7'K=C6'CKC+X= )(M'K=5lag=4*lag
;74 Colors ;CR4
;I)7! !F7'K=C6'CKC+X= )(M'K=colors= G(L'K=red=4Red
;I)7! !F7'K=C6'CKC+X= )(M'K=colors= G(L'K=green=4-reen
;I)7! !F7'K=C6'CKC+X= )(M'K=colors= G(L'K=%l$e=4Cl$e
;74 List ;CR4
;S'L'C! )(M'K=list= SIJ'K=3= ML!I7L'4
;+7!I+) G(L'K=8=4Item 8;/+7!I+)4
;+7!I+) G(L'K=D=4Item D;/+7!I+)4
;+7!I+) G(L'K=3=4Item 3;/+7!I+)4
;/S'L'C!4
;74 +ptional ;CR4
;I)7! !F7'K=!'X!= )(M'K=optional= SIJ'K=D9=4
;74 String 0s$%Cean1 ;CR4
;I)7! !F7'K=!'X!= )(M'K=s$%Cean.string= SIJ'K=D9=4
;74 )$m%er 0s$%Cean1 ;CR4
;I)7! !F7'K=!'X!= )(M'K=s$%Cean.n$m%er= SIJ'K=D9=4
;74
135
14 - JSP
;I)7! !F7'K=SCMI!= G(L'K=S$%mit=4
;I)7! !F7'K=R'S'!= G(L'K=Reset=4
;/*+RM4
;/C+#F4
;/6!ML4
1(.1,.% bean res!r$es
The SimpleBeanResources class is a resource bundle containing optional information that is
useful to the mapping process: default values, error messages, the list of optional properties, the
processing order, the form's name and the processor's name.
The default values are defined for a String, a float, a boolean and an int[]. The primitive values
must be wrapped by a Float and a Boolean in order to be stored as resources. The default values
for the properties of the contained bean could have been defined in another resource bundle
called SimpleSubBeanResources.
There are three error messages. Their role is to help the users to correct the input errors. The
mapping framework contains default error messages for each type of form element.
The list of optional properties has a single element. No error is signaled if the user doesn't
provide a value for this property.
The processing order isn't necessary to this example. t has been included here just for
demonstrative purposes.
The form's name and the processor's name are used by the JSP handler described in the next
section. These two resources aren't accessed by the mapping utilities.
Si.&'eBean9es!r$es.#a+aE
pac2age com.devsphere.examples.mapping.simpleW
p$%lic class SimpleCeanReso$rces extends java.$til.ListReso$rceC$ndle U
private static 5inal +%jectSTST contents K U
U =S#'*(L!,G(L'.stringT=3 =a%c= V3
U =S#'*(L!,G(L'.n$m%erT=3 new *loat09.8D31 V3
U =S#'*(L!,G(L'.5lagT=3 new Coolean0tr$e1 V3
U =S#'*(L!,G(L'.listT=3 new intST U D3 3 V V3
U =S'RR+R,M'SS(-'.integerT=3 =(n option m$st %e selected= V3
U =S'RR+R,M'SS(-'.colorsT=3 =+ne or more colors m$st %e
selected= V3
U =S'RR+R,M'SS(-'.listT=3 =+ne or more items m$st %e
selected= V3
U
=S+7!I+)(L,7R+7'R!I'ST=3
new StringST U
=optional=
V
V3
U
=S7R+C'SSI)-,+R#'RT=3
new StringST U
=string=3
=n$m%er=3
=integer=3
=5lag=3
=colors=3
=list=3
=optional=3
=s$%Cean=
136
14 - JSP
V
V3
U =S*+RM,)(M'T=3 =Simple*orm.html= V3
U =S7R+C,)(M'T=3 =Simple7roc.jsp= V
VW
p$%lic +%jectSTST getContents01 U
ret$rn contentsW
V
V
1(.1,.( 3S6 Hand'er
The SimpleHndl.jsp handler is based on a template that was described in a previous chapter.
The formToBean() method of com.devsphere.mapping.FormUtils sets the bean properties to
the values of the request parameters (form data). f necessary, string values are converted to
numbers. A boolean property is set to true if the request parameter is present no matter what its
value is (except "false"). The error messages that occur during the mapping process are stored in
a Hashtable.
The beanToForm() method of com.devsphere.mapping.FormUtils inserts the bean data and the
error messages into the HTML form. t inserts a VALUE attribute for text elements, a CHECKED
attribute for checkboxes and radio buttons that must be selected and a SELECTED attribute for
the list items that must be highlighted.
For a better understanding of this example, a later section of this chapter lists two JSPs that
perform the mapping and build the HTML form without using the framework.
Si.&'eHnd'.#s&E
;[Q page lang$ageK=java= [4
;[Q page importK=com.devsphere.mapping.X3 com.devsphere.logging.X= [4
;jsp:$seCean idK=simpleCean= scopeK=reM$est=
classK=com.devsphere.examples.mapping.simple.SimpleCean=/4
;[
// -et the %ean reso$rces
java.$til.Reso$rceC$ndle %eanRes
K 6andlertils.getCeanReso$rces0simpleCean.getClass011W
// Constr$ct the %ase path
String %ase7ath K reM$est.getServlet7ath01W
int slashIndex K %ase7ath.lastIndex+50I/I1W
%ase7ath K slashIndex <K &8 O %ase7ath.s$%string093 slashIndex]81 :
==W
// #etermine the 6!!7 method
%oolean is7ostMethod K reM$est.getMethod01.eM$als0=7+S!=1W
// Create a logger that wraps the servlet context
ServletLogger logger K new ServletLogger0application1W
// /rap the 5orm data
*orm#ata 5orm#ata K new Servlet*orm#ata0reM$est1W
// *orm&to&%ean mapping: reM$est parameters are mapped to %ean
properties
java.$til.6ashta%le error!a%le
K *ormtils.5orm!oCean05orm#ata3 simpleCean3 logger1W
137
14 - JSP
i5 0is7ostMethod PP error!a%le KK n$ll1 U
// Constr$ct the processorIs path
String proc7ath K %ase7ath ]
%eanRes.getString0=S7R+C,)(M'T=1.trim01W
// 7rocess the valid data %ean instance
application.getReM$est#ispatcher0proc7ath1.5orward0reM$est3
response1W
V else U
i5 0<is7ostMethod1
// Ignore the $ser errors i5 the 5orm is reM$ested with -'!.
error!a%le K 6andlertils.removeser'rrors0error!a%le1W
// Constr$ct the 5ormIs path
String 5orm7ath K %ase7ath ]
%eanRes.getString0=S*+RM,)(M'T=1.trim01W
5orm7ath K application.getReal7ath05orm7ath1W
// -et the 5orm template
*orm!emplate template K *ormtils.get!emplate0new
java.io.*ile05orm7ath11W
// -et a new doc$ment
*orm#oc$ment doc$ment K template.get#oc$ment01W
// Cean&to&5orm mapping: %ean properties are mapped to 5orm
elements
*ormtils.%ean!o*orm0simpleCean3 error!a%le3 doc$ment3 logger1W
// Send the 5orm doc$ment
doc$ment.send0o$t1W
V
[4
1(.1,.* 3S6 6r!$ess!r
The SimpleProc.jsp processor gets the beans that were validated by the JSP handler and prints
the values of their properties.
Si.&'e6r!$.#s&E
;[Q page lang$ageK=java=[4
;jsp:$seCean idK=simpleCean= scopeK=reM$est=
classK=com.devsphere.examples.mapping.simple.SimpleCean=/4
;6!ML4
;6'(#4;!I!L'4Simple %ean;/!I!L'4;/6'(#4
;C+#F4
;634Simple 'xample;/634
;74;C4 SimpleCean properties: ;/C4
;74 string K ;jsp:get7ropertB nameK=simpleCean= propertBK=string=/4
;74 n$m%er K ;jsp:get7ropertB nameK=simpleCean= propertBK=n$m%er=/4
;74 integer K ;jsp:get7ropertB nameK=simpleCean=
propertBK=integer=/4
;74 5lag K ;jsp:get7ropertB nameK=simpleCean= propertBK=5lag=/4
;74 colors K ;[K toString0simpleCean.getColors011 [4
;74 list K ;[K toString0simpleCean.getList011 [4
;74 optional K ;jsp:get7ropertB nameK=simpleCean=
propertBK=optional=/4
;74 s$%Cean.string K ;[K simpleCean.getS$%Cean01.getString01 [4
138
14 - JSP
;74 s$%Cean.n$m%er K ;[K simpleCean.getS$%Cean01.get)$m%er01 [4
;/C+#F4
;/6!ML4
;[<
p$%lic static String toString0String listST1 U
i5 0list KK n$ll \\ list.length KK 91
ret$rn ==W
i5 0list.length KK 8 PP listS9T <K n$ll1
ret$rn listS9TW
StringC$55er str%$5 K new StringC$55er01W
str%$5.append0=U =1W
5or 0int i K 9W i ; list.lengthW i]]1
i5 0listSiT <K n$ll1 U
str%$5.append0listSiT1W
str%$5.append0= =1W
V
str%$5.append0=V=1W
ret$rn str%$5.toString01W
V
p$%lic static String toString0int listST1 U
i5 0list KK n$ll \\ list.length KK 91
ret$rn ==W
i5 0list.length KK 81
ret$rn Integer.toString0listS9T1W
StringC$55er str%$5 K new StringC$55er01W
str%$5.append0=U =1W
5or 0int i K 9W i ; list.lengthW i]]1 U
str%$5.append0listSiT1W
str%$5.append0= =1W
V
str%$5.append0=V=1W
ret$rn str%$5.toString01W
V
[4
1(.1,., with!t sing the de+s&here "ra.ew!r>
ComplexForm.jsp generates the HTML form dynamically and inserts default values and error
messages. t uses 120 lines of Java-JSP-HTML mixture to generate a 40 lines HTML form. A
single call to FormUtils.beanToForm() can do the same using a pure HTML file. n addition,
beanToForm() handles and logs many types of application errors, making the testing and the
debugging easier.
ComplexHndl.jsp uses 150 lines of Java-JSP mixture to set the properties of a bean object to
the values of the request parameters. This is the equivalent of a single FormUtils.formToBean()
call.
The adding/removing of a bean property requires changes in both Complex*.jsp files. Using the
framework, you only have to add/remove a form element to/from a pure HTML file.
The localization of the Complex*.jsp files to other languages requires a lot of work and could
make the maintenance very hard. Using the framework you separate the HTML code from the
Java/JSP code. n addition, default values and error messages are kept in localizable resource
bundles. A later chapter shows how to build internationalized applications using the framework.
C!.&'eC8!r..#s&E
;[Q page lang$ageK=java= [4
139
14 - JSP
;jsp:$seCean idK=simpleCean= scopeK=reM$est=
classK=com.devsphere.examples.mapping.simple.SimpleCean=/4
;jsp:$seCean idK=error!a%le= scopeK=reM$est=
classK=java.$til.6ashta%le=/4
;6!ML4
;6'(#4;!I!L'4/itho$t $sing the 5ramewor2;/!I!L'4;/6'(#4
;C+#F4
;634'M$ivalent o5 Simple 'xample;/634
;*+RM M'!6+#K7+S!4
;74 String ;CR4
;[K get'rrorMessage0error!a%le3 =string=1 [4
;I)7! !F7'K=!'X!= )(M'K=string=
G(L'K=;jsp:get7ropertB nameK=simpleCean= propertBK=string=/4=4
;74 )$m%er ;CR4
;[K get'rrorMessage0error!a%le3 =n$m%er=1 [4
;I)7! !F7'K=!'X!= )(M'K=n$m%er=
G(L'K=;jsp:get7ropertB nameK=simpleCean= propertBK=n$m%er=/4=4
;74 Integer ;CR4
;[K get'rrorMessage0error!a%le3 =integer=1 [4
;[
String integerLa%elsST K U =+ption 8=3 =+ption D=3 =+ption 3= VW
5or 0int i K 9W i ; integerLa%els.lengthW i]]1 U
int val$e K i]8W
%oolean chec2ed K simpleCean.getInteger01 KK val$eW
[4
;I)7! !F7'K=R(#I+= )(M'K=integer= G(L'K=;[K val$e [4=
;[K chec2ed O =C6'CK'#= : == [44 ;[K integerLa%elsSiT [4
;[
V
[4
;74 *lag ;CR4
;[K get'rrorMessage0error!a%le3 =5lag=1 [4
;I)7! !F7'K=C6'CKC+X= )(M'K=5lag=
;[K simpleCean.get*lag01 O =C6'CK'#= : == [44 *lag
;74 Colors ;CR4
;[K get'rrorMessage0error!a%le3 =colors=1 [4
;[
String colorsST K simpleCean.getColors01W
i5 0colors KK n$ll1
colors K new StringS9TW
String colorLa%elsST K U =Red=3 =-reen=3 =Cl$e= VW
String colorGal$esST K U =red=3 =green=3 =%l$e= VW
5or 0int i K 9W i ; colorGal$es.lengthW i]]1 U
%oolean chec2ed K 5alseW
i5 0colors <K n$ll1
5or 0int j K 9W j ; colors.lengthW j]]1
i5 0colorsSjT.eM$als0colorGal$esSiT11 U
chec2ed K tr$eW
%rea2W
V
[4
;I)7! !F7'K=C6'CKC+X= )(M'K=colors= G(L'K=;[K colorGal$esSiT
[4=
;[K chec2ed O =C6'CK'#= : == [44 ;[K colorLa%elsSiT [4
140
14 - JSP
;[
V
[4
;74 List ;CR4
;[K get'rrorMessage0error!a%le3 =list=1 [4
;S'L'C! )(M'K=list= SIJ'K=3= ML!I7L'4
;[
int listST K simpleCean.getList01W
i5 0list KK n$ll1
list K new intS9TW
String listItemsST K U =Item 8=3 =Item D=3 =Item 3= VW
5or 0int i K 9W i ; listItems.lengthW i]]1 U
int val$e K i]8W
%oolean selected K 5alseW
i5 0list <K n$ll1
5or 0int j K 9W j ; list.lengthW j]]1
i5 0listSjT KK val$e1 U
selected K tr$eW
%rea2W
V
[4
;+7!I+) G(L' K =;[K val$e [4=
;[K selected O =S'L'C!'#= : == [44 ;[K listItemsSiT [4
;[
V
[4
;/S'L'C!4
;74 +ptional ;CR4
;[K get'rrorMessage0error!a%le3 =optional=1 [4
;I)7! !F7'K=!'X!= )(M'K=optional=
G(L'K=;jsp:get7ropertB nameK=simpleCean= propertBK=optional=/4=4
;[ i5 0simpleCean.getS$%Cean01 KK n$ll1 simpleCean.setS$%Cean0
new com.devsphere.examples.mapping.simple.SimpleS$%Cean011W [4
;74 String 0s$%Cean1 ;CR4
;[K get'rrorMessage0error!a%le3 =s$%Cean.string=1 [4
;I)7! !F7'K=!'X!= )(M'K=s$%Cean.string=
G(L'K=;[K simpleCean.getS$%Cean01.getString01 [4=4
;74 )$m%er 0s$%Cean1 ;CR4
;[K get'rrorMessage0error!a%le3 =s$%Cean.n$m%er=1 [4
;I)7! !F7'K=!'X!= )(M'K=s$%Cean.n$m%er=
G(L'K=;[K simpleCean.getS$%Cean01.get)$m%er01 [4=4
;74
;I)7! !F7'K=SCMI!= G(L'K=S$%mit=4
;I)7! !F7'K=R'S'!= G(L'K=Reset=4
;/*+RM4
;/C+#F4
;/6!ML4
;[<
String get'rrorMessage0java.$til.6ashta%le error!a%le3 String
propertB1 U
String message K 0String1 error!a%le.get0propertB1W
141
14 - JSP
i5 0message KK n$ll1
message K ==W
ret$rn messageW
V
[4
C!.&'eCHnd'.#s&E
;[Q page lang$ageK=java= [4
;jsp:$seCean idK=simpleCean= scopeK=reM$est=
classK=com.devsphere.examples.mapping.simple.SimpleCean=/4
;jsp:$seCean idK=simpleS$%Cean= scopeK=page=
classK=com.devsphere.examples.mapping.simple.SimpleS$%Cean=/4
;jsp:$seCean idK=error!a%le= scopeK=reM$est=
classK=java.$til.6ashta%le=/4
;[
simpleCean.setS$%Cean0simpleS$%Cean1W
%oolean is7ostMethod K reM$est.getMethod01.eM$als0=7+S!=1W
i5 0is7ostMethod1 U
//X string : text
[4
;jsp:set7ropertB nameK=simpleCean= propertBK=string=/4
;[
i5 0simpleCean.getString01 KK n$ll
\\ simpleCean.getString01.length01 KK 91 U
simpleCean.setString0=a%c=1W
set'rrorMessage0error!a%le3 =string=3 =M$st %e 5illed=1W
V
//X n$m%er : text
trB U
String n$m%erGal$e K reM$est.get7arameter0=n$m%er=1W
i5 0n$m%erGal$e <K n$ll PP n$m%erGal$e.length01 <K 91
simpleCean.set)$m%er0new
*loat0n$m%erGal$e1.5loatGal$e011W
else U
simpleCean.set)$m%er09.8D351W
set'rrorMessage0error!a%le3 =n$m%er=3 =M$st %e 5illed=1W
V
V catch 0)$m%er*ormat'xception e1 U
simpleCean.set)$m%er09.8D351W
set'rrorMessage0error!a%le3 =n$m%er=3 =M$st %e a n$m%er=1W
V
//X integer : radio gro$p
[4
;jsp:set7ropertB nameK=simpleCean= propertBK=integer=/4
;[
i5 0simpleCean.getInteger01 KK 91 U
set'rrorMessage0error!a%le3 =integer=3 =(n option m$st %e
selected=1W
V
//X 5lag : chec2%ox
142
14 - JSP
String 5lagGal$e K reM$est.get7arameter0=5lag=1W
i5 05lagGal$e <K n$ll1 U
5lagGal$e K 5lagGal$e.trim01W
i5 05lagGal$e.length01 KK 9 \\ 5lagGal$e.eM$als0=5alse=11
5lagGal$e K n$llW
V
simpleCean.set*lag05lagGal$e <K n$ll1W
//X color : chec2%ox gro$p
[4
;jsp:set7ropertB nameK=simpleCean= propertBK=colors=/4
;[
i5 0simpleCean.getColors01 KK n$ll
\\ simpleCean.getColors01.length KK 91 U
set'rrorMessage0error!a%le3 =colors=3
=+ne or more colors m$st %e selected=1W
V
//X list : select
[4
;jsp:set7ropertB nameK=simpleCean= propertBK=list=/4
;[
i5 0simpleCean.getList01 KK n$ll
\\ simpleCean.getList01.length KK 91 U
simpleCean.setList0new intST U D3 3 V1W
set'rrorMessage0error!a%le3 =list=3
=+ne or more items m$st %e selected=1W
V
//X optional : text
[4
;jsp:set7ropertB nameK=simpleCean= propertBK=optional=/4
;[
i5 0simpleCean.get+ptional01 KK n$ll1
simpleCean.set+ptional0==1W
//X s$%Cean.string : text
[4
;jsp:set7ropertB nameK=simpleS$%Cean= propertBK=string=
paramK=s$%Cean.string=/4
;[
i5 0simpleS$%Cean.getString01 KK n$ll
\\ simpleS$%Cean.getString01.length01 KK 91 U
simpleS$%Cean.setString0==1W
set'rrorMessage0error!a%le3 =s$%Cean.string=3 =M$st %e
5illed=1W
V
//X s$%Cean.n$m%er : text
trB U
String n$m%erGal$e K reM$est.get7arameter0=s$%Cean.n$m%er=1W
i5 0n$m%erGal$e <K n$ll PP n$m%erGal$e.length01 <K 91
simpleS$%Cean.set)$m%er0new
143
14 - JSP
*loat0n$m%erGal$e1.5loatGal$e011W
else U
set'rrorMessage0error!a%le3 =s$%Cean.n$m%er=3 =M$st %e
5illed=1W
V
V catch 0)$m%er*ormat'xception e1 U
set'rrorMessage0error!a%le3 =s$%Cean.n$m%er=3 =M$st %e a
n$m%er=1W
V
V else U
simpleCean.setString0=a%c=1W
simpleCean.set)$m%er09.8D351W
simpleCean.set*lag0tr$e1W
simpleCean.setList0new intST U D3 3 V1W
simpleCean.set+ptional0==1W
simpleS$%Cean.setString0==1W
V
i5 0is7ostMethod PP error!a%le.is'mptB011 U
[4
;jsp:5orward pageK=Simple7roc.jsp=/4
;[
V else U
[4
;jsp:5orward pageK=Complex*orm.jsp=/4
;[
V
[4
;[<
void set'rrorMessage0java.$til.6ashta%le error!a%le3
String propertB3 String message1 U
message K =;*+)! C+L+RK^=_**9999^=4= ] message ] =;/*+)!4;CR4=W
error!a%le.p$t0propertB3 message1W
V
[4
1(.1,.- sing the "ra.ew!r> with ser+'ets and 3S6s
The SimpleHndl.jsp handler is basically a Java scriptlet. That was a simple and compact way to
present a handler. The Java code could easily be moved to a utility class. A more elegant solution
is the replacement of the JSP handler with a general Java servlet.
The com.devsphere.helpers.mapping package contains an abstract class called
GenericHandler. This class is extended by BeanDispatcher, which is the bean-independent
equivalent of SimpleHndl.jsp. The JSP handler can be replaced by only a few lines that are added
to servlets.properties or web.xml:
Simple6ndl.codeKcom.devsphere.helpers.mapping.Cean#ispatcher
Simple6ndl.initparamsK^
C'(),)(M'Kcom.devsphere.examples.mapping.simple.SimpleCean3^
C'(),I#KsimpleCean3^
C(S',7(!6K/simple
or
;servlet4
;servlet&name4Simple6ndl;/servlet&name4
;servlet&
144
14 - JSP
class4com.devsphere.helpers.mapping.Cean#ispatcher;/servlet&class4
;init¶m4
;param&name4C'(),)(M';/param&name4
;param&
val$e4com.devsphere.examples.mapping.simple.SimpleCean;/param&val$e4
;/init¶m4
;init¶m4
;param&name4C'(),I#;/param&name4
;param&val$e4simpleCean;/param&val$e4
;/init¶m4
;init¶m4
;param&name4C(S',7(!6;/param&name4
;param&val$e4/simple;/param&val$e4
;/init¶m4
;/servlet4
GenericHandler and BeanDispatcher were presented in a previous chapter.
1(.1,.0 wh1 sing ser+'etsF
Using a JSP, you have to declare the bean within a <jsp:useBean> tag. f your Web application
contains many forms/beans, you have to provide a JSP handler for each bean. A servlet can be
made bean-independent.
n many cases, a servlet is identified with its class. Users invoke the servlet by requesting a
URL like this:
http://www.host.com/(pp)ame/servlet/Servlet)ame
The servlet engine associates a servlet to a class in the servlets.properties (or web.xml) file:
Servlet)ame.codeKcom.companB.Class)ame
There is nothing that can stop you associating many servlets with the same class. You may use
the same class to declare one servlet for each bean component. A standard servlet engine
running on a single JVM will instantiate the servlet class once for each servlet declaration. All
requests to one of the declared servlets will be serviced by the same instance of the servlet class.
The previous section showed how to declare a BeanDispatcher servlet. f you have another
bean-form pair, you could add a few other lines to servlets.properties:
(nother6ndl.codeKcom.devsphere.helpers.mapping.Cean#ispatcher
(nother6ndl.initparamsK^
C'(),)(M'Kcom.devsphere.examples.mapping.another.(notherCean3^
C'(),I#KanotherCean3^
C(S',7(!6K/another
The two servlets that share the same code could be invoked with something like this
http://www.host.com/(pp)ame/servlet/Simple6ndl
http://www.host.com/(pp)ame/servlet/(nother6ndl
145
15 - javaserver faces
1* - 3A7ASE97E9 8ACES
1*.1 what are #a+aSer+er "a$esF
JavaServer Faces technology is a server-side user interface component framework for Java
based web applications. This technology includes:
1. A set of APs for:
representing U components, like input fields, buttons, links
U components management
events handling
input validation
error handling
page navigation specification
support for internationalization and accessibility.
2. A JavaServer Pages (JSP) custom tag library for expressing a JavaServer Faces
interface within a JSP page.
1*.2 #a+aSer+er 8a$es Te$hn!'!g1 1.2
The latest version of JavaServer Faces technology is version 1.2, the final version of which has
been released through the Java Community Process under Java Specification Request (JSR)
252.
The latest implementation of version 1.2 is the patch release, version 1.2_09.
There are two JSF specific tag libraries defined in this specification, namely the core JSF tags
and the html JSF tags.
1*.% the ht.' 3S8 tags
This tag library contains JavaServer Faces component tags for all UComponent + HTML
RenderKit Renderer combinations defined in the JavaServer Faces specification. As of version
1.2 of the JFS specification, there are 25 HTML JSF tags.
The HTML tags can be grouped in the following categories:
inputs
outputs
146
15 - javaserver faces
commands
selections
layouts
data table
errors and messages
1*.%.1 the 'ist !" 3S8 HT2L Tags
For reference, here is an exhaustive list of the JSF HTML tags:
column
commandButton
commandLink
dataTable
form
graphicmage
inputHidden
inputSecret
inputText
inputTextArea
message
messages
outputFormat
outputLabel
outputLink
outputText
panelGrid
pnelGroup
selectBooleanCheckbox
selectManyCheckbox
selectManyListbox
selectManyMenu
selectOneListbox
selectOneMenu
selectOneRadio
n the next paragraphs, we'll have a closer look at some of these tags.
147
15 - javaserver faces
1*.%.2 hEdataTab'e
The dataTab'e tag renders an HTML 4.01 compliant table element that can be associated with
a backing bean to obtain its data as well as for event handling purposes.
The table can be customized extensively using cascading stylesheet (CSS) classes and
definitions to enhance the appearance of the table's headers, footers, columns and rows.
Common formatting techniques, such as alternating row colors, can be accomplished quite easily
with this tag.
The dataTab'e tag typically contains one or more column tags that define the columns of the
table. A column component is rendered as a single "td" element. For more information about
columns, see the column tag documentation.
A dataTab'e tag can also contain header and footer facets. These are rendered as a single "th"
element in a row at the top of the table and as a single "td" element in a row at the bottom of the
table, respectively.
ECa.&'eE
<h:dataTable id="table1" value="#{shoppingCartBean.items}" var="item">
<f:facet name="header">
<h:outputText value="Your Shopping Cart" />
</f:facet>
<h:column>
<f:facet name="header">
<h:outputText value="tem Description" />
</f:facet>
<h:outputText value="#{item.description}" />
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Price" />
</f:facet>
<h:outputText value="#{item.price}" />
</h:column>
<f:facet name="footer">
<h:outputText value="Total: #{shoppingCartBean.total}" />
</f:facet>
</h:dataTable>
/TM. Output
<table id="table1">
<thead>
<tr><th scope="colgroup" colspan="2">Your Shopping Cart</th></tr>
<tr><th>tem Description</th><th>Price</th></tr>
</thead>
<tbody>
<tr><td>Delicious Apple</td><td>$5.00</td></tr>
<tr><td>Juicy Orange</td><td>$5.00</td></tr>
<tr><td>Tasty Melon</td><td>$5.00</td></tr>
148
15 - javaserver faces
</tbody>
<tfoot>
<tr><td colspan="2">Total: $15.00</td></tr>
</tfoot>
</table>
1*.%.% hE"!r.
The "!r. tag renders an HTML form element. JSF forms use the "post-back" technique to
submit form data back to the page that contains the form. The use of the POST method is also
required and it is not possible to use the GET method for forms generated by this tag.
f your application requires the use of the GET method for form submission, your options
include using plain HTML forms, binding request parameters to backing bean properties, and
using the outputLink tag to generate dynamic hyperlinks.
ECa.&'eE
<h:form id="form1"></h:form>
/TM. Output
<form id="form1" name="form1" method="post" action="/demo/form.jsp"
enctype="application/x-www-form-urlencoded"></form>
1*.%.( hE$!..andBtt!n
The $!..andBtt!n tag renders an HTML submit button that can be associated with a
backing bean or ActionListener class for event handling purposes. The display value of the button
can also be obtained from a message bundle to support internationalization (18N).
ECa.&'eE
<h:commandButton id="button1" value="#{bundle.checkoutLabel}"
action="#{shoppingCartBean.checkout}" />
/TM. Output
<input id="form:button1" name="form:button1" type="submit" value="Check
Out" onclick="someEvent();" />
1*.%.* hEin&tTeCt
The in&tTeCt tag renders an HTML input element of the type "text".
ECa.&'eE
<h:inputText id="username" value="#{userBean.user.username}" />
/TM. Output
<input id="form:username" name="form:username" type="text" />
1*.%., .essage Tag
The .essage tag renders a message for a specific component. You can customize the
message generated by this component by applying different CSS st1'es to the message
149
15 - javaserver faces
depending on its severity (eg. red for error, green for information) as well as the detail level of the
message itself. You can also customize the standard error messages by !+erriding specific JSF
properties in your message bundle.
ECa.&'eE
;h:inp$t!ext idK=$sername= reM$iredK=_Utr$eV=
val$eK=_U$serCean.$ser.$sernameV=
errorStBleK=color:red=/4
;h:message 5orK=$sername= /4
/TM. Output
;inp$t tBpeK=text= idK=5orm:$sername= nameK=5orm:$sername= val$eK==/4
;span stBleK=color:red=4=$sername=: Gal$e is reM$ired.;/span4
1*.( the $!re 3S8 tags
The core JavaServer Faces tags define custom actions that are independent of any particular
RenderKit.
1*.(.1 the 'ist !" 3S8 C!re Tags
Here is an exhaustive list of the JSF core tags:
actionListener
attribute
convertDateTime
converter
convertNumber
facet
loadBundle
param
selecttem
selecttems
subview
validateDoubleRange
validateLength
validateLongRange
validator
valueChangeListener
verbatim
view
Some of these tags will be detailed in the next paragraphs.
150
15 - javaserver faces
1*.(.2 "E"a$et
The JSF facets specify the requirements and constraints that apply to a JSF project.
The Facet tag registers a named facet on the component associated with the enclosing tag. A
facet represents a named section within a container component. For example, you can create a
header and a footer facet for a dataTable component.
ECa.&'eE
;h:data!a%le idK=report!a%le= val$eK=_UreportCean.dailBReportV=
varK=item=4
<h:column>
<f:facet name="header">
<h:outputText value="Daily Report" />
</f:facet>
<h:outputText value="#{item}" />
</h:column>
</h:dataTable>
/TM. Output
<table id="reportTable">
<thead>
<tr><th>Daily Report</th></tr>
</thead>
<tbody>
<tr><td>tem 1</td></tr>
<tr><td>tem 2</td></tr>
<tr><td>tem 3</td></tr>
</tbody>
</table>
1*.(.% "E+a'idat!r
The Validator tag registers a named Validator instance on the component associated with the
enclosing tag. The JavaServer Faces framework includes three standard validators (see the
validateDoubleRange, validateLength, and validateLongRange tags) but the Validator interface
can be implemented by classes that provide custom validation for your application. This tag
accepts one value matching the validator D you assigned to your validator class in your Faces
configuration file. The body content of this tag must be empty.
ECa.&'eE
<h:inputText id="emailAddress"
value="#{customerBean.customer.emailAddress}">
<f:validator validatord="emailAddressValidator" />
</h:inputText>
<h:message for="emailAddress" />
/TM. Output
<input id="form:emailAddress" name="form:emailAddress" type="text"
value="fake@email"/>
nvalid email address.
151
15 - javaserver faces
1*.(.( "E+a'eChangeListener
The ValueChangeListener tag registers a ValueChangeListener instance on the component
associated with the enclosing tag. The ValueChangeListener interface should be implemented by
classes that you want to register with components that publish value change events.
Any component that receives user input, such as one of the HTML select or text input
components, can publish value change events. A component fires a value change event when its
input changes, but only if the new input is validated successfully.
You can register several ValueChangeListeners with a component and they will be invoked in
the order that they are registered. An alternative to this tag is to use a method-binding expression
pointing at a value change listener method of a backing bean on the component tag itself.
Notice in the example below the use of the JavaScript onchange() event to trigger form
submission when the list selection changes. Without this JavaScript event, the user must
manually submit the form to invoke the ValueChangeListener.
ECa.&'eE
<h:selectOneMenu id="optionMenu" value="#{optionBean.selectedOption}"
onchange="submit()">
<f:selecttems value="#{optionBean.optionList}" />
<f:valueChangeListener
type="com.mycompany.MyValueChangeListenermpl" />
</h:selectOneMenu>
/TM. Output
<select name="form:optionMenu" size="1" onchange="submit()">
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
</select>
1*.(.* "E+iew
The View tag is the container for all JavaServer Faces component tags used on a page. You
can wrap the root element of the structured markup language used in your document with this tag
to ensure that all child tags are part of the same view.
This tag is useful for internationalization (18N) purposes. t provides you with several options
for presenting your user with localized views of your application. By default the JSF framework
will attempt to select the best view for your user based on the Accept-Language header sent to
the server from the user's browser as part of the HTTP request for your page.
f the locale requested by the user is not supported by your application, the JSF framework will
use the default locale specified in your Faces configuration file. f you have not specified a default
locale, JSF will use the default locale for the Java Virtual Machine serving your application.
f your application supports the locale requested by the user, JSF will set that locale for the view
and will display the messages for that locale defined in the locale's message bundle.
You can also specify the locale for which the view is to be rendered by explicitly setting the
locale attribute of the view tag. This allows you to design localized versions of each page,
including images and styles, for each locale you wish to support.
Another option is to obtain the locale dynamically through user interaction. This information
could later be stored in a cookie and/or a database to identify which locale is preferred by your
152
15 - javaserver faces
user. The locale attribute accepts a value-binding expression that could resolve to the desired
locale.
ECa.&'eE
welcome_en.jsp (English)
<f:view locale="en">
<f:loadBundle basename="com.mycompany.MessageBundle" var="bundle" />
<h:outputText value="#{bundle.welcomeMessage}" />
</f:view>
welcome_fr.jsp (French)
<f:view locale="fr">
<f:loadBundle basename="com.mycompany.MessageBundle" var="bundle" />
<h:outputText value="#{bundle.welcomeMessage}" />
</f:view>
/TM. Output
welcome_en.jsp (English)
Welcome to our site!
welcome_fr.jsp (French)
Bienvenue notre site!
1*.* the str$tre !" a 3S8 a&&'i$ati!n
Here is a typical directory structure for a JSP application. The directory myJSFapp is the base
directory of the application.
myJSFapp
/ant
build.xml
/JavaSource
/WebContent
/WEB-NF
/classes
/lib
jsf-impl.jar
jsf-api.jar
faces-config.xml
web.xml
/pages
Comments on this structure:
.13S8a&& application base directory with application name
/ant directory containing Ant build scripts with a default bi'd.C.' file
153
15 - javaserver faces
/3a+aS!r$e application specific java source classes and properties files
/WebC!ntent contains the Web application files used by the application server or by
the web container
/WEB-IN8 contains files used as part of the runtime Web application
/$'asses compiled Java classes and properties files copied from the /JavaSource
directory
/'ib - contains libraries required by the application, like third party jar files
#s"-i.&'.#ar, #s"-a&i.#ar files included in the /lib directory, mandatory for any JSF
application
web.C.' the deployment descriptor of the application, included in the /WEB-NF
directory
"a$es-$!n"ig.C.' the JSF configuration file, included in the /WEB-NF directory
/&ages directory containing JSP and HTML presentation pages
1*., h!w d!es 3S8 w!r>F a "irst eCa.&'e
Example taken from http://www.exadel.com/tutorial/jsf/jsftutorial-kickstart.html.
A JSF application is nothing else but a servlet/JSP application. t has a deployment descriptor,
JSP pages, custom tag libraries, static resources, and so on. What makes it different is that a JSF
application is event-driven. The way the application behaves is controlled by an event listener
class. Let's have a look at the steps needed to build a JSF application:
1. Create JSP pages
2. Define navigation rules
3. Create managed beans
4. Create properties files
5. Edit JSP pages
6. Create an index.jsp file
7. Compile the application
8. Deploy and run the application
1*.,.1 $reating 3S6 6ages
Create the in&tna.e.#s& and greeting.#s& files in WebC!ntentB&agesB. You only need to
create the JSP files. The directory structure already exists.
These files will act as place holders for now. We will complete the content of the files a little bit
later.
Now that we have the two JSP pages, we can create a navigation rule.
1*.,.2 na+igati!n
Navigation is the heart of JavaServer Faces. The navigation rule for this application is
described in the "a$es-$!n"ig.C.' file. This file already exists in the skeleton directory structure.
154
15 - javaserver faces
You just need to create its contents.
n our application, we just want to go from in&tna.e.#s& to greeting.#s&. As a diagram, it
would look something like this:
"mage from )xadel Studio Pro
The navigation rule shown in the picture is defined below. The rule says that from the view
(page) in&tna.e.#s& go to the view (page) greeting.#s&, if the "outcome" of executing
in&tna.e.#s& is greeting. And that's all there is to this.
<navigation-rule>
<from-view-id>/pages/inputname.jsp</from-view-id>
<navigation-case>
<from-outcome>greeting</from-outcome>
<to-view-id>/pages/greeting.jsp</to-view-id>
</navigation-case>
</navigation-rule>
This is, of course, a very simple navigation rule. You can easily create more complex ones. To
read more about navigation rules, visit the JSP Navigation Example forum item.
1*.,.% $reating the 2anaged Bean
Next, we will create a .138Sa&& folder inside the 3a+aS!r$e folder. nside this .138Sa&&
folder, we will create a 6ers!nBean.#a+a file. This class is straight-forward. t's a simple Java
bean with one attribute and setter/getter methods. The bean simply captures the name entered by
a user after the user clicks the submit button. This way the bean provides a bridge between the
JSP page and the application logic. (Please note that the field name in the JSP file must exactly
match the attribute name in the bean.)
01.2.".0 Person,e#n.j#v#
Put this code in the file:
package myJFSapp;
public class PersonBean {
String personName;
155
15 - javaserver faces
/**
* @return Person Name
*/
public String getPersonName() {
return personName;
}
/**
* @param Person Name
*/
public void setPersonName(String name) {
personName = name;
}
}
Later you will see how to "connect" this bean with the JSP page.
01.2.".3 decl#rin$ the ,e#n in (#ces4con(i$.5ml
Now, the second part of "a$es-$!n"ig.C.' describes our Java bean that we created in the
previous steps. This section defines a bean name 6ers!nBean. The next line is the full class
name, .138Sa&&.6ers!nBean. re@est sets the bean scope in the application.
<managed-bean>
<managed-bean-name>personBean</managed-bean-name>
<managed-bean-class>myJFSapp.PersonBean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
01.2."." (#ces4con(i$.5ml
Your final "a$es-$!n"ig.C.' file should look like this:
<?xml version="1.0"?>
<!DOCTYPE faces-config PUBLC
"-//Sun Microsystems, nc.//DTD JavaServer Faces Config 1.1//EN"
"http://java.sun.com/dtd/web-facesconfig_1_1.dtd">
<faces-config>
<navigation-rule>
<from-view-id>/pages/inputname.jsp</from-view-id>
<navigation-case>
<from-outcome>greeting</from-outcome>
<to-view-id>/pages/greeting.jsp</to-view-id>
</navigation-case>
</navigation-rule>
<managed-bean>
<managed-bean-name>personBean</managed-bean-name>
<managed-bean-class>myJFSapp.PersonBean</managed-bean-class>
156
15 - javaserver faces
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
</faces-config>
1*.,.( $reating a 6r!&erties 8i'e :9es!r$e Bnd'e;
A properties file is just a file with param=value pairs. We use the messages stored in the
properties file in our JSP pages. Keeping the messages separate from the JSP page allows us to
quickly modify the messages without editing the JSP page.
Let's create a bnd'e folder in the 3a+aS!r$eB.138Sa&& folder and then a
.essages.&r!&erties file in the bnd'e folder. We need to place it in the 3a+aS!r$e folder so
that during project compilation, this properties file will be copied to the $'asses folder where the
runtime can find it.
01.2.6.0 mess#$es.properties
Put this text in the properties file:
inputname_header=JSF KickStart
prompt=Tell us your name:
greeting_text=Welcome to JSF
button_text=Say Hello
sign=!
We now have everything to create the JSP pages.
1*.,.* editing the 3S6 6ages
Two pages should already have been created in .138Sa&&BWebC!ntentB&ages.
01.2.1.0 inputn#me.jsp
Put the following coding into this file:
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<f:loadBundle basename="myJFSapp.bundle.messages" var="msg"/>
<html>
<head>
<title>enter your name page</title>
</head>
<body>
<f:view>
<h1>
<h:outputText value="#{msg.inputname_header}"/>
</h1>
<h:form id="helloForm">
<h:outputText value="#{msg.prompt}"/>
<h:inputText value="#{personBean.personName}" required=true>
157
15 - javaserver faces
<f:validateLength minimum="2" maximum="10"/>
</h:inputText>
<h:commandButton action="greeting" value="#{msg.button_text}" />
</h:form>
</f:view>
</body>
</html>
Now, let's explain the important sections in this file after displaying the code for each section
starting from the top.
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<f:loadBundle basename="myJFSapp.bundle.messages" var="msg"/>
The first line of these three is a directive that tells us where to find JSF tags that define HTML
elements and the second directive tells us where to find JSF tags that define core JSF elements.
The third line loads our properties file (resource bundle) that holds messages that we want to
display in our JSP page.
<h:inputText value="#{msg.inputname_header}" required=true>
This tag simply tells us to look in the resource bundle that we defined at the top of the page.
The re@ired attribute of the hEin&tTeCt tag insures that an empty name will not be sent. One
can also add a line like
<f:validateLength minimum="2" maximum="10"/>
to make sure that the length of this field is reasonable long.
Then, look up the value for in&tna.eIheader in that file and print it here.
1 <h:form id="helloForm">
2 <h:outputText value="#{msg.prompt}"/>
3 <h:inputText value="#{personBean.personName}" required=true>
4 <f:validateLength minimum="2" maximum="10"/>
5 </h:inputText>
6 <h:commandButton action="greeting" value="#{msg.button_text}" />
7 </h:form>
Line 1. Creates an HTML form using JSF tags.
Line 2. Prints a message from the properties file using the value of &r!.&t.
Lines 3-5. Creates an HTML input text box. n the +a'e attribute we connect (bind) this field to
the managed bean attribute that we created before.
Line 6. JSF tags for the HTML form's submit button. The button's value is being retrieved from
the properties file. While the button's a$ti!n attribute is set to greeting which matches the
navigation-outcome in "a$es-$!n"ig.C.' file. That's how JSF knows where to go next.
01.2.1.3 $reetin$.jsp
Put this coding inside the second JSP file:
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
158
15 - javaserver faces
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<f:loadBundle basename="myJFSapp.bundle.messages" var="msg"/>
<html>
<head>
<title>greeting page</title>
</head>
<body>
<f:view>
<h3>
<h:outputText value="#{msg.greeting_text}" />,
<h:outputText value="#{personBean.personName}" />
<h:outputText value="#{msg.sign}" />
</h3>
</f:view>
</body>
</html>
This page is very simple. The first three lines are identical to our first page. Theses lines import
JSF tag libraries and our properties file (resource bundle) with the messages.
The main code of interest to us is between the Gh%H...GBh%H tags. The first line will take a
message from the resource bundle and print it on the page. The second line will access a Java
bean, specifically the bean attribute &ers!nNa.e, and also print its contents on the page.
Once this page is displayed in a Web browser, you will see something like this:
Welcome to JSF, name!
1*.,., $reating the indeC.#s& 8i'e
We will now create a third JSP file that doesn't actually function as a presentation page. t uses
a JSP tag to "forward" to the in&tna.e.#s& page.
Create the indeC.#s& file inside the WebC!ntent folder. Note that this file is not created in the
&ages folder like the previous JSP files.
Having an indeC.#s& file will allow us to start the application like this:
http://localhost:8080/myJFSapp/
Now, put this coding into the file:
<html>
<body>
<jsp:forward page="/pages/inputname.jsf" />
</body>
</html>
f you look at the path for the forward, you'll notice the file suffix is .#s" and not .#s&. This is used
here, because in the we%.xml file for the application X.js5 is the URL pattern used to signal that
the forwarded page should be handled by the JavaServer Faces servlet within Tomcat.
We are almost done with this example.
159
15 - javaserver faces
1*.,.- C!.&i'ing
An Ant build script is provided for you. To build the application run the bi'd.C.' script from the
ant folder:
ant build
1*.,.0 De&'!1ing
Before you can run this application within the servlet container, we need to deploy it. We will
use null (link) deployment to deploy the application in-place. To do this we need to register a
context in Tomcat's JT!.$atH!.eKL$!n"Lser+er.C.' file.
To do this, insert this code:
<Context debug="0"
docBase="Path_to_WebContent"
path="/myJFSapp" reloadable="true"/>
near the end of the ser+er.C.' file within the H!st element just before the closing GBH!stH tag.
Of course, 6athIt!IWebC!ntent needs to be replaced with the exact path on your system to the
WebC!ntent folder inside the .138Sa&& folder (for example,
C:/examples/mBZ*Sapp//e%Content).
1*.,.4 9nning
Next, start the Tomcat server (probably using the script start&.bat in Tomcat's bin directory).
When Tomcat is done loading, launch a web browser and enter:
htt&EBB'!$a'h!stE0505B.138Sa&&. (Port 8080 is the default port in Tomcat. Your setup, though,
might possibly be different).
1*.- $reating a 3S8 a&&'i$ati!n in e$'i&se with the "a$esIDE &'gin
Example taken from http://amateras.sourceforge.jp/docs/FacesDE/SampleJSFApp.html .
1*.-.1 O+er+iew
This is a tutorial in which we create a simple JSF application to demonstrate FacesDE's
functionality. This is a "login" application, which asks an user for an D and password, verifies the
information, and forwards the user to a success or error page.
The application will use a few JSP pages with JSF elements, and a session-scoped managed
bean to coordinate their interactions. Along the way we'll use the following FacesDE functionality:
add JSF support to a project
use the New JSF/JSP file wizard
use the JSP Editor (see HTML/JSP/XML Editor)
use the faces-config.xml Editor (see faces-config.xml Editor)
As a prerequisite for the tutorial, make sure FacesDE and required plugins have been installed;
see nstalling & Uninstalling. We don't assume that a J2EE server-specific plugin, such as the
Sysdeo Tomcat plugin has been installed.
1*.-.2 Creating A 6r!#e$t
Here we create an Eclipse project, and set up folders for a web application. The folder structure
160
15 - javaserver faces
created is simply one that works for this author; your mileage may vary.
1. From the menu bar select 8i'eBNewB6r!#e$t.... The New Project wizard appears.
2. Select 3a+a 6r!#e$t; click Next.
3. Enter project name, say, js5&login; click 8inish
4. Create the web root folder, in Package Explorer select the js5&login project, and from
the menubar select 8i'eBNewB8!'der; name the folder we%root
5. Create the web pages folder, in Package Explorer select the we%root folder, and from its
context menu select 8i'eBNewB8!'der; name the folder pages. This folder will contain all
"functional" pages.
6. =se 8a$esIDE t! add 3S8 s&&!rtE we use a FacesDE wizard to create J2EE-
prescribed folders and files in webroot, and to add JSF libraries to the project.
a. in Package Explorer select the js5&login project
b. from the menubar select 8i'eBNewBOther...
c. in the wizard that appears, select A.aterasB3S8BAdd 3S8 S&&!rt; click NeCt
d. in the Add 3S8 S&&!rt page, for Web A&&'i$ati!n 9!!t enter /js5&
login/we%root; make sure all checkboxes are checked; click NeCt.
7. From the menubar open 6r!#e$tB6r!&erties
8. Select the A.ateras node; note that 9!!tE has automatically been set to /we%root;
make sure HTML validation and DTD/XSD validation are enabled.
9. Create the source folder, select the 3a+a Bi'd 6ath node; select the S!r$e tab; click
Add 8!'der...; in the dialog that appears create a folder named src directly under the
project folder (js5&login); click Mes through messages that appear.
10.Set the output folder, in the De"a't !t&t "!'der textbox at the bottom, enter js5&
login/we%root//'C&I)*/classes; click OK to dismiss the properties dialog.
Your folder structure should now be as follows:
js5&login
\
]&& src
\
]&& we%root
\
]&& /'C&I)*
\ \
\ ]&& classes 0not shown in Zava perspective1
\ \
\ ]&& li%
\
]&& pages
1*.-.% Creating N C!n"igring 2anaged Beans
Here we create a class called LoginManager which will be used as a backing bean for the
login process. We then configure it to be a managed bean.
161
15 - javaserver faces
1. n Package Explorer select the src folder; from its context menu select NewBC'ass. The
New 3a+a C'ass wizard appears.
2. n the 6a$>age field, enter login; in the Na.e field enter LoginManager. Click 8inish.
The Java code editor opens.
3. Enter and save the following code for the LoginManager class:
// LoginManager.java
pac2age loginW
p$%lic class LoginManager U
private String ,$id K ==W
private String ,pwd K ==W
p$%lic String getserI#01 U ret$rn ,$idW V
p$%lic void setserI#0String $id1 U ,$id K $idW V
p$%lic String get7assword01 U ret$rn ,pwdW V
p$%lic void set7assword0String pwd1 U ,pwd K pwdW V
p$%lic String login(ction01 U
String action K n$llW
i5 0 ,$id.eM$alsIgnoreCase0=5oo=1 PP
,pwd.eM$alsIgnoreCase0=%ar=1 1
action K =login7ass=W
else
action K =login*ail=W
ret$rn actionW
V
V
4. =se 8a$esIDE t! $!n"igre the beanE we use a FacesDE editor to configure
LoginManager as a session-scoped managed bean.
a. in Package Explorer select js5&login/we%root//'C&I)*/5aces&
con5ig.xml; from its context menu select O&en WithB"a$es-$!n"ig.C.' Edit!r.
The faces-config.xml editor opens.
b. along the bottom of the editor there are 3 tabs; click 2anaged Bean.
c. click Add; input widgets appear
d. for na.e enter mgr; for $'ass enter login.LoginManager; for s$!&e select
session.
e. from the menubar select 8i'eBSa+e, then close the editor
1*.-.( Creating 3S6 6ages
Here we create the JSP pages that make up the application's user interface. We will have 4
pages: a start page (index.jsp), and 3 content pages (login.jsp, s$ccess.jsp and
error.jsp). Content pages are placed in we%root/pages; index.jsp is placed directly in
we%root, and its sole function is to forward users to the login page.
All pages except login.jsp are simple pages with static content, so we create them first,
using the Workbench's standard file-creation facilities. Then we create login.jsp using a
FacesDE wizard.
162
15 - javaserver faces
1. Create index.jsp:
a. in Package Explorer select we%root; from its context menu select NewB8i'e; the
New File wizard appears.
b. for 8i'e na.e enter index.jsp; make sure that the parent folder is set to /js5&
login/we%root; click 8inish; the JSP Editor opens.
c. enter the following code, save the file and close the editor.
;<&& we%root/index.jsp &&4
;html4
;%odB4
;jsp:5orward pageK=5aces/pages/login.jsp= /4
;/%odB4
;/html4
2. Create success.jsp: create this file similarly to index.jsp, but in we%root/pages.
Enter the following code:
;<&& we%root/pages/s$ccess.jsp &&4
;html4
;head4
;title4js5&login;/title4
;/head4
;%odB4
;hD4S$ccess<;/hD4
;/%odB4
;/html4
3. Create error.jsp: create this file similarly to index.jsp, but in we%root/pages.
Enter the following code:
;<&& we%root/pages/error.jsp &&4
;html4
;head4
;title4js5&login;/title4
;/head4
;%odB4
;hD4'rror<;/hD4
!he $ser&id and or password were invalid. 7lease trB
again.
;/%odB4
;/html4
4. Create login.jsp:
a. in Package Explorer select we%root/pages; from its context menu select
NewBOther...; the New wizard appears.
b. select A.aterasB3S8B8a$es 3S6 8i'e; click NeCt
c. for 8i'e na.e enter login.jsp; make sure that C!ntainer is set to /js5&
login/we%root/pages, and that =se 218a$es T!.ahaw> $!.&!nents and
=se 218a$es SandB!C $!.&!nents are unchecked, and choose de"a't for
Te.&'ate; click 8inish; the FacesDE JSP Editor opens, with the following
template code.
163
15 - javaserver faces
;[Q page content!BpeK=text/htmlW charsetKCp8DED= [4
;[Q tagli% $riK=http://java.s$n.com/js5/html= pre5ixK=h= [4
;[Q tagli% $riK=http://java.s$n.com/js5/core= pre5ixK=5= [4
;html4
;head4
;meta http&eM$ivK=Content&!Bpe= contentK=text/htmlW
charsetKCp8DED=/4
;title4;/title4
;/head4
;%odB4
;5:view4
;h:5orm4
;/h:5orm4
;/5:view4
;/%odB4
;/html4
We will now edit this page to contain our input widgets, etc.
d. place the cursor between the ;title4;/title4 elements; enter js5&login
e. Open the JSF palette, and dock it along the right. (See Show View Dialog)
f. create a few blank lines between the ;h:5orm4 elements; place your cursor in
one of these lines, expand the 3S8 HT2L panel in the palette, and click on the
icon for ;h:inp$t!ext4; this inserts the corresponding JSF element at the
cursor location.
N!teE the JSP editor is aware of referenced tag libraries, and uses them for code
completion as well. Thus if you were to type ;h: and hit CT9L O S&a$ebar, you
would get a popup window of JSF HTML elements.
g. now we want to add attributes to this element, and the JSP Editor can help with
code- completion. To see this in action, place the cursor inside the <h:inputText>
element, and hit CT9L O S&a$ebar; a code-completion window pops up, as
shown below.
164
15 - javaserver faces
h. in the code-completion window scroll down to +a'e, and hit Enter; this inserts
val$eK== at the cursor. We will now bind this to the $serI# property of
LoginManager; FacesDE can provide code completion here as well.
i. place the cursor between the quotes in val$eK==, enter _Umgr., and hit CT9L O
S&a$ebar; a code-completion window pops up, with bean properties available in
mgr. This is shown below:
(Recall that we configured LoginManager as a managed bean called mgr.)
j. select $serI# from the code-completion window; complete the expression with
the closing U
k. insert another ;h:inp$t!ext4 element; set its value binding expression to
val$eK=_Umgr.passwordV=
l. insert a ;h:commandC$tton4 element; set its val$e to Login, and its action
to the value binding expression _Umgr.login(ctionV
The final code, with the barest presentational formatting, is shown below:
;[Q page content!BpeK=text/htmlW charsetKCp8DED= [4
;[Q tagli% $riK=http://java.s$n.com/js5/html= pre5ixK=h= [4
;[Q tagli% $riK=http://java.s$n.com/js5/core= pre5ixK=5= [4
;html4
;head4
;title4js5&title;/title4
;/head4
;%odB4
;5:view4
;h:5orm4
serI#: ;h:inp$t!ext val$eK=_Umgr.$serI#V=/4
;%r/47assword: ;h:inp$t!ext
val$eK=_Umgr.passwordV=/4
;%r/4;h:commandC$tton val$eK=Login=
actionK=_Umgr.login(ctionV=/4
;/h:5orm4
;/5:view4
;/%odB4
;/html4
1*.-.* Creating Na+igati!n 9'es
Here we create navigation rules among pages, using a FacesDE editor.
1. Open 5aces&con5ig.xml; it should open in the "a$es-$!n"ig.C.' Edit!r.
2. Select the Na+igati!n tab
165
15 - javaserver faces
3. from the Na+igati!n panel in the palette at left, click on 6age, then click inside the editor
window; this inserts a page icon into the editor, and the page's properties appear in the
Workbech's Properties view. This is shown below.
Note that the icon has a small triangle overlay--this indicates that something is wrong,
specifically that FacesDE could not locate a page at path /page8.jsp
4. in the 6r!&erties view, change the value of path to /index.jsp. You can also change
it on the diagram directly (select the page and click once more); notice that the warning
triangle disappears.
5. add 3 more pages, and set them to /pages/login.jsp, /pages/s$ccess.jsp and
/pages/error.jsp. Arrange them as shown below:
166
15 - javaserver faces
Now we'll add navigation rules among the pages.
6. from the palette at left, select Na+igati!n Case, then click first on the icon for
login.jsp and then on the icon for s$ccess.jsp. This inserts a forward-action
between the two pages, and is represented by an arrow. "Decharge" the mouse pointer by
clicking on the pointer icon in the palette, then click on the newly-added forward-action
icon to select it. ts properties appear in the 6r!&erties view. This is shown below:
167
15 - javaserver faces
7. in the 6r!&erties view (or direct editing on the diagram), change the value of 5rom&
o$tcome to login7ass. Recall that this is the success-value returned by
LoginManager's login(ction method. You can also change values by direct-editing
(select once and re-click) in the diagram
8. Similarly add a forward-action from login.jsp to error.jsp, and set its 5rom&
o$tcome to login*ail
We're done with setting up navigation rules. We'll set some properties in we%.xml, and we'll
then be ready to deploy the application.
1*.-., Editing web.C.'
Here we edit we%.xml for the specifics of our application. As it turns out, since we have such a
trivial application, all we need do in we%.xml is indicate the Faces Servlet mapping.
1. open we%.xml; scroll to the bottom and look for the comment
<!-- Faces Servlet Mapping -->
2. by default virtual path-based mapping is commented out, and extension-based mapping is
turned on. We want virtual path-based mapping, so uncomment it. You may comment out
the entry for extension-based mapping, or leave it as-is.
The application is now complete, and you should be able to deploy it to your server of choice.
Once deployed browse to index.jsp, and you should be automatically forwarded to
login.jsp. Use UserD/Password of "!!Bbar, and you should be sent to the success page; any
other id/password should send you to the error page.
Deployment to some servers is described below:
168
15 - javaserver faces
1*.-.- De&'!1ing T! T!.$at *.5
1. start Tomcat; open its Manager application in a browser; the default URL for this is
http://localhost:>9>9/manager/html
2. scroll down to De&'!1; we'll deploy our app by providing its directory; for C!nteCt &ath
enter /js5&login; for WA9 !r Dire$t!r1 =9L enter the path to we%root, as
5ile:///...; leave <2L C!n"igrati!n 8i'e =9L blank; click De&'!1
3. the Manager application should reload, and you should see /js5&login in the list of
running applications. Click on its link to launch the application.
1*.0 &a$>ges in the 3a+aSer+er 8a$es A6I
The classes and interfaces of the JavaServer Faces AP are grouped in several packages,
namely:
javax.faces
javax.faces.application
javax.faces.component
javax.faces.component.html
javax.faces.context
javax.faces.convert
javax.faces.el
javax.faces.event
javax.faces.lifecycle
javax.faces.model
javax.faces.render
javax.faces.validator
javax.faces.webapp
1*.4 the #a+aC."a$es &a$>age
Contains 2 classes FactoryFinder and FacesException
p$%lic 5inal class FactoryFinder extends +%ject
8a$t!r18inder implements the standard discovery algorithm for all factory objects specified in
the JavaServer Faces APs. For a given factory class name, a corresponding implementation
class is searched for based on the following algorithm. tems are listed in order of decreasing
search precedence:
f the JavaServer Faces configuration file bundled into the /'C&I)* directory of the
webapp contains a 5actorB entry of the given factory class name, that factory is used.
f the JavaServer Faces configuration files named by the javax.5aces.C+)*I-,*IL'S
169
15 - javaserver faces
ServletContext init parameter contain any 5actorB entries of the given factory class
name, those factories are used, with the last one taking precedence.
f there are any JavaServer Faces configuration files bundled into the M'!(&I)* directory
of any jars on the ServletContext's resource paths, the 5actorB entries of the given
factory class name in those files are used, with the last one taking precedence.
f a M'!(&I)*/services/U5actorB&class&nameV resource is visible to the web
application class loader for the calling application (typically as a result of being present in
the manifest of a JAR file), its first line is read and assumed to be the name of the factory
implementation class to use.
f none of the above steps yield a match, the JavaServer Faces implementation specific
class is used.
p$%lic class FacesException extends R$ntime'xception
This class encapsulates general JavaServer Faces exceptions.
1*.15 the #a+aC."a$es.a&&'i$ati!n &a$>age
Contains the following classes:
A&&'i$ati!n - A set of APs for representing U components and managing their state,
handling events and input validation, defining page navigation, and supporting
internationalization and accessibility.
A&&'i$ati!n8a$t!r1 - a factory object that creates (if needed) and returns (pplication
instances. mplementations of JavaServer Faces must provide at least a default
implementation of (pplication.
8a$es2essage - represents a single validation (or other) message, which is typically
associated with a particular component in the view. A *acesMessage instance may be
created based on a specific messageId.
8a$es2essage.Se+erit1 - used to represent message severity levels in a typesafe
enumeration.
Na+igati!nHand'er An object of this type is passed the outcome string returned by an
application action invoked for this application, and will use this (along with related state
information) to choose the view to be displayed next.
State2anager - directs the process of saving and restoring the view between requests.
State2anagerWra&&er - Provides a simple implementation of StateManager that can
be subclassed by developers wishing to provide specialized behavior to an existing
StateManager instance. The default implementation of all methods is to call through to
the wrapped StateManager.
7iewHand'er - the pluggablity mechanism for allowing implementations of or applications
using the JavaServer Faces specification to provide their own handling of the activities in
the 5ender 5esponse and 5estore 3iew phases of the request processing lifecycle. This
allows for implementations to support different response generation technologies, as well
as alternative strategies for saving and restoring the state of each view.
7iewHand'erWra&&er - Provides a simple implementation of Giew6andler that can be
170
15 - javaserver faces
subclassed by developers wishing to provide specialized behavior to an existing
Giew6andler instance. The default implementation of all methods is to call through to
the wrapped Giew6andler.
7iewEC&iredEC$e&ti!n - implementations must throw this *aces'xception when
attempting to restore the view
StateManager.restoreGiew0javax.5aces.context.*acesContext3 String3
String1 results in failure on postback.
1*.11 the #a+aC."a$es.$!.&!nent &a$>age
Defines both a set of interfaces and classes. The interfaces defined in this package are:
A$ti!nS!r$e - an interface that may be implemented by any concrete IComponent
that wishes to be a source of (ction'vents, including the ability to invoke application
actions via the default (ctionListener mechanism.
A$ti!nS!r$e2 - extends (ctionSo$rce and provides a JavaBeans property analogous
to the "action" property on (ctionSo$rce. The difference is the type of this property is
a Method'xpression rather than a MethodCinding. This allows the (ctionSo$rce
concept to leverage the new Unified EL AP.
C!nteCtCa''Ba$> - A simple callback interace that enables taking action on a specific
UComponent (either facet or child) in the view while preserving any contextual state for
that component instance in the view.
Editab'e7a'eH!'der - an extension of ValueHolder that describes additional features
supported by editable components, including Gal$eChange'vents and Galidators.
Na.ingC!ntainer - an interface that must be implemented by any IComponent that
wants to be a naming container.
StateH!'der - interface implemented by classes that need to save their state between
requests.
7a'eH!'der - an interface that may be implemented by any concrete IComponent that
wishes to support a local value, as well as access data in the model tier via a value
binding expression, and support conversion between String and the model tier data's
native data type.
The classes in this package are all U related. Here they are:
=IC!'.n - a IComponent that represents a single column of data within a parent
I#ata component.
=IC!..and - a IComponent that represents a user interface component which, when
activated by the user, triggers an application specific "command" or "action". Such a
component is typically rendered as a push button, a menu item, or a hyperlink.
=IC!.&!nent - the base class for all user interface components in JavaServer Faces.
The set of IComponent instances associated with a particular request and response are
organized into a component tree under a IGiewRoot that represents the entire content
of the request or response.
=IC!.&!nentBase - a convenience base class that implements the default concrete
behavior of all methods defined by IComponent.
171
15 - javaserver faces
=IData - a IComponent that supports data binding to a collection of data objects
represented by a #ataModel instance, which is the current value of this component itself
(typically established via a Gal$eCinding). During iterative processing over the rows of
data in the data model, the object for the current row is exposed as a request attribute
under the key specified by the var property.
=I8!r. - a IComponent that represents an input form to be presented to the user, and
whose child components represent (among other things) the input fields to be included
when the form is submitted.
=IGra&hi$ - a IComponent that displays a graphical image to the user. The user cannot
manipulate this component; it is for display purposes only.
=IIn&t - a IComponent that represents a component that both displays output to the
user (like I+$tp$t components do) and processes request parameters on the
subsequent request that need to be decoded.
=I2essage - This component is responsible for displaying messages for a specific
IComponent, identified by a clientId.
=I2essages - The renderer for this component is responsible for obtaining the messages
from the *acesContext and displaying them to the user.
=INa.ingC!ntainer - a convenience base class for components that wish to implement
)amingContainer functionality.
=IOt&t - a IComponent that has a value, optionally retrieved from a model tier bean
via a value binding expression, that is displayed to the user. The user cannot directly
modify the rendered value; it is for display purposes only.
=I6ane' - a IComponent that manages the layout of its child components.
=I6ara.eter - a IComponent that represents an optionally named configuration
parameter for a parent component.
=ISe'e$tB!!'ean - a IComponent that represents a single boolean (tr$e or 5alse)
value. t is most commonly rendered as a checkbox.
=ISe'e$tIte. - a component that may be nested inside a ISelectManB or
ISelect+ne component, and causes the addition of a SelectItem instance to the list
of available options for the parent component.
=ISe'e$t2an1 - a IComponent that represents the user's choice of a zero or more
items from among a discrete set of available options. The user can modify the selected
values. Optionally, the component can be preconfigured with zero or more currently
selected items, by storing them as an array in the val$e property of the component.This
component is generally rendered as a select box or a group of checkboxes.
=ISe'e$tOne - a IComponent that represents the user's choice of zero or one items
from among a discrete set of available options. The user can modify the selected value.
Optionally, the component can be preconfigured with a currently selected item, by storing
it as the val$e property of the component.
=I7iew9!!t - the UComponent that represents the root of the UComponent tree. This
component has no rendering, it just serves as the root of the component tree.
1*.12 the #a+a."a$es.$!.&!nent.ht.' &a$>age
172
15 - javaserver faces
Contains HTML related classes.
Ht.'C!'.n - represents a column that will be rendered in an HTML ta%le element.
Ht.'C!..andBtt!n - represents an HTML inp$t element for a button of type
s$%mit or reset. The label text is specified by the component value.
Ht.'C!..andLin> - represents an HTML a element for a hyperlink that acts like a
submit button. This component must be placed inside a form, and requires JavaScript to
be enabled in the client.
Ht.'DataTab'e - represents a set of repeating data (segregated into columns by child
UColumn components) that will be rendered in an HTML ta%le element.
Ht.'8!r. - represents an HTML 5orm element. Child input components will be
submitted unless they have been disabled.
Ht.'Gra&hi$I.age - represents an HTML img element, used to retrieve and render a
graphical image.
Ht.'In&tHidden - represents an HTML inp$t element of type hidden.
Ht.'In&tSe$ret - represents an HTML inp$t element of type password. On a
redisplay, any previously entered value will not be rendered (for security reasons) unless
the redisplaB property is set to tr$e.
Ht.'In&tTeCt - represents an HTML inp$t element of type text.
Ht.'In&tTeCtarea - represents an HTML textarea element.
Ht.'2essage - by default, the renderer!Bpe property must be set to
"javax.5aces.Message". This value can be changed by calling the
setRenderer!Bpe01 method.
Ht.'2essages - by default, the renderer!Bpe property must be set to
"javax.5aces.Messages" This value can be changed by calling the
setRenderer!Bpe01 method.
Ht.'Ot&t8!r.at - represents a component that looks up a localized message in a
resource bundle, optionally uses it as a Message*ormat pattern string and substitutes in
parameter values from nested ;"Parameter components, and renders the result. f the
"dir" or "lang" attributes are present, render a span element and pass them through as
attributes on the span.
Ht.'Ot&tLabe' - represents an HTML la%el element, used to define an accessible
label for a corresponding input element.
Ht.'Ot&tLin> - represents an HTML a (hyperlink) element that may be used to link to
an arbitrary URL defined by the val$e property.
Ht.'Ot&tTeCt - renders the component value as text, optionally wrapping in a span
element if CSS styles or style classes are specified.
Ht.'6ane'Grid - renders child components in a table, starting a new row after the
specified number of columns.
Ht.'6ane'Gr!& - causes all child components of this component to be rendered. This is
useful in scenarios where a parent component is expecting a single component to be
present, but the application wishes to render more than one.
Ht.'Se'e$tB!!'eanChe$>b!C - represents an HTML inp$t element of type chec2%ox.
The checkbox will be rendered as checked, or not, based on the value of the val$e
173
15 - javaserver faces
property.
Ht.'Se'e$t2an1Che$>b!C - represents a multiple-selection component that is rendered
as a set of HTML inp$t elements of type chec2%ox.
Ht.'Se'e$t2an1Listb!C - represents a multiple-selection component that is rendered as
an HTML select element, showing either all available options or the specified number of
options.
Ht.'Se'e$t2an12en - represents a multiple-selection component that is rendered as an
HTML select element, showing a single available option at a time.
Ht.'Se'e$tOneListb!C - represents a single-selection component that is rendered as an
HTML select element, showing either all available options or the specified number of
options.
Ht.'Se'e$tOne2en - represents a single-selection component that is rendered as an
HTML select element, showing a single available option at a time.
Ht.'Se'e$tOne9adi! - represents a single-selection component that is rendered as a set
of HTML inp$t elements of typeradio.
1*.1% the #a+a."a$es.$!nteCt &a$>age
Contains the following classes:
ECterna'C!nteCt - allows the Faces AP to be unaware of the nature of its containing
application environment. n particular, this class allows JavaServer Faces based
applications to run in either a Servlet or a Portlet environment.
8a$esC!nteCt - contains all of the per-request state information related to the processing
of a single JavaServer Faces request, and the rendering of the corresponding response. t
is passed to, and potentially modified by, each phase of the request processing lifecycle.
8a$esC!nteCt8a$t!r1 - a factory object that creates (if needed) and returns new
*acesContext instances, initialized for the processing of the specified request and
response objects.
9es&!nseStrea. - an interface describing an adapter to an underlying output
mechanism for binary output.
9es&!nseWriter - an abstract class describing an adapter to an underlying output
mechanism for character-based output.
9es&!nseWriterWra&&er - provides a simple implementation of Response/riter that
can be subclassed by developers wishing to provide specialized behavior to an existing
Response/riter instance. The default implementation of all methods is to call through
to the wrapped Response/riter.
1*.1( the #a+a."a$es.$!n+ert &a$>age
174
15 - javaserver faces
1*.1(.1 the inter"a$e C!n+erter
C!n+erter is an interface describing a Java class that can perform Object-to-String and String-
to-Object conversions between model data objects and a String representation of those objects
that is suitable for rendering.
The classes implementing this interface within this package are:
BigDe$i.a'C!n+erter
BigIntegerC!n+erter
B!!'eanC!n+erter
B1teC!n+erter
Chara$terC!n+erter
DateTi.eC!n+erter
D!b'eC!n+erter
En.C!n+erter
8L!atC!n+erter
IntegerC!n+erter
L!ngC!n+erter
N.berC!n+erter
Sh!rtC!n+erter
The package also contains one exception:
C!n+erterEC$e&ti!n - an exception thrown by the get(s+%ject01 or get(s!ext01
method of a Converter, to indicate that the requested conversion cannot be performed.
1*.1* the #a+a."a$es.e' &a$>age
Contains classes and interfaces for evaluating and processing reference expressions.
Classes:
2eth!dBinding - an object that can be used to call an arbitrary public method, on an
instance that is acquired by evaluatng the leading portion of a method binding expression
via a Gal$eCinding.
6r!&ert19es!'+er - represents a pluggable mechanism for accessing a "property" of an
underlying Java object instance.
7a'eBinding - an object that can be used to access the property represented by an
action or value binding expression.
7ariab'e9es!'+er - represents a pluggable mechanism for resolving a top-level variable
reference at evaluation time.
175
15 - javaserver faces
Exceptions:
E+a'ati!nEC$e&ti!n - an exception reporting an error that occurred during the
evaluation of an expression in a MethodCinding or Gal$eCinding.
2eth!dN!t8!ndEC$e&ti!n - an exception caused by a method name that cannot be
resolved against a base object.
6r!&ert1N!t8!ndEC$e&ti!n - an exception caused by a property name that cannot be
resolved against a base object.
9e"eren$eS1ntaCEC$e&ti!n - an exception reporting a syntax error in a method binding
expression or value binding expression.
1*.1, the #a+a."a$es.e+ent &a$>age
Contains interfaces describing events and event listeners, and event implementation classes.
nterfaces:
A$ti!nListener - listener interface for receiving (ction'vents.
8a$esListener - a generic base interface for event listeners for various types of
*aces'vents.
6haseListener - interface implemented by objects that wish to be notified at the
beginning and ending of processing for each standard phase of the request processing
lifecycle.
7a'eChangeListener - listener interface for receiving Gal$eChange'vents.
Classes:
A$ti!nE+ent - represents the activation of a user interface component (such as a
ICommand).
8a$esE+ent - the base class for user interface and application events that can be fired by
IComponents.
6haseE+ent - represents the beginning or ending of processing for a particular phase of
the request processing lifecycle, for the request encapsulated by the specified
*acesContext.
6haseId - typesafe enumeration of the legal values that may be returned by the
get7haseId01 method of the *aces'vent interface.
7a'eChangeE+ent - a notification that the local value of the source component has
been change as a result of user interface activity.
One exception - Ab!rt6r!$essingEC$e&ti!n - thrown by event listeners to terminate the
processing of the current event.
176
15 - javaserver faces
1*.1- the #a+a."a$es.'i"e$1$'e &a$>age
This package contains 2 classes.
The Li"e$1$'e class manages the processing of the entire lifecycle of a particular JavaServer
Faces request.
The Li"e$1$'e8a$t!r1 class is a factory object that creates (if needed) and returns Li5ecBcle
instances.
1*.10 the #a+a."a$es..!de' &a$>age
Contains the interface DataModelListener and several classes providing standard model data
beans for JavaServer Faces. Classes:
Arra1Data2!de' - a convenience implementation of #ataModel that wraps an array of
Java objects.
Data2!de' - an abstraction around arbitrary data binding technologies that can be used to
adapt a variety of data sources for use by JavaServer Faces components that support
per-row processing for their child components (such as I#ata).
Data2!de'E+ent - represents an event of interest to registered listeners that occurred on
the specified #ataModel.
ListData2!de' - a convenience implementation of #ataModel that wraps an List of
Java objects.
9es'tData2!de' - a convenience implementation of #ataModel that wraps a JSTL
Res$lt object, typically representing the results of executing an SQL query via JSTL
tags.
9es'tSetData2!de' - a convenience implementation of #ataModel that wraps a
Res$ltSet of Java objects. Note that the specified Res$ltSet 2=ST be scrollable.
S$a'arData2!de' - a convenience implementation of #ataModel that wraps an
individual Java object.
Se'e$tIte. - represents a single item in the list of supported items associated with a
ISelectManB or ISelect+ne component.
Se'e$tIte.Gr!& - a subclass of SelectItem that identifies a set of options that will be
made available as a subordinate "submenu" or "options list", depending upon the
requirements of the ISelectManB or ISelect+ne renderer that is actually used.
1*.14 the #a+a."a$es.render &a$>age
Contains classes defining the rendering model.
9enderer - converts the internal representation of IComponents into the output stream
177
15 - javaserver faces
(or writer) associated with the response we are creating for a particular request. Each
Renderer knows how to render one or more IComponent types (or classes), and
advertises a set of render-dependent attributes that it recognizes for each supported
IComponent.
9enderDit - represents a collection of Renderer instances that, together, know how to
render JavaServer Faces IComponent instances for a specific client. Typically,
RenderKits are specialized for some combination of client device type, markup
language, and/or user Locale. A RenderKit also acts as a Factory for associated
Renderer instances, which perform the actual rendering process for each component.
9enderDit8a$t!r1 - a factory object that registers and returns RenderKit instances.
mplementations of JavaServer Faces must provide at least a default implementation of
RenderKit.
9es&!nseState2anager - the helper class to StateManager that knows the specific
rendering technology being used to generate the response.
1*.25 the #a+a."a$es.+a'idat!r &a$>age
nterface defining the validator model, and concrete validator implementation classes.
A 7a'idat!r implementation is a class that can perform validation (correctness checks) on a
'dita%leGal$e6older.
mplementation classes:
D!b'e9ange7'idat!r - a Galidator that checks the value of the corresponding
component against specified minimum and maximum values
Length7a'idat!r - a Galidator that checks the number of characters in the String
representation of the value of the associated component.
L!ng9ange7a'idat!r - a Galidator that checks the value of the corresponding
component against specified minimum and maximum values.
The package contains an exception, as well.
A 7a'idat!rEC$e&ti!n is an exception thrown by the validate01 method of a Galidator to
indicate that validation failed.
1*.21 the #a+a."a$es.weba&& &a$>age
Contains classes required for integration of JavaServer Faces into web applications, including a
standard servlet, base classes for JSP custom component tags, and concrete tag implementations
for core tags.
AttribteTag - Tag implementation that adds an attribute with a specified name and
String value to the component whose tag it is nested inside, if the component does not
already contain an attribute with the same name.
C!n+erterTag - a base class for all JSP custom actions that create and register a
Converter instance on the Gal$e6older associated with our most immediate
178
15 - javaserver faces
surrounding instance of a tag whose implementation class is a subclass of
IComponent!ag.
8a$esSer+'et - a servlet that manages the request processing lifecycle for web
applications that are utilizing JavaServer Faces to construct the user interface.
8a$etTag - the JSP mechanism for denoting a IComponent is to be added as a 5acet
to the component associated with its parent.
=IC!.&!nentB!d1Tag - a base class for all JSP custom actions, related to a
UComponent, that need to process their tag bodies.
=IC!.&!nentTag - the base class for all JSP custom actions that correspond to user
interface components in a page that is rendered by JavaServer Faces.
7a'idat!rTag - a base class for all JSP custom actions that create and register a
Galidator instance on the 'dita%leGal$e6older associated with our most
immediate surrounding instance of a tag whose implementation class is a subclass of
IComponent!ag.
1*.22 the 3S8 'i"e$1$'e
Regardless of whether you are using JSF with JSP pages, servlets, or some other web
technology, each request/response flow that involves JSF follows a certain life cycle. Several
kinds of request/response cycles can occur in a JSF-enabled application. You can have a request
that comes from a previously rendered JSF page (a JSF request) and a request that comes from
a non-JSF page (a non-JSF request). Likewise, you can have a JSF response or a non-JSF
response. We are concerned with these three request/response pairs:
Non-JSF request generates JSF response
JSF request generates JSF response
JSF request generates non-JSF response
Of course, you can also have a non-JSF request that generates a non-JSF response. Because
this does not involve JSF in any way, the JSF life cycle does not apply.
JSP pages have a relatively simple life cycle. A JSP page source is compiled into a page
implementation class. When a web server receives a request, that request is passed to the
container, which passes the request to the page class. The page class processes the request and
then writes the response back to the client. When other pages are included or the request is
forwarded, or when an exception occurs, the process includes a few more components or pages,
but basically, a small set of classes processes a request and sends back a response.
When using JSF, the life cycle is more complicated. This is because the core of JSF is the
MVC pattern, which has several implications. User actions in JSF-generated views take place in a
client that does not have a permanent connection to the server. The delivery of user actions or
page events is delayed until a new connection is established. The JSF life cycle must handle this
delay between event and event processing. Also, the JSF life cycle must ensure that the view is
correct before rendering the view. To ensure that the business state is never invalid, the JSF
system includes a phase for validating inputs and another for updating the model only after all
inputs pass validation.
n MVC, the presentation of data (the view) is separate from its representation in the system
(the model). When the model is updated, the controller sends a message to the view, telling the
view to update its presentation. When the user takes some action with the presentation, the
controller sends a message to the model, telling the model to update its data. n JSF, the model is
composed of business objects that are usually implemented as JavaBeans, the controller is the
179
15 - javaserver faces
JSF implementation, and the U components are the view.
The JSF life cycle has six phases as defined by the JSF specification:
9est!re 7iewE n this phase, the JSF implementation restores the objects and data structures
that represent the view of the request. if this is the client's first visit to a page, the JSF
implementation must create the view. When a JSF implementation creates and renders a JSF-
enabled page, it creates U objects for each view component. The components are stored in a
component tree, and the state of the U view is saved for subsequent requests. f this is a
subsequent request, the saved U view is retrieved for the processing of the current request.
A&&'1 9e@est 7a'esE Any data that was sent as part of the request is passed to the
appropriate U objects that compose the view. These objects update their state with the data
values. Data can come from input fields in a web form, from cookies sent as part of the request,
or from request headers. Data for some components, such as components that create HTML input
fields, is validated at this time. Note that this does not yet update the business objects that
compose the model. t updates only the U components with the new data.
6r!$ess 7a'idati!nsE The data that was submitted with the form is validated (if it was not
validated in the previous phase). As with the previous phase, this does not yet update the
business objects in the application. This is because if the JSF implementation began to update the
business objects as data was validated, and a piece of data failed validation, the model would be
partially updated and in an invalid state.
=&date 2!de' 7a'esE After all validations are complete, the business objects that make up
the application are updated with the validated data from the request. n addition, if any of the data
needs to be converted to a different format to update the model (for example, converting a String
to a Date object), the conversion occurs in this phase. Conversion is needed when the data type
of a property is not a String or a Java primitive.
In+!>e A&&'i$ati!nE During this phase, the action method of any command button or link that
was activated is called. n addition, any events that were generated during previous phases and
that have not yet been handled are passed to the web application so that it can complete any
other processing of the request that is required.
9ender 9es&!nseE The response U components are rendered, and the response is sent to
the client. The state of the U components is saved so that the component tree can be restored
when the client sends another request. For a JSF-enabled application, the thread of execution for
a request/response cycle can flow through each phase, in the order listed here and as shown in
the figure below. However, depending on the request, and what happens during the processing
and response, not every request will flow through all six phases.
180
15 - javaserver faces
n the above figure, you can see a number of optional paths through the life cycle. For example,
if errors occur during any of the phases, the flow of execution transfers immediately to the Render
Response phase, skipping any remaining phases. One way this might occur is if input data is
incorrect or invalid. f data fails validation in either the Apply Request Values or Process
Validations phase, information about the error is saved and processing proceeds directly to the
Render Response phase. Also, if at any point in the life cycle the request processing is complete
and a non-JSF response is to be sent to the client, the flow of execution can exit the life cycle
without completing further phases.
181
16 - java RM
1, - 3A7A 92I
1,.1 9e.!te &r!$edre $a''s
n distributed applications, the simple act of invoking a method may take us beyond and away
from our own address space, just for the simple fact that that method is located into another
process, possibly running on a different machine. We enter the domain of Remote Procedure
Calls, which is, eventually, just another form of nter Process Communication.
The idea of RPC dates back to 1976 when the rules were defined in RFC 707.
magine now the same person in a completely different location, maybe hundreds of miles
away. Talking to him (her) is no longer . The difference is that we do not talk to that person mouth
to mouth, but mouth to phone, rather. So the communication medium is no longer, but a segment
of a sophisticated infrastructure.
Technically speaking, a servlet is a Java class that extends the GenericServlet (or, more often,
the HttpServlet) class.
The Java servlet AP provides a simple frame for building web applications on web servers.
The current Java Servlet specification (as of 10.2008) is 2.5 and is in final state. Java EE 5
SDK contains an implementation of the Java Servlet 2.5 specification.
1,.2 ser+'et $!ntainers
The servlet does not communicate directly with the client, but through a web container. The
servlet lives within this container which provides an execution environment for the servlet class.
Web containers are implemented by various vendors, in most cases as part of an application
server.
1,.2.1 N!n$!..er$ia' ser+'et $!ntainers
Apache Tomcat (formerly Jakarta Tomcat) is an open source web container available
under the Apache Software License.
Apache Geronimo is a full Java EE implementation by Apache.
Jetty
Jaminid contains a higher abstraction than servlets.
Enhydra
Winstone supports specification v2.4, has a focus on minimal configuration and the ability
to strip the container down to only what you need.
tjws spec 2.4, small footprint, modular design
1,.2.2 $!..er$ia' ser+'et $!ntainers
BEA WebLogic Server or Weblogic Express, from BEA Systems
Borland Enterprise Server
182
16 - java RM
GlassFish (open source)
Java System Application Server , from Sun Microsystems
Java System Web Server , from Sun Microsystems
JBoss (open source)
JRun , from Adobe Systems (formerly developed by Allaire Corporation)
LiteWebServer (open source)
Oracle Application Server , from Oracle Corporation
Orion Application Server , from ronFlare
Caucho's Resin Server
ServletExec , from New Atlanta Communications
WebObjects , from Apple nc.
WebSphere , from BM
1,.% ser+'et &a$>ages and $'asses
The Java servlet AP consists of 2 packages, which are part of the J2 SDK, Enterprise Edition.
These packages are:
javax.servlet
javax.servlet.http
The classes and interfaces defined in the javax.servlet package are protocol independent, while
the second one, the javax.servlet.http contains classes and interfaces which are HTTP specific.
The classes and interfaces of the Java servlet AP can be divided in several categories,
namely:
servlet implementation
servlet configuration
servlet exceptions
request and responses
session tracking
servlet context
servlet collaboration
miscellaneous
1,.( the Ser+'et inter"a$e
The Servlet interface is part of the javax.servlet package. t declares the following
methods:
183
16 - java RM
p$%lic void init0ServletCon5ig con5ig1 throws Servlet'xceptionW
p$%lic void service0ServletReM$est reM3 ServletResponse resp1 throws
Servlet'xception3 I+'xceptionW
p$%lic void destroB01 throws Servlet'xceptionW
p$%lic ServletCon5ig getServletCon5ig01W
p$%lic String getServletIn5o01W
After instantiating the servlet, the web container calls its init01 method. The method
performs all initialization required, before the servlet processes any HTTP request. The servlet
specification insures that the init01 method is called just once for any given instance of the
servlet.
The web container calls the service01 method in response to any incoming request. This
method has two arguments, arguments which implement the ServletReM$est and
ServletResponse interfaces, respectively.
More on the servlet lifecycle, in a different section.
1,.* the Generi$Ser+'et $'ass
p$%lic a%stract class -enericServlet implements
Servlet3 ServletCon5ig3 SerialiRa%le
This class provides a basic implementation of the Servlet interface. Since this class
implements the ServletCon5ig interface, as well, the developer may call ServletCon5ig
methods directly, without having to obtain a ServletCon5ig object first. All classes extending
the GenericServlet class should provide an implementation for the service01 method.
Methods specific to this class:
public void init()
public void log(String msg)
public void log(String msg, Throwable t)
1,., the Htt&Ser+'et $'ass
t is very likely that the only implementation of the Servlet interface we'll ever use is one that
processes an HTTP request. The servlet AP provides such a specific class, namely the
6ttpServlet class.
public abstract class HttpServlet extends GenericServlet implements Serializable
184
16 - java RM
The HttpServlet provides an HTTP specific implementation of the Servlet interface. This
abstract class specifies the following methods:
public void service(ServletRequest req, ServletResponse resp)
public void service(HttpServletRequest req, HttpServletResponse resp)
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
protected void doPost(HttpServletRequest req,
HttpServletResponse resp)
protected void doDelete(HttpServletRequest req,
HttpServletResponse resp)
protected void doOptions(HttpServletRequest req,
HttpServletResponse resp)
protected void doPut(HttpServletRequest req, HttpServletResponse resp)
protected void doTrace(HttpServletRequest req,
HttpServletResponse resp)
1,.- the Ser+'etC!n"ig inter"a$e
This interface abstracts configuration information about the servlet, namely:
initialization parameters (as name-value pairs)
the name of the servlet
a ServletContext object, containing web container information
This interface specifies the following methods:
public String getnitParameter(String name)
public Enumeration getnitParameterNames()
public ServletContext getServletContext()
public String getServletName()
1,.0 ser+'et eC$e&ti!ns
The Java servlet AP specifies two servlet specific exceptions:
javax.servlet.Servlet'xception
javax.servlet.navaila%le'xception
The Servlet'xception class extends java.lang.'xception and can be thrown by the
init01, service01, doXXX01 and destroB01 methods of the Servlet interface
implementations.
185
16 - java RM
The navaila%le'xception indicates to the web container that the servlet instance is
unavaialble. t also extends the java.lang.'xception class.
1,.4 the ser+'et 'i"e$1$'e
Generally, a servlet instance goes through the following stages:
instantiation
initialization
service
destroy
unavailable
The container creates a servlet instance as first response to an incoming (HTTP) request or at
container startup. Typically, the web container creates a single instance of the servlet, which will
service all incoming requests. f the servlet does not implement the
javax.servlet.Single!hreadModel, concurrent requests are serviced in more than one
service thread, which requires that the service01 method be thread safe.
After instantiation, the container calls the init01 method of the servlet, method which
performs the initialization of the servlet. Typically, this method contains JDBC driver loading, DB
connection opening, etc.
The web container makes sure that the init01 method of the servlet will be completed before
invoking its service01 method. Also, the servlet's destroB01 method will be called before the
servlet itself is destroyed.
1,.15 the Ser+'et9e@est inter"a$e
Here are some of the methods of this interface:
p$%lic +%ject get(ttri%$te0String name1
p$%lic +%ject set(ttri%$te0String name3 +%ject attr1
p$%lic 'n$meration get(ttri%$te)ames01
p$%lic int getContentLength01
p$%lic String getContent!Bpe01
p$%lic String get7arameter0String name1
p$%lic 'n$meration get7arameter)ames01
p$%lic 'n$meration get7arameterGal$es01
p$%lic String getServer)ame01
p$%lic int getServer7ort01
p$%lic String getRemote(ddr01
p$%lic String getRemote6ost01
186
16 - java RM
Most of the above methods are self explanatory. But what is the difference between a
parameter and an attribute? While the parameters of the request are part of the request itself, the
attributes of the request are attached by the web containers or by the servlets/JSPs.
There are 3 different ways for attaching and retrieving attributes. The first one is to attach
attributes to the request object. The other two use the HttpSession and ServletContext objects,
respectively. The purpose of attributes is to allow the container to provide additional data to a
servlet or JSP or to allow sending data from a servlet to another.
1,.11 the Htt&Ser+'et9e@est inter"a$e
p$%lic inter5ace 6ttpServletReM$est extends ServletReM$est
This interface contains HTTP specific methods. One has to take in account the structure of an
HTTP request when overviewing the most important methods of this interface. Here are some of
them:
p$%lic Coo2ieST getCoo2ies01
p$%lic long get#ate6eader01
p$%lic String get6eader0String name1
p$%lic 'n$meration get6eaders0String name1
p$%lic 'n$meration get6eader)ames01
p$%lic String getContext7ath01
p$%lic String get7athIn5o01
p$%lic String getH$erBString01
p$%lic String getRemoteser01
1,.12 the Ser+'et9es&!nse inter"a$e
This interface defines methods for constructing responses to servlet requests.
Here are the most important ones:
p$%lic Servlet+$tp$tStream get+$tp$tStream01
p$%lic 7rint/riter get/riter01
p$%lic void setContentLength0int len1
p$%lic void setContent!Bpe0String tBpe1
p$%lic void setC$55erSiRe0int siRe1
p$%lic int getC$55erSiRe01
p$%lic void 5l$shC$55er01
187
16 - java RM
1,.1% the Htt&Ser+'et9es&!nse inter"a$e
This interface extends the ServletResponse interface and defines methods specific for
constructing responses to HTTP requests.
Here are the most important ones:
p$%lic void addCoo2ie0Coo2ie coo2ie1
p$%lic String encodeRL0String $rl1
p$%lic void send'rror0int stat$s1
p$%lic void send'rror0int stat$s3 String message1
p$%lic void set6eader0String header)ame3 String val$e1
p$%lic void add6eader0String header)ame3 String val$e1
p$%lic void setStat$s0int stat$sCode1
1,.1( the Ser+'etC!nteCt inter"a$e
A servlet context defines servlet's view of the web application and provides access to resources
common to all servlets of the web application. Each servlet context is rooted at a specific path in
the web server. The deployment of a web application involves adding an application specific
;context4 tag which associates the the name of the application with its root directory. This is
done in server's (container's) server.xml file.
The ServletContext interface abstracts the context of a web application. A reference to an
object of this type can be obtained by invoking the getServletContext01 method of the
6ttpServlet object.
p$%lic String getMIM'!Bpe0String 5ile)ame1
p$%lic String getReso$rce0String path1
p$%lic ServletContext getContext0String $rl7ath1
p$%lic String getInit7arameter0String name1
p$%lic 'n$meration getInit7arameter)ames01
p$%lic +%ject get(ttri%$te0String name1
p$%lic 'n$meration get(ttri%$te)ames01
p$%lic void set(ttri%$te0String name3 +%ject attr1
p$%lic String remove(ttri%$te0String name1
1,.1* the Enr!'' ser+'et
The Enroll servlet services the request sent by the web browser when we submit the Enroll form
188
16 - java RM
(file Enroll.html)
Here is its abbreviated form (topics which are DB related are postponed) of the
"EnrollServlet.java" file:
package com.bank11.ccards.servlets;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class EnrollServlet extends HttpServlet
{
public void init(ServletConfig config)
throws ServletException
{
super.init(config);
}
public void doPost(HttpServletRequest req,
HttpServletResponse resp)
throws ServletException, OException
{
resp.setContent!Bpe0Ytext/htmlL1W
7rint/riter o$t K resp.get/riter01W
// o$tp$t Bo$r page here
o$t.println0=;html4=1W
o$t.println0=;head4=1W
o$t.println0=;title4Servlet;/title4=1W
o$t.println0=;/head4=1W
o$t.println0=;%odB4=1W
o$t.println0=merge=1W
o$t.println0=;%r4=1W
o$t.println0=;/%odB4=1W
o$t.println0=;/html4=1W
o$t.close01W
V
V
189
17 - JAVA MESSAGE SERVCE
1- - 3A7A 2ESSAGE SE97ICE
1-.1 32S e'e.ents
The 3a+a 2essage Ser+i$e (32S) AP is a Java Message Oriented Middleware (MOM) AP for
sending messages between two or more clients. JMS is a part of the Java Platform, Enterprise
Edition, and is defined by a specification developed under the Java Community Process as JSR
914.
The following are JMS elements:
32S &r!+ider - An implementation of the JMS interface for a Message Oriented
Middleware (MOM). Providers are implemented as either a Java JMS implementation or
an adapter to a non-Java MOM.
32S $'ient - an application or process that produces and/or consumes messages.
32S &r!d$er - a JMS client that creates and sends messages.
32S $!ns.er - a JMS client that receives messages.
32S .essage - an object that contains the data being transferred between JMS clients.
32S @ee - a staging area that contains messages that have been sent and are waiting
to be read. As the name <ueue suggests, the messages are delivered in the order sent. A
message is removed from the queue once it has been read.
32S t!&i$ - a distribution mechanism for publishing messages that are delivered to
multiple subscribers.
1-.2 32S .!de's
The JMS AP supports two models:
point-to-point or queuing model
publish and subscribe model
n the point-to-point or queuing model, a producer posts messages to a particular queue and a
consumer reads messages from the queue. Here, the producer knows the destination of the
message and posts the message directly to the consumer's queue. t is characterized by following:
Only one consumer will get the message
The producer does not have to be running at the time the consumer consumes the
message, nor does the consumer need to be running at the time the message is sent
Every message successfully processed is acknowledged by the consumer
The publish/subscribe model supports publishing messages to a particular message topic. Zero
or more subscribers may register interest in receiving messages on a particular message topic. n
this model, neither the publisher nor the subscriber know about each other. A good metaphor for it
is anonymous bulletin board. The following are characteristics of this model:
Multiple consumers can get the message
There is a timing dependency between publishers and subscribers. The publisher has to
create a subscription in order for clients to be able to subscribe. The subscriber has to
remain continuously active to receive messages, unless it has established a durable
190
17 - JAVA MESSAGE SERVCE
subscription. n that case, messages published while the subscriber is not connected will
be redistributed whenever it reconnects.
Using Java, JMS provides a way of separating the application from the transport layer of
providing data. The same Java classes can be used to communicate with different JMS providers
by using the JND information for the desired provider. The classes first use a connection factory
to connect to the queue or topic, and then use populate and send or publish the messages. On the
receiving side, the clients then receive or subscribe to the messages.
1-.% the 32S A6I &r!gra..ing .!de'
1-.( the 32S A6I
The JMS AP is provided in the Java package javax.jms.
1-.(.1 the C!nne$ti!n8a$t!r1 inter"a$e
An administered object that a client uses to create a connection to the JMS provider. JMS
clients access the connection factory through portable interfaces so the code does not need to be
changed if the underlying implementation changes. Administrators configure the connection
factory in the Java Naming and Directory nterface (JND) namespace so that JMS clients can
look them up. Depending on the type of message, users will use either a queue connection factory
or topic connection factory.
191
17 - JAVA MESSAGE SERVCE
At the beginning of a JMS client program, you usually perform a JND lookup of a connection
factory, then cast and assign it to a Connection*actorB object.
For example, the following code fragment obtains an InitialContext object and uses it to
look up a Connection*actorB by name. Then it assigns it to a Connection*actorB object:
Context ctx = new nitialContext();
ConnectionFactory connectionFactory = (ConnectionFactory)
ctx.lookup("jms/ConnectionFactory");
n a J2EE application, JMS administered objects are normally placed in the jms naming
subcontext.
1-.(.2 the C!nne$ti!n inter"a$e
Once a connection factory is obtained, a connection to a JMS provider can be created. A
connection represents a communication link between the application and the messaging server.
Depending on the connection type, connections allow users to create sessions for sending and
receiving messages from a queue or topic.
Connections implement the Connection interface. When you have a Connection*actorB
object, you can use it to create a Connection:
Connection connection = connectionFactory.createConnection();
Before an application completes, you must close any connections that you have created.
Failure to close a connection can cause resources not to be released by the JMS provider.
Closing a connection also closes its sessions and their message producers and message
consumers.
connection.close();
Before your application can consume messages, you must call the connection's start01
method. f you want to stop message delivery temporarily without closing the connection, you call
the stop method.
1-.(.% the Destinati!n inter"a$e
An administered object that encapsulates the identity of a message destination, which is where
messages are delivered and consumed. t is either a queue or a topic. The JMS administrator
creates these objects, and users discover them using JND. Like the connection factory, the
administrator can create two types of destinations: queues for Point-to-Point and topics for
Publish/Subscribe.
For example, the following line of code performs a JND lookup of the previously created topic
jms/MB!opic and casts and assigns it to a #estination object:
Destination myDest = (Destination) ctx.lookup("jms/MyTopic");
The following line of code looks up a queue named jms/MBH$e$e and casts and assigns it to a
H$e$e object:
Queue myQueue = (Queue) ctx.lookup("jms/MyQueue");
1-.(.( the 2essageC!ns.er inter"a$e
An object created by a session. t receives messages sent to a destination. The consumer can
192
17 - JAVA MESSAGE SERVCE
receive messages synchronously (blocking) or asynchronously (non-blocking) for both queue and
topic-type messaging.
For example, you use a Session to create a MessageCons$mer for either a queue or a topic:
MessageConsumer consumer = session.createConsumer(myQueue);
MessageConsumer consumer = session.createConsumer(myTopic);
You use the Session.create#$ra%leS$%scri%er01 method to create a durable topic
subscriber. This method is valid only if you are using a topic.
After you have created a message consumer, it becomes active, and you can use it to receive
messages. You can use the close01 method for a MessageCons$mer to make the message
consumer inactive. Message delivery does not begin until you start the connection you created by
calling its start01 method. (Remember always to call the start01 method; forgetting to start
the connection is one of the most common JMS programming errors.)
You use the receive method to consume a message synchronously. You can use this method
at any time after you call the start method:
connection.start();
Message m = consumer.receive();
connection.start();
Message m = consumer.receive(1000); // time out after a second
To consume a message asynchronously, a message listener object may be used.
1-.(.* the 2essageListener inter"a$e
A .essage 'istener is an object that acts as an asynchronous event handler for messages.
This object implements the MessageListener interface, which contains one method,
onMessage01. n the onMessage01 method, you define the actions to be taken when a message
arrives.
You register the message listener with a specific MessageCons$mer by using the
setMessageListener01 method. For example, if you define a class named Listener that
implements the MessageListener interface, you can register the message listener as follows:
Listener myListener = new Listener();
consumer.setMessageListener(myListener);
After you register the message listener, you call the start01 method on the Connection to
begin message delivery. (f you call start01 before you register the message listener, you are
likely to miss messages.)
When message delivery begins, the JMS provider automatically calls the message listener's
onMessage01 method whenever a message is delivered. The onMessage01 method takes one
argument of type Message, which your implementation of the method can cast to any of the other
message types.
A message listener is not specific to a particular destination type. The same listener can obtain
messages from either a queue or a topic, depending on the type of destination for which the
message consumer was created. A message listener does, however, usually expect a specific
message type and format. Moreover, if it needs to reply to messages, a message listener must
either assume a particular destination type or obtain the destination type of the message and
create a producer for that destination type.
193
17 - JAVA MESSAGE SERVCE
1-.(., the 2essage6r!d$er inter"a$e
An object created by a session that sends messages to a destination. The user can create a
sender to a specific destination or create a generic sender that specifies the destination at the
time the message is sent.
You use a Session to create a Message7rod$cer for a destination. Here, the first example
creates a producer for the destination mBH$e$e, and the second for the destination mB!opic:
MessageProducer producer = session.createProducer(myQueue);
MessageProducer producer = session.createProducer(myTopic);
You can create an unidentified producer by specifying n$ll as the argument to
create7rod$cer. With an unidentified producer, you do not specify a destination until you send
a message.
After you have created a message producer, you can use it to send messages by using the
send method:
producer.send(message);
You must first create the messages; if you created an unidentified producer, use an overloaded
send method that specifies the destination as the first parameter. For example:
MessageProducer anon_prod = session.createProducer(null);
anon_prod.send(myQueue, message);
1-.(.- the 2essage inter"a$e
An object that is sent between consumers and producers; that is, from one application to
another. A message has three main parts:
1. A message header (required): Contains operational settings to identify and route
messages
2. A set of message properties (optional): Contains additional properties to support
compatibility with other providers or users. t can be used to create custom fields or filters
(selectors).
3. A message body (optional): Allows users to create five types of messages (text message,
map message, bytes message, stream message, and object message).
The message interface is extremely flexible and provides numerous ways to customize the
contents of a message.
The JMS AP provides methods for creating messages of each type and for filling in their
contents. For example, to create and send a !extMessage, you might use the following
statements:
TextMessage message = session.createTextMessage();
message.setText(msg_text); // msg_text is a String
producer.send(message);
At the consuming end, a message arrives as a generic Message object and must be cast to the
appropriate message type. You can use one or more getter methods to extract the message
contents. The following code fragment uses the get!ext method:
Message m = consumer.receive();
if (m instanceof TextMessage) {
TextMessage message = (TextMessage) m;
194
17 - JAVA MESSAGE SERVCE
System.out.println("Reading message: " + message.getText());
} else {
// Handle error
}
1-.(.0 the Sessi!n inter"a$e
Represents a single-threaded context for sending and receiving messages. A session is single-
threaded so that messages are serialized, meaning that messages are received one-by-one in the
order sent. The benefit of a session is that it supports transactions. f the user selects transaction
support, the session context holds a group of messages until the transaction is committed, then
delivers the messages. Before committing the transaction, the user can cancel the messages
using a rollback operation. A session allows users to create message producers to send
messages, and message consumers to receive messages.
Sessions implement the Session interface. After you create a Connection object, you use it
to create a Session:
Session session = connection.createSession(false,
Session.AUTO_ACKNOWLEDGE);
The first argument means that the session is not transacted; the second means that the session
automatically acknowledges messages when they have been received successfully.
To create a transacted session, use the following code:
Session session = connection.createSession(true, 0);
Here, the first argument means that the session is transacted; the second indicates that
message acknowledgment is not specified for transacted sessions.
195
18 - ENTERPRSE JAVA BEANS
10 - ENTE969ISE 3A7A BEANS
10.1 enter&rise #a+a beans +erss :!rdinar1; #a+a beans
(Ordinary) Java beans provide a format for general-purpose components, while the EJB
(Enterprise Java Beans) architecture provides a format for highly specialized business logic
components.
What are Enterprise Java Beans? A collection of Java classes together with an xml file,
bundled into a single unit. The Java classes must follow certain rules and must offer certain
callback methods.
The EJBs will run in an EJB container which is part of an application server.
Version 1.1 of EJB specification provides two EJB types:
session beans - intended to be used by a single client (client extension on the server);
bean's life span can be no longer than client's
entity beans - object oriented representation of data in a DB; multiple clients can access it
simultaneously while its life-span is the same as the data it represents
The 2.0 EJB specification adds another bean type:
message-driven beans
The current EJB specification is 3.0. Novelties in this specification try to make the development
of EJBs easier. t provides annotations for every type of metadata previously addressed by
deployment descriptors, so no XML descriptor is needed and beans deployment can be done just
through a plain .jar file into the application server.
10.2 enter&rise #a+a beans ar$hite$tre
196
18 - ENTERPRSE JAVA BEANS
10.% the e#b $!ntainer and its ser+i$es
The EJB container provides an execution environment for a component. The component lives
inside a container, container which offers services to the component. On the other side, the
container lives (in general) in an application server, server which provides an execution
environment for containers.
The main reason for using EJBs is to take advantage of the services provided by the container.
These services are:
persistence - DB interaction
transactions - transaction management can be complex, especially if we have more
databases and more access components
data caching - no developer coding, improved performance
security - EJB access can be stated without extra coding
error handling - consistent error handling framework - logging, component recovery
scalability
portability
manageability
10.( the h!.e inter"a$e
The home interface of an ejb is an interface that extends the EJBHome interface. t provides
methods named create() with application specific arguments, returning the remote interface and
throwing Create'xception and Remote'xception. t uses only argument types allowed by
the RM standard.
Handle abstraction for a network reference to an EJB.
The methods specified by the EJBHome interface (not implemented (in general) by the
programmer) are the following:
p$%lic void remove06andle han1 throws Remote'xception3 Remove'xception
p$%lic void remove0+%ject primarBKeB1 throws Remote'xception3
Remove'xception
p$%lic 'ZCMeta#ata get'ZCMeta#ata01 throws Remote'xception
p$%lic 6ome6andle get6ome6andle01 throws Remote'xception
Code example for the a home interface, called MyBeanHome:
pac2age mBCeansW
import.javax.ejb.*;
import java.rmi.RemoteException;
public interface MyBeanHome extends EJBHome
197
18 - ENTERPRSE JAVA BEANS
{
MyBeanObject create() throws CreateException,
RemoteException;
}
10.* the re.!te inter"a$e
The remote interface of a bean is a standard Java interface that extends the 'ZC+%ject and
Remote inter5aces and declares the business logic methods of the bean. The developer does
not implement this interface.
While the Remote interface declares no methods, the 'ZC+%ject declares the following ones:
p$%lic 'ZC6ome get'ZC6ome01 throws Remote'xception
p$%lic +%ject get7rimarBKeB01 throws Remote'xception
p$%lic 6andle get6andle01 throws Remote'xception
p$%lic %oolean isIdentical0'ZC+%ject o%j1 throws
Remote'xception
p$%lic void remove01 throws Remote'xception3 Remove'xception
Code example for a remote interface called MyBeanObject:
package myBeans;
import.javax.ejb.*;
import java.rmi.RemoteException;
public interface MyBeanObject extends EJBObject
{
// assume that we have two business logic methods
void processEntry(String firstName, String lastName, int custd)
throws RemoteException;
void deleteEntry(int custd) throws RemoteException;
}
10., $'ient &r!gra..erAs +iew&!int
For an EJB client application, we need to know:
1. how to create or find the bean
2. what methods to use (know its interface)
3. how to release its its resources
198
18 - ENTERPRSE JAVA BEANS
The client is able to create an EJB through an object implementing the EJBHome interface.
This object acts like a factory for EJBs, creating them for the client application.
The client gains access to the EJB through a remote interface, implemented by an object built
by the EJB host in the deployment process.
Here are the main parts of the client code:
athenti$ati!n
Client's authentication is done in a way which is server specific. n the case of an web
application, this can be done (for example) through SSL.
getting an initia' $!nteCt
if the client is another EJB executing in the same container and the bean to be used is
declared as a resource in the deployment descriptor, the nitialContext is already available:
Context ctx K new InitialContext01W
if the client executes outside the container, getting the nitialContext requires the usage of
some server-side properties. Here is an example:
trB
{
Properties prop = new Properties();
prop.put(Context.NTAL_CONTEXT_FACTORY,
"org.jnp.interfaces.NamingContextFactory";
prop.put(Context.PROVDER_URL,
"localhost:1099");
Context ctx = new nitialContext(prop);
}
"ind the h!.e inter"a$e !" the bean
for a client executing inside the container, the code may look like:
+%ject homeRe5 K ctx.loo2$p0=java:comp/env/ej%/MBCean=1W
if the client executes outside the container, the bean can be associated to any name in the
JND name space. t is JND's task to identify the resource associated to the name provided:
199
18 - ENTERPRSE JAVA BEANS
+%ject homeRe5 K ctx.loo2$p0=MBCean=1W
$ast the h!.e inter"a$e re"eren$e
To make sure that the client works with the underlying communication protocol, the client
should use the narrow() method of javax.rmi.PortableRemoteObject:
MBCean6ome home K 0MBCean6ome17orta%leRemote+%ject.narrow0homeRe53
MBCean6ome.class1W
$reate an instan$e !" the bean
The instance of the bean is created on the server. The client only has a remote interface to this
instance (i.e. the client has a stub).
Here is the code:
MBCean+%ject mBCean+%ject K home.create01W
$a'' bsiness .eth!ds !n the bean
mBCean+%ject.process'ntrB0=#$mitrasc$=3 =Gasile=3 889D1W
re.!+e the bean instan$e
mBCean+%ject.remove01W
10.- bean &r!gra..erAs +iew&!int
An EJB consists of (at least) 3 classes and an xml file. t is bean's programmer task to create
them (at least), as follows:
1. the bean itself (the class that contains the business logic )
2. the home interface of the bean
3. the remote interface of the bean
4. the deployment descriptor, which is an xml file, called ej%&jar.xml
Since the home interface and the remote interface have been detailed in the previous sections,
200
18 - ENTERPRSE JAVA BEANS
we concentrate now on the bean class itself. Besides the implementation of the business methods
(which were declared in the remote interface, as well), the bean class must implement (although
the implementation itself may be empty) a certain set of methods, set which is specific to each
major type of beans (session or entity).
Assuming that our bean (called MyBean) is a session bean, the code implementing this class
may look like this:
package myBeans;
import.javax.ejb.SessionContext;
public class MyBean implements javax.ejb.SessionBean
{
public void processEntry(String firstName, String lastName, int custd)
{
// method implementation
...
}
public void deleteEntry(int custd)
{
// method implementation
...
}
// mandatory methods for session beans
// method implementations may be empty
public void ejbCreate() {}
public void ejbRemove() {}
public void ejbActivate() {}
public void ejbPassivate() {}
public void setSessionContext(SessionContext ctx) {}
}
The deployment descriptor of the bean will be detailed in another section.
10.0 sessi!n beans
There are two types of session beans, namely state"' and state'ess beans.
A stateful session bean preserves data between client accesses. A stateless bean does not.
When an EJB server needs to conserve its resources, it can evict stateful session beans from
memory. This reduces the number of instances maintained by the server. To &assi+ate the bean
and preserve its conversational state, the bean's state is serialized to a secondary storage. When
a client invokes a method on the EJB object, the object is a$ti+ated, that is, a new stateful
instance is instantiated and populated from the passivated storage.
201
18 - ENTERPRSE JAVA BEANS
10.4 $!ntainer $a''ba$>s "!r sessi!n beans
There are 5 mandatory callbacks for classes implementing the SessionBean interface.
p$%lic void ej%(ctivate01
p$%lic void ej%7assivate01
p$%lic void ej%Create01
p$%lic void ej%Remove01
p$%lic void setSessionContext0SessionContext ctx1
The first two methods will never be called for stateless session beans, because the container
will never activate a stateless session bean.
10.15 the 'i"e $1$'e !" a state"' sessi!n bean
Figure 14.1 illustrates the stages that a session bean passes through during its lifetime. The
client initiates the life cycle by invoking the create method. The EJB container instantiates the
bean and then invokes the setSessionContext and ej%Create methods in the session bean.
The bean is now ready to have its business methods invoked.
Figure 14.1 Life Cycle of a Stateful Session Bean
While in the ready stage, the EJB container may decide to deactivate, or passivate, the bean by
moving it from memory to secondary storage. (Typically, the EJB container uses a least-recently-
used algorithm to select a bean for passivation.) The EJB container invokes the bean's
ej%7assivate method immediately before passivating it. f a client invokes a business method
on the bean while it is in the passive stage, the EJB container activates the bean, calls the bean's
ej%(ctivate method, and then moves it to the ready stage.
At the end of the life cycle, the client invokes the remove method, and the EJB container calls
the bean's ej%Remove method. The bean's instance is ready for garbage collection.
Your code controls the invocation of only two life-cycle methods: the create and remove
202
18 - ENTERPRSE JAVA BEANS
methods in the client. All other methods in Figure 13.1 are invoked by the EJB container. The
ej%Create method, for example, is inside the bean class, allowing you to perform certain
operations right after the bean is instantiated. For example, you might wish to connect to a
database in the ej%Create method.
10.11 the 'i"e $1$'e !" a state'ess sessi!n bean
Because a stateless session bean is never passivated, its life cycle has only two stages:
nonexistent and ready for the invocation of business methods. Figure 14.2 illustrates the stages of
a stateless session bean.
Figure 14.2 Life Cycle of a Stateless Session Bean
10.12 entit1 beans
Entity beans represent actual data (usually, stored in a Database).
The EJB container provides the developer several persistence services:
1. container callbacks to manage caching within a transaction
2. support for concurrent access
3. maintaining a cache between transactions
4. providing all the persistence management code (no SQL code necessary)
There are 2 main types of entity beans.
C26s (Container Managed Persistence)
B26s (Bean Managed Persistence) for which the bean developer provides the actual
203
18 - ENTERPRSE JAVA BEANS
persistence (SQL) code
10.1% &ri.ar1 >e1s
Every entity bean has a primary key. This primary key must be represented by a primary key
class. The requirements that must be satisfied by the primary key are different for the two main
types of entity beans.
For BMPs:
the primary key can be any legal RM/OP type
it must provide suitable implementations for hashCode(), equals()
must have a unique value among beans of a particular type
For CMPs:
the container must be able to create a primary key
the key class must have a no argument constructor
The fully qualified name of the primary key is always specified in the deployment descriptor
(except when it is not known until deployment)
An example:
;prim&2eB&class4com.%an288.ccards.C$stomerI#;/prim&2eB&class4
or
;prim&2eB&class4java.lang.String;/prim&2eB&class4
n the case of CMP using a simple type as primary key, the field is specified:
;prim&2eB&5ield4sports!eamI#;/prim&2eB&5ield4
10.1( .andat!r1 $a''ba$>s "!r entit1 beans
Besides the CRUD callbacks which are discusses later in this section, an entity bean must
implement (although this implementation may be left empty) the following methods:
p$%lic void ej%(ctivate01
p$%lic void ej%7assivate01
p$%lic void set'ntitBContext0'ntitBContext ctx1
p$%lic void $nset'ntitBContext01
204
18 - ENTERPRSE JAVA BEANS
CRUD translates through Create, Read, Update and Delete. These methods are mandatory for
entity beans.
10.1(.1 $reate
When a client calls a create01 method on a session bean's home interface, an instance of
that bean is created. On the other side, when a client calls create01 on an entity bean's home
interface, state data is stored into data store (usually, a Database) (we actually insert a record in a
database). This is transactional data that is accessible to multiple clients. We can have more
create01 methods, all throwing Remote'xception, Create'xception.
Each create01 method from the Home interface of the bean has 2 correspondent methods in
the bean implementation class, namely ej%Create01 and ej%7ostCreate01, methods which
have the same parameters, in the same order, as the parameters in the original create01
method.
the return type of the ej%Create01 is the same as the primary key, but the developer returns
null for CMP.
for BMP, ej%Create01 must have insertion SQL code and returns an instance of the primary
key, not null.
10.1(.2 read
ej%Load01, left empty most of the time in CMP, but needs actual SQL code in BMP
the bean's persistence implementation may choose to defer loading until it is used
ej%Load01 may contain processing code
10.1(.% &date
ej%Store01 in CMP; the method can be used for preprocessing data to be stored, but in
general, it is empty.
in BMP, actual SQL update code; the updated data is to be stored immediately
10.1(.( de'ete
the corresponding method in the bean implementation class is ej%Remove01
data is deleted from DB (in the CMP case), for BMPs, the programmer will create actual SQL
code.
10.1* the 'i"e $1$'e !" an entit1 bean
Figure 14.3 shows the stages that an entity bean passes through during its lifetime. After the
EJB container creates the instance, it calls the set'ntitBContext method of the entity bean
class. The set'ntitBContext method passes the entity context to the bean.
After instantiation, the entity bean moves to a pool of available instances. While in the pooled
stage, the instance is not associated with any particular EJB object identity. All instances in the
pool are identical. The EJB container assigns an identity to an instance when moving it to the
ready stage.
There are two paths from the pooled stage to the ready stage. On the first path, the client
205
18 - ENTERPRSE JAVA BEANS
invokes the create method, causing the EJB container to call the ej%Create and
ej%7ostCreate methods. On the second path, the EJB container invokes the ej%(ctivate
method. While an entity bean is in the ready stage, it's business methods can be invoked.
There are also two paths from the ready stage to the pooled stage. First, a client can invoke the
remove method, which causes the EJB container to call the ej%Remove method. Second, the
EJB container can invoke the ej%7assivate method.
Figure 14.3 Life Cycle of an Entity Bean
At the end of the life cycle, the EJB container removes the instance from the pool and invokes
the $nset'ntitBContext method.
n the pooled state, an instance is not associated with any particular EJB object identity. With
bean-managed persistence, when the EJB container moves an instance from the pooled state to
the ready state, it does not automatically set the primary key. Therefore, the ej%Create and
ej%(ctivate methods must assign a value to the primary key. f the primary key is incorrect,
the ej%Load and ej%Store methods cannot synchronize the instance variables with the
database. The ej%(ctivate method sets the primary key (id) as follows:
id K 0String1context.get7rimarBKeB01W
n the pooled state, the values of the instance variables are not needed. You can make these
instance variables eligible for garbage collection by setting them to n$ll in the ej%7assivate
method.
10.1, .essage-dri+en beans
A message-driven bean is an enterprise bean that allows J2EE applications to process
206
18 - ENTERPRSE JAVA BEANS
messages asynchronously. t acts as a JMS message listener, which is similar to an event listener
except that it receives messages instead of events. The messages may 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 currently process only JMS messages, but in the future they may be
used to process other kinds of messages.
10.1,.1 when t! se .essage-dri+en beans
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 in an
asynchronous manner, message-driven bean can be used.
10.1,.2 di""eren$es between .essage-dri+en beans and the !ther e#bAs
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.
n several respects, a message-driven bean resembles a stateless session bean.
a message-driven bean's instances retain no data or conversational state for a specific
client.
all instances of a message-driven bean are equivalent, allowing the EJB container to
assign a message to any message-driven bean instance. The container can pool these
instances to allow streams of messages to be processed concurrently.
a single message-driven bean can process messages from multiple clients.
The instance variables of the message-driven bean instance can contain some state across the
handling of client messages - for example, a JMS AP connection, an open database connection,
or an object reference to an enterprise bean object.
When a message arrives, the container calls the message-driven bean's onMessage method to
process the message. The onMessage method normally casts the message to one of the five
JMS message types and handles it in accordance with the application's business logic. The
onMessage method may call helper methods, or it may invoke a session or entity bean to
process the information in the message or to store it in a database.
A message may be delivered to a message-driven bean within a transaction context, so that all
operations within the onMessage method are part of a single transaction. f message processing
is rolled back, the message will be redelivered.
10.1,.% di""eren$es between .essage-dri+en beans and state'ess sessi!n
E3Bs
Although the dynamic creation and allocation of message-driven bean instances mimics the
behavior of stateless session EJB instances, message-driven beans are different from stateless
session EJBs (and other types of EJBs) in several significant ways:
message-driven beans process multiple JMS messages asynchronously, rather than
processing a serialized sequence of method calls.
message-driven beans have no home or remote interface, and therefore cannot be
directly accessed by internal or external clients. Clients interact with message-driven
beans only indirectly, by sending a message to a JMS Queue or Topic.
207
18 - ENTERPRSE JAVA BEANS
10.1,.( $!n$rrent s&&!rt "!r .essage-dri+en beans
Message-driven Beans support concurrent processing for both topics and queues. Previously,
only concurrent processing for Queues was supported.
To ensure concurrency, change the we%logic&ej%&jar.xml deployment descriptor max&
%eans&in&5ree&pool setting to >1. f this element is set to more than one, the container will
spawn as many threads as specified. For more information on this element see, max-beans-in-
free-pool.
10.1,.* in+!>ing a .essage-dri+en bean
When a JMS Queue or Topic receives a message, use WebLogic Server to call an associated
message-driven bean as follows:
1. Obtain a new bean instance.
Obtain a new bean instance from the connection pool if one already exists, or create a
new one. See Creating and Removing Bean nstances.
2. f the bean cannot be located in the pool and a new one must be created, call the bean's
setMessageDrivenContext() to associate the instance with a container context. The bean
can utilize elements of this context as described in Using the Message-Driven Bean
Context.
3. Call the bean's onMessage() method to perform business logic. See mplementing
Business Logic with onMessage().
N!teE These instances can be pooled.
10.1,., de+e'!&ing .essage-dri+en beans
To create message-driven EJBs, you must follow certain conventions described in the JavaSoft
EJB 2.0 specification, as well as observe several general practices that result in proper bean
behavior.
10.1,.- bean $'ass re@ire.ents
The EJB 2.0 specification provides detailed guidelines for defining the methods in a message-
driven bean class. The following output shows the basic components of a message-driven bean
class. Classes, methods, and method declarations in bold are required as part of the EJB 2.0
specification:
public class MessageTraderBean implements javax.ejb.MessageDrivenBean {
public MessageTraderBean! {...};
// An EJB constructor is required, and it must not
// accept parameters. The constructor must not be declared as
// final or abstract.
public void onMessage(javax.jms.Message MessageName) {...}
// onMessage() is required, and must take a single parameter of
// type javax.jms.Message. The throws clause (if used) must not
// include an application exception. onMessage() must not be
// declared as final or static.
public void ejb"emove! {...}
// ejbRemove() is required and must not accept parameters.
// The throws clause (if used) must not include an application
208
18 - ENTERPRSE JAVA BEANS
//exception. ejbRemove() must not be declared as final or static.
#inali$e%&'
// The EJB class cannot define a finalize() method
}
Creating and Removing Bean nstances
The WebLogic Server container calls the message-driven bean's ej%Create01 and
ej%Remove01 methods when creating or removing an instance of the bean class. As with other
EJB types, the ej%Create01 method in the bean class should prepare any resources that are
required for the bean's operation. The ej%Remove01 method should release those resources, so
that they are freed before WebLogic Server removes the instance.
Message-driven beans should also perform some form of regular clean-up routine outside of the
ej%Remove01 method, because the beans cannot rely on ej%Remove01 being called under all
circumstances (for example, if the EJB throws a runtime exception).
10.1,.0 sing the .essage-dri+en bean $!nteCt
WebLogic Server calls setMessage#rivenContext01 to associate the message-driven bean
instance with a container context.This is not a client context; the client context is not passed along
with the JMS message. WebLogic Server provides the EJB with a container context, whose
properties can be accessed from within the instance by using the following methods from the
Message#rivenContext interface:
getCaller7rincipal01
isCallerInRole01
setRoll%ac2+nlB01& The EJB can use this method only if it utilizes container-
managed transaction demarcation.
getRoll%ac2+nlB01 & The EJB can use this method only if it utilizes container-
managed transaction demarcation.
getser!ransaction01& The EJB can use this method only if it utilizes bean-
managed transaction demarcation.
N!teE Although get'ZC6ome01 is also inherited as part of the Message#rivenContext
interface, message-driven EJBs do not have a home interface. Calling get'ZC6ome01
from within a message-driven EJB instance yields an IllegalState'xception.
10.1,.4 i.&'e.enting bsiness '!gi$ with !n2essage:;
The message-driven bean's onMessage01 method performs all of the business logic for the
EJB. WebLogic Server calls onMessage01 when the EJB's associated JMS Queue or Topic
receives a message, passing the full JMS message object as an argument. t is the message-
driven EJB's responsibility to parse the message and perform the necessary business logic in
onMessage01.
Make sure that the business logic accounts for asynchronous message processing. For
example, it cannot be assumed that the EJB receives messages in the order they were sent by
the client. nstance pooling within the container means that messages are not received or
processed in a sequential order, although individual onMessage01 calls to a given message-
driven bean instance are serialized.
See javax.jms.MessageListener.onMessage() for more information.
209
18 - ENTERPRSE JAVA BEANS
10.1,.15 hand'ing eC$e&ti!ns
Message-driven bean methods should not throw an application exception or a
Remote'xception, even in onMessage01. f any method throws such an exception, WebLogic
Server immediately removes the EJB instance without calling ej%Remove01. However, from the
client perspective the EJB still exists, because future messages are forwarded to a new instance
that WebLogic Server creates.
10.1,.11 transa$ti!n ser+i$es "!r .essage-dri+en beans
As with other EJB types, message-driven beans can demarcate transaction boundaries either
on their own (using bean-managed transactions), or by having the WebLogic Server container
manage transactions (container-managed transactions). n either case, a message-driven bean
does not receive a transaction context from the client that sends a message. WebLogic Server
always calls a bean's onMessage01 method by using the transaction context specified in the
bean's deployment descriptor, as required by the EJB 2.0 specification.
Because no client provides a transaction context for calls to a message-driven bean, beans that
use container-managed transactions must be deployed using the ReM$ired or )otS$pported
transaction attribute in ej%&jar.xml. Transaction attributes are defined in ej%&jar.xml as
follows:
<assembly-descriptor>
<container-transaction>
<method>
<ejb-name>MyMessageDrivenBeanQueueTx</ejb-name>
<method-name>*</method-name>
</method>
<trans-attribute>NotSupported</trans-attribute>
</container-transaction>
</assembly-descriptor>
10.1,.12 .essage re$ei&ts
The receipt of a JMS message that triggers a call to an EJB's onMessage01 method is not
generally included in the scope of a transaction. For EJBs that use bean-managed transactions,
the message receipt is always outside the scope of the bean's transaction, as described in the
EJB 2.0 specification.
For EJBs that use container-managed transaction demarcation, WebLogic Server includes the
message receipt as part of the bean's transaction only if the bean's transaction attribute is set to
ReM$ired.
10.1,.1% .essage a$>n!w'edg.ent
For message-driven beans that use container-managed transaction demarcation, WebLogic
Server automatically acknowledges a message when the EJB transaction commits. f the EJB
uses bean-managed transactions, both the receipt and the acknowledgment of a message occur
outside of the EJB transaction context. WebLogic Server automatically acknowledges messages
for EJBs with bean-managed transactions, but the deployer can configure acknowledgment
semantics using the jms-acknowledge-mode deployment parameter.
Deploying Message-Driven Beans in WebLogic Server
To deploy a message-driven bean on WebLogic Server, you edit the XML file to create the
deployment descriptors that associate the EJB with a configured JMS destination.
210
18 - ENTERPRSE JAVA BEANS
Deployment Descriptors
The deployment descriptor for a message-driven bean also specifies:
Whether the EJB is associated with a JMS Topic or Queue
Whether an associated Topic is durable or non-durable
Transaction attributes for the EJB
JMS acknowledgment semantics to use for beans that demarcate their own transactions
10.1,.1( de&'!1.ent e'e.ents
The EJB 2.0 specification adds the following new XML deployment elements for deploying
message-driven beans.
message&driven&destination specifies whether the EJB should be associated
with a JMS Queue or Topic destination.
s$%scription&d$ra%ilitB specifies whether or not an associated Topic
should be durable.
jms&ac2nowledge&mode specifies the JMS acknowledgment semantics to use
for beans that demarcate their own transaction boundaries. This element has
two possible values: (!+,(CK)+/L'#-' (the default ) or
#7S,+K,(CK)+/L'#-'.
These elements are defined in the ej%&jar.xml deployment file, as described in the EJB 2.0
specification. The following excerpt shows a sample XML stanza for defining a message-driven
bean:
<enterprise-beans>
<message-driven>
<ejb-name>exampleMessageDriven1</ejb-name>
<ejb-class>examples.ejb20.message.MessageTraderBean</ejb-class>
<transaction-type>Container</transaction-type>
<message-driven-destination>
<jms-destination-type>
javax.jms.Topic
</jms-destination-type>
</message-driven-destination>
...
</message-driven>
...
</enterprise-beans>
n addition to the new ej%&jar.xml elements, the we%logic&ej%&jar.xml file includes a
new message-driven-descriptor stanza to associate the message-driven bean with an actual
destination in WebLogic Server.
10.1- the 'i"e $1$'e !" a .essage-dri+en bean
Figure 13.4 illustrates the stages in the life cycle of a message-driven bean.
211
18 - ENTERPRSE JAVA BEANS
The EJB container usually creates a pool of message-driven bean instances. For each instance,
the EJB container instantiates the bean and performs these tasks:
1. t calls the setMessage#rivenContext method to pass the context object to the
instance.
2. t calls the instance's ej%Create method.
Figure 13.4 Life Cycle of a Message-Driven Bean
Like a stateless session bean, a message-driven bean is never passivated, and it has only two
states: nonexistent and ready to receive messages.
At the end of the life cycle, the container calls the ej%Remove method. The bean's instance is
then ready for garbage collection.
10.10 the de&'!1.ent des$ri&t!r
The deployment descriptor of an EJB contains information about the bean in relation to the
application it belongs to.
This information can be divided into two main categories:
structural information related to a particular EJB.
application assembly information
Although not an exhaustive one, here is a typical list of entries (elements) in a deployment
descriptor:
1. access control entries - security issues; which users can access a bean or a particular
method of a bean
2. bean home name - name under which the bean is registered under JND
3. control descriptors - specifies control attributes for transactions
4. EJB class name
5. environment properties
212
18 - ENTERPRSE JAVA BEANS
6. the home interface name
7. the remote interface name
8. session specific elements
9. entity specific elements
10. attributes - like transaction, isolation level, security
Keeping in mind that the application assembler is to follow, here is how the deployment
descriptor may look like:
;Oxnm versionK=8.8=O4
;ej%&jar4
;entrprise&%eans4
;session4
;ej%&name4CC'nroll;/ej%&name4
;home4com.%an288.ccards.ej%.CC'nroll6ome;/home4
;remote4com.%an288.ccards.CC'nroll+%ject;/remote4
;ej%&class4com.%an288.ccards.CC'nroll;/ej%&class4
;session&tBpe4Stateless;/session&tBpe4
;transaction&tBpe4Container;transaction&tBpe4
;ej%&re54
;ej%&re5&name4ej%/CC(cco$nt;/ej%&re5&name4
;ej%&re5&tBpe4'ntitB;/ej%&re5&tBpe4
;home4com.%an288.ccards.ej%.(cco$nt6ome;/home4
;remote4com.%an288.ccards.ej%.(cco$nt+%j;/remote4
;/ej%&re54
;sec$ritB&role&re54
;description4
!his role relates to cash advances 5rom (!Ms
;/description4
;role&name4Cash(dv(!M;/role&name4
;sec$ritB&role&re54
;/session4
;entitB4
;ej%&name4(cco$nt;/ej%&name4
;home4com.%an288.ccards.ej%.(cco$nt6ome;/home4
;remote4com.%an288.ccards.(cco$nt%ject;/remote4
213
18 - ENTERPRSE JAVA BEANS
;ej%&class4com.%an288.ccards.(cco$nt;/ej%&class4
;persistence&tBpe4Container;/persistence&tBpe4
;prim&2eB&class4java.lang.Integer;/prim&2eB&class4
;reentrant4*alse;/reentrant4
;cmp&5ield4
;5ield&name4acco$nt)$m%er;/5ield&name4
;/cmp&5ield4
;cmp&5ield4
;5ield&name4$ser)ame;/5ield&name4
;/cmp&5ield4
;cmp&5ield4
;5ield&name4c$stomerI#;/5ield&name4
;/cmp&5ield4
;cmp&5ield4
;prim&2eB&5ield4acco$nt)$m%er;/prim&2eB&5ield4
;/cmp&5ield4
;env&entrB4
;env&entrB&name4env/min7aBment7erc;/env&entrB&name4
;env&entrB&tBpe4java.lang.*loat;/env&entrB&tBpe4
;env&entrB&val$e4D.E;/env&entrB&val$e4
;/env&entrB4
;/entitB4
;/enterprise&%eans4
;/ej%&jar4
The assembly descriptor combines EJBs into a deployable application. Here is a very lean one:
;/ej%&jar4
;enterprise&%eans4
...
;/enterprise&%eans4
<assembly-descriptor>
;container&transaction4
;method4
;ej%&name4CC'nroll;/ej%&name4
;method&name4X;/method&name4
214
18 - ENTERPRSE JAVA BEANS
;/method4
;trans&attri%$te4ReM$ired;/trans&attri%$te4
;/container&transaction4
;/assem%lB&descriptor4
;/ej%&jar4
215