JavaServer Faces标准请求/响应周期

JSF实现使用一个控制器servlet 来处理请求,然后执行 JSF 生命周期.如图显示了JSF 生命周期中的事件处理。 

JSF生命周期

上图是正常的JSF组件的生命周期.一共12个.

记住,所有JSF事件都在服务器上执行,当在JSF页面中提供一个事件处理程序时,就是告诉JSF实现当服务器处理页面中的用于输入时,应在生命周期的适当位置处理相应的事件.

从"应用请求值"阶段开始,JSF实现会创建事件并在每个生命周期阶段期间将其添加到事件队列中.

FacesContext 包含与单个 JavaServer Faces 请求的处理以及相应响应的呈现相关的所有每个请求的状态信息。它传递给请求处理生命周期的每个阶段,并且可能被修改。

注意事件监听器可通过下列三种方式之一影响JSF生命周期: 

   (1) 让生命周期正常进行。 

   (2)  调用FacesContext 类的RenderResponse 方法以忽略生命周期的其他部分,直接跳转到“呈现响应”阶段。 

   (3)  调用FacesContext 类的responseComplete 方法以完全略过生命周期的其他阶段。

两个方法的具体资料如下:

abstract public void renderResponse()

通知 JavaServer faces 实现,完成请求处理生命周期的当前阶段后,应该立即进入呈现响应阶段,忽略尚未执行的任何阶段。

Throws IllegalStateException: 如果释放此实例后调用此方法 

abstract public void responseComplete()

通知 JavaServer Faces 实现,已经生成了此请求的 HTTP 响应(如 HTTP 重定向),完成当前阶段后,应该立即终止请求处理生命周期。

Throws IllegalStateException: 如果释放此实例后调用此方法 

请求(一般不算在JSF生命周期中)

第一阶段:还原视图

第二阶段:应用请求值+过程事件

第三阶段:过程验证+过程事件

第四阶段:更新模型值+过程事件

第五阶段:调用应用程序+过程事件

第六阶段:呈现响应

响应(一般不算在JSF生命周期中)

首尾的请求,响应,如图所示是单独在外的.而剩下的就是真正意义上的JSF生命周期处理的步骤.

第一阶段:还原视图

在JSF生命周期的第一个阶段"还原视图"中,会有一个来自 FacesServlet 控制器的请求。控制器会对请求进行考查,并提取出视图的 ID,这是由页面的名字来确定的.

JSF框架控制器使用这个视图ID来为当前的视图查找组件。

如果这个视图尚未存在,那么 JSF 控制器就会创建它.

如果这个视图早已存在,那么 JSF 控制器就会使用它.这个视图包含所有的GUI组件.

(题外话:这也会造成ajax请求在生命周期中无法重置掉页面上input框的值,造成验证错误后,再次打开dialog,错误值仍然存在.但仍然是利大于弊,只需要在JSF生命周期中修改JSF生命周期,在ajax验证后再次进入进入生命周期,重置内容!ResetInputAjaxActionListener.就OK了).

生命周期的这个阶段表示为三个视图实例:新视图,原始视图和后视图,每个视图的处理方式都不相同。

FacesContext对象包含了 JSF 用来管理当前会话中当前请求的 GUI 组件状态所需要的所有状态信息。FacesContext 将视图保存在自己的 viewRoot 属性中;viewRoot 包含了当前视图 ID 的所有 JSF 组件。

1.在 新视图 的情况中,JSF会构建Faces页面的视图,并将事件处理程序和验证程序绑定到组件上。这个视图被保存在FacesContext对象中。

2.在原始视图的情况中(第一次加载的是一个页面),JSF 会创建一个空视图.这个空视图会在用户事件产生时进行填充。JSF可以直接从原始视图过渡到进行响应的阶段。

3.在后视图(postback)的情况中(用户返回之前访问过的页面),包含页面的视图早已经存在了,因此只需要进行恢复就可以了。在这种情况中,JSF 就使用现有视图的状态信息来重构状态。后视图的下一个阶段是应用请求值。

第二阶段:应用请求值+过程事件

应用请求值阶段的目的是让每个组件检索自己当前的状态信息.与JSF中转换器息息相关.

这些组件必须首先通过FacesContext对象进行检索或创建(使用其值).虽然组件值也可以从cookie或头文件中进行检索,但是它们通常是通过请求参数进行检索的.

如果一个输入组件的即时事件处理属性immediate="true/false"没有设置为true,那么就会对这些值进行转换.因此,如果"域"被绑定到一个 Integer 属性上,那么该值就会被转换为一个Integer类型。如果值的转换失败了,那么就会生成一个错误消息,并在 FacesContext 中进行排队,在产生响应的阶段会显示其中的消息,同时还会显示所有的验证错误.

如果一个输入组件的即时事件处理属性immediate="true/false"被设置为 true,那么这些值就会被转换为适当的类型(注意:是转换为适当类型,也就是说不会去进行转换的判断!!!),并进行有效性验证。然后转换后的值会被保存到组件中。如果值转换或值的有效性验证失败了,就会生成一个错误消息,并在 FacesContext 中进行排队,在产生响应的阶段会显示其中的消息,同时还会显示所有的验证错误。

第三阶段:过程验证+过程事件

生命周期中的第一个事件处理发生在应用请求值阶段之后。

在这个阶段中,每个组件都有一些值需要根据应用程序的验证规则进行有效性验证.这些验证规则可以是预先进行定义的(JSF 中提供的),也可以由开发者进行定义.

用户所输入的值会与这些验证规则进行比较.如果说输入的值无效,就会向 FacesContext 中添加一个错误消息,并且该组件会被表示为无效的。

如果一个组件被表示为无效的,那么 JSF 就会转到产生响应的阶段,在这个阶段中会显示当前的视图,以及验证错误消息。

如果没有有效性验证错误,那么 JSF 就会转到更新模型值的阶段。

如果在一个命令组件的及时处理属性immediate="true/false"被设置为 true,那么"将也只会跳过这个表单"上的验证过程.

第四阶段:更新模型值+过程事件

这个阶段负责更新服务器端模型的实际值.

通常来讲,这都是通过更新后台bean的属性实现的.只有那些与组件值绑定在一起的bean属性才会被更新.(其实就是backbean得到属性值了.....)

注意这个阶段发生在有效性验证之后,因此可以确保拷贝到bean属性的值都是有效的(至少在表单域一级都是有效的,在业务规则一级仍可能无效).

第五阶段:调用应用程序+过程事件

在生命周期的这个阶段JSF控制程序会调用程序来处理表单的提交操作.组件值已经经过了类型转换和有效性验证,并被应用到模型对象中了(其实就是后台的backbean已经得到了前台的值,搞不清楚有些资料为什么总要说的很高深,- -!),因此您现在可以使用它们来执行应用程序的业务逻辑了.

在这个阶段,您还可以为一个给定的序列或很多可能的序列指定后面的逻辑视图,这可以通过为一次成功的表单提交定义一个特定的结果并返回这个结果来实现。

例如:在成功输出时,将用户重定向到下一页中。要让这种导航工作能够起作用,您需要在faces-config.xml文件中创建一个到"成功输出"的映射作为一条导航规则。

一旦导航发生之后,您就转换到生命周期的最后一个阶段了.

第六阶段:呈现响应

在视图中显示当前状态中的所有组件

参照于网址https://my.oschina.net/zhaoqian/blog/71866

原文地址:https://www.cnblogs.com/jk-heart/p/8857168.html