`
xiang37
  • 浏览: 433406 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

JSF生命周期

阅读更多
作为下一代WEB框架标准,JSF在视图颗粒度与生命周期规划方面都做的不错。


    对于生命周期的执行,所有的操作都归结到Lifecycle这个接口。接口包括了两个主要的方法:
    public abstract void execute(FacesContext context) throws FacesException和public abstract void render(FacesContext context) throws FacesException;前者是用来执行各个生命周期的阶段,也就是除了render之外的其他五个阶段,而且是按照相应的顺序执行。而 render,是执行最后一个阶段,展示页面。可能有人不太理解,为什么不把两个方法合并成一个方法,刚开始,我也是这么认为。既然已经定义了相应的Phase,何必要把最后的render过程分离出来。看了sun 的RI实现类,发现在render之前需要进行context.getResponseComplete()判断,可能规范中,认为render是必须要执行的阶段,其他的阶段可以跳过,所以分离了相应的方法,同时在执行前,为了避免重复输出,需要对render过程进行特殊的处理.

    周期阶段如下图所示:




   关于六个阶段的说明:

1  RESTORE_VIEW:查找原有的view ,恢复原有的状态,如果没有,则调用ViewHandler.createView,如果为post操作,则按照顺序执行各个阶段。
否则执行RENDER_RESPONSE阶段。
2 APPLY_REQUEST_VALUES:读取客户端参数,处理各个组件的processDecodes方法,内部调用decode方法,由Renderer执行decode方法
3 PROCESS_VALIDATIONS:执行组件的processValidators方法,对于UIInput执行validate方法,用于绑定值,调用convert,和validate
4  UPDATE_MODEL_VALUES:执行组件的processUpdates方法,对于UIViewRoot,执行broadcastEvents和notifyPhaseListeners
所有的UIInput,执行updateModel方法。
5  INVOKE_APPLICATION:调用UIViewRoot.processApplication方法。这一过程主要读取相应的action配置,如果存在action,则调用 action,也就是调用应用逻辑。在执行完相应的逻辑后,查询action是否返回值,如果有,由navigationHandler去读取下一个 view id。
6  RENDER_RESPONSE:展示view,调用ViewHandler.renderView,展示view。

每 个阶段定义定义的都比较清晰,有一点需要注意的是,在处理请求时,并不一定会执行每个阶段,可能其中会直接跳到最后的render response阶段。举例来说,如果validator时,存在错误信息,那么就会直接到render response阶段,而下一个阶段不会执行。

    对应不同的解析阶段,可以对应不同的解析监听,示例程序如下:

 
  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}" />.这部分比较简单。

注:本文参照了帖子http://www.iteye.com/topic/76988和http://blog.csdn.net/woai_432/archive/2008/05/11/aspx

分享到:
评论

相关推荐

    JSF生命周期总结JSF生命周期总结

    JSF生命周期总结JSF生命周期总结JSF生命周期总结JSF生命周期总结JSF生命周期总结JSF生命周期总结

    JSF 生命周期 实例详解

    JSF生命周期主要分为6个阶段:恢复视图、应用请求值、过程验证、更新模型值、调用应用逻辑和渲染响应。这些阶段构成了一个处理HTTP请求的连贯流程,使得开发者能够更好地组织和管理Web应用程序的各个组件。 1. **...

    JSF生命周期及组件开发

    ### JSF生命周期及组件开发详解 #### 一、JSF生命周期概述 JavaServer Faces (JSF) 是一种基于Java EE标准的服务器端组件框架,用于简化企业级Web应用程序的开发。JSF提供了一种声明式的组件化编程模型,使得...

    jsf生命周期学习文档

    【JSF生命周期详解】 JSF(JavaServer Faces)是一种基于Java的Web应用程序开发框架,它以组件为中心,简化了服务器端应用程序的用户界面构建。JSF的核心组成部分包括预定义的UI组件、事件驱动的编程模型以及支持第...

    JSF生命周期及组件开发P

    JSF生命周期是指从客户端发起请求到服务器响应的过程,它包括了五个主要阶段:恢复视图、应用请求的值、处理验证、更新模型值、调用程序和处理事件以及进行响应。 1. **恢复视图阶段**: 在这个阶段,JSF框架通过...

    JSF生命周期的事件处理

    ### JSF生命周期的事件处理 JavaServer Faces(简称JSF)是Java平台提供的一种用于构建企业级Web应用程序的标准框架。JSF通过定义一套简洁而强大的API来帮助开发者更轻松地开发用户界面。其中,JSF的生命周期管理...

    JSF生命周期实例,还要多长啊

    JSF生命周期是理解其工作原理的关键,它包括六个主要阶段:恢复视图、应用请求值、处理验证、更新模型值、调用应用逻辑和渲染响应。在这些阶段中,每个阶段都有特定的任务,确保用户输入被正确处理并更新到服务器端...

    jsf生命周期和一部分标签介绍

    JSF生命周期是理解其工作原理的关键,该过程分为六个阶段:恢复视图、应用请求值、处理验证、更新模型值、调用应用事件和渲染响应。 1. **恢复视图阶段(Restore View)**: 在这个阶段,JSF框架试图找到与当前...

    JSF 应用程序的生命周期.rar

    总的来说,JSF生命周期提供了一种有序的方式来处理Web应用程序的用户交互,简化了开发流程,同时也提供了强大的功能和灵活性。开发者可以根据需求利用JSF的生命周期特性,优化应用程序的性能和用户体验。

    (转自IBM)JavaServer Faces 1.2 入门,第 2 部分 JSF生命周期、转换、检

    博文链接:https://kencool.iteye.com/blog/178031

    jsf的必读教科书

    本篇文章将基于《JavaServer Faces Specification Version 2.2》文档的关键信息,深入解读JSF 2.2的核心概念、生命周期以及一些关键特性。 #### 二、JSF 2.2 版本概述 JSF 2.2 版本是由Oracle公司发布的一个重要...

    jsf例子\监听器 例子

    4. **事件处理与JSF生命周期的关系**: 在JSF生命周期的不同阶段,事件被处理并传播给已注册的监听器。监听器可以决定是否中断或继续生命周期。例如,如果监听器在处理值变化事件时发现错误,它可以调用`...

    jsf1.2 source code

    API提供了如`UIComponent`、`FacesContext`、`PhaseListener`等核心组件和上下文对象,它们构成了JSF生命周期的基础。开发者可以使用这些接口来创建自定义组件,实现监听器,以及处理请求和响应。 ### 2. `jsf-ri` ...

    JSF基础教程 简体中文

    要开发 JSF 组件,您需要更深入了解 JSF 的一些处理细节,包括了 JSF 生命周期以及 JSF 框架。 o JSF 生命周期 o 概述自订组件 简单实例 在不考虑组件有子组件的情况下,这边以实际的一个例子来说明开发组件的过程...

    精通JSF中文教程精通JSF中文教程

    通过深入学习本教程,您将掌握JSF的基础知识,包括组件使用、Managed Beans的创建、EL表达式的运用以及JSF生命周期的理解。结合实际项目实践,您将能够熟练运用JSF来构建高效、稳定的Web应用程序。

    jsf demo 各种实例

    **JSF生命周期** 包含6个主要阶段:恢复视图、应用请求值、处理验证、更新模型值、调用应用业务逻辑和呈现响应。在每个阶段,JSF处理用户的输入、执行验证、更新模型并生成响应。 **JSF示例** 在"jsfdemo"这个...

    jsf入门资料,总共6章

    要开发自定义组件,你需要熟悉JSF生命周期中的各个阶段,并理解每个阶段的作用。下面是一些关键步骤: - **理解组件生命周期**:在开发组件之前,确保你完全理解JSF的生命周期。这对于正确地处理组件状态至关重要。...

    JSF教程(有关jsf实例的操作步骤)

    JSF生命周期** JSF组件经历了六步生命周期:恢复视图、应用请求值、处理验证、更新模型值、调用应用程序和呈现响应。每一步都提供了插入自定义行为的机会,如验证用户输入或执行业务逻辑。 **4. Facelets** ...

Global site tag (gtag.js) - Google Analytics