`
zhangdaiscott
  • 浏览: 417193 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
8fb25857-16b4-3681-ab5e-e319f45c42a8
Jeecg快速开发平台
浏览量:0
文章分类
社区版块
存档分类

JSF请求处理过程(二)请求处理过程总览(FacesServlet#service)

 
阅读更多

JSF请求处理过程(二)请求处理过程总览(FacesServlet#service)
更新日期:2009-07-20 点击:这总览,很明显是看FacesServlet的service方法。在FacesServlet的初始化过程中,构造出了全局的FacesContextFactory对象和LifeCycle对象。可以把FacesContextFactory看做是一个“请求包装工厂”,于是很明显,每当一个请求到达FacesServlet的时候,第一步便是拿着请求,到包装工厂里面包装一下,而包装的结果就是一个FacesContext。代码如下:
1 FacesContext context = facesContextFactory.getFacesContext(servletConfig.getServletContext(), request, response, lifecycle);
在包装过程中,实际上是创建了一个com.sun.faces.context.FacesContextImpl对象,FacesContextImpl类继承了jsf-api项目中的javax.faces.context.FacesContext。FacesContextImpl的构造方法的第一个参数是一个叫做ExternalContext的接口的实现,查看其源代码,可以看到ExternalContextImpl类耦合了Servlet API,而FacesContextImpl与Servlet API无关。实际上,在这里,做到了JSF可以不仅仅使用在Servlet环境中,正如ExternalContext接口的注释中所说,在Servlet环境中使用JSF和在Portlet环境中使用JSF的不同,实际上就是使用了不同的ExternalContext。在FacesContextFactoryImpl中构造FacesContextImpl的代码如下:

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

1 FacesContext ctx = new FacesContextImpl(new ExternalContextImpl((ServletContext) sc,(ServletRequest) request,(ServletResponse) response),lifecycle);
FacesContextImpl的构造方法中,还做了另外一件事情,就是根据配置确定了RenderKitFactory,显然不同的RenderKitFactory可以产生不同的RenderKit,而不同RenderKit对象是针对不同客户端的,所以对于浏览器、移动设备等等,会有不同的RenderKit。FacesContextImpl的构造方法中代码如下:

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

1 this.externalContext = ec;
2 setCurrentInstance(this);
3 this.rkFactory = (RenderKitFactory)FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
在代码中我们经常使用FacesContext.getCurrentInstance()这个静态方法来获取与当前请求对应的FacesContext对象,实际上是在FacesContext类里面有一个静态的ThreadLocal对象用来存放了当前请求线程对应的FacesContext对象,于是上面的代码中setCurrentInstance(this)就是把当前构造出来的这个FacesContext对象放到了ThreadLocal里面。
FacesContext创建出来以后,正如上面所说,要让他经过LifeCycle这个“Filter Chain”的逐步处理了。那么,Filter Chain里面放的是一个一个Filter,那么LifeCycle这个Chain里面放的是什么呢?答案是Phases。
FacesServlet让FaceContext通过LifeCycle的处理,分成了两个部分。一个部分是调用LifeCycle的execute方法,执行逻辑,第二个部分是调用LifeCycle的render方法,呈现响应。FacesServlet.service中代码如下:

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

1 lifecycle.execute(context);
2 lifecycle.render(context);
在LifeCycleImpl这个实现中,存放了一个Phase对象的数组,存放了7个Phase。其中第一个是null,然后依次是视图重建、应用请求值、验证、更新模型值、执行应用程序、呈现响应。在execute方法中,调用了从视图重建开始到执行应用程序为止的5个Phase,而在render方法中,调用了最后一个Phase,也就是呈现响应。在LifeCycleImpl类中,代码如下:

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

//The Phase instance for the render() method
private Phase response = new RenderResponsePhase();

// The set of Phase instances that are executed by the execute() method
// in order by the ordinal property of each phase
private Phase[] phases = {
null, // ANY_PHASE placeholder, not a real Phase
new RestoreViewPhase(),
new ApplyRequestValuesPhase(),
new ProcessValidationsPhase(),
new UpdateModelValuesPhase(),
new InvokeApplicationPhase(),
response
};
在Servlet Filter中,可以由每一个Filter来决定是否要调用下一个Filter,从而决定是否让请求继续通过Filter Chains中的后续Filter,是链式调用的过程。而在LifeCycle的execute方法中,是用一个for循环顺序执行几个Phase。在每一个Phase执行完之后,都会检查FaceContext对象中是否设置了停止后续处理直接呈现响应的标志(renderResponse)或者已经完成了响应无需后续处理也不需要经过呈现响应阶段了(responseComplete),如果标志为true,那么就不再执行后续Phase。
LifeCycleImpl的execute方法主要代码如下:

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

1 for (int i = 1, len = phases.length -1 ; i < len; i++) { // Skip ANY_PHASE placeholder
2
3 if (context.getRenderResponse() ||
4 context.getResponseComplete()) {
5 break;
6 }
7
8 phases[i].doPhase(context, this, listeners.listIterator());
9
10 }
在LifeCycle的render方法中,也会检查FacesContext的responseComplete状态,如果为true,那么就不再执行render Phase。于是我们此刻知道了在我们自己所写的一些代码或者JSF库里面的一些代码中,调用FacesContext的responseComplete方法和renderResponse得作用原理。render方法主要代码如下:


Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

1 if (!context.getResponseComplete()) {
2 response.doPhase(context, this,listeners.listIterator());
3 }
另外注意,Phase这个概念、接口,以及几个实现,都是jsf-ri项目中的,而在jsf-api中不存在Phase这个概念。所以,LifeCycle是JSF标准的内容,而通过几个Phase来处理请求这种实现是sun的参考实现的做法。
最后,可以看到对于每一个phase都调用了doPhase方法,同时把LifeCycle和FacesContext当做参数传入了。值得注意的是,所谓的phaseListener,也传入了phase的doPhase方法中,由此大约能够想明白这个“阶段监听器”的道理了。

分享到:
评论

相关推荐

    JSF请求处理生命周期图

    JSF请求处理生命周期图

    jsf+jpa+spring整合过程

    用于整合jsf+jpa+spring,绝对详细可靠

    JavaServer Faces 2.0完全参考手册(JSF2.0中文版) 1/2

    《JavaServer Faces 2.0完全参考手册》对所有jsf功能都进行了解释,包括请求处理生命周期、托管bean、页面导航、组件开发、ajax、验证器、国际化和安全。贯穿全书的专家组意见提供了关于jsf设计的内部信息。 推荐...

    jsf分页 jsf分页 jsf分页

    jsf 分页 jsf 分页 jsf 分页 jsf 分页

    jsf实例jsf实例 JSF学习 JSF jar包 JSF

    jsf实例 JSF学习 JSF jar包 JSF jsf实例 JSF学习 JSF jar包 JSFjsf实例 JSF学习 JSF jar包 JSF jsf实例 JSF学习 JSF jar包 JSF

    JSF入门级教程

    *FacesServlet*:FacesServlet是一个核心的Servlet,负责处理JSF请求和响应。 *NavigationHandler*:NavigationHandler是一个抽象类,负责处理页面之间的导航关系。 1.4 导航规则设置 JSF框架提供了一个可配置的...

    JSF 详解

    JSF提供了一种额外的类似Swing的,事件处理的方式来处理用户的输入事件。JSF提供了两种事件类型,ActionEvent,用于处理命令和ValueChangeEvent,用于处理数据更改。 代码示例: ```java package nick; public ...

    第8章 JSF事件处理(熊)课件及示例程序

    第8章 JSF事件处理(熊)课件及示例程序 第8章 JSF事件处理(熊)课件及示例程序

    JSF Java Server Faces (JSF)框架

    JSF是一种用于构建Java Web 应用程序的标准框架(是Java Community Process 规定的JSR-127标准)。JSF(Java Server Faces)技术为开发基于网络用户界面的Java开发者提供了标准的编程接口API以及标签库。就像Struts框架...

    JSF基础教程 简体中文

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

    JSF中文教程jsf

    JSF中文教程JSF中文教程JSF中文教程JSF中文教程

    《JSF_实战》非常好的JSF学习书

    《JSF_实战》非常好的JSF学习书《JSF_实战》非常好的JSF学习书《JSF_实战》非常好的JSF学习书《JSF_实战》非常好的JSF学习书《JSF_实战》非常好的JSF学习书《JSF_实战》非常好的JSF学习书《JSF_实战》非常好的JSF...

    JAVA WEB JSF

    JSF 的主要优势之一就是它既是 Java Web 应用程序的用户...为了准备提供页面对应用程序数据访问的 JSF 上下文和防止对页面未授权或不正确的访问,所有与应用程序的用户交互均由一个前端FacesServlet(控制器)来处理。

    JSF开发介绍JSF开发介绍

    JSF开发介绍JSF开发介绍JSF开发介绍JSF开发介绍JSF开发介绍JSF开发介绍JSF开发介绍JSF开发介绍JSF开发介绍

    JSF的工作方式 JSF架构 JSF模型 JSF事件类型

    主要讲述JSF的工作方式 JSF的工作方式 JSF架构 JSF模型 JSF事件类型

    core jsf 1.2 jsf 核心

    jsf1.2 core jsf jsf核心

    jsf视频jsf视频0

    jsf 视频 java faces jsf 视频 java faces jsf 视频 java faces

    jsf第一个例子 jsf架包 jsf实例

    第一个JSF程序,初学JSF者必备,jsf架包 jsf实例

    jsf2.0 文件上传组件

    #文件上传后是以.tmp为后缀的临时文件存储在服务器上,请求处理完成后系统将自动删除该临时文件,需要自行保存文件到需求的目录 uploadFile.path=E:/ #设置上传文件总大小的上限 uploadFile.sizeMax=1024*1024*50 #...

    JSF入门教程JSF入门教程

    JSF入门教程 JSF入门教程 JSF入门教程

Global site tag (gtag.js) - Google Analytics