Introduction to Java Server Faces

Java Server Faces (JSF) is a third-generation technology for constructing web application interfaces for Java web applications. In these lecture notes I will be introducing you to the latest version of JSF, JSF 2.0. This latest iteration of JSF includes a large number of features that make JSF easier to use, thus making it an attractive technology for use in this course.

The architecture of a JSF application

JSF applications consist to two major elements, JSF pages and Java beans. The pages are the interface of a JSF application. Pages are constructed using a system of tags in much the same way that HTML uses tags to construct web pages. Although JSF tags are similar to HTML tags, JSF has its own unique syntax. These lecture notes will introduce you to the most commonly used JSF tags and teach you the syntax rules governing their use.

The programming logic and most of the functionality in the JSF application resides in a collection of Java Beans. These beans are objects designed to live in the context of a web application server. A system of annotations is used to help integrate the bean classes with the special environment of the application server. These lecture notes will explain that system of annotations and show how beans and JSF pages cooperate to make web applications.

We will be running our JSF web applications in the GlassFish application server. This application server is included in the Java edition of NetBeans, and NetBeans offers good support for creating JSF applications and deploying them to GlassFish.

Basics of JSF tags

JSF pages are composed of elements. Elements are either simple strings or more complex constructs delimited with tags. Every tag has a name and one or more attributes. Every tag begins with '<' and ends with '>'.

JSF elements come in two basic forms, simple elements and compound elements.

A simple element consists of a single tag ending in '/>'. An example is the JSF commandButton element, which represents a clickable button with an associated action.

<h:commandButton value="Greet Me!" action="greeting"/>

The value attribute of the commandButton tag specifies the text that should appear in the button.

A compound element consists of a start tag and end tag pair with the same name. Other page elements can be nested inside the start/end pair. An example is the panelGrid element, which represents a rectangular panel whose nested elements are laid out in a grid. The columns attribute of the panelGrid specifies how many columns to use for the grid.

<h:panelGrid columns="2">
  Enter your name:
  <h:inputText value="#{user.name}"/>
</h:panelGrid>

JSF pages can also contain comments. Comments are delimited by '<!--' and '-->'.

<!-- A comment -->

Standard elements of a JSF page

All JSF pages have the following basic structure:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html">
    <h:head>
        <title>A Title</title>
    </h:head>
    <h:body>
            <!-- Body contents go here. -->
    </h:body>
</html>

Since the JSF language is an application of XML, the first line is a special tag identifying this as an XML document. The second tag identifies the XML application in use in this document.

The html tag marks the boundary of the page. This tag contains one or more XML namespace attributes that declare the tag libraries in use in the document.

The html element contains two nested elements, the head and the body. heads typically contains just a title for the page, which will be displayed in the title bar when the page is displayed in a browser. Most of the interesting stuff in a JSF page appears in the body.

Don't be overly concerned with the syntax of these elements at this point - we will be using NetBeans to construct our JSF pages, and NetBeans will generate most of this syntax for us automatically when we create a new JSF page.

A Java Bean

Sitting behind the pages of a JSF application you will find one or more Java Beans. Here is an example of a simple bean class.

package jsfhello;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

@ManagedBean
@SessionScoped
public class User {
    private String name;

    public User() {
        name = "";
    }

    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
}

A Java Bean class is a class that meets a rather minimal set of requirements. The class must have a parameterless constructor and one or more properties. Each property consists of a member variable and associated get and set methods that provide access to that property. The member variable and get and set methods have to follow a naming convention - the name of the property is the name used for the member variable, and the get and set methods must have names getProperty and setProperty, where Property is the capitalized form of the property name.

Also in this source file you will see a couple of annotations.

@ManagedBean
@SessionScoped

Annotations set up specialized metadata that the Java compiler embeds in the generated class. The application server will read those annotations when it loads that class, and the annotations will direct the application server to use that class in specific ways.

The @ManagedBean annotation denotes this bean class as a managed bean. Managed beans are objects meant to be accessed from the JSF pages of the application via the bean name. By default, the name associated with a bean is simply the lowercase form of its class name. Thus, this bit of code sets up a managed bean with the name of 'user'.

The @SessionScoped annotation sets up the scope of the bean. All beans have a lifetime which is determined by their scope. Several different scopes are possible.

A bean with application scope persists for the entire lifetime of the application. As long as the server is running, that bean will be present. A bean with application scope has just one instance, which is shared by all users of the application.

A bean with session scope persists for the duration of a user session. The bean appears when the user accesses the first page of the application and typically disappears again when the session times out or the user closes their browser window. A bean with session scope will have one instance for each user session that the application is running. If 20 users are currently using the application, there will be 20 separate bean instances attached to those individual sessions.

A bean with result scope persists only for the duration of one request/response cycle.

The JSF Hello World Example

We are now ready to see our first complete JSF example. This example consists of two pages, the start page for the application and a greeting page, and one bean, the user bean shown above.

When the user comes to the start page they will see a simple form that asks them to enter their name.

Clicking the button takes the user to a page that displays a greeting.

Here is the code for the start page, index.xhtml:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html">
  <h:head>
    <title>First JSF Example</title>
  </h:head>
  <h:body>
    <h:form>
      <h:panelGrid columns="2">
        Enter your name:
        <h:inputText value="#{user.name}"/>
      </h:panelGrid>
      <h:commandButton value="Greet Me!" action="greeting"/>
    </h:form>
  </h:body>
</html>

The body of this page contains a form. Forms typically contain one or more input elements and at least one commandButton. The input element in this page is the inputText element

<h:inputText value="#{user.name}"/>

This element gets rendered on the page as a text field that the user can type input text into. The element has a value attribute that specifies what should be done with the value that the user types into that field. This value is an expression in the JSF expression language that says that the value should be linked to the name property of the user bean. Note that we have already set up a managed bean with the name user in session scope, and that the user bean does have a name property.

When the user clicks the button displayed in the form, that initiates form processing. The first step in form processing is to move any values the user has placed in the input elements down to their associated bean properties. Next, an action takes place. This action can take the form of a method call to some bean object, or can be a simple navigation action. The action property of the commandButton for this form is a simple string, which indicates that we simply want to navigate to the page greeting.xhtml when the button gets clicked.

Here is the code for greeting.xhtml.

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html">
  <h:head>
    <title>Welcome to JSF</title>
  </h:head>
  <h:body>
    Hello, #{user.name}!
  </h:body>
</html>

This is an even simpler page that displays a single line of text in its body. That text contains embedded within it an expression in the expression language:

#{user.name}

This expression indicates that it wants to be replaced by the current value of the name property found in the user bean. Note that the form in the start page set this property, so this page can read it and display it. This provides us with a simple mechanism for passing data from one page to another via bean properties.

Building this example in NetBeans

Here are the steps you will need to follow to get this example up and running in NetBeans.

  1. Create a new project in NetBeans. Choose the Web Application project type, and name the project.
  2. Click the checkbox next to JavaServer Faces in the Frameworks dialog.
  3. The project will open with an index.xhtml JSF page. Replace the contents of that index page with the code you see above.
  4. Right-click on Source Packages folder in the Projects pane and select the option New/JSF Managed Bean. If JSF Managed Bean does not appear as one of the options, go to New/Other... and select JSF Managed Bean from the JavaServer Faces category. Name the bean class User and give it session scope.
  5. Right-click in the body of the User class and select Insert Code... followed by Add Property... In the dialog that appears name the new property 'name'. To reduce clutter in the generated code, you might want to turn off the checkbox for generating javadocs.
  6. Right-click on the Web Pages folder in the Project pane and select New/JSF Page. Name the page greeting and replace the code that gets generated with the code you see above for the greeting.xhtml page.
  7. Run your application. That will start the GlassFish server and open a browser window to run your application.