JSF Lifecycle Diagram
APPLY_REQUEST_VALUES
ProcessEvents
ProcessDecodes
RESTORE_VIEW
BuildComp Tree
ParsePDL
ApplySaved State(Post Only)
HTTP POST / Partial Submit
PROCESS_VALIDATIONS
ProcessEvents
ProcessValidators
FacesRequest
HTTPGET
If immediate=“true” then Actions, Action Listeners, and Value Change Listeners fire here
<f:view><h:form><h:outputLabel /><h:inputText />
Facelet View Markup UIViewRoot
HtmlForm
HtmlOutputLabel
Component Tree
Value Change Listeners Fire
Here
ICESOFT TECHNOLOGIES INC. www.icefaces.org
Conversion/Validation Failure
UPDATE_MODEL_VALUES
ProcessUpdates
ProcessEvents
INVOKE_APPLICATION
ProcessApplication
ProcessEvents
RENDER_RESPONSE
ProcessRenderers
SaveComp State
Conversion/Validation Success
FacesResponse
Actions & Action Listeners fire
here
<h:inputText /><h:commandButton />
</h:form></f:view> HtmlCommandButton
HtmlInputText
JSF Lifecycle
• The framework defines a lifecycle that executes in distinct phases:– Restore View
– Apply Request Values
– Process Validations
– Update Model Values
ICESOFT TECHNOLOGIES INC. www.icefaces.org
– Update Model Values
– Invoke Application
– Render Response
JSF Lifecycle Phase: Restore View
RESTORE_VIEW
BuildComp Tree
ParsePDL
ApplySaved State(Post Only)
<f:view><h:form><h:outputLabel /><h:inputText />
Facelet View Markup UIViewRoot
HtmlForm
HtmlOutputLabel
Component Tree
ICESOFT TECHNOLOGIES INC. www.icefaces.org
• The Restore View phase restores an existing view from the previous request, or creates a new view for an initial request
• The resulting view is put into the current FacesContext
<h:inputText /><h:commandButton />
</h:form></f:view> HtmlCommandButton
HtmlInputText
JSF Lifecycle Diagram (HTTP GET)
RESTORE_VIEW
BuildComp Tree
ParsePDL
(GET Only)
FacesRequest
HTTPGET
<f:view><h:form><h:outputLabel /><h:inputText />
Facelet View Markup UIViewRoot
HtmlForm
HtmlOutputLabel
Component Tree
ICESOFT TECHNOLOGIES INC. www.icefaces.org
RENDER_RESPONSE
ProcessRenderers
SaveComp State
FacesResponse
<h:inputText /><h:commandButton />
</h:form></f:view> HtmlCommandButton
HtmlInputText
JSF Lifecycle Phase: Render Response
• The Render Response phase is responsible for– Invoking component renderers for the appropriate client device
– Sending a fully encoded response back to the client
– The response is typically HTML markup that is written to the HttpServletResponse OutputStream
Rendered HTML for Web Browser
ICESOFT TECHNOLOGIES INC. www.icefaces.org
RENDER_RESPONSE
ProcessRenderers
SaveComp State
<html id="document:html"><body id="document:body"><form id="form1">
<label for="firstName" /><input id="firstName" /><input type="submit" />
</form></body>
Rendered HTML for Web Browser
JSF Lifecycle Diagram (HTTP POST – Valid Values)
APPLY_REQUEST_VALUES
ProcessEvents
ProcessDecodes
RESTORE_VIEW
BuildComp Tree
ApplySaved State(POST Only)
HTTP POST / Partial Submit
PROCESS_VALIDATIONS
ProcessEvents
ProcessValidators
FacesRequest
UIViewRoot
HtmlForm
HtmlOutputLabel
Component Tree
ICESOFT TECHNOLOGIES INC. www.icefaces.org
UPDATE_MODEL_VALUES
ProcessUpdates
ProcessEvents
INVOKE_APPLICATION
ProcessApplication
ProcessEvents
RENDER_RESPONSE
ProcessRenderers
SaveComp State
Conversion/Validation Success
FacesResponse
HtmlCommandButton
HtmlInputText
JSF Lifecycle Phase: Apply Request Values
• The Apply Request Values phase is where submitted request parameters are mapped to their corresponding UIInput components
APPLY_REQUEST_VALUES
ProcessEvents
ProcessDecodes
UIViewRoot
HtmlForm
HtmlOutputLabel
Component Tree
RequestParameterValues
ICESOFT TECHNOLOGIES INC. www.icefaces.org
HtmlCommandButton
HtmlInputText
// Process decodes does something// kind of like this for each// EditableValueHolder:String firstName =
request.getParameter(“firstName”);UIInput.setSubmittedValue(firstName);
JSF Lifecycle Phase: Process Validations
• The Process Validations phase is where submitted values are processed by JSF converters and validators
PROCESS_VALIDATIONS
ProcessEvents
ProcessValidators
UIViewRoot
HtmlForm
HtmlOutputLabel
Component Tree
ICESOFT TECHNOLOGIES INC. www.icefaces.org
HtmlCommandButton
HtmlInputText
• If any component fails validation, then– The component’s valid property is set to false
– A FacesMessage is added to the FacesContext
// If validation passes:UIInput.setValid(true);
// Otherwise:UIInput.setValid(false);
JSF Lifecycle Phase: Update Model Values
• If conversion & validation passes, then the Update Model Values phase is reached
• If EL value bindings were specified on UIInput components, then those component values are set in the model
• For example, the following EL value binding:
ICESOFT TECHNOLOGIES INC. www.icefaces.org
<h:inputText value=“#{MyBean.firstName}”/>
… will cause the MyBean.setFirstName()method to be called and will pass it the result of HtmlInputText.getValue()
UPDATE_MODEL_VALUES
ProcessUpdates
ProcessEvents
Conversion/Validation Success
JSF Lifecycle Diagram (HTTP POST – Invalid Values)
APPLY_REQUEST_VALUES
ProcessEvents
ProcessDecodes
RESTORE_VIEW
BuildComp Tree
ApplySaved State(POST Only)
HTTP POST / Partial Submit
PROCESS_VALIDATIONS
ProcessEvents
ProcessValidators
FacesRequest
UIViewRoot
HtmlForm
HtmlOutputLabel
Component Tree
ICESOFT TECHNOLOGIES INC. www.icefaces.org
UPDATE_MODEL_VALUES
ProcessUpdates
ProcessEvents
INVOKE_APPLICATION
ProcessApplication
ProcessEvents
RENDER_RESPONSE
ProcessRenderers
SaveComp State
FacesResponse
HtmlCommandButton
HtmlInputText
Conversion/Validation Failure
JSF Lifecycle Phase: Invoke Application
• The Invoke Application phase is responsible for reacting to the submitted values by invoking methods in managed-beans that perform some kind of action
• ActionListener methods are called first, then Actions
• Markup Examples:
ICESOFT TECHNOLOGIES INC. www.icefaces.org
<h:commandButtonactionListener=
“#{MyBean.checkAll}” />
<h:commandButton action=“#{MyBean.submit}” />
INVOKE_APPLICATION
ProcessApplication
ProcessEvents
JSF Lifecycle Diagram: Events
APPLY_REQUEST_VALUES
ProcessEvents
ProcessDecodes
RESTORE_VIEW
BuildComp Tree
ParsePDL
ApplySaved State(Post Only)
HTTP POST / Partial Submit
PROCESS_VALIDATIONS
ProcessEvents
ProcessValidators
FacesRequest
If immediate=“true” then Actions, Action Listeners, and Value Change Listeners fire here
Value Change Listeners Fire
Here
ICESOFT TECHNOLOGIES INC. www.icefaces.org
UPDATE_MODEL_VALUES
ProcessUpdates
ProcessEvents
INVOKE_APPLICATION
ProcessApplication
ProcessEvents
RENDER_RESPONSE
ProcessRenderers
SaveComp State
Conversion/Validation Success
FacesResponse
Actions & Action Listeners fire
here
In JSF 1.x, there are no events that fire here
Phase Listeners
• PhaseListeners can be extremely helpful for application customization, optimization, and debugging
• Must implement the following interface:– javax.faces.application.PhaseListener
• Use javax.faces.event.PhaseId to specify which phase to listen for
ICESOFT TECHNOLOGIES INC. www.icefaces.org
• Register implementing class in the faces-config.xml
<lifecycle><phase-listener>training.jobApplication.lifecycle.LoggingPhaseListener
</phase-listener></lifecycle>
Exercise: Overview
• The goal of this exercise is to add a PhaseListener to the jobApplication project
• The PhaseListener will simply log the Phase ID to the Tomcat console log, before and after phases execute
ICESOFT TECHNOLOGIES INC. www.icefaces.org
Step 1: Create LoggingPhaseListener.java
LoggingPhaseListener
ICESOFT TECHNOLOGIES INC. www.icefaces.org
Step 2: Paste Java Code
• For the sake of convenience, open the LoggingPhaseListener.java file in the Eclipse Java Editor and paste the following code as the body of the LoggingPhaseListener class:
private static final long serialVersionUID = 5805974145765679633L;
private static final Log log = LogFactory.getLog(LoggingPhaseListener.class);
public void afterPhase(PhaseEvent phaseEvent) {
ICESOFT TECHNOLOGIES INC. www.icefaces.org
if (log.isInfoEnabled()) {log.info("AFTER PHASE: " + phaseEvent.getPhaseId().toString());
}}public void beforePhase(PhaseEvent phaseEvent) {if (log.isInfoEnabled()) {
log.info("BEFORE PHASE: " + phaseEvent.getPhaseId().toString());}
}public PhaseId getPhaseId() {return PhaseId.ANY_PHASE;
}
Step 3: Paste XML
• Paste the following XML fragment into the faces-config.xml file:<lifecycle>
<phase-listener>
training.jobapplication.lifecycle.LoggingPhaseListener
</phase-listener>
ICESOFT TECHNOLOGIES INC. www.icefaces.org
</lifecycle>
• This fragment will cause the LoggingPhaseListener class to be registered as a PhaseListener when the JSF framework initializes
Step 4: Configure Log4J
• Create a file named log4j.properties in the src folder
• Paste the following into the file:log4j.rootLogger=ERROR, A1
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%d{ABSOLUTE} %-5p
ICESOFT TECHNOLOGIES INC. www.icefaces.org
log4j.appender.A1.layout.ConversionPattern=%d{ABSOLUTE} %-5p [%c{1}:%L] %m%n
log4j.logger.training.jobapplication.lifecycle.LoggingPhaseListener=DEBUG
Step 5: Copy Log4J JAR
• Find the web/WEB-INF/lib/log4j.jar file in the solution
• Copy the log4j.jar file to the WEB-INF/lib folder of your project
ICESOFT TECHNOLOGIES INC. www.icefaces.org
Step 6: Run Application
• Re-publish/Re-deploy the jobApplication project to Tomcat
• Start Firefox and visit the following URL:– http://localhost:8080/jobApplication/applicantForm.iface
ICESOFT TECHNOLOGIES INC. www.icefaces.org
Step 6: Examine Tomcat Console Log
• Examine the Tomcat console log for PhaseListener output
• Note that only RESTORE_VIEW and RENDER_RESPONSE took place
ICESOFT TECHNOLOGIES INC. www.icefaces.org
• Type a value for the First Name field and click submit
• Examine Tomcat console log again for more phase output
JSF Form Validation
• JSF provides two ways of performing form validation:
– Individual field validation
– Interdependent field validation
• Individual field validation is accomplished in several ways:
– Adding a required attribute to a tag
– Adding a validator attribute to a tag
– Adding a validator component as a child of a tag
ICESOFT TECHNOLOGIES INC. www.icefaces.org
– Adding a validator component as a child of a tag
– The h:message component is used to show validation errors in context, next to the offending field
• Interdependent field validation is performed during actions
– The h:messages component is used to show interdependent field validation error messages
Exercise: Overview
• The goal of this exercise is to add form validation to the jobApplication project
ICESOFT TECHNOLOGIES INC. www.icefaces.org
Step 1: Add required attribute
• In order to make the First Name field be a required field for validation purposes, the required attribute needs to be set
• In the applicantForm.xhtml file, replace this:<h:inputText id="firstName" value="#{applicant.firstName}" />
• With this:<h:inputText id="firstName" required="true" value="#{applicant.firstName}" />
• When the user clicks the Submit Application button, the Process
ICESOFT TECHNOLOGIES INC. www.icefaces.org
• When the user clicks the Submit Application button, the Process Validations phase will fail and the corresponding h:message component will show the error message
– Note that the value of the for attribute of the h:message component must be the same as the id attribute of the h:inputText component,i.e.: <h:message for="firstName" />
Step 2: Add Last Name Field
• Paste the following into applicantForm.xhtml below the First Name table row:
<tr>
<td><h:outputLabel for="lastName" value="Last Name:" /></td>
<td><h:inputText id="lastName" required="true" value="#{applicant.lastName}" /></td>
<td><h:message for="lastName" /></td>
</tr>
ICESOFT TECHNOLOGIES INC. www.icefaces.org
• Add a getter/setter to the Applicant.java class for the lastName property
Step 3: Add Travel Percentage Field
• Paste the following into applicantForm.xhtml below the Last Name table row:
<tr><td><h:outputLabel for="travelPercentage" value="Travel
Percentage:" /></td><td><h:inputText id="travelPercentage" required="true"
value="#{applicant.travelPercentage}"><f:validateLongRange minimum=“0" maximum="100" />
</h:inputText></td>
ICESOFT TECHNOLOGIES INC. www.icefaces.org
<td><h:message for="travelPercentage" /></td></tr>
• Note that the f:validateLongRange component is used to constrain the value between 0 and 100
• Add a getter/setter to the Application.java class for the travelPercentage property as a String (not an Integer)
Step 4: Add Log Output
• Add the following code to the top of the ApplicantForm.submit() method:
System.out.println("submit() firstName=" + this.applicant.getFirstName());
System.out.println("submit() lastName=" + this.applicant.getLastName());
System.out.println("submit() travelPercentage=" + this.applicant.getTravelPercentage());
ICESOFT TECHNOLOGIES INC. www.icefaces.org
this.applicant.getTravelPercentage());
Step 5: Interdependent Validation
• Add the following code inside the firstName=“John” condition of the ApplicantForm.submit() method:
if (this.applicant.getLastName().equals("Doe")) {
String msg = "John Doe already works for us";
FacesMessage facesMessage = new FacesMessage(FacesMessage.SEVERITY_ERROR, msg, msg);
FacesContext facesContext = FacesContext.getCurrentInstance();
ICESOFT TECHNOLOGIES INC. www.icefaces.org
String clientId = null; // this is a global message
facesContext.addMessage(clientId, facesMessage);
return "retry";
}
• This will cause an interdependent field validation error when the user enters “John” as the First Name and “Doe” as the Last Name
Step 6: Add Global Messages Component
• Paste the following into applicantForm.xhtml after the h:form component:
<h:messages globalOnly="true" />
ICESOFT TECHNOLOGIES INC. www.icefaces.org
Step 7: Run Application
• Run the appication in the web browser
• Enter the following and click Submit Application:– First Name: John
– Last Name: (leave it blank)– Travel Percentage: 101
• You should see an in-line error messages to the right of the Last Name and Travel Percentage files
• Enter the following and click Submit Application:– First Name: John
– Last Name: Doe
– Travel Percentage: 50abcd
ICESOFT TECHNOLOGIES INC. www.icefaces.org
– Travel Percentage: 50abcd
• You should see an in-line error message next to the Travel Percentage field
• Enter the following and click Submit Application:– First Name: John
– Last Name: Doe
– Travel Percentage: 50
• Validation should fail with the global error message “John Doe already works for us”
• Enter a different last name
• Validation should pass
JSF Converters
• Converters exist to coerce input to model bean properties of a type other than String, and to format output of model bean properties
• Resources:– J2EE 1.4 Tutorial: Using the Standard Converters
– ICEfaces Tutorial: Using JSF converters with ICEfaces components
ICESOFT TECHNOLOGIES INC. www.icefaces.org
– ICEfaces Tutorial: Using JSF converters with ICEfaces components
– John Deringer’s Article on JSF Validators/Converters
Implicit Conversion
• JSF can implicitly convert a component’s value to a model bean property that is of a type other than String
• In the previous exercise, you may have noticed that the travelPercentage JavaBean property was a String– Note that in the next exercise, we will change the travelPercentage
to an Integer type
ICESOFT TECHNOLOGIES INC. www.icefaces.org
to an Integer type
Explicit Conversion
• If you want your markup to be more precise with respect to conversion, you can specify a explicit conversion of a component’s value
• There are two ways to specify a converter:– Using the converter attribute, for example:
<h:inputText value="#{modelBean.age}"
ICESOFT TECHNOLOGIES INC. www.icefaces.org
<h:inputText value="#{modelBean.age}" converter="javax.faces.Integer" />
– Using the f:converter component, for example:
<h:inputText value="#{modelBean.age}">
<f:converter converterId="javax.faces.Integer" />
</h:inputText>
Standard Converters
• The JSF framework comes with several standard converters
• The f:converterNumber component will convert a component’s value to a concrete subclass of java.lang.Number and has several attributes that control formatting, for example:<f:convertNumber type="currency" />
ICESOFT TECHNOLOGIES INC. www.icefaces.org
• The f:convertDateTime component exists to convert a component’s value to java.util.Date, for example:<f:convertDateTime pattern= "MM/dd/yyyy" />
• See java.text.SimpleDateFormat for a listing of date format patterns
Custom Converters
• In addition to the standard converters, JSF allows you to define your own converters, for example:<my:ssnConverter />
• Custom converters must be registered in faces-config.xml in a <converter> element, and must have a corresponding Java class that implements javax.faces.convert.Converter
ICESOFT TECHNOLOGIES INC. www.icefaces.org
Java class that implements javax.faces.convert.Converter
Exercise: Overview
• The goal of this exercise is to:– Change the data type of travelPercentage from String to Integer in
order to let implicit conversion take place
– Add a Date of Birth field and use a JSF converter to convert the input to java.util.Date
ICESOFT TECHNOLOGIES INC. www.icefaces.org
Step 1: Setup Implicit Integer-Based Conversion
• In the Applicant.java file, change the datatype of the travelPercentage field from String to Integer– The getter/setter methods have to be changed as well
ICESOFT TECHNOLOGIES INC. www.icefaces.org
Step 2: Add Date of Birth Property
• In the Applicant.java file, paste the following:
private Date dateOfBirth;
public Date getDateOfBirth() {
return dateOfBirth;
}
ICESOFT TECHNOLOGIES INC. www.icefaces.org
public void setDateOfBirth(Date dateOfBirth) {
this.dateOfBirth = dateOfBirth;
}
Step 3: Add Date of Birth Markup
• In the applicantForm.xhtml file, add the following table row below the Travel Percentage row:
<tr>
<td><h:outputLabel for="dateOfBirth" value="Date of Birth:" /></td>
<td><h:inputText id="dateOfBirth" required="true" value="#{applicant.dateOfBirth}">
<f:convertDateTime pattern="MM/dd/yyyy" />
ICESOFT TECHNOLOGIES INC. www.icefaces.org
<f:convertDateTime pattern="MM/dd/yyyy" />
</h:inputText></td>
<td><h:message for="dateOfBirth" /></td>
</tr>
Step 4: Run Application
• Re-publish/deploy the jobApplication project
• Run the application in the web browser
• Enter the following and click Submit Application:– First Name: John
– Last Name: Doe
– Travel Percentage: 50
ICESOFT TECHNOLOGIES INC. www.icefaces.org
– Travel Percentage: 50
– Date of Birth: 1/1/1970
• Notice that the Date of Birth has a leading zero, since the datePattern was specified as MM/dd/yyyy
Top Related