JSF is a server side user interface component framework for Java technology based Web applications. Often people think that itís a client side technology which is a misconception. Just as an example, client side UI framework is Swing.

Please note that it is server side instead of client side framework. JSF architecture includes many things that are related to UI management and are handled at the server instead of at client side. Please also note that JSF is a UI component framework. JSF architecture includes UI components that handle UI.


JSF provides a specification and reference implementation for web application development framework. The specification defines various things such as UI component model, event and listener model, validator model, back-end data integration model.

Goal of JSF

The primary goal of JSF is to allow tool vendors to provide easy to use
tools using JSF underneath. This provides the developers the ease of building Web
applications using drag and drop model as they do in standalone Swing based applications. An example is Sun Java Studio Creator.


Why JSF?

Following are the positives of JSF that answers the question: Why we should use JSF?

- JSF provides the Model View Controller based Web application framework.
- It provides clean separation of roles and is easy to use.
- It provides UI component framework which is extensible.
- It also provides rendering architecture in which UI components can be associated with multiple renderers.
- JSF is designed with multiple client types in mind.
- A clean separation between behavior, logic and presentation.


Servlet/JSP/Struts vs JSF

Often people ask that why we should use JSF when we have Servlet and JSP? Another question is why we should use JSF when we have Sturts?

Let me answer these. JSP and Servlet do not provide built-in UI component model.

Struts sure is a powerful framework but it was designed with a different focus. The focus of Struts is to provide a controller framework while the focus of JSF is to provide UI component framework.

Struts does not provide the built-in UI component model and it does not support UI component event model, nor state management of UI components, and because Struts is more or less tied up with HTML, it does not support the independence between UI components and a particular renderer.



Lifecycle if JSF page

The client makes an HTTP request for the page, and the server responds with the page translated to HTML. Since there are extra features that JSF offers, the lifecycle provides some additional services to process a page.

JavaServer Faces - Basics-lifecycle.jpg

A JavaServer Faces page is represented by a tree of UI components, called a view.

The lifecycle starts when a client makes a request for the page. During the lifecycle, the JSF implementation must build the view while considering state saved from the previous postback.

When the client performs a postback of the page, the JSF implementation must perform several tasks, such as validate the data input of components in the view and convert input data to types specified on the server side. The JavaServer Faces implementation performs all of these tasks as a series of steps in the lifecycle.


Phases - Request Processing Lifecycle

Following phases are involved in processing a client request:

1.Reconstitute component tree phase
2.Apply request values phase
3.Process validations phase
4.Update model values phase
5.Invoke application phase
6.Render response phase

The JavaServer Faces component architecture is designed such that the functionality of the components is defined by the component classes, whereas the component rendering can be defined by a separate renderer.

Component writers can define the behavior of a component once, but create multiple renderers, each of which defines a different way to render the component to the same client or to different clients.

Page authors and application developers can change the appearance of a component on the page by selecting the tag that represents the appropriate component/renderer combination

A render kit defines how component classes map to component tags appropriate for a particular client. The JavaServer Faces implementation includes a standard
RenderKit class for rendering to an HTML client. For every UI component that a render kit supports, the render kit defines a set of Renderer objects.

Each JSP custom tag in the standard HTML RenderKit is composed of the component functionality, defined in the UIComponent class, and the rendering attributes, defined by the Renderer.


UI Components

UIComponent/UIComponentBase are the base class for all user interface components. Standard UIComponent subclasses are:

UICommand, UIForm, UIOutput, UIGraphic, UIInput, UIPanel, UIParameter, UISelectBoolean, UISelectMany, UISelectOne

Example:

Java Code:
<h:inputText id="userNo"
value="#{UserNumberBean.userNumber}"/>

Validators and Converters

Converters are plug-in for conversions.

Java Code:
<h:input_text valueRef=testingBean.today
convertor=DateTime/>
Validators are used to perform correctness checks on UIInput values.

Java Code:
<h:input_text valueRef=testingBean.today
<f:validator_length minimum=6 maximum='10 />

Example

The following greeting.jsp page is presented as an example JSF page.

Java Code:
<HTML>
<HEAD> <title>Hello</title> </HEAD>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<body bgcolor="white">
<f:view>
<h:form id="helloForm" >
<h2>Hi. My name is Duke. I'm thinking of a number from
<h:outputText value="#{UserNumberBean.minimum}"/> to
<h:outputText value="#{UserNumberBean.maximum}"/>. Can you guessit?</h2>
<h:graphicImage id="waveImg" url="/wave.med.gif" />
<h:inputText id="userNo" value="#{UserNumberBean.userNumber}">
<f:validateLongRange minimum="0" maximum="10" />
</h:inputText>
<h:commandButton id="submit" action="success" value="Submit" />
<p>
<h:message style="color: red; font-family: 'New Century Schoolbook', serif;
font-style: oblique; text-decoration: overline" id="errors1" for="userNo"/>
</h:form>
</f:view>
</HTML>
A request for JSF page is made when a link is clicked or a button is pressed. In this, the JSF implementation begins the restore view phase.

If it is the first time, an empty view is created. JSF implementation builds the view of the JavaServer Faces page, wires up event handlers and validators and finally saves the view in the FacesContext.


The view for the presented greeting.jsp page will have the UIView component at the root of the tree, helloForm as its child and the rest of the JavaServer Faces UI components (userNo, submit, errors1) as children of helloForm.


Navigation model

Application developer is responsible for creating and defining the navigation model. It is defined in application configuration file (Facesconfig.xml).

A sample navigation model is presented below:

Java Code:
<navigation-rule>
<from-tree-id>/login.jsp</from-tree-id>
<navigation-case>
<from-outcome>success</from-outcome>
<to-tree-id>/menu.jsp</to-tree-id>
</navigation-case>
<navigation-case>
<from-outcome>failed</from-outcome>
<to-tree-id>/error.jsp</to-tree-id>
</navigation-case>
</navigation-rule>

A sample managed bean declaration in Faces.config.xml is given below:


Java Code:
<managed-bean>
<managed-bean-name>
LoginFormBean
</managed-bean-name>
<managed-bean-class>
myapp.LoginFormBean
</managed-bean-class>
<managed-bean-scope>
request
</managed-bean-scope>
</managed-bean>

Sample JSF page

Creating JSF page is simple and easy. There are few things to remember which I will list down.

The page must include JSF tag library and HTML and core tags.

All the JSF tags must enclosed between a set of view tag.
Use JSF form and form component tags.
Use <h:input_text> and not <input type=text>
Use <h:command_button> and not <input type=submit>
A page may include validators and event listeners on any form components

For example:

Java Code:
<f:view>
<f:form formName=logonForm>
<h:panel_grid columns=2>
<h:output_text value=Username:/>
<h:input_text id=username length=16
valueRef=logonBean.username/>
<h:output_text value=Password:/>
<h:input_secret id=password length=16
valueRef=logonBean.password/>
<h:command_button type=submit
labelLog On
actionRef=logonBean.logon/>
<h:command_button type=reset
label=Reset/>
</h:panel_grid>
</f:form>
</f:view>

Review the code presented above. We have a text field named username whose value is mapped to logonBean's attribute username. This mapping info has to be in
faces-confog.xml and there has to be a bean with the required getters and setters.

Next step is to define page navigation rules in the configuration file.

Java Code:
<navigation-rule>
<from-tree-id>/login.jsp</from-tree-id>
<navigation-case>
<from-outcome>success</from-outcome>
<to-tree-id>/menu.jsp</to-tree-id>
</navigation-case>
</navigation-rule>

<navigation-rule>
<from-tree-id>/login.jsp</from-tree-id>
<navigation-case>
<from-outcome>failure</from-outcome>
<to-tree-id>/error.jsp</to-tree-id>
</navigation-case>
</navigation-rule>
Then configure web.xml

Java Code:
<context-param>
<param-name>
javax.faces.application.CONFIG_FILES
</param-name>
<param-value>/WEB-INF/faces-config.xml
</param-value>
</context-param>
<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>
We will need following JARs to make it work:

WEB-INF/lib/jsf-api.jar
WEB-INF/lib/jsf-ri.jar
WEB-INF/lib/jstl.jar
WEB-INF/lib/jsf-el.jar
WEB-INF/lib/standard.jar
WEB-INF/lib/commons-beanutils.jar
WEB-INF/lib/commons-digester.jar
WEB-INF/lib/commons-collections.jar
WEB-INF/lib/commons-logging.jar


Developing the Application Backend

As an application developer, you are responsible of writing the classes that handles business logic and data. In other words, you are responsible for backend part of the application. Lets assume that you are developing a newsletter subscription form. In that case you may create a class called Subscriber to hold the subscriber information:

Java Code:
package com.mycompany.newsservice.models;

public class Subscriber {
private String emailAddr;
private String[] subscriptionIds;

public String getEmailAddr( ) {
return emailAddr;
}
public void setEmailAddr(String emailAddr) {
this.emailAddr = emailAddr;
}
public String[] getSubscriptionIds( ) {
return subscriptionIds;
}
public void setSubscriptionIds(String[] subscriptionIds) {
this.subscriptionIds = subscriptionIds;
}
}
The class defines a String attribute and a String array with getter and setters. We use standard conventions for getter and setter methods. This makes it easy to use properties of this class as JSF UI component models.

When a subscription is registered or updated, the information must be saved somewhere,
likely in a database or in some XML file. You have to write a separate class for persisting the contents.

To keep the example simple, we will simply print the contents on the console using the following method:


Java Code:
public void save( ) {
StringBuffer subscriptions = new StringBuffer( );
if (subscriptionIds != null) {
for (int i = 0; i < subscriptionIds.length; i++) {
subscriptions.append(subscriptionIds[i]).append(" ");
}
}
System.out.println("Subscriber Email Address: " + emailAddress +
"\nSubscriptions: " + subscriptions);
}
Thatís all for the backend we need for the sample application.

Letís assume that the component writer implements the action event processing method in a new class called SubscriberHandler:

Java Code:
package com.mycompany.newsservice.handlers;
import com.mycompany.newsservice.models.Subscriber;
public class SubscriberHandler {
private Subscriber subscriber;

public void setSubscriber(Subscriber subscriber) {
this.subscriber = subscriber;
}

public String saveSubscriber( ) {
subscriber.save( );
return "success";
}
}

The SubscriberHandler class has two methods: a setter method (setSubscriber(...)) for associating it with an instance of the Subscriber class and a method for handling the Save button ActionEvent (saveSubscriber(...)). The saveSubscriber( ) method simply calls the save( ) method on the Subscriber instance and returns success.

Hereís a snippet of the configuration file with the declarations for the
example application classes:

Java Code:
<faces-config>
...
<managed-bean>
<managed-bean-name>subscr</managed-bean-name>
<managed-bean-class>
com.mycompany.newsservice.models.Subscriber
</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>subscrHandler</managed-bean-name>
<managed-bean-class>
com.mycompany.newsservice.handlers.SubscriberHandler
</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<managed-property>
<property-name>subscriber</property-name>
<value>#{subscr}</value>
</managed-property>
</managed-bean>
...
</faces-config>

The following JSP page is with JSF elements for the subscription form (newsservice/subscribe.jsp)


Java Code:
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<html>
<head>
<title>Newsletter Subscription</title>
</head>
<body>
<f:view>
<h:form>
<table>
<tr>
<td>Email Address:</td>
<td>
<h:inputText value="#{subscr.emailAddr}" />
</td>
</tr>
<td>
<td>News Letters:</td>
<td>
<h:selectManyCheckbox value="#{subscr.subscriptionIds}">
<f:selectItem itemValue="1" itemLabel="JSF News" />
<f:selectItem itemValue="2" itemLabel="IT Industry News" />
<f:selectItem itemValue="3" itemLabel="Company News" />
</h:selectManyCheckbox>
</td>
</tr>
</table>
<h:commandButton value="Save"
action="#{subscrHandler.saveSubscriber}" />
</h:form>
</f:view>
</body>
</html>

The email address input component is represented by the <h:inputText> element.

Java Code:
<h:inputText value="#{subscr.emailAddr}" />
The value attribute contains a value binding expression that binds the component to the emailAddr property of an application bean named subscr.

Happy coding.