JSF的工作方式

开发 后端
本文介绍JSF的工作方式,以及处理生命周期的各个阶段和应用配置文件注册JavaBeans。

1.JSF的工作方式

JSF应用是通过处理由页面中组件触发的事件来工作的。这些事件是由用户的动作引起的。比如,当用户单击一个按钮时,按钮会触发一个事件,通过编写监听这个事件的监听器,JSF开发人员可以决定当特定事件发生时JSF应用应该做什么。也就是说,JSF应用是事件驱动的。图1说明了JSF应用的处理过程。

JSF应用是事件驱动的
图1  JSF应用是事件驱动的

当一个事件发生时(比如,用户单击了一个按钮),事件通知通过HTTP发往服务器。服务器端使用叫作FacesServlet的特殊servlet处理该通知。Web容器里的每个JSF应用都有它自己的FacesServlet。
在后台,每个JSF请求都触发3件事情,如图2 JSF的工作方式。

JSF的工作方式
图2  JSF的工作方式

为了处理JSF请求,它们必须交由FacesServlet处理,指定这种重定向是通过部署描述符中的servlet和servlet-mapping标记来实现的。

  1. <!-- Faces Servlet --> 
  2. <servlet> 
  3. <servlet-name>Faces Servlet</servlet-name> 
  4. <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> 
  5. <load-on-startup>1</load-on-startup> 
  6. </servlet> 
  7. <!-- Faces Servlet Mapping --> 
  8. <servlet-mapping> 
  9. <servlet-name>Faces Servlet</servlet-name> 
  10. <url-pattern>/faces/*</url-pattern> 
  11. </servlet-mapping> 

这表示所有请求的URL中都必须包含/faces/这个字符串模式,servlet-mapping元素下的url-pattern元素指定了这一点。注意:

可以指定一个上下文参数saveStateInClient并赋给它一个true值,以此来强制JSF把状态存放在客户端而不是服务器端。如果您打算这么做,必须在部署描述符中的servlet元素之前加入如下的context-param元素。

  1. <context-param> 
  2. <param-name>saveStateInClient</param-name> 
  3. <param-value>false</param-value> 
  4. </context-param> 

FacesServlet生成一个叫作FacesContext的对象,它包含了处理请求所必须的信息。更确切地说,FacesContext对象中包含Web容器传给FacesServlet的services方法的 ServletContext、ServletRequest及ServletResponse对象。在处理过程中,主要修改的就是这个 FacesContext对象。接着就是处理,处理器是一个叫作Lifecycle的对象。FacesServlet把控制权转交给Lifecycle,Lifecycle对象分6个阶段来处理FacesContext对象,我们稍后将会看到这些阶段。注意:

Lifecycle对象处理JSP请求所需的一系列动作称为请求处理生命周期(request processing lifecycle),这个词自始至终贯穿本书。

JSF的工作方式允许使用一个应用配置文件来配置JSF应用。讨论过Lifecycle对象的处理阶段后,我们会讨论如何使用这个配置文件来注册JavaBeans。

2.理解请求处理生命周期的各个阶段

Lifecycle对象分6个阶段来处理JSF请求(被封装在FacesContext对象里,而FacesContext对象就是处理过程中由Lifecycle读取并修改的对象),过程如下:
◆重建组件树 JSF应用里的JSP页面被表示成一个组件树。在这个阶段,通过重建这棵树来开始Lifecycle的处理过程。每个组件树都有一个在整个应用范围里惟一的标识符,此标识符是所请求URI的路径信息部分。比如,对于一个URI为/faces/index.jsp的请求,组件树的标识符就是 /index.jsp。生成的组件树保存在FacesContext对象中,以备后面的处理过程所用。
◆应用请求值 在这个阶段,使用请求里的当前值来更新每个组件的本地值。这些值可能来自请求参数、请求的报头及cookie等。在这个阶段的处理中,组件可以往事件队列里加入某些事件,这些事件可在随后的处理阶段处理。
◆处理验证 当每个组件的本地值被更新后,在此阶段中,Lifecycle对象会验证这些值的合法性。要求验证的组件必须提供验证逻辑的实现。作为选择,开发人员可以为一个组件注册零个或多个验证器。如果发现外部验证器,那么还会应用这些外部验证器里的验证逻辑来验证本地值。
◆更新模型值 只有当组件树中所有组件的本地值都通过验证后,才有可能到达该阶段。在这个阶段里,LifeCycle更新应用的模型数据。组件在这个阶段也可以排列事件。
◆调用应用 在这个阶段,JSF实现处理所有应用层次的事件,比如提交表单或链接到其他页面等。
◆呈现响应 在这个阶段,JSF实现将响应发回客户端。

由于请求处理生命周期里的应用请求值、处理验证、更新模型值和调用应用等阶段都可以在当前请求对应的FacesConetxt的实例里排列事件,因此,JSF实现必须在这些阶段后处理这些事件。

在两个阶段中间,Lifecycle对象会检查所有需要调用的事件监听器。当编写事件监听器时,需要选择事件监听器应在哪个阶段过后调用。或者,也可以编写一个在不同阶段后调用的事件监听器。图3表明了处理JSF请求的各个阶段。标有“处理事件”的方框表示Lifecycle对象在该处执行事件监听器。

请求处理生命周期的各个阶段

图3  请求处理生命周期的各个阶段

注意,事件监听器可能会改变处理过程。它可以指示Lifecycle对象直接跳到***一个阶段,或是在当前事件处理完后马上退出。

3.使用应用配置文件注册JavaBeans
可以通过一个应用配置文件很容易地配置JSF应用。在这个文件里,可以注册应用中用到的JavaBeans,通过指定页面导航规则定义程序控制流程,注册自定义组件及执行其他配置工作等。

应用配置文件是一个XML文件,可以有好几种声明方式。最简单的方式是把它放到WEB-INF目录中,并且命名为faces-config.xml。应用配置文件的根元素是faces-config。下面是应用配置文件的框架:

  1. <?xml version="1.0"?> 
  2. <!DOCTYPE faces-config PUBLIC  
  3. "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.0//EN"  
  4. "http://java.sun.com/dtd/web-facesconfig_1_0.dtd"> 
  5. <faces-config> 
  6. </faces-config> 

JSF应用的许多方面都可以通过应用配置文件来配置。在这里,我们主要关注如何注册JavaBeans(用于本章稍后的例子)。第15章会详细讲解应用配置文件。在一个JSP页面里,可以使用jsp:useBean动作告诉JSP容器,正在使用jsp:useBean动作的class特性里指定的JavaBean,如下所示:

  1. <jsp:useBean id="numberBean" class="ch02.NumberBean" scope="session"/> 

这将告诉Web容器装入JavaBean类并且在JSP页面被调用时创建一个实例。jsp:useBean动作只需要在一个页面里声明,而在同一个应用的所有JSP页面里可用。在JSF应用中允许您做到这一点,而不是在应用配置文件中注册JavaBean。

使用<jsp:useBean>有一个缺点,如果一个页面在包含jsp:useBean动作的页面之前被调用,Web容器会抛出一个异常。这是因为这个页面试图使用一个尚未创建的JavaBean。而使用应用配置文件注册该JavaBean就不会有这个问题。

对于每个打算在应用配置文件里注册的JavaBean,使用faces-config元素中的managed-bean标记,在managed-bean元素中有下列子元素:
◆managed-bean-name 标记定义从JSP页面里引用JavaBean时使用的名称。
◆managed-bean-class元素 指明JavaBean类。
◆managed-bean-scope元素 定义JavaBean的作用域。
下面是managed-bean的一个例子:

  1. <managed-bean> 
  2. <managed-bean-name>myBean</managed-bean-name> 
  3. <managed-bean-class>myPackage.MyBean</managed-bean-class> 
  4. <managed-bean-scope>session</managed-bean-scope> 
  5. </managed-bean> 

本例中的managed-bean元素定义了一个类型为myPackage.MyBean的JavaBean,在JSF应用的JSP页面里可以用名称myBean来引用它,它的作用域是session,表示开始一个用户会话时就创建这个bean的一个实例。

【编辑推荐】

  1. 简述JSF入门介绍
  2. JSF和Struts的区别概述
  3. 编写JSF自定义复合组件的原则和技巧
  4. 选择JSF不选Struts的十大理由
  5. Tapestry和JSF对比
责任编辑:佚名 来源: 中国IT实验室
相关推荐

2009-07-10 13:55:48

Swing控件

2009-09-28 13:39:01

Hibernate工作

2009-07-14 12:47:07

WebWork工作方式

2010-08-06 10:41:59

Flex命名空间

2016-10-27 17:49:07

群晖群晖科技NAS

2009-08-13 18:36:29

C#数组工作方式

2010-07-22 09:01:02

SQL Server镜

2010-01-25 14:57:49

Android数据库

2023-03-20 15:34:00

ChatGPT人工智能

2024-03-27 14:51:23

2021-12-07 10:18:06

首席信息官技术发展企业管理者

2011-07-14 13:20:49

Servlet过滤器

2009-02-25 10:52:00

路由器原理工作方式协议

2022-12-02 13:43:54

供应链首席供应链官

2022-08-29 20:06:04

楼宇自控物联网

2024-04-15 08:00:00

生成式AI人力资源ChatGPT

2013-09-04 11:16:12

物联网

2015-08-18 09:24:49

云技术工作应用人工智能

2010-04-16 16:39:25

Oracle细粒度

2012-11-27 09:12:39

思杰移动云计算
点赞
收藏

51CTO技术栈公众号