版权说明:本文书写过程中参照了红帽的技术文档;本系列文章中的部分测试代码为红帽公司版权所有,因此不能提供源码文件。
一、Rich Web应用
富Web应用程序是具有以下特征的应用程序:
丰富的页面组件,是具有标准安装软件外观的用户界面元素。例如,单击按钮可创建弹出模式对话框以处理信息。丰富的组件使用<script>标记写入页面中包含的非常复杂的Javascript库中。今天有许多优秀的开源组件库。在本课程中,我们将使用RichFaces组件。
丰富的应用程序的标志之一是缺少页面重新加载和减少页面导航。例如,您在表单上输入数据,然后单击“提交”按钮。没有明显的等待响应。这是因为是使用了Ajax技术将数据传输到服务器并在后台接收响应。
鉴于Ajax和丰富的UI组件的组合,我们看到单个工作单元在一个页面上完成。这大大减少了Web应用程序中的页面数量,但代价是单个页面内的复杂性增加。工作单元可以是发票输入,其中发票输入的所有功能在一个页面上可用:创建,更新,删除和查询。我们将看到RichFaces如何能够大大降低复杂性并加速此类丰富应用程序的开发。
二、Ajax简介
Ajax是Asynchronous Javascript和XML的缩写。现代浏览器配备了Javascript语言可用的对象,允许将数据异步发布到服务器并接收响应。该对象与强大的基于对象的语言模型相结合,并且访问HTML(DOM)的对象模型用于创建非常令人满意的用户体验。应用程序的响应性通常达到已安装软件的响应性。没有更多的等待浏览器刷新进入工作单元的下一步。
JSF2生命周期本机处理Ajax处理。可以在执行和呈现阶段部分更新组件树。使用facelets标记在页面上对组件进行分组,以指示要处理和呈现的组件。
虽然有内置的JSF标记可以管理Ajax事务,但我们将把注意力集中在这个单元中的RichFaces标记库上。
三、Ajax表单提交
我们将看到的第一个特性,是能够提交表单数据并仅在页面的该部分调用JSF生命周期而无需重新加载页面。 以下是声明注册表单的页面部分(简化以供讨论):
繁重的工作由<a4j:commandButton>标签完成。 这类似于<h:commandButton>标记,但有两个属性:
此属性设置为对要提交的组件进行分组的面板的id。 在此示例中,将更新新成员bean的名称、电子邮件和电话号码。
此属性设置为面板的id,该面板对操作完成后要呈现的组件进行分组(执行和呈现阶段)。
action属性就像常规facelets命令按钮一样,属性将在EL引用的bean和在托管bean上调用的方法中更新,也由EL引用。
在许多a4j标签上都可以找到execute和render属性。 这些属性不仅接受要呈现的组件的id。 他们可以接受:
要渲染的空格分隔的组件列表
@form - 提交在其嵌入的表单中定义的所有字段
@this - 组件本身内声明的区域或组件
@none - 不渲染页面的任何部分
@all - 渲染页面上的所有组件
要使用RichFaces标记,需要声明其命名空间,如下所示:
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich"
四、RichFaces组件
快速入门展示了许多RichFaces组件,包括:
我们访问RichFaces组件的展示:http://showcase.richfaces.org找到所有组件的演示以及每个演示的源代码。
RichFaces库引入了流行的jQuery库。 快速入门演示了使用jQuery在注册新成员时显示消息。
如何在页面上放置一个组件,例如列出当前库存的表格,并在库存发生变化时自动更新,即使库存交易不是来自你? 使用RichFaces推送。 RichFaces推送组件适用于基于JMS或CDI事件的数据源。 页面上的RichFaces组件充当服务器上发生的事件的侦听器。 我们将审查基于CDI事件的组件版本。
首先,必须从某个托管bean发布事件。 要启用推送功能,只需将注释@Push添加到事件的注入站点即可。 其他一切都是一样的:调用Event <T> .fire(T)来发布事件。 以下是RichFaces快速入门的示例:
接下来,我们必须为这些事件设置订阅者。 这是通过RichFaces <a4j:push>标记完成的:
有关上面代码段的注意事项:
现在让我们看一下Ajax连接。 <a4j:push>标记表示它通过在MemberRegistration中将@Push注释中的主题设置为相同主题值的地址属性来侦听的主题。 Javascript回调函数ondataavailable执行包含jQuery逻辑的代码。 在push标签内,我们有一个<a4j:ajax>标签。 此标记声明每当调用dataavailable回调时,都会呈现包含成员列表数据表的可折叠面板。
四、客户端验证
我们可以使用RichFaces使用Ajax支持的字段验证。 每当用户选中一个字段时,就会进行验证,并显示任何消息,其中<rich:message>标签与具有for属性的字段相关。 如果字段参与Ajax表单提交,则也会进行验证。
快速入门使用客户端验证,使用JSF页面中的<rich:validator>标记和相应成员实体bean属性上的JSR-303 bean验证注释。 以下是显示验证注释的Member类的一部分:
以下是使用<rich:validator>和<rich:message>标记实现客户端验证的JSF页面的一部分:
五、对象验证
有时需要应用涉及对象中多个字段的验证逻辑。 需要能够在JSF生命周期中的某个点应用验证,我们知道所有属性值已成功存储在支持页面的托管bean中。 可以使用RichFaces图验证器。 使用图形验证器分为两步。 首先,必须将<rich:graphValidator>标记放在必须在对象验证开始之前更新的字段周围。 这是一个例子:
<rich:graphValidator>标记指向要使用EL验证的对象。 在这种情况下,将处理Invoice对象。 请注意,正在处理的对象通常是其数据属性由其正文中的UI组件更新的对象。
请注意,图验证器的id是“gv”。 这个名字并不重要; 它可以是任何名字。 该ID用于<rich:messages>标记,位于其下方几行。 这告诉Faces将为组件“gv”生成的消息放在这里。 这就是我们与facelets的关系。
现在,我们需要向Invoice添加对象验证方法。 使用@AssertTrue注释对象验证方法。 您可以拥有任意数量的验证方法。 在撰写本文时,方法名称必须以“是”开头。 请务必在@AssertTrue注释中指定验证消息。 以下是对象验证方法的示例:
六、实验验证:将应用程序转换为富应用程序
本应用要展示的效果是:从前台插入一个发票信息以后,信息会被存储到数据库中;同事,前台触发查询,这时候新插入的发票信息可以被push到前台显示。
首先通过JBDS导入maven项目。
查看依赖:
运行应用:
UI界面:
输入信息,点击提交查询:
可以查到刚刚插入的信息(从数据库推到前台)
源码分析
打开index.xhtml文件。
请注意为rich和a4j标记库添加了名称空间声明:
发票输入表单周围添加了<rich:panel>。 删除了两个<ui:fragment>组件,因为页面的上半部分将与页面底部交互而不提交整个页面。
探索Ajax表单提交
<h:commandButton>已替换为其Ajax等效项。 完成命令按钮操作后,将呈现包含表单的<rich:panel>:
<rich:panel id="invoiceEntry" header="Invoice Entry">
<h:form id="invoice">
...
<a4j:commandButton execute="@form" action="#{orderEntry.create}"
render="invoiceEntry" />
...
</h:form>
</rich:panel>
探索客户端验证
探索对象验证
接下来,我们添加了一个涉及多个bean的编辑。 我们使用了RichFaces对象验证功能<rich:graphValidator>。
验证将验证税收类型是否在发票应纳税时设置为值。
验证方法已添加到Invoice类中。 只要以“is”开头,可以将此方法命名为您喜欢的任何方法。 我们应用了@AssertTrue验证注释,以便图形验证器将找到此方法并在对象验证阶段调用它:
接下来,我们将图形验证器添加到JSF页面。 我们确保设置适当的属性,以便验证Invoice对象:
我们确保对象验证消息将与其他全局消息一起显示在面板顶部:
<rich:messages for="gv"/>
gv“匹配<rich:graphValidator>的id。
探索推送功能
我们在OrderEntry类中添加了一个类型为Invoice的推送事件。 我们在create()方法中放置逻辑来触发事件,在将发票插入数据库后传递它:
我们在JSF页面中添加了<a4j:push>和相关标签。 我们确保主题地址属性与@Push注释中设置的主题一致。 当新数据可用时,将显示“invoiceTable”面板。
我们必须确保以下内容位于<a4j:push>标记中:
ondataavailable=""
在此步骤中,我们将探索一个工具提示,该工具提示将在鼠标悬停在发票编号列上时显示发票详细信息。
在第一列的定义(<rich:column>)的末尾添加了以下代码:
效果: