前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >富Web应用的架构与转化方法:Web应用系列第二篇

富Web应用的架构与转化方法:Web应用系列第二篇

作者头像
魏新宇
发布2018-10-23 15:18:41
3.5K0
发布2018-10-23 15:18:41
举报

版权说明:本文书写过程中参照了红帽的技术文档;本系列文章中的部分测试代码为红帽公司版权所有,因此不能提供源码文件。

  • 本文的内容仅限于技术探讨,不能作为指导生产环境的素材;
  • 本文分为系列文章,将会有多篇,初步预计将有多篇。
  • 笔者鼓励读者购买红帽培训获得更多系统性的培训。

一、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>标记,但有两个属性:

  • execute

此属性设置为对要提交的组件进行分组的面板的id。 在此示例中,将更新新成员bean的名称、电子邮件和电话号码。

  • render

此属性设置为面板的id,该面板对操作完成后要呈现的组件进行分组(执行和呈现阶段)。

action属性就像常规facelets命令按钮一样,属性将在EL引用的bean和在托管bean上调用的方法中更新,也由EL引用。

在许多a4j标签上都可以找到execute和render属性。 这些属性不仅接受要呈现的组件的id。 他们可以接受:

要渲染的空格分隔的组件列表

@form - 提交在其嵌入的表单中定义的所有字段

@this - 组件本身内声明的区域或组件

@none - 不渲染页面的任何部分

@all - 渲染页面上的所有组件

要使用RichFaces标记,需要声明其命名空间,如下所示:

代码语言:javascript
复制
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich"

四、RichFaces组件

快速入门展示了许多RichFaces组件,包括:

    • <rich:panel> The registration form is surrounded by a rich panel. The panel includes a header area and borders that define the region.
    • <rich:validator>, <rich:message>, <rich:messages> The validator works with any of the validator mechanisms. The validation is activated on form submission or when the user tabs out of the field. Each of the form fields in the quickstart is using a validator and message component based on JSR-303 bean validation. The messages tag displays global messages beside the register button. Using Ajax messages are updated dynamically when the validation event occurs.
    • <rich:collapsiblePanel> The members table is surrounded by a collapsible panel.
    • <rich:dataTable> The members table is produced using a rich data table. In its simplest use, it looks very much like a facelets data table. However, this rich component and related table components can produce some very sophisticated tables including collapsible sub tables, sorting, and filtering.
    • <a4j:commandLink> The Ajax command link works the same as the Ajax command button. It appears as a link instead of a button.
    • <rich:popupPanel> The popup panel, as its name implies, produces floating panels that are optionally modal. In this quickstart, a popup is used to display the member's details based on clicking the "view" link in a given row of the member table.

我们访问RichFaces组件的展示:http://showcase.richfaces.org找到所有组件的演示以及每个演示的源代码。

RichFaces库引入了流行的jQuery库。 快速入门演示了使用jQuery在注册新成员时显示消息。

如何在页面上放置一个组件,例如列出当前库存的表格,并在库存发生变化时自动更新,即使库存交易不是来自你? 使用RichFaces推送。 RichFaces推送组件适用于基于JMS或CDI事件的数据源。 页面上的RichFaces组件充当服务器上发生的事件的侦听器。 我们将审查基于CDI事件的组件版本。

首先,必须从某个托管bean发布事件。 要启用推送功能,只需将注释@Push添加到事件的注入站点即可。 其他一切都是一样的:调用Event <T> .fire(T)来发布事件。 以下是RichFaces快速入门的示例:

接下来,我们必须为这些事件设置订阅者。 这是通过RichFaces <a4j:push>标记完成的:

有关上面代码段的注意事项:

  • 使用一些jQuery逻辑输出Javascript,以根据事件的内容显示消息。 触发pushEvent时,您可以看到在MemberRegistration.register()方法中格式化的消息。
  • 显示数据库中所有成员的数据表已在可折叠面板中声明,其id为“memberList”

现在让我们看一下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>:

代码语言:javascript
复制
<rich:panel id="invoiceEntry" header="Invoice Entry">
	<h:form id="invoice">
...
    <a4j:commandButton execute="@form" action="#{orderEntry.create}"
					render="invoiceEntry" />
...
    </h:form>
</rich:panel>

探索客户端验证

  • 我们为表单中的每个输入组件添加了丰富的验证器(包括单选按钮等)。
  • 我们将<h:message>标记转换为其RichFaces等效标记,仅显示详细消息。
  • 我们删除了<h:messages>组件,并在面板顶部显示了RichFaces全局消息显示。
  • 我们在Invoice类中添加了适当的bean验证注释:
  • 公司名称,联系人姓名和电子邮件不能为空 - 我们使用@NotEmpty
  • 电子邮件必须采用有效格式 - 我们使用@Email

探索对象验证

接下来,我们添加了一个涉及多个bean的编辑。 我们使用了RichFaces对象验证功能<rich:graphValidator>。

验证将验证税收类型是否在发票应纳税时设置为值。

验证方法已添加到Invoice类中。 只要以“is”开头,可以将此方法命名为您喜欢的任何方法。 我们应用了@AssertTrue验证注释,以便图形验证器将找到此方法并在对象验证阶段调用它:

接下来,我们将图形验证器添加到JSF页面。 我们确保设置适当的属性,以便验证Invoice对象:

我们确保对象验证消息将与其他全局消息一起显示在面板顶部:

代码语言:javascript
复制
<rich:messages for="gv"/>

gv“匹配<rich:graphValidator>的id。

探索推送功能

我们在OrderEntry类中添加了一个类型为Invoice的推送事件。 我们在create()方法中放置逻辑来触发事件,在将发票插入数据库后传递它:

我们在JSF页面中添加了<a4j:push>和相关标签。 我们确保主题地址属性与@Push注释中设置的主题一致。 当新数据可用时,将显示“invoiceTable”面板。

我们必须确保以下内容位于<a4j:push>标记中:

代码语言:javascript
复制
ondataavailable=""

在此步骤中,我们将探索一个工具提示,该工具提示将在鼠标悬停在发票编号列上时显示发票详细信息。

在第一列的定义(<rich:column>)的末尾添加了以下代码:

效果:

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-10-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 大魏分享 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云服务器
云服务器(Cloud Virtual Machine,CVM)提供安全可靠的弹性计算服务。 您可以实时扩展或缩减计算资源,适应变化的业务需求,并只需按实际使用的资源计费。使用 CVM 可以极大降低您的软硬件采购成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档