分享

JSF中请求过程的生命周期

 软件团队头目 2006-08-30

JSF中请求过程的生命周期

 


前面我们讲了JSF中包含的:组件、事件、监听器以及很多好用的组件,这些功能都使得JSF的开发变得更简单。那么这些部分的执行过程是什么样的呢?为了更容易理解,我们讲分析JSF框架的底层Servlet API,这对于你更好的理解JSF的执行过程是有好处的。了解了这些内容也有助于你开发出更好的应用程序,因为你明白底层到底是如何运行的。当然如果你是一个WEB界面开发人员,你完全可以跳过这个部分。
在这一节中我们讲讨论JSF是如何对请求作出响应的。或者说,由包含JSF组件的页面发出的请求是如何被JSF处理的。
图2.4是一个状态图,它显示了当接收到来自客户端发出的请求后JSF是如何处理的,即JSF的请求处理过程。这个过程开始于JSFservlet接收到一个来自客户端的请求(记住JSF是建立在Servlet基础之上的)

图2.4

列表2.2对以上每一个状态进行了注释,其中主要有六个状态,每一个状态之后多会有相应的时间产生。JSF将这些事件交给相应的监听器进行处理,不管监听器是处理某些业务逻辑还是组件,都能够继续跳转到最终的状态,显示响应结果。监视器也可以跳过最终的状态直接显示一个响应结果,比如它可以返回一个二进制内容,执行一个页面跳转或者返回其他与JSF有关的内容比如XML文档或者是一个HTML。
以上六个步骤中有四个可以产生消息,它们分别是:接收请求值(Apply Request Values),执行验证(Process Validations),更新模型值(Update Model Vlaues),和提交应用程序(Invoke Application)。不管是否带有消息,这些状态都能够向用户反馈响应,除非监听器、装饰器或者组件自身直接返回响应。这些状态之后是一个依据时间主线提交应用程序的过程。一系列的组件、校验过程、支持Bean和模型对象将被更新。简单的讲,JSF为你完成了大部分工作:它捕获了请求的详细信息并把它们传输给包含组件和时间的高层视图,而且还更新了相关对象的属性。
表2.2 JSF 各个状态的请求响应过程

状态
描述
触发的事件
还原页面(Restore View)
为选择的页面查找或创建一个组件树。一些组件,比如HtmlCommandButton组件在此状态下将产生动作事件(或者其他事件)
状态事件
接收请求值(Apply Request Values)
比较请求传输的值并更新相应组件的值,也可以使用转换器。如果出现异常将抛出一个异常消息。同时会产生来自请求参数的事件。
状态事件
数据模型事件
动作事件
处理验证(Process Validations)
对每个组件执行验证。可能会产生验证消息。
状态事件
数据模型事件
值变化事件
更新模型值(Update Model Values)
更新与组件相关的所有模型对象和支持Bean的值。可能会产生异常消息。
状态事件
数据模型事件
提交应用程序(Invoke Application)
调用注册的监听器。缺省的监听器将执行命令组件(比如HtmlCommandButton)的事件方法或者选择下一个要显示的视图。
状态事件
动作事件
返回相应(Render Response)
显示当前逻辑指定的下一个响应页面。
状态事件

为了让你对此有一个更清晰的了解。我们将通过一个hello world的例子展示JSF处理请求过程的整个生命周期。这个例子来自于我们前面章节讲述的hello.jsp。列表2.1显示了实际上Http的处理过程。
列表2.1 Http 的请求过程
POST /jia-hello-world/faces/hello.jsp HTTP/2.1 (1)接收来自URL的请求
Host: deadlock:8080
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:2.2.1)
Gecko/20021130
Accept: text/xml,application/xml,application/xhtml+xml,text/html;
q=0.9,text/plain;q=0.8,video/x-mng,image/png,
image/jpeg,image/gif;q=0.2,text/css,*/*;q=0.1
Accept-Language: en-us, en;q=0.50
Accept-Encoding: gzip, deflate, compress;q=0.9
Accept-Charset: ISO-8859-1, utf-8;q=0.66, *;q=0.66
Keep-Alive: 300
Connection: keep-alive
Referer: http://deadlock:8080/jia-hello-world/faces/hello.jsp (2)同样是接收来自URL的请求
Cookie: JSESSIONID=58324750039276F39E61932ABDE319DF (3)会话标记
Content-Type: application/x-www-form-urlencoded
Content-Length: 92
welcomeForm%3AhelloInput=64& (4)组件值
welcomeForm%3AredisplayCommand=Redisplay&
welcomeForm=welcomeForm
我们并不打算讨论Http处理的详细过程,不过上表其中几行与我们的讨论是有关的:
(1)请求数据来源于/jia-hello-world/faces/hello.jsp 这个连接的POST数据。
(2)这里的referer(引用)是由请求页面产生的,他与/jia-hello-world/faces/hello.jsp是相同的页面。
(3)这里的Cookies将被Servlet容器使用,它用于将请求数据映射到一个指定的会话中。在这个例中JSF使用Servlet会话来存储当前的视图(页面也可以保存在由客户端控制的一个值对象中,比如隐藏字段中)。
(4)这是非常重要的一个部分,这里包含了JSF传输的实际参数值(&用于分隔不同的参数,%3A将被解析为“:”冒号)。首先是一个名为 welcomeForm:helloInput的参数,并且它的值是64,这个值是通过浏览器页面输入的,第二个参数名为welcomeForm: redisplayCommand,他的值是“Redisplay”,最后一个参数是welcomeForm,它的值也是welcomeForm。在下面 的讲解中我们将逐步介绍这些值是如何处理的。
一旦JSF接收到请求,它就会创建并实例化一个javax.faces.context.FacesContext对象。这个对象代表当前的请求状态,并且负责处理底层Servlet request对象的各个部分,事件监听器可以通过它获得当前页面的操作句柄,以此来进行增加消息、记录事件等等操作。在JSF中它代表了请求处理生命周期的整个过程。我们将在下面的讲解中依次讨论每一个状态。


Thursday, August 24, 2006

JSF中的导航功能

 

之前我们讲述的概念中所有操作都是在一个单独的页面上。在实际的Web应用开发中,这是不太可能的。Web应用的开发会有很多页面,我们必须提供一种方法实现不同页面之间的切换。实现从一个页面到另一个页面切换的机制被称为“导航”。

JSF中有一套非常完善的导航系统。导航控制器根据请求实现的返回值确定下一个页面跳转到哪里。对于给定的页面,一个导航规则定义了根据业务逻辑的动作事件判断页面应该如何跳转。根据导航规则发生的每一个页面跳转被称为一个导航事件。导航规则定义在JSF的配置文件中。下面这个例子演示了针对longin.jsp页面的两个导航事件:success和failure的一个导航规则。

<navigation-rule>
     <from-view-id>/login.jsp</from-view-id>
     <navigation-case>
     <from-outcome>success</from-outcome>
     <to-view-id>/mainmenu.jsp</to-view-id>
     </navigation-case>
    <navigation-case>
    <from-outcome>failure</from-outcome>
    <to-view-id>/login.jsp</to-view-id>
    </navigation-case>
</navigation-rule>

如你所见,每一个出口对应一个JSP页面,这里你不需要通过编码实现这些规则。如果你曾经使用过Struts你对这种定义方式一定不会陌生。你会发现,所有的导航事件只映射一个出口(对应一个jsp),也就是说,如果将来需要进行变更你只需要修改需要变更的那一个页面就可以了而不是修改多处。

现在,JSF中的几个基本概念已经介绍完了。在随后的讲解中我们会看到更多的例子。已经这些概念集中到一起是如何使用的。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多