Tapestry开发者指南(1)

来源:百度文库 编辑:神马文学网 时间:2024/04/29 09:29:02
第一章 介绍
Tapestry是一个全面的网络应用框架,使用Java。Tapestry不是应用服务器。Tapestry是用在应用服务器中的框架。Tapestry不是应用。Tapestry是一个创建网络应用的框架。Tapestry不使用JSP。Tapestry是使用JSP的另一种选择。Tapestry不是一个脚本环境。Tapestry使用组件对象模型, 而不是简单的脚本,来创建高度动态, 交互式的网页。
Tapestry基于Java ServletAPI 版本2.2, 与JDK 1.2及以上版本兼容。Tapestry使用一个成熟的组分模型,将网络应用划分成层状的组件。每个组分有具体任务来生成网页(也就是,生成HTML页面的部份), 和反应HTML 查询(譬如, 点击链接, 或提交表单)。
Tapestry框架实际上承担处理应用流程和服务器端客户状态的所有责任。这允许开发商集中于应用的事务和表示方面。Tapestry以对象、方法和属性,代替URLs 和查询参量, 重构网络应用开发的观念.
Copyright @ 2000, 2001, 2002, 2003 The Apache software foundation
1.1.1 脚本对组件
多数主流的网络应用框架都基于某种脚本的形式。这些框架(经常被包入网络或应用服务器中) 有:
o Sun JavaServer Pages
o 微软Active Server Pages
o Allaire ColdFusion
o PHP
o WebMacro
o FreeMarker
o Velocity
所有这些系统都是读取HTML 模板文件, 并在其中执行一些处理。这些处理由directives来标识. Directives - HTML 模板中的特别标记, 用以表明动态行为。
每个框架有一种脚本语言。对JavaServer Pages,就是Java。对ASP,是Visual basic。通常, directives是插入HTML中的脚本语言的片段。例如, 这个片段来自假定的JSP 页面, 显示购物车的一部分。
<%
String userName = (String)session.getAttribute("userName");
%>

Contents of shopping cart for
<%= userName %>:


大多数文本, 作为静态的HTML被送直接地返回到客户浏览器。斜体的文本标识脚本代码。
第一大块代码用以从HttpSession中提取用户名, 所谓每个客户的便笺簿(这是Java Servlet 的API的一部分;其它系统有某一相似的结构)。第二个块用以将表达式的值插入HTML。这里, 表达式只是变量userName的值。它可以更复杂点, 如,调用Java 对象的一个方法而返回的结果。
这类例子经常被用来显示脚本方式是多么有用和强有力的。实际上, 它显示了脚本方式的弱点.
首先, 我们在HTML 文件中有这么多Java 代码。问题是... HTML 编辑器不会理解JSP句法, 或不能确认,在脚本部分中的Java代码是正确的, 或是否能编译。有效性的检验被推延,直到在应用中观看页面时才能进行。页面中的所有错误将被显示作为运行时错误。这里有Java代码是不自然的... Java 代码应该完全在IDE 中开发。
在我曾开发过的真实的JSP应用中, 各个JSP 文件是30%- 50% 的Java 。很少的Java 是简单的表现逻辑, 象< % = userName% >这样,大多数是更大的代码块,需要‘设定‘表现逻辑。还有其它的”好”的大块代码, 要通过很多的结果表单进行循环操作。
在一个设计团队和技术团队分开的环境里, 没人会感到非常愉快。设计团队不太可能知道JSP 或Java 句法。技术团队也有困难使用由设计团队队提供的 HTML 文件。同样, 二个团队没有好的共同语言来描述他们对每个页面的要求。
Tapestry的一个设计目标是对HTML 的最小的冲击。许多针对模板的系统增加几个不同的directives来将值插入到HTML中, 以条件来标记代码块,进行重复和其它操作。Tapestry则相当不一样; 它允许以现有的标记用一种完全融合的方式来标记动态部分。
Tapestry组件是任一个带jwcid 属性的HTML 标记 ("jwc"代表"Java Web Component")。作为比较, 与前面JSP 例子等效的一个Tapestry模板:

Contents of shopping cart for
John Doe:


这里在页面中定义了名为insertUserName的组件。为协助HTML 开发, 本例的值, 包括了"John Doe",但当框架使用HTML 模板时, 这是自动编辑的。 标记简单地表明了Tapestry组件将去何处...它不标识任何组件的行为。会在别处, 在组件规格文件中提供组件的行为,。
页面的规格文件的部份定义insertUserName 组件是什么, 并且它做什么:
(1)
(2)

(1)id 属性给出组件的唯一识别符, 这与HTML 模板匹配。type属性用以指定使用哪种组件。
(2)binding标识组件怎么得到它需要的数据。在这个例子, insert组件要求绑定它的值参量, 该值被插入到回应的HTML页面中。这绑定的类型(还有其他的), 从visit对象中提取userName属性 (visit对象: 中心的,应用所定义的对象,用以在Tapestry应用中存放多数的服务器端状态)。
Tapestry真正擅长的是做一些复杂的事, 而不只是简单地生成输出。例如,我们假设, 只有当用户的购物车里有东西时, 应该使能checkout按钮。在JSP 世界中, 可能象这样:
<%
boolean showLink;
String imageURL;
showLink = applicationObject.getHasCheckoutItems();
if (showLink)
imageURL = "/images/Checkout.gif";
else
imageURL = "/images/Checkout-disabled.gif";
if (showLink)
{
String linkURL;
linkURL = response.encodeURL("/servlet/checkout"); %>

<% } %>
Checkout<%
if (showLink)
out.println("
");
%>
这里假设, applicationObject确定用户是否输入了任何结算项目。可以推测, 这个对象由一个控制的servlet来提供, 或被置入HttpSession中。
对应的Tapestry的HTML 模板则更加简单:
Checkout
更多的部分在页面的规格文件中:
(1)
Checkout
(2)

(3)



(4)

(1)组件checkoutLink 是一个PageLink, 这个组分在应用中创建一个指向其它页面的链接。Tapestry负责生成适当的URL 。
(2)将参量设为disable来允许关闭链接; 这里当购物车为空时, 它被关闭。
(3)一个Rollover组件插入图象; 它必须是在一些链接组件里面(譬如PageLink), 并且对链接是否使能或不能是敏感的; 当设为不能时, 插入另外一个图象。这里未显示Rollover组件生成动态鼠标效果的能力。
(4)Tapestry使用抽象, aasets, 来标识图象、stylesheets 和其它资源。Rollover组件要参考的是assets, 而不是URL 。
这个例子的重点是, JSP 开发者必须考虑一个字符一个字符地生成HTML。进一步来说, Java 代码与HTML 的比例迅速变得不可收拾。相反, Tapestry开发者考虑组件行为,并以一种典雅的方式动态地指定其行为。