It is extremely important to JSF programmers to know how JSF requests are processed behind the scenes. Each JSF request, from its submission to completion, known as life-cycle, is processed by a series of phases, known as life-cycle phases [Figure 28.1:] named as follows:
- Restore View
- Apply Request Values
- Process Validations
- Update Model Values
- Invoke Application
- Render Response
During these phases, a JSF engine performs all necessary jobs such as
- Validates incoming data, converts them to server-side data types and generates error messages when they fail.
- Updates model objects with incoming data.
- Invokes server-side application to perform tasks further.
- Saves the request state to be provided to the subsequent requests.
- Generates a response back to the client, including the “follow-up” requests made by the browser for images, scripts, and style sheets.
The following sections give a short description of these phases.
1. Restore View
When a JSF page is requested, usually by clicking a link or a button component, the request processing life-cycle begins with this phase. Note that for each UI presented in a client, a tree of UI components, called faces view is maintained in the server side. In fact the client UI is obtained (rendered) from this view.
The task of this phase is to build a new empty view when a request is made for the first time. The life-cycle then advances to the Render Response phase, during which the view is populated with the components corresponding to elements in the page. For subsequent requests, it restores the view (created previously for the first request).
The view also contains validators, converters, event handlers (if any), etc. The tree is saved to be used by other phases in a FacesContext type container object which holds all the information
required to process current request. All the components, event handlers, converters and validators have the access to this container to extract necessary information.
2. Apply Request Values
This is the next phase in the request processing life-cycle and is executed only for a postback request that refers to some previously requested page. A postback request is usually sent from an already rendered JSF page by submitting a form containing some elements. In this phase, the individual components of restored view tree is updated with the values of form elements. More specifically, the processDecodes() method on all the components is called. The process of extracting name-value pair and applying matching incoming value to the UI component is known as decoding.
Equivalently, the following happens for each uiinput component in the view tree:
input.setSubmittedValue(request.getParameter(input.getClientId()));
Here input is a UIInput type component and request is HttpServletRequest. Note that new values are applied to those components that are capable of holding a value. Components (such as text fields, labels) that implement javax.faces.component.ValueHolder interface has an attribute value and can hold a value. Components that implement the EditableValueHolder interface, can hold values that can be edited by the user. If the immediate attribute of these editable components is set to true, then converters, validators and value change listeners (if any attached) will also be invoked in this phase. However, failing of any conversions or validations transfers the control directly to the Render Response phase.
Components (such as buttons, links etc.) that implement ActionSource interface may generate action events and hence are called action components. Action events (if any) associated with these components are queued in this phase. If immediate attribute of the action components are set to true, then action events are fired in this phase. Otherwise, they are fired in the Invoke Application phase.
Note that not all the phases occur in all the cases in order. A call to renderResponse() method at any time, on the current FacesContext stops the current processing and skips the control directly to the Render Response phase.
FacesContext.getCurrentInstance().renderResponse();
Note that this phase does not yet update the business objects that compose the model. It updates only the UI components with the new data.
3. Process Validations
This phase invokes (if it was not already done in the previous phase) convertors and validators (if any) attached to the components to convert and validate the data captured in the previous phase.
More specifically, the processValidators() method is invoked on all the components of view tree. The processValidators() method, in turn, calls the associated converters and validators. Any conversion/validation error at this stage causes the control to jump directly to the Render Response phase skipping Update Model Values and Invoke Application phases.
Validators and convertors may be attached to the components in many ways. The following attached a validator to a text component by setting its required attribute to true.
<h:inputText id=”login” required=”true” />
The task of the validator is to check if the value of the text component is empty or not. A detailed discussion on how to attach convertors and validators can be found later in this chapter.
Event listeners for editable components are also called (if not already called in Apply Request Values phase).
4. Update Model Values
If the process validation phase is passed successfully without any validation error, the model objects are updated with the validated data from the request. However, JSF runtime will update only the bean properties pointed at by an input component’s value attribute. Also, if the data type of a property is not a String or a Java primitive, data conversion occurs in this phase. If there is any error, similar thing happens as validation errors i.e. the life cycle advances directly to the render response phase so that the page is re-rendered with errors displayed. Any event listener (such as phase listener) registered to this phase is also notified with the event object.
5. Invoke Application
Event listeners for action components, such as command buttons, links are called (if not already called in Apply Request Values phase i.e. immediate attribute was set to false).
6. Render Response
In this phase, the entire component tree is rendered and sent to the client. After the content of the view is rendered, the response state is saved so that subsequent requests can access it and it is available to the restore view phase.
Source: Uttam Kumar Roy (2015), Advanced Java programming, Oxford University Press.