http://lipeng3252642.blog.163.com/blog/static/101626428200811532127925/
第一阶段:恢复视图.
? ? ? ? 仅仅重建组件树(视图). 由FacesServletr控制器进行管理的"用户请求"(内容,一般为JSP)",创建唯一视图ID(XXX.JSP). 如果是"回传",即视图存在,则直接使用.
第二阶段:应用请求值.
? ? ? ? 用来自客户端的最新数据(即,上次输入的存放在托管Bean的属性里的值(第四阶段:更新模型值);如果是首次请求,即为Faces- config.xml里初始化的值.)更新这些服务器端组件(绑定属性的组件调用getXxx方法,从托管Bean的属性里获取其值).
? ? ? ? 如果Manage Bean(托管Bean) 的scope 为Request,则每次"用户请求"都要初始化托管Bean(Faces-config.xml里的Bean进行初始化,按Manage-rule 进行设置属性,如果显示说明的话).更新组件值,调用getXxx,即绑定属性的组件检索其值.
? ? ? ? 如果托管Bean 已初始化,即scope=session并已"用户请求"过,则仅更新组件值,调用getXxx,即绑定属性的组件检索其值.
? ? ? ? 如果请求值为空,则直接返回到第六阶段:渲染响应.
第三阶段:验证请求值
? ? ? ? 进行验证请求.
第四阶段:更新模型值
? ? ? ? 调用setXxx方法,更新托管Bean的属性值.
第五阶段:调用应用
? ? ? ? 对队列里的事件进行调用.
第六阶段:渲染响应
? ? ? ? 在视图中显示所有组件(调用getXxx方法给组件赋值,然后绘制出来传给用户) .
现在我将用一个例子来说明JSF的生命周期。废话就不多说了,用实例来解释一下吧!
首先我们需要一个自定义的Listener. 实现PhaseListener接口。
package com.jsflifecycle.test;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;
public class MyPhaseListener implements PhaseListener
{
? public void afterPhase(PhaseEvent event)
? {
??? if(event.getPhaseId().equals(PhaseId.RESTORE_VIEW))
??? {
?????? System.out.println("after restore view: phase id - " + PhaseId.RESTORE_VIEW);
??? }
??? if(event.getPhaseId().equals(PhaseId.APPLY_REQUEST_VALUES))
??? {
????? System.out.println("after APPLY_REQUEST_VALUES: phase id - " + PhaseId.APPLY_REQUEST_VALUES);
??? }
??? if(event.getPhaseId().equals(PhaseId.PROCESS_VALIDATIONS))
??? {
????? System.out.println("after PROCESS_VALIDATIONS: phase id - " + PhaseId.PROCESS_VALIDATIONS);
??? }
??? if(event.getPhaseId().equals(PhaseId.UPDATE_MODEL_VALUES))
??? {
????? System.out.println("after UPDATE_MODEL_VALUES: phase id - " + PhaseId.UPDATE_MODEL_VALUES);
??? }
??? if(event.getPhaseId().equals(PhaseId.INVOKE_APPLICATION))
??? {
????? System.out.println("after INVOKE_APPLICATION: phase id - " + PhaseId.INVOKE_APPLICATION);
??? }
??? if(event.getPhaseId().equals(PhaseId.RENDER_RESPONSE))
??? {
????? System.out.println("after RENDER_RESPONSE: phase id - " + PhaseId.RENDER_RESPONSE);
??? }
? }
? public void beforePhase(PhaseEvent event)
? {
??? if(event.getPhaseId().equals(PhaseId.RESTORE_VIEW))
??? {
?????? System.out.println("before restore view: phase id - " + PhaseId.RESTORE_VIEW);
??? }
??? if(event.getPhaseId().equals(PhaseId.APPLY_REQUEST_VALUES))
??? {
????? System.out.println("before APPLY_REQUEST_VALUES: phase id - " + PhaseId.APPLY_REQUEST_VALUES);
??? }
??? if(event.getPhaseId().equals(PhaseId.PROCESS_VALIDATIONS))
??? {
????? System.out.println("before PROCESS_VALIDATIONS: phase id - " + PhaseId.PROCESS_VALIDATIONS);
??? }
??? if(event.getPhaseId().equals(PhaseId.UPDATE_MODEL_VALUES))
??? {
????? System.out.println("before UPDATE_MODEL_VALUES: phase id - " + PhaseId.UPDATE_MODEL_VALUES);
??? }
??? if(event.getPhaseId().equals(PhaseId.INVOKE_APPLICATION))
??? {
????? System.out.println("before INVOKE_APPLICATION: phase id - " + PhaseId.INVOKE_APPLICATION);
??? }
??? if(event.getPhaseId().equals(PhaseId.RENDER_RESPONSE))
??? {
????? System.out.println("before RENDER_RESPONSE: phase id - " + PhaseId.RENDER_RESPONSE);
??? }
? }
? public PhaseId getPhaseId()
? {
??? // TODO Auto-generated method stub
??? return PhaseId.ANY_PHASE;
? }
}
注意:getPhaseId()方法的返回值,这个监听器的作用很简单,就是为了显示信息。
当然还需要在faces-config.xml中进行配置:
??? <lifecycle>
??? ??? <phase-listener>
??? ??? ??? com.jsflifecycle.test.MyPhaseListener
??? ??? </phase-listener>
??? </lifecycle>
接下来,我们再准备一个自定义的Validator.和一个自定义的Convorter.他们分别实现Validator接口和Converter接口。
package com.jsflifecycle.test;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.ConverterException;
public class MyConverter implements Converter
{
? public Object getAsObject(FacesContext context, UIComponent component, String value)
????? throws ConverterException
? {
??? System.out.println("getAsObject :? value====>" + value);
???? if(value.equals("leap")){
??? ??? ?value="lipeng";
??? ??? ?System.out.println("************value********>" + value);
???? }
??? return value;
? }
? public String getAsString(FacesContext context, UIComponent component, Object value)
????? throws ConverterException
? {
??? System.out.println("getAsString : value====>" + value);
??? return (String)value;
? }
}
package com.jsflifecycle.test;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;
public class MyRequiredValidator implements Validator
{
? public void validate(FacesContext context, UIComponent component, Object value)
????? throws ValidatorException
? {
??? System.out.println("my validdator: component id=====>" + component.getId()
??????? + " value====>" + value);
??? String value1? = (String)value;
??? if(value1.equals("123")){
??? ??? value="456";
??? }
??? //throw new ValidatorException(new FacesMessage("my validator failed"));
? }
}
大家可以看到。这些代码的作用就是为了打印信息,以便我们可以跟踪生命周期的过程。当然不要忘记在faces-config.xml中配置上
<converter>
??? ??? <converter-id>myConverter</converter-id>
??? ??? <converter-class>
??? ??? ??? com.jsflifecycle.test.MyConverter
??? ??? </converter-class>
??? </converter>
??? <validator>
??? ??? <validator-id>myRequiredValidator</validator-id>
??? ??? <validator-class>
??? ??? ??? com.jsflifecycle.test.MyRequiredValidator
??? ??? </validator-class>
??? </validator>
当然了 还得一个 Backing Bean 来测试。
package com.jsflifecycle.test;
import javax.faces.event.PhaseId;
public class User {
private String name;
private String password;
public String login() {
??? ?System.out.println(" ==========login============= "+ name);
??? ?//setName("login");
??? return "";
}
public String getName() {
??? ?System.out.println(" =======getName============= "+ name);
??? return name;
}
public void setName(String name) {
??? ?System.out.println(" =======setName============= "+ name);
??? this.name = name;
}
public String getPassword() {
??? ?System.out.println(" =======getPassword============= "+ password);
??? return password;
}
public void setPassword(String password) {
??? ?System.out.println(" =======setPassword============= "+ password);
??? this.password = password;
}
}
把Backing Bean加入到faces-config.xml中配置上
<managed-bean>
??? ??? <managed-bean-name>user</managed-bean-name>
??? ??? <managed-bean-class>
??? ??? ??? com.jsflifecycle.test.User
??? ??? </managed-bean-class>
??? ??? <managed-bean-scope>session</managed-bean-scope>
??? ??? <!--? <managed-property>
??? ??? ??? <property-name>name</property-name>
??? ??? ??? <value>leap</value>
??? ??? </managed-property>
?????????? -->
??? </managed-bean>
最后来一个页面测试一下吧!
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<f:view>
??? <h:form id="form">
??? ??? <h:panelGrid columns="3" cellpadding="3" cellspacing="3"
??? ??? ??? headerClass="login-heading">
??? ??? ??? ??? <h:outputText value="userName" />
??? ??? ??? <h:inputText id="userName" value="#{user.name}" maxlength="30">
??? ??? ??? ??? <f:converter converterId="myConverter" />
??? ??? ??? ??? <f:validateLength maximum="30" minimum="3" />
??? ??? ??? </h:inputText>
??? ??? ??? <h:message for="userName" errorClass="errors" />
??? ??? ??? ??? <h:outputText value="password"/>
??? ??? ??? <h:inputSecret id="passwordInput"? value="#{user.password}" maxlength="20" size="20">
??? ??? ??? ??? <f:validator validatorId="myRequiredValidator" />
??? ??? ??? </h:inputSecret>
??? ??? ??? <h:message for="passwordInput" errorClass="errors" />
??? ??? ??? <h:commandButton action="#{user.login}" value="submit" />
??? ??? </h:panelGrid>
??? </h:form>
</f:view>
通过以上配置,查看一下打印的信息就很清楚的理解JSF的生命周期了。暂时现些到这吧得睡觉了。