对jsf理解

基本上来说JSF应用就像普通的web应用一样运行在Servlet容器中。一个典型的JSF应用通常包括:

Java Bean组件,完成业务于逻辑 事件监听器 页面 服务器端帮助类,比如DAO类

显示UI组件的taglib 代表事件处理器(event handler),校验器(validator)和其他动作的taglib代表服务器上状态的UI组件 Backing beans定义UI组件的属性和函数校验器(validator),转换器(converter),事件监听器,事件处理器 配置的资源文件JSF的页面用代表UI组件的自定义标签来显示HTML,一般还可能有其他核心动作的自定义标签如校验器,事件处理器。这些标签由JSF提供

角色与分工

  • 页面开发:通常是美工,用HTML脚本等,在JSF中用JSF的自定义标签

  • 应用开发:写应用逻辑,事件处理,对象转换,校验器等

  • 组件开发:写自定义的UI组件,有UI经验,或扩展JSF的标准组件

  • 应用架构师:设计web应用,确保应用伸缩性,定义页面流转,配置beans,注册应用的对象

  • 工具提供商:提供开发工具

45.4.2. JSF页面的生命周期

JSF页面的生命周期与JSP页面的生命周期相类似:客户相页面发出HTTP请求,服务器返回翻译成HTML的响应,但JSF提供了更多处理页面的服务。生命周期与页面编写者无关,这个概念主要面对开发人员。

45.4.2.1. 重建视图阶段(Restore View Phase)

当请求JSF页面时,如点击按钮或链接,JSF开始重建视图阶段。

在这个阶段JSF建立页面的视图,给视图中的组件设置事件处理器、校验器,在FacesContext中保存视图。FacesContext含有所有处理请求的信息,所以页面元素包括组件标签、事件处理器、转换器、校验器都要接触FacesContext。如果请求是第一次的请求,JSF在这个阶段产生一个空的视图,生命周期进入显示应答阶段,这个空的视图会在页面返回的时候用到。如果请求是返回的请求,对应于这个页面的视图已经存在,JSF用存在客户端或服务器端的信息重建视图。

45.4.2.2. 应用视图值阶段(Apply Request Values Phase)

在组件树重建后,每一个树上的组件用decode方法从请求中解出其新的值,这个值保存在组件中。如果值数据转换失败,产生与此组件相联系的错误,并入FacesContext的上下文,错误信息在其后的显示应答阶段显示。

如果任何decode方法或事件监听器调用了当前FacesContext的renderResponse方法,则JSF直接跳到显示应答阶段。如果在这个阶段有事件产生,JSF广播事件到感兴趣的监听器。

如果此时应用转到另一个web应用或应答不含有JSF组件,则调用FacesContext.renderComplete方法。在此阶段结束时,所有组件已得到新值,错误信息和事件已入队列。

45.4.2.3. 处理校验阶段(Process Validations Phase)

此阶段,JSF处理所有组件树上注册的校验器,检查设置了校验的组件属性,如果值不合法JSF在上下文(FacesContext)中加入错误信息,生命周期直接进入显示应答阶段,显示错误信息,如果有转换错误也会显示。

如果任何validate方法或事件监听器调用上下文的renderResponse方法,JSF直接跳到显示应答阶段。

45.4.2.4. 更新模型值阶段(Update Model Values Phase)

在JSF确定数据合法之后,遍历组件树,从组件中取得相应值设置到服务器对象上。

如果任何updateModels或监听器调用renderResponse方法,JSF直接跳到显示应答阶段。

45.4.2.5. 调用应用阶段(Invoke Application Phase)

此阶段,JSF除了应用级别事件,如:表格提交或到其它页面的链接等;重建视图时产生的事件广播到感兴趣的监听器上,JSF计算应答到新的页面。

45.4.2.6. 显示应答阶段(Render Response Phase)

此阶段,如果应用是JSP页面,JSF将控制转到JSP容器。

如果是第一次请求,执行JSP页面是会把页面上显示的组件加到组件树中。当JSP容器遍历页面的标签时组件会将自己显示出来。如果是返回的请求且在其它阶段产生了错误,则显示原始页面并显示错误信息。

45.4.3. UI组件模型

JSF的UI组件是可配置可重用的,组件可以是最简单的如一个按钮,也可以组合如包括若干组件的表格

JSF提供:

一套确定UI组件状态和行为的UIComponent类

  • 定义了怎样显示组件的显示模型

  • 定义了怎样处理组件事件的事件与监听模型

  • 定义了怎样注册数据转换器到组件的数据转换模型

  • 定义了怎样注册校验器到组件的校验模型

45.4.3.1. UI组件类

SF提供一套UI组件类和与其相关联的行为接口,如:保持组件状态,保持对象引用,驱动事件处理,显示标准组件等。

所有JSF UI组件扩展UIComponentBase类,包含以下组件类:

  • UIComponent:表示UIData的一个数据列

  • UICommmand:激活产生行为

  • UIData:一个由DataModel实例表示数据集合的绑定

  • UIForm:提交到应用的一组数据,HTML里就是form标记

  • UIGraphic:显示一个图片

  • UIInput:接受用户数据输入,UIOutput的子类

  • UIMessage:显示本地化信息

  • UIMessages:显示本地化信息集合

  • UIOutput:显示数据输出

  • UIPanel:管理子组件的摆放

  • UISelectBoolean:用户选择或不选择来获得一个布尔值,UIInput的子类

  • UISelectItem:选择单一项

  • UISelectItems:选择多项

  • UISelectMany:允许用户选择多项,UIInput子类

  • UISelectOne:允许用户选择单项,UIInput子类

  • UIViewRoot:组件树的根

除了扩展UIComponentBase类,组件还可以实现一个或多个行为接口,这些接口定义了特定的行为:

  • ActionSouce:表示组件可以发生行为事件

  • EditableValueHolder:扩展ValueHolder类,定义可编辑组件的额外特性如校验、发出值变化事件

  • NamingContainer:强制以此组件为根的组件必须有唯一ID

  • StateHolder:表示组件在请求之间保存状态

  • ValueHolder:组件保存局部状态

  • UICommand实现ActionSouce和StateHolder。UIOutput实现StateHolder和ValueHolder;UIInput实现EditableValueHolder,StateHolder,ValueHolder;UIComponentBase实现StateHolder。可以参考JSF的JavaDoc(http://java.sun.com/j2ee/javaserverfaces/1.1/docs/api/index.html),当然这些类和接口是面向组件编写者的,页面开发和应用开发者只需要使用组件就可以了。

45.4.3.2. 组件显示模型

JSF的组件架构设计成组件的功能由组件类决定,而它显示出来是什么样子由另外的显示器(renderer)决定。这样的设计包含了这样的考虑:组件编写者写一次组件的行为却可以定义多个显示器,由显示器决定呈现给客户组件的样子,可以是同一个客户或不同的客户;页面编写者或应用开发者可以通过更换不同组件与显示器结合的tag来改变组件在页面上的样子。

显示包(render kit)定义了对特定客户的组件与标记之间的映射。我们对JSF的支持包含了HTML客户的标准显示包。显示包对其支持的每一种UI组件都定义了一套显示器类,每一个Renderer类不同的显示组件的方式,比如:UISelectOne有三个不同的显示器,或者显示成圆按钮,或者显示成多选框,或者显示成下拉框。

标准显示包里的每一个自定义标签由组件功能和显示属性组成。例如,UICommand组件就可以显示成按钮或一个链接,功能都是发生一个动作。

Apusic服务器中提供HTML显示的自定义标签,如下表:

标签 功能 显示 样子
column UIData组件的一列数据 HTML表的一列 表格的一列
commandButton 提交表格 HTML<input type=type>元素,type值为submit,image,reset 按钮
commandLink 链接到其他页或页面的某一位置 HTML<a href>元素 链接
dataTable 数据包装 HTML<table>元素 动态更新的表
form 输入表,表内的标签接收的数据和表一起提交 HTML<form>元素
graphicImage 显示图片 HTML<image>元素 图片
inputHidden 页面中包含隐藏变量 HTML<input type=hidden>元素
inputSecret 加密输入 HTML<intput type=password>元素 密码输入
inputText 输入字符串 HTML<input type=text>元素 字符串输入
inputTextarea 多行字符串 HTML<textarea>元素 多行字符串输入
message 显示本地化信息 如果用了style是HTML的<span>元素 文本字符串
messages 显示多个本地化信息 如果用了style,是HTML的多个<span> 同上
outputLabel 输入项的标记 HTML的<label>元素 文本
outputLink 链接到其它页或其它位置但每有动作事件 HTML<a>元素 链接
outputFormat 显示本地化信息 文本 文本
outputText 显示一行文字 文本 文本
panelGrid 显示表 HTML包含<td>和<tr>的<table>元素
panelGroup 同一父组件下的一套组件组 表的一行
selectBooleanCheckbox 用户可以改变布尔选择的值 HTML<input type=checkbox>元素 选择框
selectItem UISelectOne组件的一项 HTML<option>元素
selectItems UISelectOne组件选项列表 HTML<option>元素的列表
slectManyCheckbox 复选框 HTML<select>元素 列表框
selectManyListbox 复选列表 HTML<select>元素 列表框
selectManyMenu 多个项目中可多选 同上 可滚动多选框
selectOneListbox 所有选择中选一个 同上 列表框
selectOneMenu 多个项目中选一 同上 可滚动选择框
selectRadio 选一项 HTML<input type=radio>元素 圆按钮
45.4.3.3. 转换模型

JSF应用可以将组件联系在服务器对象数据上,如Java Bean称为backing bean,应用存取组件的数据通过调用组件的对象属性。当组件绑定对象,应用有两个组件数据的视图:模型视图,数据是由数据类型表示的,如int或long;表示视图,这时数据可由客户读写,如:java.util.Date可以表示为mm/dd/yy格式的字符串。Apusic服务器JSF实现自动转换转换这两个视图间的数据,但要求与组件相联系的bean属性是组件数据支持的类型,例如:与UISelectBoolean组件相联系的bean属性是java.lang.Boolean,JSF自动将组件数据从String转换为Boolean,当然组件数据必须与合适的数据类型相绑定,即UISelectBoolean必须与类型boolean或java.lang.Boolean相绑定。

如果是非标准数据,你可以在UIOutput或其子类组件上注册转换器(Conveter),到时转换器将完成两个视图间数据的转换。

转换器可以自行编写,有三个步骤:完成Conveter接口、注册转换器、页面编写者在需要转换数据的组件标签上应用这个转换器。

45.4.3.4. 事件和监听器模型

JSF的事件监听模型与JavaBean的事件机制类似,但要求强事件类型且监听器接口由UI组件生成。

Event对象确定产生事件和存储事件信息的组件。如果要处理事件提示,应用要完成监听器接口,并注册在产生事件的组件上。当用户激活某个组件,如单击某个按钮,一个事件产生,这时JSF调用监听器方法处理事件。

JSF支持三类事件:值改变、动作事件、数据模型事件。

动作事件发生在用户激活了完成ActionSource接口的组件,包括按钮和链接。

值改变事件发生在用户改变了UIInput及其子类组件所代表的值,例如用户选择了一个单选框,则产生这个组件值变成true的事件,这种类型的事件可以由如UIInput、UISelectOne、UISelectMany、UISelectBoolean等组件产生,不过这种事件的产生是以没有校验错产生为前提的。由这种组件的immediate属性来决定动作事件的处理是在应用调用阶段(invoke application phase)或应用请求值阶段(apply request phase)1;值变化事件是在校验阶段(validation phase)或应用请求值阶段。

数据模型事件UIData组件的一行被选中的情况下,具体见高级功能。

有两个方法使你的应用响应动作事件或值变化事件:完成处理事件的监听器类,并在组件标签内使用valueChangeListener标签或actionListener标签以注册监听器到这个组件;完成backing bean的方法来处理事件,并从标签的合适属性上使用方法绑定表达式(method- binding expression)来引用它。

如果你自己编写组件产生事件,除了上述步骤还要编写事件类,然后手动将事件入组件的事件队列。

45.4.3.5. 校验模型

JSF支持校验可编辑组件的本地数据,如文本输入组件,校验发生在本地值更新之前。JSF定义了一系列标准校验器做常规数据校验,在核心标签里定义了一套完成Validator接口的标签,大多数标签都有多个属性用来配置校验器,如允许组件数据的最大最小值。页面编写者使用时在组件标签内部使用校验器标签即注册了这个校验器。

你也可以自己编写校验器来达到完成自定义的校验,有两种方式:完成Validator接口或完成backing bean的方法,如果是完成Validator接口就必须注册校验器,然后再写一个自定义标签;如果是完成backing bean的方法就需要从组件标签的validator属性引用此校验器

45.4.4. 导航(Navigation)模型

基本上来说所有web应用都是一系列的页面组成,这就有一个基本任务是如何管理这些页面的导航,JSF的导航模型管理页面的流转非常容易。JSF定义导航(navigation)是指当点击一个按钮或链接时系统选择下一个要显示的页面的规则,这些规则定义在JSF的配置文件中。

简单的导航规则先在配置文件中定义规则,然后在按钮或链接的action属性中指定得出的字符串结果,这个字符串就是系统选定的导航规则。复杂的应用则需要开发人员写动作(action)方法,在一定的计算后得到下一个要显示的页面,而触发的组件应用此方法。

当点击一个按钮或链接时,与此相关联的组件产生动作事件,动作事件由缺省动作监听器(ActionListener)处理,触发组件的动作方法;动作方法由应用开发人员在backing bean中定义,完成一定的计算输出逻辑结果的字符串代表处理结果;监听器输出处理结果并传给缺省导航处理器(Navigation Handler),导航处理器通过匹配在配置文件中定义的输出字符串或动作方法来选择下一个页面。

导航规则定义了怎样从一个页面浏览到应用中的其它页面的规则,每一个导航项(navigation case)定义了一个目标页和或者是逻辑输出字符串或者是动作方法的引用,或者二者都有。 例如:

<navigation-rule>

<from-view-id>/greeting.jsp</from-view-id>

<navigation-case>

<from-outcome>success</from-outcome>

<to-view-id>/response.jsp</to-view-id>

</navigation-case>

</navigation-rule>

这个规则说明当greeting.jsp页面上的按钮或链接被激活并且逻辑输出字符串是success时应用从greeting.jsp流转到response.jsp。

45.4.5. Backing Bean管理

Web应用的另一个重要功能就是资源的管理,包括分离UI组件与商业逻辑对象,数据对象;还包括在合理可见范围内管理与存储这些对象。JSF应用通常包括一个或多个与UI组件相联系的backing bean。Backing bean定义了绑定在组件值或组件实例上的UI组件属性。Backing bean也可以定义与组件相联系的功能方法,如校验、事件处理、导航处理等。页面编写者用EL(Expression Language)将组件值与实例和backing bean属性绑定,或者从UI组件的标签里引用backing bean的方法,EL用#{}作为分隔符。JSF表达式可以是值绑定或方法绑定,可以混合字符串、求值、JSP2.0EL定义的操作符。

例如:绑定userNo组件的值到backing bean UserNumberBean的userNumber属性,同时用backing bean的validate方法完成组件值的校验,以确保用户输入的是有效值。

<h:inputText id="userNo" value="#{UserNumberBean.userNumber}" validator="#{UserNumberBean.validate}" />

绑定到组件属性的值必须是组件支持的类型,如:UserNumberBean的userNumber属性是整数类型,而UIInput组件支持此类型。UIInput组件除了validator属性还有一个valueChangeListener属性响应UIInput组件产生的ValueChangeEvent事件。 完成ActionSource接口的组件可以用actonListener和action属性来对应backing bean的方法,actionListener对应处理动作事件的方法,action对应与导航输出逻辑串的计算相关的方法。也可以用标签(tag)来绑定backing bean的属性和组件实例,如:<inputText binding="#{UserNumberBean.userNoComponent}" />,绑定的属性必须与组件的接受的类型一致,如上面的inputText标签必须是这样编写:

UIInput userNoComponent = null;

...

public void setUserNoComponent(UIInput userNoComponent) { this.userNoComponent = userNoComponent;

}

public UIInput getUserNoComponent() { return userNoComponent;

}

当组件实例与backing bean相绑定,则backing bean的属性保持组件的当前状态;而如果将组件值与backing bean绑定,JSF在update model生命周期时backing bean会更新组件的状态。 绑定组件实例的好处是backing bean可以在程序里修改组件属性,backing bean可以自己实例化组件而不需要页面编写者来做;绑定组件值的好处是页面编写者可以控制组件属性,backing bean不需要依赖JSF API,有利于分离表示层与模型层,JSF可以自动完成bean属性的数据转换,不需要程序员来做。

大多数情况下可以使用组件值绑定,只有在你需要动态改变组件的某一属性时才需要绑定组件实例,例如应用在某些条件下才显示某个组件,你可以依据不同的条件设定组件的rendered属性。

Backing bean的创建与存储由在配置文件中指定,由managed bean机制来管理。

除了可以用binding、value属性来引用bean,还可以创建ValueBinding来引用bean的更多资源。

45.4.6. 更多参考:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值