ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.


AddThis Social Bookmark Button

Introducing JavaServer Faces

by 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:

  1. Author JSP pages, using JSF components that encapsulate HTML elements.
  2. Write a JavaBean as the state holder of user-input and component data.
  3. 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 two events: ActionEvent and ValueChangedEvent. ActionEvent is fired when the user submits a form or clicks a button, and ValueChangedEvent is triggered when a value in a JSF component changes.

Related Reading

Mac OS X for Java Geeks
By Will Iverson

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 the 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 FacesContext 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 servlet-mapping 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-name>Faces Servlet</servlet-name>

<!-- Faces Servlet Mapping -->
    <servlet-name>Faces Servlet</servlet-name>

The request URL must contain the pattern in the <url-pattern> element. This is not hard to achieve. Note also that the <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" />

An action listener must implement the javax.faces.event.ActionListener interface and a value-changed listener must implement javax.faces.event.ValueChangedListener. Let's build a simple JSF application that illustrates how event-driven JSF is.

A Simple JSF Application

Source Code

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 the javax.faces package.
  • 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 myJSFApp.

directory structure of the JSF application
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"?>
    "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"

    <!-- Faces Servlet -->
        <servlet-name>Faces Servlet</servlet-name>
        <load-on-startup> 1 </load-on-startup>

    <!-- Faces Servlet Mapping -->
        <servlet-name>Faces Servlet</servlet-name>

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 the pattern /faces/ in the URL must be passed to the Faces servlet.

Pages: 1, 2

Next Pagearrow