JSF 2.0阅读笔记:视图状态 (一)

最近终于抽空阅读了JSR314与相关的API代码,把一些心得整理一下。

JSF 2.0阅读笔记:视图状态

[b]什么是视图状态[/b]

在JSF中,一个页面,或者叫视图(View),在服务器端是通过一棵组件树来描述的。组件树中的每一个节点,对应着视图上的每一个组件,是组件在服务器端的内部表述模型,称为组件类实例。JSF请求处理生命周期中的所有行为,包括校验、转换、事件分发、渲染等等,都是围绕组件树进行的。任何时候,只要把组件树完整地建立起来,我们就拥有了它所表述的视图在请求处理生命周期中所需要的全部信息。这些信息,就称为视图状态信息。通常来说,视图状态信息包括了组件树的结构信息,组件中每一个组件的属性值,以及所有附加到这些组件上的其他对象(例如转换器和校验器等等)。而我们编写页面(xhtml或jsp)的行为,事实上是在定义组件树的初始状态。在JSF1.2规范中,官方只规定了一种编写页面的方式,jsp。在JSF2.0中,对定义页面初始状态的方式进行了抽象,支持多种页面定义方式,每一种方式称为一种视图声明语言(ViewDeclarationLanguage,或称VDL)。

在对页面的首次请求中,JSF引擎根据VDL的描述建立起初始状态的组件树。在后续的处理与postback处理中,应用系统会对视图状态进行修改。例如修改组件属性值,动态增删组件等等。由于http协议是无状态的,每次请求完毕后与这次请求相关的状态都会丢失。JSF引擎就承担起在请求处理生命周期的起始阶段把上一次请求的组件树恢复重建起来的职责。显然,实现这一目的最直接的做法是把整棵组件树保存在session中。但是,出于性能与服务器资源占用的综合考虑,JSF的实现框架通常会把恢复组件树的必要信息进行抽取和编码,以某种形式保存在session中或传递到客户端。在JSF规范中,就把这些信息称为视图状态。请注意“视图状态”这个术语的多重含义,在请求处理的语境中,它指组件树的当前状态。在恢复视图的语境中,它指“以某种形式传递到下一次请求,JSF引擎能根据它来重建组件树的必要信息”。至于这些“必要信息”保存的形式和传递的方式,根据具体实现不同而不同,可以是保存在session中组件树,也可以是经过序列化和BASE64编码的一串字符串。为了避免混淆,在下文中“视图状态”统一采用后一种含义。对于前一种含义,采用“组件树当前状态”来表述。

JSF规范和API把生产视图状态的过程划分为采集与编码两个阶段。采集的逻辑通过继承javax.faces.application.StateManager抽象类来实现,负责遍历组件树,把组件树结构(包括组件对象的类型信息,和组件对象之间的层次关系)、每个组件的状态信息和附加对象信息抽取出来,构造出一个可序列化的对象数组。编码阶段(针对把视图状态传递到客户端的情况),通过继承javax.faces.render.ResponseStateManager抽象类来实现,负责把上述的对象数组转换为某种可在网络上传输的(BASE64编码),安全的(加密)编码形式,并向响应流中输出。同理,在根据视图状态恢复组件树的过程中,也存在解码和恢复两个阶段,同样由上述两个抽象类的实现类来负责。当然,其中的实现细节都是JSF框架的实现者才需要关心的事,组件开发人员和应用开发人员都无需关心。

[b]JSF 2.0之前的视图状态[/b]

在JSF 1.2或更早版本中,视图状态一直是一个尾大不掉的难题。

[color=blue]首先,组件类上存在大量的强类型的属性对象域,使得单个组件的视图状态尺寸虚高。[/color]比如说,组件有一个布尔型的属性叫immediate,那么组件开发者就会在这个组件类中加入一个private boolean immediate对象域。同时,由于要跟踪这个属性是否被显式地设置过,还要加入一个private boolean isImmediateSet对象域来记录。这样一来,即使在某个页面中我可能从来都没使用过这个属性,但这些对象域的值最终都会被加入到视图状态中去。可想而知,对于一个复杂的组件体系模型,单个组件上的属性数目很可能达到上百个,而事实上每次使用的只不过是其中三五个,将会使整个视图状态尺寸无谓地增大。需要注意的是,JSF规范中并没有规定要使用强类型对象域的方式来保存组件属性,但JSF1.2的官方API中采用了这种做法,导致组件开发者不得不效仿。

[color=blue]其次,组件开发者必须为每个组件类实现saveState与restoreState方法,来采集与恢复强类型对象域的状态。[/color]组件类上存在的大量强类型对象域,有的甚至没有作为JavaBean属性对外公开,是无法统一采集与恢复的。因此JSF规范为组件类准备了saveState与restoreState接口方法,组件开发者必须在每个组件类上覆盖这两个方法,依次采集与恢复各个需要保存状态的对象域。这为组件开发者带来了大量琐碎的重复工作。一些JSF实现采用了自动生成代码的方法来避开这个问题,但在开发组件的过程中需要人手去触发代码生成过程,不免令人不爽。

[color=blue]第三,视图状态尺寸极易失控,使应用开发者陷入两难处境。[/color]由于上述第一点原因,结构稍为复杂一点的页面往往会产生尺寸巨大的视图状态信息。更令人崩溃的是,JSF规范针对这种状况给出了一种火上浇油,掩耳盗铃式的“解决方案”:您可以选择把视图状态保存在服务器端,用内存换带宽;也可以选择把它传递到客户端,在下一次请求再提交上来,用带宽换内存。这下好了,应用程序员都变成了揭不开锅的小媳妇,小心翼翼地算着手上有几角几分,到底要带宽呢,还是要内存。要带宽,就意味着服务器资源吃紧,强并发用户数降低。要内存,就意味着明确表示56k modem与3G不得入内,也意味着需要尽量减少ajax提交频率。手心是肉,手背也是肉,你要割哪面?我曾尝试过加入gzip压缩方案来减少视图状态尺寸,但发现效果并不理想。虽然确实能把视图状态尺寸缩小到60%左右,但又把CPU扯进来了,无非是把两难选择变成了三难选择。治标不如治本,归根结底,从本质上减少视图状态尺寸才是正路。

[color=blue]第四,视图状态必须存在。[/color]事实上,并不是所有页面都需要更改视图状态,那么对于那些一直保持初始状态的视图,是否可以不保存视图状态,而改为在每次请求处理从原始页面重新构建组件树呢?答案是不行!JSF1.2规范只支持JSP这一种页面语言,而JSP本身是无比开放的,应用开发者倾向于在JSP中直接嵌入业务脚本,并且预期这些脚本只会在首次请求时才运行。在每次postback(特别是ajax postback)中都执行这些脚本显然不是应用开发者想要的。而JSF作为一个开发框架,与其禁止程序员在JSP中嵌入业务逻辑,造成概念上的混乱,还不如接受性能“稍慢”的现状。Facelets框架的出现改变了这种状况,为基于初始视图状态的“优化视图状态”提供了理论上的可能。Facelets页面只关心组件树的初始状态描述,无法嵌入业务逻辑(时髦的说法是没有side effect)。JSF的实现者可以在任何有需要的时候重新解析页面,获取到一份初始视图状态。

(待续)
这是2个压缩包中的第个,请与第二个并下载,然后随便解压其中个即可。如果只想下载其中部分,可下载pdf: http://download.csdn.net/detail/oqqsun12345678/5215337 这个pdf是665页中的前404页,后面200多页在: http://download.csdn.net/detail/oqqsun12345678/5215345 资料内容简介 出版日期: 2012年1月1日 《JavaServer Faces 2.0完全参考手册》针对javaserver faces(jsf)2.0中的变化进行了全面的修订与更新,涵盖了javeee的官方标准web开发架构的每个方面。在这本权威著作中,sun microsystems公司中的jsf合作规范领导者展示了如何创建动态的、跨浏览器的web应用程序,由于保留了较高质量的代码和可扩展性,这些应用程序可以给用户带来极为优秀的体验。 《JavaServer Faces 2.0完全参考手册》提供了个综合的示例应用程序,可以将其用作您自己的jsf应用程序的模型。该示例应用程序的代码可以从网上下载。《JavaServer Faces 2.0完全参考手册》对所有jsf功能都进行了解释,包括请求处理生命周期、托管bean、页面导航、组件开发、ajax、验证器、国际化和安全。贯穿全书的专家组意见提供了关于jsf设计的内部信息。 推荐编辑 《JavaServer Faces 2.0完全参考手册》主要内容:搭建开发环境并构建JSF应用程序。理解JSF请求处理生命周期。使用Facelets视图声明语言、托管bean和JSF表达式语言(EL)。按照JSF导航模型声明个页面,包括新的“隐式导航”功能。使用用户界面组件模型和JSF事件模型,包括支持可添加书签的页面以及POST、REDIRECT、GET模式。使用为模型数据验证设立的新的JSR-303bean验证标准。创建可以使用Ajax的定制用户界面组件。使用定制的非用户界面组件来扩展JSF。管理安全、可访问性、国际化和本地化。学会使用Liferay的JSF团队领导开发的JSF和Portlet,Liferay是处于领导地位的JavaPortal开发商。 全面介绍JSF2.0、详述如何使用Ajax,以及按照JSF2.0、的方式构建组件、快速理解众多可以直接运行的代码示例。 作者 作者:(美国)伯恩斯 (Ed Burns) (美国)沙尔克 (Chris Schalk) (美国)格里芬 (Neil Griffin) 译者:陶克 熊淑华 伯恩斯,Ed Burns是Sun Microsystems公司的高级主管工程师,此外还是JavaServer Faces共同规范的领导者。他与其他人合著了JavaServer Faces:The Complete Reference书,并且是Secrets of the Rock Star Programmers书的作者。 沙尔克,Chris Schalk是developer advocate,致力于提升Google的API和技术。他当前在国际化Web开发社区工作,主要研究新的Google App Engine和Open Social API。 格里芬,Neil Griffin是Liferay Portal的委员以及JSF开发团队领导者,并且是Portlet Faces项目的合作创始人。 目录 第I部分 javaserver faces框架 第1章 javaserver faces简介 1.1 什么是javaserver faces 1.2 javaserver faces的历史 1.2.1 公共网关接口 1.2.2 servletapi 1.2.3 java服务器页面 1.2.4 apachestruts 1.2.5 spring框架和springmvc 1.2.6 javaserverfaces的诞生 1.3 javaserver faces设计目标 1.4 jsf应用程序架构 1.4.1 jsf请求处理生命周期 1.4.2 jsf导航模型 第2章 构建个简单的javaserver faces应用程序 2.1 应用程序概述 2.1.1 jsfreg应用程序文件 2.1.2 jsf软件栈 2.1.3 装配jsfreg应用程序 2.1.4 配置文件 2.1.5 facelets页面 2.2 构建和运行应用程序 2.3 应用程序关键部分 回顾 第3章 javaserver faces请求处理生命周期 3.1 jsf请求处理生命周期概述 3.1.1 请求处理生命周期的功能 3.1.2 与其他web技术的区别 3.1.3 服务器端视图的自动管理与同步 3.1.4 请求
这是2个压缩包中的第二个,请并将第个下载后,随便解压其中个即可。 如果只希望下载其中部分即可阅读,可下载另个pdf: http://download.csdn.net/detail/oqqsun12345678/5215337 内容简介 出版日期: 2012年1月1日 《JavaServer Faces 2.0完全参考手册》针对javaserver faces(jsf)2.0中的变化进行了全面的修订与更新,涵盖了javeee的官方标准web开发架构的每个方面。在这本权威著作中,sun microsystems公司中的jsf合作规范领导者展示了如何创建动态的、跨浏览器的web应用程序,由于保留了较高质量的代码和可扩展性,这些应用程序可以给用户带来极为优秀的体验。 《JavaServer Faces 2.0完全参考手册》提供了个综合的示例应用程序,可以将其用作您自己的jsf应用程序的模型。该示例应用程序的代码可以从网上下载。《JavaServer Faces 2.0完全参考手册》对所有jsf功能都进行了解释,包括请求处理生命周期、托管bean、页面导航、组件开发、ajax、验证器、国际化和安全。贯穿全书的专家组意见提供了关于jsf设计的内部信息。 推荐编辑 《JavaServer Faces 2.0完全参考手册》主要内容:搭建开发环境并构建JSF应用程序。理解JSF请求处理生命周期。使用Facelets视图声明语言、托管bean和JSF表达式语言(EL)。按照JSF导航模型声明个页面,包括新的“隐式导航”功能。使用用户界面组件模型和JSF事件模型,包括支持可添加书签的页面以及POST、REDIRECT、GET模式。使用为模型数据验证设立的新的JSR-303bean验证标准。创建可以使用Ajax的定制用户界面组件。使用定制的非用户界面组件来扩展JSF。管理安全、可访问性、国际化和本地化。学会使用Liferay的JSF团队领导开发的JSF和Portlet,Liferay是处于领导地位的JavaPortal开发商。 全面介绍JSF2.0、详述如何使用Ajax,以及按照JSF2.0、的方式构建组件、快速理解众多可以直接运行的代码示例。 作者 作者:(美国)伯恩斯 (Ed Burns) (美国)沙尔克 (Chris Schalk) (美国)格里芬 (Neil Griffin) 译者:陶克 熊淑华 伯恩斯,Ed Burns是Sun Microsystems公司的高级主管工程师,此外还是JavaServer Faces共同规范的领导者。他与其他人合著了JavaServer Faces:The Complete Reference书,并且是Secrets of the Rock Star Programmers书的作者。 沙尔克,Chris Schalk是developer advocate,致力于提升Google的API和技术。他当前在国际化Web开发社区工作,主要研究新的Google App Engine和Open Social API。 格里芬,Neil Griffin是Liferay Portal的委员以及JSF开发团队领导者,并且是Portlet Faces项目的合作创始人。 目录 第I部分 javaserver faces框架 第1章 javaserver faces简介 1.1 什么是javaserver faces 1.2 javaserver faces的历史 1.2.1 公共网关接口 1.2.2 servletapi 1.2.3 java服务器页面 1.2.4 apachestruts 1.2.5 spring框架和springmvc 1.2.6 javaserverfaces的诞生 1.3 javaserver faces设计目标 1.4 jsf应用程序架构 1.4.1 jsf请求处理生命周期 1.4.2 jsf导航模型 第2章 构建个简单的javaserver faces应用程序 2.1 应用程序概述 2.1.1 jsfreg应用程序文件 2.1.2 jsf软件栈 2.1.3 装配jsfreg应用程序 2.1.4 配置文件 2.1.5 facelets页面 2.2 构建和运行应用程序 2.3 应用程序关键部分 回顾 第3章 javaserver faces请求处理生命周期 3.1 jsf请求处理生命周期概述 3.1.1 请求处理生命周期的功能 3.1.2 与其他web技术的区别 3.1.3 服务器端视图的自动管理与同步 3.1.4 请求处理生命周期的各阶段 3.2 观察请求处理生命周期 3.3 与请求处理生命周期有关的高级主题 3.3.1 使用immediate属性 3.3.2 阶段侦听器 3.3.3 异常处理程序 3.4 关键的生命周期概念 第4章 facelets视图声明语言 4.1 jsf中使用模板化的威力 4.2 jsp与facelets的异同 4.3 使用facelets执行模板化 4.4 facelets模板化标签使用指南 4.4.1 ui:composition 4.4.2 ui:decorate 4.4.3 ui:define 4.4.4 ui:insert 4.4.5 ui:include 4.4.6 ui:param 4.5 facelets非模板化标签使用指南 4.5.1 ui:component 4.5.2 ui:fragment 4.5.3 ui:remove 4.5.4 ui:debug 第5章 托管bean与JSF表达式语言 5.1 托管bean概念 5.1.1 简单托管bean示例 5.1.2 初始化托管bean属性 5.1.3 把List和Map声明为托管bean 5.1.4 托管bean的相互依赖 5.1.5 使用EL设置托管属性 5.2 控制托管bean生命周期 5.3 JSF表达式语言 5.3.1 JSFl.1 与JSFl.2 之间表达式语言的关键区别 5.3.2EL概念 5.3.3 值表达式 5.3.4 表达式操作符 5.3.5 方法表达式 5.4 托管bean的Web应用程序开发细节 5.4.1 采用编程方式访问托管bean 5.4.2 使用托管bean作为JSF页面的支撑bean 第6章 导航模型 6.1 使用隐式导航 6.2 JSF导航系统概述 6.2.1 回顾MVC-控制器 6.2.2 Navigation HandleI-幕后主管 6.2.3 Faces动作方法说明 6.3 构建导航规则 6.3.1 静态导航示例 6.3.2 动态导航示例 6.4 更复杂的导航示例 6.4.1 使用通配符 6.4.2 使用条件导航 6.4.3 使用重定向 6.4.4 视图参数的XML配置 6.4.5 在Servlet错误页上使用JSF组件 第7章 用户界面组件模型 7.1 什么是用户界面组件 7.1.1 基于组件的Web开发的兴起 7.1.2 Java Server Faces用户界面组件的目标 7.2 JSF用户界面组件架构介绍 7.2.1 用户界面组件树(视图) 7.2.2 用户界面组件和相关的“活动部分 7.3 组件资源 7.4 用户界面组件和Facelets 7.4.1 用编程方式访问用户界面组件 7.4.2JSF视图中绑定用户界面组件的有用建议 第8章 数据转换与数据验证 8.1 验证和转换的示例 8.2 转换和验证揭秘 8.3 Faces转换器系统 8.3.1 Date Time Converter 8.3.2 Number Converter 8.3.3 关联转换器与UI Component实例 8.3.4 转换器的生命周期 8.3.5 定制转换器 8.4 Faces验证系统 8.4.1 Long Range Validator 8.4.2 Double Range Validator 8.4.3 Length Validator 8.4.4 必需的工具Required Validator 8.4.5 Reg Ex Validator 8.4.6 Bean Validator …… 第9章 jsf事件模型 第II部分 扩展javaserver faces 第10章 应用jsf:虚拟教练应用程序简介 第11章 构建定制用户界面组件 第12jsf与ajax 第13章 构建非用户界面定制组件 第14章 保护javaserver faces应用程序 第III部分 javaserver faces工具与库 第15章 配置javaserver faces应用程序 第16章 标准的jsf组件库 附录jsf portlet
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值