JSF 2.2和HTML5

虽然只是小版本的升级,但对于希望在JSF应用中使用HTML5技术的开发人员而言,JSF 2.2带来的更新很重要,尤其是pass through能力,它允许在JSF组件不知情的情况下传递HTML属性。

HTML5中增加了很多新特性,其中有些是在已有的元素上增加了对新属性的支持。例如,input元素的type属性支持text、search、email、url、tel、range、number和date等属性值。另外,它还有一系列的自定义数据属性,用来在HTML元素上关联少量数据。这些数据不会显示,但可以用JavaScript读取。

对于像JSF这样基于组件的库,上述情况带来一个问题:为了识别新属性,所有已有的组件必须更新。对于需要显式支持这些属性的组件而言,的确如此。但在很多情况下,组件只需要在最终生成的标记中包含这些属性即可。JSF 2.2的pass-through属性就是这样实现的。

在Facelet页中,pass-through属性可以通过以下三种方法设置:

1. 通过组件标签的命名空间属性

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:p="http://java.sun.com/jsf/passthrough">
    <h:form>
        <h:inputText value="#{bean.value}" p:placeholder="Enter text"/>
    </h:form>
</html>

2. 通过TagHandler f:passThroughAttribute设置单个属性

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core">
    <h:form>
        <h:inputText value="#{bean.value}" >
            <f:passThroughAttribute name="placeholder" value="Enter text" />
        </h:outputText>
    </h:form> 
</html>

3. 通过TagHandler f:passThroughAttributes设置多个属性

<h:outputText value="Something" >
    <f:passThroughAttributes value="#{bean.multipleAttributes}" />
</h:outputText>

#{bean.multipleAttributes}代表一个Map<String,Object>对象。它的值可以是常量,也可以是表达式。

通过使用Express Language 3(Java EE 7的一部分),多个属性也可以通过EL表达式直接定义。

<h:outputText value="Something" >
    <f:passThroughAttributes value="{"one":1, "two":2, "three":3}" />
</h:outputText>

上述改变结果是,开发人员现在可以使用纯HTML来编写JSF视图,这是Wicket等竞争对手框架经常被提及的优势。

在服务器端,可以使用类UIComponent的新方法getPassThroughAttributes()getPassThroughAttributes(boolean create) 来设置属性。

UIComponent component = new SomeComponent();
Map passThrough = component.getPassThroughAttributes();
passThrough.put("placeholder", "Enter text");

与pass through能力一起,JSF 2.2还进行了两项意义重大的增强:Faces Flow和“无状态视图(Stateless Views)”。

Faces Flow

Faces Flow的灵感来自ADF “任务流(Task Flows)”和Spring“页面流(Web Flow)”。它提供了对流的直接支持。流被定义为节点间的流转,可以引导用户浏览一组页面和一些相关用例。节点可以是:

  • “一个视图(A View)”:应用程序中的任何JSF页面
  • “一次方法调用(A Method Call)”:通过EL表达式从流图调用应用逻辑
  • “一个开关(A Switch)”:在流图中基于布尔型EL表达式进行导航决策
  • “一次流调用(A Flow Call)”:带参数调用另一个流并接收返回值
  • “一次流返回(A Flow Return)”:返回至调用流

节点定义了流的入口和出口。

JSF 2.2引入了如下两个新注释:

  • @FlowScoped是一个CDI作用域,定义了bean在特定流中的作用范围。Bean在进入该作用域时自动激活,而退出时自动失效。
  • @FlowDefinition是一个类级别的注释,它允许通过FlowBuilder API定义流。

最后,引入了新的EL对象#{flowScope},用于流的本地存储。该对象对应 facesContext.getApplication().getFlowHandler().getCurrentFlowScope()

“无状态视图(Stateless Views)”

许多框架是有状态的,尤其是组件框架。但是如果状态信息不需要维护会有若干优点,最重要的是可以避免集群中节点间的状态复制,或者避免使用粘性会话保证请求返回至发起节点。与上述优点相比,提升框架性能和降低内存消耗等经常被提及的优点就不是那么确定无疑了。虽然状态可能导致Web框架的性能以及内存消耗问题,但在企业应用中这种影响实际上是微不足道的。JSF 2.x的“部分状态保存(Partial State Saving)”仅更新有变化的状态,使得应用和保存状态的过程相当高效,对性能的影响较小。同样地,状态信息占用的内存也非常小。

JSF的无状态实现方式很直观,处理<f:view>的TagHandler将其布尔值属性transient 传递给UIViewRoot#setTransient即可。如果页面设置为临时的,JSF StateManager就不存储它的任何数据,页面还原时,它也会被创建为无状态的。

JSF 2.2还有许多其它小的变化。Arjan Tijms在J-Development上的文章进行了更为详尽的说明。

参考英文原文:JSF 2.2和HTML5

感谢杨赛对本文的审校。

给InfoQ中文站投稿或者参与内容翻译工作,请邮件至[email protected]。也欢迎大家通过新浪微博(@InfoQ)或者腾讯微博(@InfoQ)关注我们,并与我们的编辑和其他读者朋友交流。

你可能感兴趣的:(JSF 2.2和HTML5)