Tapestry 和 Wicket 的比较

JSF 和 Struts 是开发人员在进行 Web 开发时使用的传统的组件框架。但还有另外一种选择,Tapestry 和 Wicket,它们是面向组件的 Web 框架,其设计目标专门针对 Web 应用程序创建。本文采用 Tapestry 和 Wicket 技术开发了一个简单的应用程序示例,该程序实现了一个 to-do 列表的工作流。

Tapestry 和 Wicket 被宣扬为流行的基于组件的现代 Web 框架。与 Model 2 架构框架 Struts 或 Spring MVC 不同,Tapestry 和 Wicket 为 Web 开发过程提供了一种全新的方式,即以看待基于 GUI 的独立应用程序相同的方式来考虑 Web 应用程序及其行为和组件交互。

典型的基于组件的应用程序表示一个页面集合,它由一套组件组成。而这些 组件可能由更小的组件组装而成。用户交互是一种特定的组件事件。这是与基于 MVC 的应用程序的主要区别,后者的交互入口点是一个 servlet 或一个具有一般属性的操作(例如 URLs 及其参数、表单等)。

使用基于组件的框架的开发人员通过实现事件驱动模型来关注组件和组件交互。 Servles、HTTP 会话和其他来自 servlet API 的实体被移动到更低的级别并且从来不会被直接使用。然而,通过声明组件及其属性,开发人员需要管理服务器端的状态,这种状态可能是会话持久性的。

与 JSF 或使用 JSP 和 Velocity 标记的 WebWorks 不同,Tapestry 和 Wicket 都使用它们自己的模板系统,允许创建完全符合 HTML 标准的 HTML 模板。 这使我们可以清晰地实现关注点分离:从事 GUI 的 Web 设计者不用考虑应用程序是在何种平台之上编写;同样,实现组件的应用程序的开发人员不用考虑页面的最终设计是否使用 stub 元素进行调试和测试。 Tapestry 和 Wicket 都支持这种分离。

Tapestry 一览

目前,Tapestry V4.1 是该项目的正式发行版。V5.0 目前正处于积极开发中, 从团队开始从头编写 Tapestry 到撰写本文之际,已有 18 个月有余。 尽管 V5.0 还没有公开发布,可以肯定地说它与先前的版本完全不同,因为它不是向后兼容的。 由于不能确定 V5.0 的状态,我们主要侧重于 V4.1。

Tapestry V4.1 主要基于 HiveMind 微内核,这是控制反转(Inversion-of-Control)容器的一个严格表示。 所有的 Tapestry 服务都是使用 HiveMind 注册的。

一个典型的 Tapestry 组件由以下部分组装而成:一个组件说明(一个 XML 描述符)、组件逻辑(Java™ 编程语言的一部分)、UI 布局(一个 HTML 模块)。

Wicket 一览

Wicket 架构的核心是组件 类,所有组件和标记容器对其进行扩展。 组件主要负责处理其模型 — IModel 界面的一个实现。模型表示与组件实例相关的任何类型的数据并定义其行为。IModel 中一个著名的实现是 LoadableDetachableModel,它允许传递临时数据、在呈现组件之前加载数据、在不需要时将其移除(撤销),从而减少了 Wicket 会话的大小。

Wicket 页面也是组件,如果具有状态,则它们的状态将保存在 Wicket 会话中。页面可以启用版本,因此每当页面状态发生改变(查看页面、修改其组件状态等)时,将连同一个递增的版本编号进行保存。





回页首


开发过程

本节说明在 Tapestry 和 Wicket 中如何完成典型的任务。注意下面的代码片段大多数取自较大的代码源,比如组件和页面。因此,它们可能包含此处没有描述的一些业务方法的调用。

支持的数据类型

这两个框架都支持 Java 数据类型。Tapestry 采用对象图导航语言(Object-Graph Navigation Language,OGNL)。它是一种获取和设置 Java 对象属性的表达式语言。Wicket 用它独有的机制进行数据绑定。 有 两 种 方便的实现可以动态检索和更新对象属性:PropertyModelCompoundPropertyModel

我们来查看一个应用 float 类型的示例。在 Tapestry 中,按照以下方式指定一个具有 float 值的文本字段:


清单 1. Tapestry 代码示例
                
<component id="weight" type="TextField">
<binding name="value" value="ognl:weight"/>
<binding name="translator" value="translator:number,pattern=#.#"/>
<binding name="displayName" value="literal:Weight"/>
</component>

Wicket 中按照以下方式指定这种文本字段:


清单 2. Wicket 代码示例
                
FormComponent field = new TextField("weight", Float.class);
field.setLabel(new Model("Weight"));
add(field);

因此,可以自然地使用简单的数据类型,比如 stringintegerfloat,甚至是 BigDecimal

验证

作为一条经验法则,应该针对业务规则验证所有的用户输入。Tapestry 和 Wicket 都能够对表单输入字段执行服务器端或客户机端(使用 DHTML)的验证。思考一下在服务器端如何完成这个任务。在框架中将按照以下方式通过特定的验证程序进行字段输入验证:


清单 3. Tapestry 验证程序
                
<component id="weight" type="TextField">
...
<binding name="validators" value="validators:min=1,max=500"/>
</component>


清单 4. Wicket 验证程序
                
...
field.add(NumberValidator.range(1, 500));

如果没有符合要求的验证程序,也可以定义一个自定义字段验证程序。 如果产生任何验证错误,都应该向用户显示以表明输入无效。

在 Tapestry 中,我们应当在字段之上定义一个循环,跟踪默认的 ValidationDelegate 表单 bean,从而显示所有的表单错误。


清单 5. ValidationDelegate 表单 bean
                
<property name="currentFieldTracking"/>
<component id="errors" type="For">
<binding name="source" value="beans.delegate.fieldTracking"/>
<binding name="value" value="currentFieldTracking"/>
</component>
<component id="isInError" type="If">
<binding name="condition" value="currentFieldTracking.inError"/>
</component>
<component id="error" type="Delegator">
<binding name="delegate" value="currentFieldTracking.errorRenderer"/>
</component>

相应的 HTML 标记如下所示:


清单 6. Wicket 验证程序
                
<ul jwcid="errors">
<li jwcid="isInError">
<span jwcid="error">Form validation error </span>
</li>
</ul>

在 Wicket 中,FeedbackPanel 实现了显示多种错误的功能:add(new FeedbackPanel("feedback"));。HTML 标记如下: <span wicket:id="feedback" /></div>

要启用客户端验证,需要将 clientValidationEnabled 参数添加到 Tapestry 的一个表单中,如下所示:


清单 7. Tapestry 中的客户端验证
                
<component id="actionForm" type="Form">
<binding name="delegate" value="beans.delegate"/>
<binding name="clientValidationEnabled" value="true"/>
</component>

基于相同的目的,Wicket 中采用AjaxFormValidatingBehavior 类。


本文转自:IBM developerWorks 中国

请点击此处查看全文


你可能感兴趣的:(Tapestry 和 Wicket 的比较)