ONJava.com    
 Published on ONJava.com (http://www.onjava.com/)
 See this if you're having trouble printing code examples


Using JSF

by Andrei Cioroianu
09/03/2003

The JavaServer Faces (JSF) technology provides standard APIs and tag libraries needed by Java developers that build web-based user interfaces. Craig McClanahan, the author of the Apache Struts framework, co-leads the JSF project at Sun. This will ensure an easy migration from the popular Apache project to the JSF standard. Like the Struts framework, JSF defines a set of JSP tags that generate HTML form elements that can be bound to JavaBean properties. From the application developer's perspective, the two frameworks are similar, but JSF will probably get more support from tool developers, because it is a Java standard. In the future, all J2EE application servers might actually be required to support JavaServer Faces.

Sun has recently released its Java Web Services Developer Pack 1.2, which includes a reference implementation (Early Access 4 — EA4) of the JSF Specification (Version 1.0, Public Review Draft 2). The EA4 version implements new features such as actions, managed beans, and navigation rules. This article focuses on these new features and shows how to take advantage of JSF in order to build forms, validate user input, and bind user interface components to JavaBean properties.

Related Articles:

Introducing JavaServer Faces -- JavaServer Faces, or JSF, is heralded as the next step in server-side programming. It promises to make your life easier, your programs more maintainable, and maybe even your job more enjoyable. Budi Kurniawan demonstrates JSF, explaining why it's useful and if it lives up to its promises.

This article contains a web application made of four main components. A JavaBean class (PBean.java) acts as a data model, holding some text and its attributes: font, size, color, alignment, etc. A JSF-based form (edit.jsp) allows users to provide values for the properties of the JavaBean. Another Java class (PBuilder.java) generates an HTML paragraph with the given text and attributes. Finally, a JSP page (view.jsp) shows the generated paragraph.

The JSF-based form
Figure 1. The JSF-based form

Building the JSF Form

Source Code

Download the source code for this example application.

Handling HTML forms is one of the most common tasks when you develop web applications. A good framework can save a lot of development time because there are many routine operations that can be done automatically, or reduced to just a few declarations in an XML file. It is also possible to simplify web development using well-designed JSP tag libraries. The JavaServer Faces framework provides JSP tags for rendering HTML forms, manages the state of the forms, validates user-input reporting errors, lets you bind user interface components to JavaBean properties, and does many other things that increase your productivity. JSF also has a rich API that you can use to build custom user interface (UI) components, custom validation classes (validators), and server-side event listeners.

JSF contains two tag libraries called JSF Core and HTML Basic. The former provides a few general tags and some other tags that let you register validators and event listeners to UI components. The latter contains JSP tags that render HTML UI components such as buttons, text fields, checkboxes, lists, etc. The edit.jsp page uses many of these tags to build its form. The standard prefixes of these two tag libraries are f and h, and they are declared at the beginning of edit.jsp:

<%@ taglib prefix="f" uri="http://java.sun.com/jsf/core" %>
<%@ taglib prefix="h" uri="http://java.sun.com/jsf/html" %>

The <f:use_faces> tag is a container tag that must enclose all other JSF tags that are used in a page. It doesn't generate any HTML content, but it triggers internal JSF mechanisms. The <h:form> tag generates a <form> HTML element that can contain UI components.

<html>
<head>
<title>Edit</title>
</head>
<body>

<f:use_faces>
    <h:form formName="pform">
    ..........
    </h:form>
</f:use_faces>

</body>
</html>

The above JSP code generates the following HTML fragment:

<html>
<head>
<title>Edit</title>
</head>
<body>
    <form method="post" action="/usingjsf/faces/edit.jsp">
    ..........
    </form>
</body>
</html>

The next section describes the JavaBean model of the application.

Managed Beans

Like many other web frameworks, JSF separates the user interface from the model objects that encapsulate data and application logic. When the HTML user interface is generated with the JSF tags, the JSF framework gets the data from the JavaBean model and sets the state of the UI components that make the HTML form. When the user submits the form, JSF validates the user input. If everything is okay, JSF stores the user input in the JavaBean model and the HTTP request can be forwarded to another page following a "navigation rule." If there are validation errors, JSF returns the form with error messages, so that the user can correct the input errors.

The PBean class follows the JavaBean patterns, implementing java.io.Serializable and providing get and set methods for its properties: text, size, font, color, align, bold, italic, and underline. For each user of the application, JSF creates a PBean instance that is stored within the session JSP scope with the pbean ID as specified in an XML configuration file named faces-config.xml. JSF also initializes the properties of the JavaBean instances with the values that are provided in faces-config.xml. This XML file may contain other JSF configuration parameters, including the navigation rules, which are explained later in the article.

The following XML fragment contains the declarations related to the JavaBean that is managed by JSF:

<?xml version="1.0"?>

<!DOCTYPE faces-config PUBLIC
    "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.0//EN"
    "http://java.sun.com/dtd/web-facesconfig_1_0.dtd">

<faces-config>
    ..........
    <managed-bean>
        <managed-bean-name>pbean</managed-bean-name>
        <managed-bean-class>
            com.devsphere.articles.usingjsf.PBean
        </managed-bean-class>
        <managed-bean-scope>session</managed-bean-scope>
        <managed-property>
            <property-name>text</property-name>
            <null-value/>
        </managed-property>
        <managed-property>
            <property-name>size</property-name>
            <value>3</value>
        </managed-property>
        <managed-property>
            <property-name>font</property-name>
            <values>
                <value>Arial</value>
                <value>Courier New</value>
            </values>
        </managed-property>
        <managed-property>
            <property-name>color</property-name>
            <value>green</value>
        </managed-property>
        <managed-property>
            <property-name>align</property-name>
            <value>left</value>
        </managed-property>
        <managed-property>
            <property-name>bold</property-name>
            <value>false</value>
        </managed-property>
        <managed-property>
            <property-name>italic</property-name>
            <value>true</value>
        </managed-property>
        <managed-property>
            <property-name>underline</property-name>
            <value>false</value>
        </managed-property>
    </managed-bean>
</faces-config>

The managed beans that are created by JSF can be stored within the request, session, or application scopes, depending on the value of the <managed-bean-scope> element, which may also contain none. JSF will not create a JavaBean instance if an object is already registered within the given scope with the given ID.

UI Components and Validation

The <h:form> element of edit.jsp contains several UI components, which are detailed in the following sections. The HTML code of each component is generated with a JSF component tag, such as <h:input_textarea>, that may contain other JSF tags, such as the <f:validate_required> tag, which tells JSF to make sure that the user provides some input.

The components that handle the user input are bound to JavaBean properties using valueRef="pbean.property" attributes. JSF gets and sets the values of the managed bean properties as described in the previous section.

There are JSF component tags that don't handle any user input. For example, <h:output_text> can be used to output some text or the value of a read-only JavaBean property.

Each component has a unique ID that is either specified with the id attribute or generated automatically by JSF. The UI components that require validation need the id attribute so that the validation errors can be printed with <h:output_errors for="id"/>.

validation errors
Figure 2. Validation errors

Text Area

The text area component of the JSF form lets the user provide some content for the paragraph that is generated by PBuilder.java and presented by view.jsp. The edit.jsp page displays a label with <h:output_text> and uses <h:input_textarea> to generate a <textarea> HTML element that has three rows and 30 columns. The <f:validate_required> tag registers a JSF validator that will signal an error if the user leaves the text area empty. This error is shown with the <h:output_errors> tag that does nothing if the error isn't present. The for attribute of <h:output_errors> has the same value as the id attribute of <h:input_textarea>:

<f:use_faces>
    <h:form formName="pform">
        <p><h:output_text value="Text:"/><br>
        <h:input_textarea id="text" valueRef="pbean.text"
                rows="3" cols="30">
            <f:validate_required/>
        </h:input_textarea>
        <br><h:output_errors for="text"/>
        ..........
    </h:form>
</f:use_faces>

The above JSP code generates the following HTML fragment:

<form method="post" action="/usingjsf/faces/edit.jsp">
    <p>Text:<br>
    <textarea name="text" 
        cols="30" rows="3">JavaServer Faces</textarea>
    <br>
    ..........
</form>

The valueRef="pbean.text" attribute of <h:input_textarea> tells JSF to look for a JavaBean instance whose ID is pbean, and to store the text provided by the user into the text property of the JavaBean instance. When the HTML form is generated, JSF inserts the value of the text property within the <textarea> HTML element. The PBean class implements the get and set methods that are called by JSF to retrieve and change the property's value:

public class PBean implements java.io.Serializable {

    private String text;

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

    ..........

}

In addition to <h:input_textarea>, JSF offers several tags that generate text fields: <input_text>, <h:input_number>, <input_secret> (for passwords), <input_date>, <input_datetime>, and <input_time>. The <input_hidden> tag can be used to generate hidden form fields.

Text Field

The text field component of the edit.jsp page accepts only a numeric value between 1 and 7. The HTML code is generated with <h:input_number>, which contains two validators. The <f:validate_required> was described in the previous section. The <f:validate_longrange> validator verifies if the numeric value provided by the user is within the given range. If not, the validation error is reported to the user with <h:output_errors>.

<f:use_faces>
    <h:form formName="pform">
        ..........
        <p><h:output_text value="Size: [1-7]"/><br>
        <h:input_number id="size" valueRef="pbean.size" size="2">
            <f:validate_required/>
            <f:validate_longrange minimum="1" maximum="7"/>
        </h:input_number>
        <br><h:output_errors for="size"/>
        ..........
    </h:form>
</f:use_faces>

The above JSP code generates the following HTML fragment:

<form method="post" action="/usingjsf/faces/edit.jsp">
    ..........
    <p>Size: [1-7]<br>
    <input type="text" name="size" id="size" value="3" size="2">
    <br>
    ..........
</form>

The text field is bound to the size property, whose type is int. The value of the size property (3) is used to set the value attribute of the numeric input field when the HTML form is generated. Assuming that there are no validation errors, JSF updates the JavaBean when it receives the user input containing a new value for the size property of the JavaBean. The size attribute of <h:input_number> specifies the character length (2) of the text field, and has nothing to do with the JavaBean property.

public class PBean implements java.io.Serializable {

    ..........

    private int size;

    public int getSize() {
        return size;
    }

    public void setSize(int size) {
        this.size = size;
    }

    ..........

}

In addition to <f:validate_required> and <f:validate_longrange>, JSF provides a few other validator tags: <validate_doublerange>, <validate_stringrange>, <validate_length>, and <validator>. The last one is a generic tag that lets you register your own custom validators to UI components. You can also create your own library of validator tags.

List Box

The <h:selectone_listbox> and <h:selectmany_listbox> tags produce HTML <select> elements that the web browser displays as list boxes. The former JSF tag allows the user to select a single item, while the latter is used when multiple items could be selected.

The edit.jsp page uses <h:selectmany_listbox> to generate a list box that contains a few font names. The HTML <option> elements that describe the list items are generated with the <h:selectitem> JSF tag:

<f:use_faces>
    <h:form formName="pform">
        ..........
        <p><h:output_text value="Font:"/><br>
        <h:selectmany_listbox id="font" valueRef="pbean.font">
            <h:selectitem itemValue="Arial"
                itemLabel="Arial"/>
            <h:selectitem itemValue="Courier New"
                itemLabel="Courier New"/>
            <h:selectitem itemValue="Times New Roman"
                itemLabel="Times New Roman"/>
        </h:selectmany_listbox>
        ..........
    </h:form>
</f:use_faces>

The above JSP code generates the following HTML fragment:

<form method="post" action="/usingjsf/faces/edit.jsp">
    ..........
    <p>Font:<br>
    <select name="font" multiple size="3">	
        <option value="Arial" selected>Arial</option>
        <option value="Courier New" selected>Courier New</option>
        <option value="Times New Roman">Times New Roman</option>
    </select>
    ..........
</form>

The list box is bound to the font property, whose type is String[]. The first getFont() method uses clone() to return a copy of the internal array that must be protected from external accesses. The first setFont() method uses clone() to retain a copy of the provided array that can be modified by the second setFont() method.

public class PBean implements java.io.Serializable {

    ..........

    private String fontArray[];

    public String[] getFont() {
        return (String[]) fontArray.clone();
    }

    public void setFont(String fontArray[]) {
        this.fontArray = (String[]) fontArray.clone();
    }

    public String getFont(int index) {
        return fontArray[index];
    }

    public void setFont(int index, String font) {
        if (fontArray == null)
            fontArray = new String[index+1];
        else if (fontArray.length <= index) {
            String oldFontArray[] = fontArray;
            fontArray = new String[index+1];
            for (int i = 0; i < oldFontArray.length; i++)
                fontArray[i] = oldFontArray[i];
        }
        fontArray[index] = font;
    }

    ..........

}

When the HTML form is generated, JSF adds the selected HTML attribute to any list item whose value is contained by the font array of the JavaBean model. Assuming that there are no validation errors, JSF updates the JavaBean property when it receives the user input containing new selected fonts.

Drop-Down List

The <h:selectone_menu> tag generates a drop-down list containing a few colors.

It contains <h:selectitem> tags, as in the case in the list box:

<f:use_faces>
    <h:form formName="pform">
        ..........
        <p><h:output_text value="Color:"/><br>
        <h:selectone_menu id="color" valueRef="pbean.color">
            <f:validate_required/>
            <h:selectitem itemValue="black" itemLabel="Black"/>
            <h:selectitem itemValue="red" itemLabel="Red"/>
            <h:selectitem itemValue="blue" itemLabel="Blue"/>
            <h:selectitem itemValue="green" itemLabel="Green"/>
        </h:selectone_menu>
        <br><h:output_errors for="color"/>
        ..........
    </h:form>
</f:use_faces>

The above JSP code generates the following HTML fragment:

<form method="post" action="/usingjsf/faces/edit.jsp">
    ..........
    <p>Color:<br>
    <select name="color" size="1">
        <option value="black">Black</option>
        <option value="red">Red</option>
        <option value="blue">Blue</option>
        <option value="green" selected>Green</option>
    </select>
    <br>
    ..........
</form>

The drop-down list is bound to the color property, whose type is String:

public class PBean implements java.io.Serializable {

    ..........

    private String color;

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    ..........

}

When the HTML form is generated, JSF adds the selected HTML attribute to the list item whose value is equal to the color property of the JavaBean model. Assuming that there are no validation errors, JSF updates the JavaBean property when it receives the user input containing a new color.

Radio Buttons

The <h:selectone_radio> and <h:selectitem> tags produce a group of radio buttons:

<f:use_faces>
    <h:form formName="pform">
        ..........
        <p><h:output_text value="Alignment:"/><br>
        <h:selectone_radio id="align" valueRef="pbean.align"
                layout="LINE_DIRECTION">
            <f:validate_required/>
            <h:selectitem itemValue="left" itemLabel="Left"/>
            <h:selectitem itemValue="center" itemLabel="Center"/>
            <h:selectitem itemValue="right" itemLabel="Right"/>
        </h:selectone_radio>
        <br><h:output_errors for="align"/>
        ..........
    </h:form>
</f:use_faces>

The above JSP code generates the following HTML fragment:

<form method="post" action="/usingjsf/faces/edit.jsp">
    ..........
    <p>Alignment:<br>
    <table border="0">
        <tr>
            <td><input type="radio" checked 
                name="align" value="left"> Left</td>
            <td><input type="radio" 
                name="align" value="center"> Center</td>
            <td><input type="radio"
                name="align" value="right"> Right</td>
        </tr>
    </table>
    <br>
    ..........
</form>

The radio buttons are bound to the align property:

public class PBean implements java.io.Serializable {

    ..........

    private String align;

    public String getAlign() {
        return align;
    }

    public void setAlign(String align) {
        this.align = align;
    }

    ..........

}

When the HTML form is generated, JSF adds the checked HTML attribute to the radio button whose value is equal to the align property of the JavaBean model. Assuming that there are no validation errors, JSF updates the JavaBean property when it receives the user input containing a new alignment.

Checkboxes

The edit.jsp page contains three checkboxes that are generated with <h:selectboolean_checkbox>. These UI components are contained by an HTML table that is generated with the <h:panel_grid> and <h:panel_group>:

<f:use_faces>
    <h:form formName="pform">
        ..........
        <p><h:output_text value="Style:"/><br>
        <h:panel_grid columns="3" border="0" cellspacing="5">
            <h:panel_group>
                <h:selectboolean_checkbox id="bold"
                    valueRef="pbean.bold"/>
                <h:output_text value="Bold"/>
            </h:panel_group>
            <h:panel_group>
                <h:selectboolean_checkbox id="italic"
                    valueRef="pbean.italic"/>
                <h:output_text value="Italic"/>
            </h:panel_group>
            <h:panel_group>
                <h:selectboolean_checkbox id="underline"
                    valueRef="pbean.underline"/>
                <h:output_text value="Underline"/>
            </h:panel_group>
        </h:panel_grid>
        ..........
    </h:form>
</f:use_faces>

The above JSP code generates the following HTML fragment:

<form method="post" action="/usingjsf/faces/edit.jsp">
    ..........
    <p>Style:<br>
    <table border="0" cellspacing="5">
        <tr>
            <td><input type="checkbox" 
                 name="bold">Bold</td>
            <td><input type="checkbox"  
                 name="italic" checked>Italic</td>
            <td><input type="checkbox"  
                 name="underline">Underline</td>
        </tr>
    </table>
    ..........
</form>

The three checkboxes are bound to the bold, italic, and underline Boolean properties:

public class PBean implements java.io.Serializable {

    ..........

    private boolean bold;

    public boolean isBold() {
        return bold;
    }

    public void setBold(boolean bold) {
        this.bold = bold;
    }
    private boolean italic;

    public boolean isItalic() {
        return italic;
    }

    public void setItalic(boolean italic) {
        this.italic = italic;
    }
    private boolean underline;

    public boolean isUnderline() {
        return underline;
    }

    public void setUnderline(boolean underline) {
        this.underline = underline;
    }

    ..........

}

When the HTML form is generated, JSF adds the checked HTML attribute to each checkbox whose associated JavaBean property is true. Assuming that there are no validation errors, JSF updates the JavaBean properties when it receives the user input.

In this example, the checkboxes are generated separately. JSF offers another tag, called <h:selectmany_checkboxlist>, which can be used to generate a group of checkboxes. JSF also has two other tags, named <h:panel_list> and <h:panel_data>, which can be used to generate tables from collections and arrays.

Command Buttons

The faces-config.xml file defines a navigation rule that tells JSF what to do when the user clicks one of the command buttons of the page whose path is specified within <from-tree-id> (/edit.jsp). There are two navigation cases defined within separate <navigation-case> elements:

..........
<faces-config>
    <navigation-rule>
        <from-tree-id>/edit.jsp</from-tree-id>
        <navigation-case>
            <from-outcome>editOutcome</from-outcome>
            <to-tree-id>/edit.jsp</to-tree-id>
        </navigation-case>
        <navigation-case>
            <from-outcome>viewOutcome</from-outcome>
            <to-tree-id>/view.jsp</to-tree-id>
        </navigation-case>
    </navigation-rule>
    ..........
</faces-config>

The /edit.jsp page contains two buttons generated with <h:command_button>. Each of them has an ID, a label, a command name (not used here, but required by JSF), and an action or actionRef attribute:

<f:use_faces>
    <h:form formName="pform">
        ..........
        <p>
        <h:command_button id="view" label="View"
            commandName="viewCmd" action="viewOutcome"/>
        <h:command_button id="boldUpperCase"
            label="Bold Upper Case / View"
            commandName="boldUpperCaseCmd"
            actionRef="pbean.boldUpperCaseAction"/>
    </h:form>
</f:use_faces>

The above JSP code generates the following HTML fragment:

<form method="post" action="/usingjsf/faces/edit.jsp">
    ..........
    <p>
    <input type="submit" name="view" value="View">
    <input type="submit" name="boldUpperCase" 
        value="Bold Upper Case / View">
</form>

JSF validates the form data every time the browser submits the user input. If there are no errors signaled by validators and no type-conversion errors, JSF takes into account the navigation cases. For the first button, JSF gets the viewOutcome value of the action attribute, which matches the text of the <from-outcome> element of the second navigation case. Therefore, JSF will forward the HTTP request to /view.jsp, which is the path contained by the <to-tree-id> element of the second navigation case.

When the user clicks the second button, JSF calls the getBoldUpperCaseAction() method of the PBean object. This method returns an instance of BoldUpperCaseAction, which is an inner class of PBean. Then, JSF calls the invoke() method that returns an outcome determined at runtime rather than hard-coded within the HTML file:

public class PBean implements java.io.Serializable {

    ..........

    public BoldUpperCaseAction getBoldUpperCaseAction() {
        return new BoldUpperCaseAction();
    }

    public class BoldUpperCaseAction
            extends javax.faces.application.Action {
        public String invoke() {
            String ucText = getText().toUpperCase();
            if (isBold() && getText().equals(ucText))
                return "viewOutcome";
            else {
                setBold(true);
                setText(ucText);
                return "editOutcome";
            }
        }
    }

}

If the bold property is true and all letters of text are majuscules, JSF follows the second navigation case, forwarding the HTTP request to /view.jsp as in the case of the other button. Otherwise, invoke() sets the bold property to true, converts all characters of the text property to upper case, and returns editOutcome, telling JSF to follow the first navigation case which keeps /edit.jsp as the current page.

Processing the Form Data

The PBuilder class contains a static method that takes a PBean instance and builds an HTML paragraph with the properties of the JavaBean object:
package com.devsphere.articles.usingjsf;

public class PBuilder {

    public static String toHTML(PBean pbean) {
        StringBuffer buf = new StringBuffer();
        buf.append("<p align=\"");
        buf.append(pbean.getAlign());
        buf.append("\">");
        buf.append("<font size=\"");
        buf.append(pbean.getSize());
        buf.append("\" color=\"");
        buf.append(pbean.getColor());
        buf.append("\"");
        Object font[] = pbean.getFont();
        if (font != null && font.length > 0) {
            buf.append(" face=\"");
            for (int j = 0; j < font.length; j++) {
                if (j > 0)
                    buf.append(',');
                buf.append(font[j]);
            }
            buf.append("\"");
        }
        buf.append(">");
        if (pbean.isBold())
            buf.append("<b>");
        if (pbean.isItalic())
            buf.append("<i>");
        if (pbean.isUnderline())
            buf.append("<u>");
        String s = pbean.getText();
        int n = s.length();
        for (int i = 0; i < n; i++) {
            char ch = s.charAt(i);
            switch (ch) {
                case '<':
                    buf.append("<");
                    break;
                case '>':
                    buf.append(">");
                    break;
                case '&':
                    buf.append("&");
                    break;
                case '"':
                    buf.append(""");
                    break;
                default:
                    buf.append(ch);
            }
        }
        if (pbean.isUnderline())
            buf.append("</u>");
        if (pbean.isItalic())
            buf.append("</i>");
        if (pbean.isBold())
            buf.append("</b>");
        buf.append("</font>");
        buf.append("</p>");
        return buf.toString();
    }

}

The view.jsp page uses <jsp:useBean> to get the JavaBean instance managed by JSF, calls the toHTML() method of PBuilder, and outputs the resultant HTML paragraph. The <h:command_hyperlink> tag of JSF is used to provide a link back to edit.jsp:

<%@ taglib prefix="f" uri="http://java.sun.com/jsf/core" %>
<%@ taglib prefix="h" uri="http://java.sun.com/jsf/html" %>

<html>
<head>
<title>View</title>
</head>
<body>

<jsp:useBean id="pbean" scope="session"
    class="com.devsphere.articles.usingjsf.PBean"/>

<%= com.devsphere.articles.usingjsf.PBuilder.toHTML(pbean) %>

<f:use_faces>
    <h:command_hyperlink label="Back to Editing" href="edit.jsp"/>
</f:use_faces>

</body>
</html>

text presented by view.jsp
Figure 3. Text presented by view.jsp

Application Configuration

The JSF framework has a controller servlet named FacesServlet that must intercept the requests to any JSP page containing JSF tags. The servlet is configured in the web.xml application descriptor and is mapped to the /faces/* URL pattern. To activate the servlet, the paths of the JSP pages must be start with "faces." The index.jsp home page of the application uses response.sendRedirect() to redirect the browser to the faces/edit.jsp form:

<% response.sendRedirect("faces/edit.jsp"); %>

The path of the faces-config.xml file is specified as the value of a context parameter in the web.xml descriptor, which also contains a listener registration and a few other parameters that are specific to the reference implementation of JSF. Here is the content of web.xml:

<?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>

    <context-param>
        <param-name>javax.faces.application.CONFIG_FILES</param-name>
        <param-value>/WEB-INF/faces-config.xml</param-value>
    </context-param>

    <context-param>
        <param-name>com.sun.faces.saveStateInClient</param-name>
        <param-value>false</param-value>
    </context-param>

    <context-param>
        <param-name>com.sun.faces.validateXml</param-name>
        <param-value>true</param-value>
    </context-param>

    <listener>
        <listener-class>com.sun.faces.config.ConfigListener</listener-class>
    </listener>

    <servlet>
        <servlet-name>FacesServlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>FacesServlet</servlet-name>
        <url-pattern>/faces/*</url-pattern>
    </servlet-mapping>

</web-app>

When generating a form for the first time, JSF builds a so-called component tree, an object structure containing information about the UI components, the validators registered to them, and so on. When the user submits the form data, JSF uses the information from the component tree to do some processing, such as validating the user input. By default, JSF stores the component tree as a session attribute. This works well once the application is finished. During development, however, when you make changes to the JSF form, including adding or removing UI components, JSF will throw exceptions because it doesn't discard the stale component tree when the JSP page is modified. The workaround is to switch the saveStateInClient flag declared in web.xml to true. After this change, JSF will serialize the component tree within the HTML form as a hidden field instead of storing it as a session attribute.

Summary

This article has presented the basic features of the JSF framework, showing how to build forms with the JSF tags. As any early-access package, the JSF Reference Implementation EA4 is not ready for deployment, but most of its functionality is usable. After more than two years spent in the Java Community Process, JSF is welcome; Java developers really need a standard tag library for building web user interfaces and a standard API for building custom web components.

Resources

Andrei Cioroianu is the founder of Devsphere and an author of many Java articles published by ONJava, JavaWorld, and Java Developer's Journal.


Return to ONJava.com.

Copyright © 2009 O'Reilly Media, Inc.