JSF请求处理生命周期的高度概述)_第1页
JSF请求处理生命周期的高度概述)_第2页
JSF请求处理生命周期的高度概述)_第3页
JSF请求处理生命周期的高度概述)_第4页
JSF请求处理生命周期的高度概述)_第5页
已阅读5页,还剩15页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、前一章演示的简单JavaServer Faces应用程序示例,介绍了 JSF的许多实用 方面。但是,在进入更高级JSF开发时,有一个JSF的关键部分非常重要:请求 处理生命周期。请求处理生命周期担当着使JavaServer Faces运行起来的“幕 后”引擎的角色。本章研究 JavaServer Faces请求处理生命周期背后的关键概 念,并解释如何用定义良好的基于事件的方式处理Web 青求。对请求处理生命周期的全面理解非常重要,因为在后续章节介绍高级JSF开发主题时,会多次提到 请求处理生命周期的不同阶段。3.1 JSF请求处理生命周期的高度概述从历史上看,Web应用程序必需的大部分开发,主

2、要是处理We四户端的HTTP请求。随着 WebA传统的静态文档传送模型(在这种模型中,只请求静态 We b页面,没有参数)转变到动态环境(要求WebS用程序处理大量进入参数),对日益复杂的请求的处理需求,不可避免地增长起来。这使WetS用程序开发变 得相当烦琐。例如,请看下面在 Java servlet 或JSP小程序中处理进入请求参 数 firstname 和 lastname 的代码:String firstname = request.getParameter("firstname");String lastname = request.getParameter(&q

3、uot;lastname");/ Do something with firstname and lastname考虑到现在多数高级 WetS用程序即使不处理几千个,也要处理上百个参数, 就可以看出上面这种参数处理方法很容易就会变得很烦琐。有经验的WebFF发人员都知道,编写处理进入请求参数的代码通常包含以下 步骤: 编写对进入数据执行验证并把进入数据转换成服务器端数据类型的代码,并在验证/转换失败时初始化错误消息。 编写用新数据更新服务器端数据的代码。 编写调用服务器端应用程序、执行数据库查询之类任务的代码。 编写把响应渲染回客户端的代码。幸运的是,请求处理生命周期可以用一种连贯的

4、、基于事件的方式处理这项 工作。专家组意见 在专家组讨论的JavaServer Faces全部元素中,请求处理生命周期得到的贡献最多,参与的成员最广,而且 是从1.0规范开发之后,发展最多的元素。例如,最初要求把 view描述放在JSP页面之外的独立XML文件中。因为发明 了 ViewHandler 类所以撤销了这个要求,ViewHandler 类就是在讨论生命周期的过程中产生的。3.1.1 请求处理生命周期到底做什么简而言之,过去必须自行编写代码才能处理的必要的后端处理,现在全由请 求处理生命周期执行。除了处理进入的请求参数,它还管理服务器端的用户界面 组件集,并把它们与用户在客户端浏览器中

5、看到的组件同步。3.1.2 请求处理生命周期与其他Web技术的区别对比其他更传统的 亚版术(从CGI、Java servlet 到Struts 这样的框架), 请求处理生命周期用定义良好的基于事件的方式自动执行了大部分常见服务器 端WetFF发任务。使用Jakarta Struts 这样的框架,用带有表单bean和Struts动作的代码把 一些请求处理做得更正规,但实际的数据处理仍在较低层次 (与JSF相比)上进 行。Struts编程模型对servlet API提供的抽象比JSF提供的少。例如,在St ruts中,可以这样定义代表提交表单属性的表单 Bean:<form-bean nam

6、e="loginbean" type="org.apache.struts.action.DynaActionForm">vform-property name="userid" type="java.lang.String"/>vform-property name="password" type="java.lang.String"/></form-bean>定义之后,可以像下面这样在应用程序中访问字段值:String userid = (S

7、tring)(DynaActionForm)form).get("userid");这很像能用JSF所做的事情,但在使用Struts时,没有把字段属性直接 绑定 到Java类属性并让属性的值在表单提交时自动同步的能力。3.1.3 自动服务器端视图管理和同步如图3-1所示,JSF请求处理生命周期能把服务器端 Java Bean属性自动同 步到有层次的组件集(根据呈现给客户端用户的用户界面) 的能力,是它与其他 WebJJ术相比的主要优势。由于Web天生是无状态的,即客户端与服务器之间的一个事务对前一个事务 没有记忆,所以JavaServer Faces通过自动维护代表客户端当

8、前状态的服务器 端视图(view)而解决了这个问题。这允许JSF开发人员把精力集中在服务器端 组件,由请求处理生命周期或“衔接”(plumbing)负责服务器端视图的同步和在客户端浏览器上显示什么。编写代码处理每个请求值或者修改用户界面状态的 烦琐工作,都通过一组阶段(phase)(每个阶段中,都用连贯的方式执行具体 的数据处理任务)由JavaServer Faces请求处理生命周期自动处理JSt'AppLi图3-1客户端用户界面的服务器端表示3.1.4 请求处理生命周期阶段是什么处理进入的请求数据,通常需要不同类型的工作,包括检查进入的数据是否 有效、触发服务器端的应用程序逻辑以完成

9、请求,以及最后把响应渲染给客户端。 JSF请求处理生命周期用前后连贯的顺序执行这些任务,而且在一组定义良好的阶段的控制之下。这种方式允许每个阶段清晰地描述执行本阶段之前需要存在的 前提条件,以及本阶段执行之后会存在的后置条件。下面是生命周期的各个阶段。 恢复视图:在内存中恢复或创建代表客户端用户界面信息的服务器端组件树(视图)。 应用请求值:用来自客户端的最新数据更新这些服务器端组件。 处理验证:对新数据执行验证和数据类型转换。 更新模型值:用新数据更新服务器端模型对象。 调用应用程序:调用满足请求所需要的应用程序逻辑,然后如果有需要,再导航到新页 面。 渲染响应:把响应渲染给请求客户端。图3

10、-2显示了这些阶段合在一起构成的请求处理生命周期的高级视图。可以贯穿本章和看到,它执行了 Wete用程序中的对进入数据进行处理的全部任务。本书的其余部分,将介绍这个图中的不同事件和阶段。FkbisW求现在来深入研究每个生命周期处理阶段中到底发生了什么。姓附 H件响以宛畋事件图3-2 JavaServer Faces请求处理生命周期1 .恢复视图前面提到过,Faces视图是用户界面组件的服务器端树,它提供了在客户端 显示的用户界面的镜像表示(请参见图 3-3)。恢复视图阶段的任务是根据前一 个事务恢复现有视图,或者根据新请求创建新视图。如果是新请求(“没有回传”), 就创建新视图,并保存在父容器

11、对象 FacesContext内。FacesContext充当与当 前请求有关的数据在通过整个请求处理生命周期过程中的存储。We»F发人员不必担心多个用户请求会把 FacesContext中的应用程序数据混淆,因为servlet API保证请求操作是线程安全的,即所有对 FacesContext的操作,都保证是在 一个独立线程上针对每个用户请求进行的。";H-词rHa. j ,rr i ”if,ir ljHtm 晒putRx*utPe时L 4innBnpuxTe-KL卜匚修叱两制4盟展;理 IpLrni廊e氤噂1世而nN证痴;唾I l II 也We即got图3-3服务器端用

12、户界面组件树(又称作视图”)2 .应用请求值恢复了视图之后的下一阶段一一 应用请求值阶段一一做的是对进入的请求值或信息名称-值对进行处理。视图层次结构中的每个用户界面组件节点,现在都 能得到客户端发送来的更新值,如图 3-4所示JKF 1皿kiraliuti App/n |t(WTr 4rrdLdllT .&力 i-4 r»HMd&eb cl-One-fta & 口W5e*rlHb iiF£el«L-3reMerAj|jmi Hki氤ItiTdli lulTtWLiLTeil用 LiFitlri 网ilrtgTrntJI V.dVjRn,

13、:图3-4应用请求值在幕后,JSF运行时在用户界面组件树的视图(或 UIViewRoot)上调用高级 方法(processDecodes(),把请求值应用到用户界面组件。这导致所有子组 件都递归地调用它们的processDecodes()方法。在第10章将会看到,用户界 面组件的processDecodes()方法或者更具体的decode()方法,允许组件对 进入的请求名称-值对进行“解码”,并把匹配的新进入值应用到用户界面组件 的value属性。应当指出,只有能够容纳值的用户界面组件(例如输入字段)才有新值应用 到它们。一般来说,有两类组件:一类是有值的组件,例如文本字段、复选框和 标签;另

14、一类是引起动作的组件,例如按钮和链接。所有具有value属性的组件 都实现ValueHolder接口。所有表单元素类型的组件,如果它的值可以由用户编 辑,那么就都实现EditableValueHolder 接口。所有引起动作的组件(按钮或链 接)都实现 ActionSource 接口。JSF1.2 提示 对于 JSF 1.2,动作组件实现的是 ActionSource2 接口,而不是 ActionSource。ActionSource2 扩展自 JSF 1.1 的ActionSource ,它允许使用1.2中新的统一 EL。关于1.2中统一 EL的细节,将在第4章提供。例如,按钮(UIComm

15、andE其他实现ActionSource的组件)在表单提交期间, 不用新值更新;它只需记录自己是否被单击。如果单击了,就引起称为动作事件 (ActionEvent )的事件进入队列。稍后就会看到动作事件到底是什么,以及它 如何允许与按钮或链接单击相对应的定制代码的执行。虽然请求处理生命周期用连贯的方式处理不同阶段,但阶段的执行顺序可以 为特殊情况而变化。例如,可能想向表单添加一个Cancel按钮。在单击时,它会跳过所有验证,不处理表单的值,直接导航到另一个页面。要改变请求处理生 命周期的处理顺序,只需设置组件的immediate属性。本章后面将会介绍,在不 同的组件上设置immediate属性

16、会有不同的效果。3 .处理验证应用请求值阶段完成之后,就要执行对进入数据进行转换和验证的处理验证阶段(第7章将详细解释数据类型转换和验证)。JSF运行时调用主processValidators( )方法(在 UIViewRoot 实例上),启动这个阶段。processValidat ors()与processDecodes()方法类似,也是递归地进入组件树,调用每个组 件的 processValidators( )方法。在调用每个组件的 processValidators( ) 方法时,与组件相关的转换器或验证器就会被调用。 注意 数据类型转换实际是发生在验证之前,但是在同一处理验证阶段内开始

17、。这是必需的,因为要执行验证,数据首先 必须转换成服务器端数据类型。在第2章的JSFReg示例中看到过,验证器和转换器可以用若干种方式与用户 界面组件关联。在示例中,验证请求可以通过设置组件本身的属性(例如把 inp utText组件的required属性设置为“ true ”)与组件关联,也可以通过注册定制验证代码(例如通过设置组件的validator 属性,向组件附加电子邮件验证方 法)与组件关联。第2章的示例也有一个转换器,通过插入 convertDateTime 转换器标签作为输入组件的子组件,与“出生日期" ( dob) inputText (UIInp ut)组件关联。验

18、证(或转换)失败的组件的 valid属性会设置成“false ",并把FacesM essage消息放进FacesContext队列,如图3-5所示。然后,当响应被渲染回用 户(在渲染响应 阶段)时,可以用Faces的Message或Messages组件显示消息, 以便用户纠正错误或重新提交。JSKm沁it &叩LtflMfitVjilnua Ms#-i 。皿“2 i JdaiMli LllKIEEF2iri'-d M D* Mln左 MdJtn <c fCcmtd Frii" AJi-iisJl. ka/dad 印望 小知"U SefflC

19、r Unt OaMt * E 图3-5处理验证阶段中遇到验证和转换错误4 .更新模型值假设进入的数据已经通过验证和转换,现在要把数据分配给值绑定到用户界面组件的模型对象。回忆一下第 2章的示例。在这个示例中,我们创建了一个 J ava类UserBean,把它注册成托管bean,并用JSF表达式语言把属性绑定到贡 面上的不同用户界面组件。正是在 更新模型值阶段,实际的托管bean或模型对 象的属性,被它们绑定的用户界面组件的新值更新。这个操作背后实际的机制与其他阶段相似:在 UIViewRoot实例上调用proc essUpdates()方法,初始化processUpdates()组件方法的逐级

20、调用,proc essUpdates()方法又对每个类型为UIInput或者从它扩展的组件调用updateM odel()方法。这么做是合理的,因为UIInput类型的组件(例如输入字段、选 择菜单)是能够把用户输入值传递给模型属性的唯一组件类型。如图 3-6所示, 在这个阶段末尾,模型对象(托管 bean)的值绑定属性都被来自组件的新值更 新。这个阶段揭示了 JavaServer Faces的一部分秘密:只要把JavaBean属性绑 定到一组JSF用户界面组件,不需要手动编码,它们就能自动更新。glSalectlta司Html3««4CT(fWR«llCHtin

21、lMrtHWwirntn汽竹SeanUwUewi,U*iMAn,Q nCtLfrrt I 卜用 eW*f|,rug* 加恻 kbUuv&Mn 4MMMf)<User6eana«ma l|WWIi图3-6在更新模型值阶段更新模型对象属性KtfTiCcrwTwwiadrMj5 .调用应用程序现在,已经看到了 JSF请求处理生命周期如何执行从 Web请求获得进入数据、 验证数据/把数据转换成合适的服务器端数据类型,以及把数据分配给模型对象 等工作。对Webff发人员来说,这只是Wetg用程序编写工作的一半。另一半是: 取得进入数据,真正对数据进行操作,例如调用处理数据的外部方

22、法。这正是调用应用程序阶段的作用。回忆本章前面所述,用户界面组件既可以容纳值(实现 EditableValueHold er)也可以是ActionEvent来源(实现ActionSource )(例如在单击按钮(UI Command时)。定制动作代码,又称为 动作方法或动作侦听器方法就是在调用 应用程序阶段调用的。幕后,在调用应用程序阶段中,UIViewRoot的processApplication( )方 法被调用,它又把队列中这个阶段的事件广播到每个实现ActionSource (对JSF 1.2 是 ActionSource2 )的 UIComponent组件。这是通过调用每个 UICo

23、mpone nt的broadcast)方法做到的,实际上就是“触发了” 动作事件,接着就由动作侦听器处理这些动作事件。可以用默认动作侦听器编写定制动作方法或动作侦 听器方法并把它们绑定到 UIComponent (实现ActionSource 的UIComponent), 处理动作事件。编写定制动作方 法或动作侦听器方法,并把它们绑定到实现ActionSource的UlComponent,为开发人员提供了参与请求处理生命周期的钩子(hook),通过钩子,开发人员就能调用任何定制逻辑。图 3-7演示了这一点。UlVlewRwtami 叫rI| / I| 1一、> nyBMMddCDnfir

24、nwciJiBrjI图3-7在调用应用程序阶段调用定制应用程序逻辑第8章将重新研究JSF事件模型到底如何工作,并提供关于 Faces事件处理 确切顺序的更多细节。还应当指出,导航到不同页面,也发生在调用应用程序阶段。第5章将介绍一个基本的登录应用程序,研究导航到底是怎么发生的。登录应用程序使用了一 个绑定到login (UICommanc技钮的简单动作。当用户单击按钮时,触发动作事 件,动作事件又在调用应用程序阶段调用定制动作方法,处理登录凭据。请记住,这个代码只有在进入的数据已经通过前面阶段(转换和验证已经完成)之后才会执行。登录成功时,会导航到新页面。6.渲染响应现在到了 JSF请求处理生

25、命周期的最后阶段,在这个阶段渲染响应。为把整 个响应渲染回客户端,又一次逐级对每个组件调用encodeXX()方法。在第10章将学习到,编码方法是用户界面组件(或者更具体点,组件的渲染器)向客户 端渲染组件的方法。渲染的标记语言可以是任何语言,例如HTML WMLXM导除了把响应渲染给客户端,渲染响应阶段还保存视图的当前状态,以便可以 在后续Web青求中访问和恢复状态。图3-8演示了如何用客户端标记渲染响应。 这时,视图的当前状态被保存下来,供未来请求之用。另外,实际还有更多精细的幕后细节与渲染响应阶段有关,但本章介绍的范 围之内。其中包括:处理静态内容(又称为“模板”源)与组件的动态内容交织

26、 的情况;处理各种动态输出源;在保持顺序正确的同时把它们协调成一个可视的 响应。一般来说,使用JSF时不需要处理这些细节。图3-8在渲染响应阶段渲染响应并保存状态JSF1.2提示 渲染响应阶段在JSF 1.2中被显著地重新设计了,以解决由于 HTML、JSP定制标签和JSF组件在一个页面 中混杂而引起的一些棘手问题。这些问题的主要诱因,是为了渲染而执行JSP页面,而且在执行页面的同时构建组件树”这一要求。这要求JSP和JSF都要写入同一输出流,有时会造成渲染输出以意外顺序出现。JSF 1.2中的新方法是:只为构建树这个唯一目标执行页面,而不为渲染页面执行它。页面中的原始HTML/标记和JSP定

27、制标签输出被转化成瞬态 UlOutput组件(不在页面状态中保存)。这样,页面执行之后,页面的整个内容 就表示在视图层次结构中,视图又被递归遍历,就像其他生命周期阶段一样3.2 实际观察请求处理生命周期看过每个请求处理生命周期阶段背后的理论之后,是时候看看生命周期的实际作用了。回顾第2章所示的JSF注册(JSFRe。应用程序(如图3-9所示)。 我们要作为与应用程序交互并提交注册表单 (register.jsp )的用户,经历全部 生命周期阶段。(1)查看register.jsp 页面的初始请求:为了第一时间看到注册表单页面, 用户需要直接发送对注册页面URL的请求,用精简方式触发请求处理生命

28、周期的 一次运行。请求首先由Faces控制器servlet处理,控制器为这个请求创建一个 FacesContext实例,并初始化对生命周期的调用。由于这是查看注册页面的初 始请求(也叫做“无回传”请求),恢复视图阶段创建一个空视图( UIViewRoo t)组件树,并把它保存在 FacesContext实例中。J. 'fei-: p irrnl nn 1. pp nn<l'K3ri >Inlvrnri M k,.她城 01KB NJSF RegiiilTfltiDn Afip1111mliI mnLmHeGMfO 福ik 0 FigDiiroCBrlAi:m 刎EE

29、mi 圻 iirwr*Ifj,1 ,LK4 m«Mfi图3-9 register.jsp: JSFReg应用程序的注册页面视图创建之后,因为在请求中没有进入字段数据需要验证或处理(也叫做“无回传”请求),生命周期立即前进到渲染响应阶段。在这个阶段,空视图组件树 由注册页面源代码中引用的组件(显示输入字段和提交按钮)填充。树填充之后, 组件就把自己渲染到客户端。同时,保存视图组件树的状态,供后续请求使用。用户现在看到在浏览器中渲染的注册页面。(2)用户在注册页面中输入无效数据:假设用户忘记输入了自己的姓,还输入了格式错误的日期,就单击了 Register按钮(如图3-10所示)。曰 A

30、 EkTipM JngHrr Fz出 Fte怖£rr-itER 阡141Gt 0门 - Ml即6;而 k-鬲: “ 衿 £» F.rgw 诉看 咋*审:-j.i -> ITtp:r-V«:*¥M> »MQ>rwrteW.fe®¥; Qtid :=iMSiSgiiiiiSgSgiSgigSiMSggggiiiwSBSSiiBSBSSiSBiia>iiSSii 二一一 .'JSK KpgislrativH AppH ¥ glralis FirmFfdtFflfiK sQan工诩

31、部邮任VrtdoftDn &n»r VSx ii rtqjnrciQtadsf- Miiv O FwiMr3uflkrh -"呻"i网、110出闺澳 c w加1KqmdEFTwd 学如l画gBE 上珏!电.5k和由I电吗西 '心油1 融 Cww*l« d *力 ww*图3-10在注册页面输入错误数据当JSF运行时接收到请求时,进入初始的恢复/创建视图阶段,这次它恢复刚 才在用户前一个请求之后保存的视图组件树。这通常叫做“回传”,因为这个请 求的HTT叨法是POST(因为要“传送”新表单数据)。然后进入应用请求值阶 段,即使请求中的进入值不

32、完全有效,也用请求中的进入值更新组件。在这个阶段没有错误发生,因为每个用户界面组件只是把请求参数的提交值保存为Strin g值,还不是转换后的(服务器端数据类型)值或验证过的值。用户界面组件把 这个值保存在一个特殊的经过预转换/预验证的submittedValue JavaBean属性 中,它只是原样保存请求参数的String值。应用请求值阶段完成后,启动处理验证阶段。这时,由于进入的日期数据格 式无效,无法转变成java.util.Date数据类型(对应着托管 bean UserBean的“dob”属性),发生转换错误。一条消息被放入队列,组件被标记为无效,处 理继续进行。余下的有效字段值被

33、应用到对应的用户界面组件。在每个用户界面组件调用它的验证方法时,要容纳 lastName值的组件遇到 验证错误,因为在回传请求中没有为它提供值。还记得前面姓氏输入字段的 equired ”属性设置为“ true ”。作为验证错误的结果,生命周期把UIInput组件lname (last name )的属性设置为无效,并把对应的表示这个字段必须有值 的Faces消息放入队列。这时,处理验证阶段完成。因为有验证和转换错误,所以生命周期直接跳到渲染响应阶段,然后渲染同 一个注册页面(register.jsp ),把对应的错误消息放在last name字段和日期 字段旁边。回想一下,每个消息组件到每个

34、输入字段组件的分配,是通过分配它们的ID实现的,如下所示:<h:inputText value="#UserBean.lastName" required="true" id="lname"/><h:message for="lname"/>除了把响应渲染给客户端,渲染响应阶段也保存视图组件树,供后续请求使 用。(3)用户纠正验证错误,重新提交表单:在响应中看到错误消息后,用户对 表单进行纠正,提供姓氏并输入格式正确的日期值,然后重新提交。这次,在处 理请求时,恢复视图阶段恢复保存的视图树,

35、并前进到应用请求值阶段,在这个 阶段把新值应用到视图组件树。阶段转移到处理验证阶段,这次在这个阶段没遇 到验证或转换错误。然后触发更新模型值阶段。这时,托管 bean (UserBean) 的属性被表单中提交的新值更新,如图 3-11所示。JSf igistriti.oD Ap pR *tii« Hi id FmuECljffw 丁油yrrUri'.CMlRCCCLMarAtEn0|UISh vl|内同用苴M外刮F欣电图3-11用验证后的值更新UserBean模型对象更新模型值阶段完成之后,触发的下一阶段是调用应用程序阶段。还记得调用应用程序阶段为JSF开发人员提供了调用定制

36、逻辑的途径。 例如,应用程序可能需要执行查询数据库的代码。执行定制逻辑是通过动作方法实现的,动作方法在调用应用程序阶段被调用,但只有在队列中有动作事件时(例如单击了按钮或链接)才调用。在JSFRe亦例中,在单击Register按钮时,一个动作事件被放 入队列,1是由于Register按钮(UICommandE件)的action属性硬编码成文 字值“register ",所以没有调用定制动作方法,调用应用程序阶段完成。这时, 导航处理程序处理动作事件,出现一个导航。然后在最终的渲染响应事件中显示 导航事件的结果。现在再来看一遍:注册页面成功通过验证、UserBean托管bean用表单提

37、交的值更新之后,生命周期到了渲染响应阶段,这时需要把格式化的响应发送回用 户。这时,必须确定要发送回客户端的响应。正如在第5章中会更全面介绍的那样,导航处理程序负责确定是否只是用同一页面进行响应,还是导航到新页面。还记得JSFRe亦例有一个action属性硬编码成“register ”,由于它与faces -config.xml文件中定义的导航规则对应,所以渲染的响应是要导航到新页面(c onfirm.jsp )。请记住,如果没有设置导航按钮的action属性,或者没有对应的导航规则,那么渲染的响应就会是同一页面,不会出现导航。图 3-12显示了 NavigationHandler 如何利用f

38、aces-con巾g.xml中定义的规则确定是否需要导航。 注意 关于Faces导航模型的详细说明,将在第 5章提供。中nHaftd好r尚博支好心叱tM 4兴图3-12在调用应用程序阶段,根据动作的结果渲染响应3.3 与请求处理生命周期有关的高级主题看过JSF请求处理生命周期在默认情况下对基本表单的处理方式,现在来看 些稍微复杂的示例。3.3.1 使用 immediate 属性这一节介绍Faces的一项极为重要的特性:immediate属性,它允许更灵活 的生命周期执行方式。立即处理动作事件假设想在注册页面上添加一个Cancel按钮,单击这个按钮时,不论表单上输入了什么,都会立即把用户路由回m

39、ain.jsp页面。要实现这个功能,必须添加一个返回主页面的导航规则,还要在页面上添加一个按钮或链接组件,组件的动作设置为导航规贝U " cancel” 的from-outcome。 下面是 faces-config.xml 中的 新导航规则:<navigation-rule><from-view-id>/register.jsp</from-view-id><navigation-case><from-outcome>cancel</from-outcome><to-view-id>/main.js

40、p</to-view-id></navigation-case></navigation-rule>下面是新添加到Register页面的Cancel按钮,它的action硬编码设置成“c ancel ” :<h:commandButton value="Cancel" action="cancel" />但是,如果就此停止,那么很快就会遇到问题!如图3-13所示,如果想再次 运行应用程序,但是立即单击Cancel按钮,就会卡在那里。出现这个问题是因为即使刚才用空表单单击 Cancel按钮,仍然把它当作“回传

41、”请求进行处理, 这意味着JSF生命周期开始进行处理,而且假定从表单传来了进入的名称-值对。 但是由于表单实际是空的,所以在导航处理程序能处理“cancel”动作事件并把 同一页面响应渲染回客户端之前,先遇到了验证错误。显然,需要有一个在正常JSF在它的immediate属性中提供生命周期处理流程之中允许异常的解决方案 的就是这个功能。JSFAppm 加廿 4 irrnedu % T rm图3-13因为验证错误而卡在页面上如果给Cancel按钮(或任何 UICommandK件)添加了 immediate属性,并 把它的值设置成“ true ”,就能允许生命周期立即跳过验证,导航回 main.jsp 页面。一般来说,在UICommandK件上把immediate属性设置为“ true ”,会引 起动作事件在处理验证阶段之前,在应用请求值阶段就立即触发,这样就不会遇 到验证错误。这样就有了把生命周期“短路”的效果,可以避免验证,取消更新 任何模型的值。3.3.2 立即处理验证和转换实现EditableValueHolder 接口的组件(像输入字段)带有选项,可以根据 i

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论