JavaServer Faces (JSF) is a standardized specification for building User Interfaces (UI) for server-side applications. Before JavaServer Faces, developers who built web applications often relied on building HTML user interface components with servlets or JavaServer Pages (JSP pages). This is mainly because HTML user interface components are the lowest common denominator that web browsers support. The implication, of course, is that such web applications do not have rich user interfaces, compared with standalone fat clients, and therefore less functionality and/or poor usability. While applets can be used to develop rich user interfaces, web application developers don't always know what clients will be accessing the application and/or they may have no access to the client device.
In addition, if you have taken part in developing a large-scale web system, you may have come across technical challenges, such as how to implement custom components like a query builder or a table viewer for building database queries. Building such custom components requires expertise and a significant amount of time to build and test the new libraries. In an ideal environment, developers would be able to use pre-built, tested, and highly configurable components to integrate into their application development environment.
JavaServer Faces (JSF) is a server-side technology for developing web applications with rich user interfaces. With JSF, you can resolve such technical challenges as creating custom user interface components. This is because JSF technology is a user interface framework for building Java-based web applications that run on the server side, and render the user interface back to the client. That's right! The user interface code runs on the server, responding to events generated on the client.
Rich user interfaces consist of a set of rich components. There are a number of options out there today for building rich server-side user interfaces, such as Flash, Swinglets, and Jade. However, these solutions are proprietary; the tools and runtimes that support their development are usually only available through a single vendor. JSF is, above all, a standard, which means that the developer does not get locked into a single vendor. The specification expert group is actually made up of representatives from all the major tool vendors in the Java community. Thus, developers will have no shortage of choices for tools, and probably will be able to use an updated version of a tool they are using today. While the tool vendors are cooperating on the specification, they will compete with each other in their implementations. This will benefit the developer community in terms of features and in the choice of custom components each vendor makes available. Tool Vendors provide an Integrated Development Environment (IDE) to help you build and deploy your JSF applications. The following vendors offer tools to support JSF development.
Component Vendors provide reusable building blocks for application development and integration into JSF-based tools. Components cover a wide range of uses including reporting, charts and graphs, fields, and navigational components. Here are some of the vendors who offer components that support the JavaServer Faces specification.
JavaServer Faces technology is based on the Model View Controller (MVC) architecture for separating logic from presentation, so if you have been practicing this, you'll feel at home with JSF.
This article provides a fast-track, code-intensive tutorial to get you started with JSF. The article also:
- Provides an introduction to JSF
- Describes the benefits of JSF
- Describes the internals of JSF
- Describes the genesis of JSF applications
- Gives you a taste of the effort involved in developing JSF applications
- Provides sample code that you can adapt for your own applications
- Discuss the JSF support in the Sun Java Studio Creator IDE
If you are looking for more advanced topics, please see Chapters 17 - 21 of the J2EE 1.4 Tutorial.
JavaServer Faces (JSF) is a technology that is being led by Sun Microsystems as JSR 127 under the Java Community Process (JCP). The objective is to create a standard framework for user interface components for web applications. As mentioned earlier, JSF lets you build web applications that run on a Java server and render the user interface back to the client. This technology provides web application lifecycle management through a controller servlet, and a rich component model with event handling and component rendering.
To get started using JavaServer Faces, the first thing you should do is download a JavaServer Faces compatible implementation. All of the tool vendors listed above provide a JavaServer Faces compatible development and runtime environment. You can get a FREE JavaServer Faces Compatible runtime environment by downloading the J2EE 1.4 SDK, which includes support for JavaServer Faces. you can also get a copy of Java Studio Creator from Sun as part of your subscription to the Sun Developer Network.
Note that as a minimum requirement, JSF runs on Servlet 2.3 and JSP 1.2. Figure 1 depicts the high-level architecture of JSF.
|
The JSF technology consists of two main components:
- Java APIs to represent UI components, manage state, handle events, and validate input. The API has support for internationalization and accessibility.
- Two JSP custom tag libraries for expressing user interface (UI) components within a JSP page, and for wiring components to server-side objects. Page authors can easily add UI components to their pages.
Figure 2 shows the relationship between the client, the server, and JSF.
|
Here, the JSP page represents the user interface components using the JSF custom tag library, rather than hard coding them with a markup language. The UI for the application manages the objects rendered by the JSP page.
Several types of users can benefit from this technology, including:
- Page authors who use markup languages, such as HTML, will use the JSP tag library for expressing JavaServer Faces rich user interface components.
- Application developers who write the model objects and event handlers.
- Component developers who will create custom components based on the JSF components.
- Tools vendors who will provide tools that incorporate JSF technology into a new generation of tools that simplify the development of multi tier, web-based applications.
- Application Server vendors who provide a runtime environment that incorporates JSF technology into a new generation of Application Servers that can deploy multi tier, web-based applications that use JSF technology.
This technology also opens up the market for reusable web user interface components. Developers and vendors can use JSF as the building blocks for developing custom faces.
One of the advantages of JSF is that it is based on the Model View Controller (MVC) architecture, to offer a clean separation between presentation and logic. This may ring a bell for those who are using existing web frameworks such as Struts. However, note that JSF and Struts are not competing technologies, and in fact, they interoperate together. JSF, however, does have some advantages over Struts. For example, in Struts there is only one way to render an element, while JSF provides several mechanisms for rendering an individual element. It is up to the page designer to pick the desired representation, and the application developer doesn't need to know which mechanism was used to render a component. (Here's a link for more information on the integration of JSF and Struts.) Readers may notice that the author of Struts, Craig McClanahan, is also the co-specification lead for JSF, as well as an employee of Sun Microsystems.
A JSF application is just like any other Java technology-based web application; it runs in a Java servlet container, and contains:
- JavaBeans components (or model objects) containing application-specific functionality and data
- Event listeners
- JSP pages
- Server-side helper classes
- A custom tag library for rendering UI components
- A custom tag library for representing event handlers and validators
- UI components represented as stateful objects on the server
- Validators, event handlers, and navigation handlers. (Validators are used to validate data on individual components before the server-side data is updated.)
- Application configuration resource file for configuring application resources
Here is a simple example using the tag libraries. For a list of component tags support and other information on JSF, please refer to the JavaServer Faces specification and Chapter 17 - 21 of the J2EE 1.4 Tutorial.
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> |
The JSF component architecture is designed in such a way that the component classes maintain a component's state. A renderkit defines how component classes map to component tags appropriate for a particular client. The JSF reference implementation, which is discussed later, includes a standard RenderKit for rendering to an HTML client. Each JSP component in the HTML RenderKit is composed of the component functionality defined by the UIComponent
class, and the rendering attributes defined by the Renderer
. For example, the tags commandButton
and commandHyperlink
both represent a UIComponent
, but they are rendered in two different ways. The button component is rendered as a button and the hyperlink is rendered as a hyperlink.
When a JSP page is created using JSF components, a component tree or a view
is built into memory on the server with each component tag corresponding to a UIComponent
instance in the tree. The component tree is used by the JSF framework to handle your application request and create a rendered response. When an event is generated (for example, user clicks on a button), the JSF lifecycle handles the event and generates an appropriate response. Note that the entry point into the JSF framework is the FacesServlet
. It acts as the front controller and handles request processing lifecycle.
The JSF reference implementation 1.1 comes with the following:
html_basic.tld
: A JSP custom tag library for building JSF applications that render to an HTML clientjsf_core.tld
: A JSP custom tag library for representing core actions independent of a particular render kit- APIs that provide user interface components, model object management, pluggable rendering, server-side validation, data conversion, event processing, page flow management, and custom extensibility for all of these features
- A set of demos located in the
samples
directory of the installation
The JSF Reference Implementation 1.1 can be downloaded here. When you unzip the archive, you'll get a directory structure like this (under Windows):
c:\jsf-1_1> |
The example
directory contains WAR and source files for sample applications. The lib
directory contains the JAR files that JSF depends on. The JAR files are:
commons-beanutils.jar
: Utilities for defining and accessing JavaBeans component propertiescommons-collections.jar
: Extensions of the J2SE Collections Frameworkcommons-digester.jar
: For processing XML documentscommons-logging.jar
: A general purpose, flexible logging facility to allow developers to instrument their code with logging statementsjsf-api.jar
: Contains thejavax.faces.*
API classesjsf-impl.jar
: Contains the implementation classes of the JSF Reference Implementation
Note that the JSF framework uses the JavaServer Pages Standard Tag Library (JSTL), and therefore it is assumed that the web container you use provides the necessary JAR files for JSTL.
The JSF RI can be easily set up to be used with virtually any web container. The RI comes with installations instructions on how to use it with Apache Tomcat, Java WSDP 1.3, and Sun Java System Application Server Platform Edition 8. The installation process is usually a matter of copying some JAR files, such as jsf-api.jar
and jsf-impl.jar
from the lib
directory of the JSF RI to your web container's lib
directory. For this article, however, the Sun Java Application Server Platform Edition 8 that comes with the Sun Java Studio Creator was used. The Sun Java Application Server Edition 8 can be downloaded from here and this already includes support for JSF.
If you are using the Sun Java Application Server Edition 8, you can easily get started by deploying the sample applications that come with the JSF RI by following these two simple steps:
- Start the application server
- Deploy the
.war
files from thesamples
directory of your JSF RI onto the application server. This can be done using thedeploytool
or by runningasant deploy
, but the easiest way is to copy the.war
files to theautodeploy
directory (on my machine, this directory isC:\Sun-Studio-Creator\SunAppServer8\domains\creator\autodeploy
.
Now, you can start your favorite web browser and enter a URL to run a sample JSF application: http://localhost:18080/
jsf-guessNumber
or any other sample application that starts with jsf-
. Here is a sample output:
|
This section describes a sample application, a guessing number game, that comes with the JSF RI. The application, as shown in Figure 3 above, asks you to guess a number between 0 and 10, inclusive. If you enter the wrong number, you'll see something similar to Figure 4, and when you finally enter the right number, you'll see something similar to Figure 5. This application will give you a taste of the effort involved in developing web applications using the JSF technology.
|
|
A JSF application consists of the following files:
- JSP pages with JSF components representing the UI
- JavaBeans to hold the model data
- Application configuration files specifying the JSF controller servlet, managed beans, and navigation handles
In the guess number sample application, three JSP pages are used: index.jsp
, greeting.jsp
, and response.jsp
. Let's start with the index.jsp
page.
The index.jsp page: This page is shown in Code Sample 1.
Code Sample 1: index.jsp
<html> |
As you can see, this page simply forwards the user to the main page, greeting.jsp
, and therefore in your application you can do without it.
The greeting.jsp page: This is the main page presented to the user, which is shown in Figure 3 above. Code Sample 2 shows the content of this page.
Code Sample 2: greeting.jsp
<html> |
The greeting.jsp
page demonstrates several features that you will use in most of your JSF applications. These are:
- In order to use JSF tags, you need to include the
taglib
directives to thehtml
andcore
tag libraries that refer to the standard HTML renderkit tag library, and the JSF core tag library, respectively. - A page containing JSF tags is represented by a tree of components whose root is the
UIViewRoot
, which is represented by theview
tag. All component tags must be enclosed in theview
tag. Other content such as HTML and other JSP pages can be enclosed within that tag. - A typical JSP page includes a form, which is submitted when a button is clicked. The tags representing the form components (such as textfields and buttons) must be nested inside the
form
tag. - The
outputText
tag represents a label. Thegreeting.jsp
page has two such tags that display the numbers 0 and 10. Thevalue
attribute of the tag gets the values from theminimum
andmaximum
properties of a bean class,UserNumberBean
, using value-binding expressions that have the syntax#{bean-managed-property}
- The
graphicImage
tag is used to reference an image. - The
inputText
tag represents an input text field component. Theid
attribute represents the ID of the component object represented by this tag, and if it is missing, then the implementation will generate one. Thevalidator
attribute refers to a method-binding expression pointing to a backing bean method that performs validation on the component's data. - The
commandButton
tag represents the button used to submit the data entered in the text field. Theaction
attribute helps the navigation mechanism to decide which page to open next. - The
message
tag displays an error message if the data entered is not valid. Thefor
attribute refers to the component whose value failed validation.
The response.jsp page: This page, which is similar to Figure 4 and 4 above, is displayed as a response to the user's clicking the Submit
button. Code Sample 3 shows the content of this page whose tags have already been explained.
Code Sample 3: response.jsp
<html> |
A typical JSF application uses a bean with each page in the application. The bean defines the properties and methods associated with the UI components used on the page. A bean can also define a set of methods that perform functions, such as validating the component's data, for the component. The model object bean is like any other JavaBeans component: it has a set of accessor methods. Code Sample 4 shows a sample JavaBean component, which is referenced in the greeting.jsp
and response.jsp
pages.
Code Sample 4: UserNumberBean.java
package guessNumber; |
An application configuration resource file, faces-config.xml
, is used to define your managed beans, validators, converters, and navigation rules. Code Sample 5 shows the faces-config.xml
file for the guess number application that defines navigation rules and the mapping of managed beans.
Code Sample 5: faces-config.xml
<?xml version='1.0' encoding='UTF-8'?> |
The task of defining navigation rules involves defining which page is to be displayed after the user clicks on a button or a hyperlink. Each <navigation-rule>
element defines how to get from one page as defined by the <form-view-id>
to the other pages of the application. A <navigation-rule>
element can contain any number of <navigation-case>
elements that define the page to open next using the <to-view-id>
based on a logical outcome defined by the <from-outcome>
. This outcome is defined by the action
attribute of the component that submits the form (such as the commandButton
in Code Samples 2 and 3).
In addition, the beans need to be configured in the faces-config.xml
file so that the implementation can automatically create new instances of the beans as needed. The <managed-bean>
element is used to create a mapping between a bean name and class. The first time the UserNumberBean
is referenced, the object is created and stored in the appropriate scope.
Finally, in order to use the JSF framework in your web applications, you need to define the FaceServlet
and its mapping in your deployment descript file, web.xml
. This servlet acts as the front controller and handles all JSF-related requests. Code Sample 6 shows the web.xml
file for the guess number application. An important thing to note is the javax.faces.STATE_SAVING_METHOD
paramter, which is used to specify where the state should be saved (the client in this case). If you want to save the state on the server (this is the default in the JavaServer Faces reference implementation), then specify server
instead of client
in the param-value
. Note that if the state is saved on the client, the state of the entire view is rendered to a hidden field on the page.
Code Sample 6: web.xml
<?xml version='1.0' encoding='UTF-8'?> |
The easiest way to start creating your own JSF applications is by adapting some of the file from the guess number application. Here is how to get started:
- Create the following directory (for example,
MyApp
) and its structure under thesamples
directory of your JSF RI:c:\jsf-1_1\samples\MyApp
\src
YourBeans.java
\web
YourJSP-pages.jsp
AnyImages.gif
\WEB-INF
web.xml
faces-config.xml
- Create the JSP pages and the model objects (beans).
- Modify the
web.xml
andfaces-config.xml
as needed for your application. - Copy the file
build.properties.sample
tobuild.properties
. This file is located in thesamples
directory, then set thetomcat.home
property to the location of the application server installation. And finally, set the other self-explanatory properties as described in the file. - To build and package your application, create a
build.xml
file such as the one in Code Sample 7, and place it in your directory (for example,MyApp
).Code Sample 7: build.xml
<project name="MyFirst" default="build.war" basedir=".">
<property file="../build.properties"/>
<!-- Configure the context path for this application -->
<property name="context.path" value="/jsf-MyFirst"/>
<property name="example" value="jsf-MyFirst" />
<property name="build" value="${basedir}/build" />
<path id="classpath">
<pathelement location="${commons-beanutils.jar}"/>
<pathelement location="${commons-collections.jar}"/>
<pathelement location="${commons-digester.jar}"/>
<pathelement location="${commons-logging.jar}"/>
<pathelement location="${jsf-api.jar}"/>
<pathelement location="${jsf-impl.jar}"/>
<pathelement location="${jstl.jar}"/>
<pathelement location="${build}/${example}/WEB-INF/classes"/>
<pathelement location="${servlet.jar}"/>
</path>
<target name="clean" >
<delete dir="${build}" />
<delete dir="${context.path}" />
</target>
<target name="prepare" description="Create build directories.">
<mkdir dir="${build}/${example}" />
<mkdir dir="${build}/${example}/WEB-INF" />
<mkdir dir="${build}/${example}/WEB-INF/classes" />
<mkdir dir="${build}/${example}/WEB-INF/lib" />
</target>
<!-- Executable Targets -->
<target name="build" depends="prepare,deploy.copyJars"
description="Compile Java files and copy static files." >
<javac srcdir="src" destdir="${build}/${example}/WEB-INF/classes">
<include name="**/*.java" />
<classpath refid="classpath"/>
</javac>
<copy todir="${build}/${example}/WEB-INF">
<fileset dir="web/WEB-INF">
<include name="*.xml" />
</fileset>
</copy>
<copy todir="${build}/${example}/">
<fileset dir="web">
<include name="*.html" />
<include name="*.gif" />
<include name="*.jpg" />
<include name="*.jsp" />
<include name="*.xml" />
</fileset>
</copy>
<copy todir="${build}/${example}/WEB-INF/classes/${example}" >
<fileset dir="web" >
<include name="*properties"/>
</fileset>
</copy>
</target>
<target name="deploy.copyJars" if="build.standalone">
<copy todir="${build}/${example}/WEB-INF/lib" file="${commons-beanutils.jar}" />
<copy todir="${build}/${example}/WEB-INF/lib" file="${commons-collections.jar}" />
<copy todir="${build}/${example}/WEB-INF/lib" file="${commons-logging.jar}" />
<copy todir="${build}/${example}/WEB-INF/lib" file="${commons-digester.jar}" />
<copy todir="${build}/${example}/WEB-INF/lib" file="${jsf-api.jar}" />
<copy todir="${build}/${example}/WEB-INF/lib" file="${jsf-impl.jar}" />
<copy todir="${build}/${example}/WEB-INF/lib" file="${jstl.jar}" />
<copy todir="${build}/${example}/WEB-INF/lib" file="${standard.jar}" />
</target>
<target name="build.war" depends="build">
<!-- create a war file for distribution -->
<jar jarfile="${example}.war" basedir="${build}/${example}"/>
<copy todir=".." file="${example}.war" />
<delete file="${example}.war" />
</target>
</project> - Modify the
build.xml
shown in Code Sample 6 to suit your needs. - Go to the
MyApp
directory and run the commandasant
. Your application will be built and a.war
(for example,jsf-MyFirst.war
) file will be created in thesamples
directory. - To deploy the application, ensure that the application server is running, copy the
.war
file to theautodeploy
directory of your Sun Java Application Server 8 (such asC:\Sun-Studio-Creator\SunAppServer8\domains\creator\autodeploy
). - Now, your can test your application using the URL:
httpL://localhost:18080/jsf-MyFirst
.
The Sun Java Studio Creator is an Integrated Development Environment (IDE) for developing state-of-the-art web applications. Based on JSF technology, this IDE simplifies writing Java code by providing well-defined event handlers for incorporating business logic, without requiring developers to manage details of transactions, persistence, and other complexities. In addition, it supports the web applications architecture as defined in the J2EE BluePrints.
Web applications in the Java Studio Creator development environment are supported by a set of JavaBeans components, called managed beans, which provide the logic for initializing and controlling JSF components and for managing data across page requests (a single round trip between the client and server), user sessions, or the application as a whole. When you add your own code to components and to the application, you will be adding Java code to these beans. Figure 6 shows the JSF Palette in the Java Studio Creator.
|
As you can see, JSF Components are organized into categories:
- Added Components: JSF components you have written or acquired elsewhere and imported into the Java Studio Creator development environment
- JSF Standard Components: The basic set of components including form fields, hyperlinks, labels and text. The JSF components are organized into logical groups by function.
- JSF Validators/Converters: Components that modify or validate data in other components but are not themselves displayed
- Advanced: JSP tags for advanced JSF features. These tags generally do not have a visual appearance and are only useful if you are familiar with both the JSP and JSF technologies.
JavaServer Faces (JSF) is a user interface framework for building web applications that run on the server side and render the user interface back to the client. It lets you develop tools that simplify coding web-based Java applications. Sun and other members of the JSF expert group -- which includes Borland, IBM, Macromedia, and Oracle, along with many other companies and individuals -- are evaluating ways to incorporate JSF technology into a new generation of tools that simplify the development of multi tier web-based applications. One of these tools is Sun's Java Studio Creator.
Users of your JSF-based web applications will appreciate the wide range of user actions made available by JSF controls. You can offer more features, more conveniently than you can with a standard HTML front end. And remember, JSF requires little more effort than an ordinary JSP configuration -- but with many more benefits.