Introducing JavaServer Facesby Budi Kurniawan
JavaServer Faces (JSF) has been dubbed the next big thing in Java web programming. With JSF, you use web components on your web pages and capture events caused by user actions. In the near future, Java tools will support this technology. Developing web applications will be similar to the way we write Swing applications today: dragging and dropping controls and writing event listeners. This article is an introduction to JSF. It highlights the most important aspect of JSF: JSF applications are event-driven. Also, it offers a sample JSF application that illustrates the event-driven-ness of JSF. To understand this article, you need to be familiar with servlets, JSP, JavaBeans, and custom tag libraries.
First of all, a JSF application is a servlet/JSP application. It has a deployment descriptor, JSP pages, custom tag libraries, static resources, et cetera. What makes it different is that a JSF application is event-driven. You decide how your application behaves by writing an event listener class. Here are the steps you need to take to build a JSF application:
- Author JSP pages, using JSF components that encapsulate HTML elements.
- Write a JavaBean as the state holder of user-input and component data.
- Write an event listener that determines what should happen when an event
occurs, such as when the user clicks a button or submits a form. JSF supports
ActionEventis fired when the user submits a form or clicks a button, and
ValueChangedEventis triggered when a value in a JSF component changes.
Now, let's take a look at how JSF works in detail.
How JSF Works
JSP pages are the user interface of a JSF application. Each page contains JSF components that represent web controls, such as forms, input boxes, and buttons. Components can be nested inside of another component; an input box can reside inside a form. Each JSP page is represented by its component tree. JavaBeans store the data from user requests.
Here is the interesting part: every time the user does something, such as
clicking a button or submitting a form, an event occurs. Event notification is
then sent via HTTP to the server. On the server is a web container that employs
a special servlet called the Faces servlet. The Faces servlet, represented by
javax.faces.webapp.FacesServlet class, is the engine of all
JSF applications. Each JSF application in the same web container has its own
Faces servlet. Another important object is
javax.faces.context.FacesContext, which encapsulates all necessary
information related to the current request.
In the background, the processing performed by the Faces servlet is
complex. However, you don't need to know all the details. Just bear in mind
that the Faces servlet builds a component tree of the JSP page whose control
fires an event. The Faces servlet knows how to build the tree because it has
access to all JSP pages in the application. The Faces servlet also creates an
Event object and passes it to any registered listener. You can
obtain the component tree of a JSP page from the
object associated with the request.
An event fired by a web control on the client browser is encapsulated in an
HTTP request, alongside other information such as
the browser type, the request URL, etc. Therefore, all requests that need Faces servlet processing must be directed to this servlet. How do you invoke
the Faces servlet with every HTTP request? Easy. Just use a
element in your deployment descriptor to map a particular URL pattern with the
Faces servlet. By convention, you use the
/faces/* pattern, such
as the following.
<!-- Faces Servlet --> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <!-- Faces Servlet Mapping --> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>/faces/*</url-pattern> </servlet-mapping>
The request URL must contain the pattern in the
<url-pattern> element. This is not hard to achieve. Note also that
<servlet> element, which contains the Faces servlet, has a
<load-on-startup> element, to make sure the servlet is loaded
when the application is first started.
To capture the event fired by a component, you must write an event listener
for that component and register it with the component. Do this by enclosing the
<action_listener> element in the custom tag representing the
component. For example, to allow a listener named
jsfApp.MyActionListener to capture the action event fired by a
command button called
submitButton, write the following code in
your JSP page:
<h:command_button id="submitButton" label="Add" commandName="submit" > <f:action_listener type="jsfApp.MyActionListener" /> </h:command_button>
An action listener must implement the
javax.faces.event.ActionListener interface and a value-changed
listener must implement
Let's build a simple JSF application that illustrates how event-driven
A Simple JSF Application
Download the source code for the example application.
We'll build a simple JSF application that can add two numbers. To run this application, you need Tomcat 5 and JSF v1.0 EA4 (included in the Java Web Services Developer Pack (JWSDP) 1.2. The application consists of:
- adder.jsp, a JSP page
NumberBean, a JavaBean for storing user data
MyActionListener, an action listener
- web.xml, a deployment descriptor
For your JSF application to work, it needs a set of .jar files containing the JSF reference implementation and other libraries. Once you install the JWSDP 1.2, you can find these files under its jsf/lib directory. Copy these .jar files to the WEB-INF/lib directory. Here is the list of all .jar and .tld files.
- jsf-api.jar contains the Faces servlet and related classes in
- jfs-ri.jar is the reference implementation of JSF.
- jstl_el.jar handles JSTL expression language syntax.
- standard.jar is required to use JSTL tags and is referenced by JFS reference implementation classes.
In addition, a JSF application will need the following libraries, which are part of the Apache Jakarta project. These libraries are included in the application accompanying this article.
- commons-beanutils.jar contain utilities for defining and accessing JavaBeans component properties.
- commons-digester.jar is the library containing the Apache Common Digester classes.
- commons-logging.jar is a general-purpose, flexible logging facility.
The following subsections discuss each part of the sample JSF application. The final subsection, "Compiling and Running the Application," explains how the JSF application works.
Creating the Directory Structure
Start by creating a directory structure for your JSF application. In
Tomcat, this goes under webapps. Figure 1 depicts the directory
structure for an application called
Figure 1. The directory structure of the JSF application
Writing the Deployment Descriptor
Just like any other servlet/JSP application, this application needs a deployment descriptor, as shown in Listing 1.
Listing 1. The deployment descriptor (the web.xml file)
<?xml version="1.0"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <!-- Faces Servlet --> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup> 1 </load-on-startup> </servlet> <!-- Faces Servlet Mapping --> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>/faces/*</url-pattern> </servlet-mapping> </web-app>
There are two sections in the deployment descriptor. The
<servlet> element registers the Faces servlet, and the
<servlet-mapping> element states that any request containing
/faces/ in the URL must be passed to the Faces
Pages: 1, 2