About NewTechnoBuzz
Advertise
Contact Us

Tuesday, July 15, 2014

Request Processing Lifecycle Phases in JSF

In order for you to understand how JSF framework masks the underlying request processing nature of the Servlet API and to analyze how JSF processes each request. The client makes an HTTP request for the page, and the server responds with the page translated to HTML. However, because of the extra features that JavaServer Faces technology offers, the life cycle provides some additional services to process a page.

The life cycle of a JSF page is similar to JSP. A JavaServer Faces page is represented by a tree of UI components called a view. The JSF page lifecycle starts, when the client requests for a page. During the lifecycle, the JavaServer Faces implementation must build the view while considering state saved from a previous submission of the page.

When a page is submitted by a client, the JSF implements the tasks such as - data input validation of the view components and converting input data to types specified on the server side.
In its life cycle, the JSF performs all these designated tasks in a series of steps.

  • Restore View
  • Apply Request Values
  • Process Validations
  • Update Model Values
  • Invoke Application
  • Render Response

Below is the normal flow of control for request processing in JSF.

JSF Life cycle

Request Processing Life Cycle Scenarios

A JSF application supports two kinds of responses and two kinds of requests:
  • Faces Response: A servlet response that was created by the execution of the Render Response Phase of the request processing life cycle.
  • Non-Faces Response: A servlet response that was not created by the execution of the Render Response phase. Example of this scenario is a JSP page that does not incorporate JSF components.
  • Faces Request: A servlet request that was sent from a previously generated Faces response. Example of this scenario is a form submit from a JSF user interface component, where the request URI identifies the JSF component tree.
  • Non-Faces Request: A servlet request that was sent to an application component, such as a servlet or JSP page, rather than directed to a JSF component tree.
These different requests and responses result in three possible life cycle scenarios that can exist for a JSF application:

Scenario 1: Non-Faces Request Generates Faces Response

An example of this scenario occurs when hyperlink is clicked on an HTML page and opens a JSF page. To render a Faces response from a non-Faces request, an application must provide a mapping to FacesServlet, which accepts incoming requests and passes them to the life cycle implementation for processing. When generating a Faces response, the application must create a new view, store it in the FacesContext, acquire object references needed by the view, and call FacesContext.renderResponse, which forces immediate rendering of the view by skipping to the Render Response Phase.

Scenario 2: Faces Request Generates Non-Faces Response

Sometimes, a JSF application might need to redirect to a different web application resource or might need to generate a response that does not contain any JSF components. In these situations, the developer must skip the rendering phase (i.e. Render Response Phase) by calling FacesContext.responseComplete. The FacesContext contains all the information associated with a particular Faces request. This method can be invoked during the Apply Request Values Phase, Process Validations Phase, or the Update Model Values Phase.

Scenario 3: Faces Request Generates Faces Response

This is the most common scenario for the life cycle of a JSF application. This scenario involves a JSF component submitting a request to a JSF application utilizing the FacesServlet because the request has been handled by the JSF implementation, no additional steps are required by the application to generate the response. All listeners, validators and converters will automatically be invoked during the appropriate phase of the standard life cycle.

Note: Life – cycle handles two kinds of requests:
  • Initial Request: A user requests the page for the first time.
  • Postback: A user submits the form contained on a page that was previously loaded into the browser as a result of executing an initial request.

Free Search Engine Submission

Which steps in the life cycle are executed depends on whether or not the request originated from a JSF application and whether or not the response is generated with the rendering phase of the JavaServer Faces life cycle.
In normal flow request processing, JSF executes all of the phases.

Phase 1 : Restore View

  • When a request for a JSF page is made, such as when a link or a button is clicked, then the JSF implementation begins the Restore View phase.
  • JSF framework controller uses the view ID (typically JSP name) to look up the components for the current view. If the view isn’t available, the JSF controller creates an empty view. The empty view will be populated when the page is processed during a postback.
  • JSF implementation builds the view of the page, wires event handlers and validators to components in the view, and saves the view in the FacesContext instance. The FacesContext instance contains all the information needed to process a single request. All the application's component tags, event handlers, converters, and validators have access to the FacesContext instance.
  • If the request for the page is a postback, a view corresponding to this page already exists. During this phase, the JavaServer Faces implementation restores the view by using the state information saved on the client or the server. Lifecycle continues to execute the remaining phases.
  • This is the phase that requires the least intervention by application code.
<f:view>
 <h:form>
  
     <p>Enter your username:
         <h:inputText
             value='#{LoginBean.username}'
             id='usernameTxtField'
             required='true'/>
         <h:message for='usernameTxtField' />
     </p>
  
     <p>Enter your password:
         <h:inputSecret
             value='#{LoginBean.password}'
             id='passwordTxtField'
             required='true'/>
         <h:message for='passwordTxtField' />
     </p>
  
 <h:commandButton value='Login' action='loginUser'/>
  
 </h:form>
</f:view>

The above form has a root UI Component called 'view'. It has three child components namely a text-field (with identifier 'usernameTxtField'), a password-field (with identifier 'passwordTxtField') and a command button with name 'Login'. So, this whole set-up represents a view.

The state of the view can either be stored on Server or in Client Browser. If it is stored in Server, then it might be cached in HttpSession object, else it may be represented as hidden text-fields in the client end. The strategy whether the view state is stored in Server or Client is determined by the property called 'javax.faces.STATE_SAVING_METHOD'.

The default value for this property is 'server' which means that the view state is restored in the Server. The other permitted value is 'client'. This property is specified in the Configuration file (web.xml) as follows,


<context-param>
 <param-name>
   javax.faces.STATE_SAVING_METHOD
 </param-name>
 <param-value>client</param-value>
</context-param>

Phase 2 : Apply Request Values Phase

  • The request parameters are read and their values are used to set the values of the corresponding UI components. This process is called decoding.
  • The value is then stored locally on the component. If the conversion of the value fails, an error message associated with the component is generated and queued on FacesContext. This message will be displayed during the render response phase, along with any validation errors resulting from the process validations phase.
  • If some components on the page have their immediate event handling property is set to true, then the validation, conversion, and events associated with these components takes place in this phase instead of the Process Validations phase. For example, you could have a Cancel button that ignores all values on a form.
  • If the application needs to redirect to a different web application resource or generate a response that does not contain any JavaServer Faces components, it can call FacesContext.responseComplete.
At the end of this phase, the components are set to their new values, and messages and events have been queued.

<p>Enter your Phone No
 <h:inputText value='#{EmployeeBean.phoneNumber}' id='phoneNumber'
 required='true'>
 <f:validator validatorId='PhoneNumberValidator' />
 </h:inputText>
 <h:message for='phoneNumber'/>
</p>

The above code defines a Custom Validator called PhoneNumber Validator which will validate the given string against some standard format. It is possible to define and attach any number of Validators to a Component. In this phase, JSF Implementation will traverse over the UIViewRoot to fetch all the child components and ask the child components to validate themselves by calling the method UIComponentBase.processValidators().

Phase 3 : Process Validations Phase

  • During this phase, the JavaServer Faces implementation processes all validators registered on the components in the tree. It examines the component attributes that specify the rules for the validation and compares these rules to the local value stored for the component.
  • Any input can be scanned by any number of validators. These Validators can be pre-defined or defined by the developer.
  • If the local value is invalid, the JavaServer Faces implementation adds an error message to the FacesContext instance, and the life cycle advances directly to the render response phase so that the page is rendered again with the error messages displayed. If there were conversion errors from the apply request values phase, the messages for these errors are also displayed.
  • If the application needs to redirect to a different web application resource or generate a response that does not contain any JavaServer Faces components, it can call FacesContext.responseComplete.
This Phase will process any Validations that are configured for UI Components. Consider the following code snippet,

Phase 4 : Update Model Values Phase

  • In this phase, JSF implementation will update the bean properties pointed at by an input component's value attribute.
  • Converters are invoked to parse string representations of various values to their proper primitive or object types. If the data cannot be converted to the types specified by the bean properties, the life cycle advances directly to the render response phase so that the page is re-rendered with errors displayed.
  • If any updateModels methods or any listeners called renderResponse on the current FacesContext instance, the JavaServer Faces implementation skips to the render response phase.
  • The difference between this phase and Apply Request Values - that phase moves values from client–side HTML form controls to server–side UI components; while in this phase the information moves from the UI components to the backing beans.
If the Application has reached this phase, then it is obvious that the user has entered syntactically valid values. The values that are stored in UI Components will be made to synchronize with the Model objects, which are usually Backing Beans.
Consider the following code snippet


<f:view>
 <h:form>
  
     <p>Enter your username:
         <h:inputText
             value='#{LoginBean.username}'
             id='usernameTxtField'
             required='true'/>
         <h:message for='usernameTxtField' />
     </p>
  
     <p>Enter your password:
         <h:inputSecret
             value='#{LoginBean.password}'
             id='passwordTxtField'
             required='true'/>
         <h:message for='passwordTxtField' />
     </p>
  
 <h:commandButton value='Login' action='loginUser'/>
  
 </h:form>
</f:view>

In the above code snippet, we defined two UI Components namely a text-field and a password field. The corresponding model object for this form is the LoginBean class. Since the LoginBean is treated as a Backing Bean, the application should have defined this in the Faces Configuration file as follows,


<managed-bean>
 <managed-bean-name>LoginBean</managed-bean-name>
 <managed-bean-class>
   com.gsms.web.login.LoginBean
 </managed-bean-class>
 <managed-bean-scope>request</managed-bean-scope>
</managed-bean>

affiliate_link

Phase 5 : Invoke Application Phase

  • During this phase, the JavaServer Faces implementation handles any application-level events, such as submitting a form or linking to another page.
    • Application level events handled
    • Application methods invoked
    • Navigation outcome calculated
  • If the view being processed was reconstructed from state information from a previous request and if a component has fired an event, these events are broadcast to interested listeners.
In this phase, all the listeners that are registered for the UI Components will be invoked and the listeners will usually contain the application specific logic. Note that, for all action components there always exists Default Action Listeners which when invoked will display the current page.

Consider the code snippet which defines an Action Listener for the Button click,


<h:commandButton value='Login' action='#{ActionListener.doSomeAction}'/>

Phase 6 : Render Response Phase

  • The values are transferred back to the UI components from the bean including any modifications that may have been made by the bean itself or by the controller.
  • JSF implementation delegates authority for rendering the page to the JSP container if the application is using JSP pages. If this is not an initial request, the components are already added to the tree so they needn't be added again. In either case, the components will render themselves as the JSP container traverses the tags in the page.
  • If the request is a postback and errors were encountered during the apply request values phase, process validations phase, or update model values phase, the original page is rendered during this phase. If the pages contain message or messages tags, any queued error messages are displayed on the page.
  • After the content of the view is rendered, the state of the response is saved so that subsequent requests can access it and it is available to the restore view phase.

This article provided an overview about the various phases that are involved in JSF Request Processing.

Please feel free to post comments or questions if you have any. Also, if you find that the article language is difficult to understand, then please provide a feedback so that we can do our best to make it simple.

0 comments