JSF生命周期详解

我们知道JSF生命周期一共有6个phase.关于这六个phase的图表说明,很多参考资料上都有,我个人觉得JSF in action这本书上的图标说明比较直观,也比较好理解。现在我将用一个例子来说明JSF的生命周期。这个例子是JSF1.1环境下编写的。

为了方便理解:我先把这6个phase写到这里:

1.Restore view

2.Apply request values.

3.Process validations.

4.Update model values.

5.Invoke applications.

6.Render response.

为了演示具体的步骤,首先我们需要一个自定义的Listener. 实现PhaseListener接口。

package  com.achievo.jason.listener;

import  java.io.UnsupportedEncodingException;
import  java.nio.charset.Charset;

import  javax.faces.component.UIInput;
import  javax.faces.event.PhaseEvent;
import  javax.faces.event.PhaseId;
import  javax.faces.event.PhaseListener;
import  javax.servlet.http.HttpServletRequest;
import  javax.servlet.http.HttpServletResponse;

import  org.apache.commons.lang.CharSet;

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.achievo.jason.listener.MyPhaseListener </ phase-listener >
  
</ lifecycle >

接下来,我们再准备一个自定义的Validator.和一个自定义的Convorter.他们分别实现Validator接口和Converter接口。

package  com.achievo.jason.validator;

import  javax.faces.application.FacesMessage;
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);
    
//throw new ValidatorException(new FacesMessage("my validator failed"));
  }


}
package  com.achievo.jason.converter;

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);
    
return value;
  }



  
public String getAsString(FacesContext context, UIComponent component, Object value)
      
throws ConverterException
  
{
    System.out.println(
"getAsString : value====>" + value);
    
return (String)value;
  }


}

大家可以看到。这些代码的作用就是为了打印信息,以便我们可以跟踪生命周期的过程。当然不要忘记在faces-config.xml中配置上

   < converter >
    
< converter-id > myConverter </ converter-id >
    
< converter-class > com.achievo.jason.converter.MyConverter </ converter-class >
  
</ converter >
  
< validator >
    
< validator-id > myRequiredValidator </ validator-id >
    
< validator-class > com.achievo.jason.validator.MyRequiredValidator </ validator-class >
  
</ validator >

以上准备工作完成后,我们需要准备一个简单的登录页面,和一个简单的BackBean.就可以开始我们验证了。

< f:view >
      
< h:form  id ="form" >
      
< t:panelGrid  columns ="3"  cellpadding ="3"  cellspacing ="3"  headerClass ="login-heading" >
           
< h:outputLabel  for ="userNameInput" >
          
< t:outputText  value ="Name"   />
        
</ h:outputLabel >
        
< t:inputText  id ="userNameInput"  maxlength ="30"   >
          
< f:validateLength  maximum ="30"  minimum ="3"   />
        
</ t:inputText >
        
< h:message  for ="userNameInput"  errorClass ="errors"   />

        
< h:outputLabel  for ="passwordInput" >
          
< t:outputText  value ="Password"   />
        
</ h:outputLabel >
        
< t:inputSecret  id ="passwordInput"  maxlength ="20"  size ="20" >
          
< f:validator  validatorId ="myRequiredValidator"   />
        
</ t:inputSecret >
        
< h:message  for ="passwordInput"  errorClass ="errors"   />

         
< h:commandButton  action ="#{authentication.login}"  value ="submit" >
     
< t:panelGrid >
     
</ h:form >
</ f:view >

这里是一个代码片段,使用到了Tomahwark技术。读者可以把全部的<t:>开头的标签换成<h: >的标签就可以了。

最后:使用一个Back Bean.一个很简单的Bean就可以了。加上Name 和Password属性。加一个login方法。

返回字符串。在配置文件中,导航到一个显示页面。在现实页面中,用<h:outputText>标签显示信息就可以了

如:<h:outputText value="#{bean.name}" />.这部分比较简单。我就不详细写了。

到目前为止,我们整个代码已经写完了。读者可以把这些代码COPY自己环境里运行。然后查看打印出来的信息。

相信会对你理解生命周期有很大的帮助。在运行的过程中,你可以通过改变按钮的:immediate属性。和input输入域的immediate属性。得到不同的信息。

由于时间关系,今天写到这里。我只能下次来详细介绍上面代码运行显示的结果及其原因。不过读者现在已经可以自己运行代码来理解生命周期。

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值