dev2dev 首页 > 资源中心 > 技术文章
探索AJAX运行时产品
摘要
引发当今Ajax浪潮的浏览器技术早在1999年就存在了。但由于最初编程接口过于低级,处理起来极其困难,而且构成Ajax的浏览器和JavaScript技巧对客户机的要求过高。近几年来,随着具有更多内存、处理器以及网络带宽容量等资源的终端的普及,Ajax逐渐日益成为为Web应用程序开发富用户界面的现实途径。影响之一就是推出了一组Ajax运行时框架,尝试为开发人员提供了更多可行的应用程序编程模型。
本文通过比对一些可比较的特征来尝试分类整理这些框架。希望读者阅读后能了解一些用来细分Ajax产品集合的工具,以便更轻松地理解其间的差异、缩减需要查看的子集数,并制订出更明智的选择。
免责声明:本文关注的是Java EE 世界。不同流派的其他技术如 .NET和Ruby中还有许多有意思的东西值得探讨,但这些都不在本文讨论的范围内。
简介
Ajax是Asynchronous JavaScript And XML的缩写。它是一种创建被媒体称为富Internet应用程序的Web那类Web应用程序的可行技术。RIA之所以被称为“富”,首先,相对于传统的页面刷新式Web应用程序,它更类似于桌面应用程序。比如,可以将页面控件以一种细粒度的方式互连(更改列表框中的值可能会导致页面上另外一个控件被启用或禁用,甚至完全消失)。Ajax还启用了许多在传统Web应用程序中无法实现的可视化效果。其中一些功能如下:
富应用程序的另一个同样重要的特征就是UI与数据源(即服务器)之间的通信,这种通信无需像传统Web应用程序那样要求进行页面刷新。
Ajax并不是用来创建富Web应用程序的惟一方式。也可以使用Adobe的Flash插件,在当今市面上的大多数浏览器中都可看到这种插件。其他可选方法还包括使用某种特定于浏览器的富UI技术,比如Internet Explorer中的XAML以及Mozilla的XUL等。Ajax最大的优势在于它是一个真正的零内存占用解决方案:绝大多数现代浏览器都支持它,并且它仅使用客户端本身具备的内容。客户机上不需要有任何额外的插件即可与服务器端的Ajax应用程序保持同步。
这并不是说不同浏览器在Ajax技术的实现方面不存在差异。本地浏览器API无论是在语义还是行为层面上都是非标准化的。Ajax应用程序通常无需考虑不同浏览器上的实现差异,其原因在于Ajax 运行时框架本身考虑了这些问题。
在最低层没有框架的情况下,原始Ajax编程要求:
- 一个到达服务器的异步管道(即一个API与既不会冻结UI,也不会刷新Web页面的服务器通信)。这里是XMLHttpRequest 对象
- 一种用于构造和解析消息并操纵浏览器DOM的语言。这里是JavaScript。
- 一种创建初始页面布局的标记语言(并非必须,但经常使用)。这里是DHTML。
- 一种在Web页面和服务器间流动的消息所用的数据表示。一般采用XML,但由于XMLHttpRequest对象不对数据流进行检查,因此可以采用服务器和客户端间达成共的任何表示JSON(JavaScript Object Notation)是一种流行的替代方法。
由于浏览器间的差异性以及在该层次上工作的可用开发工具的相对不成熟性和平台依赖状况,使用原始Ajax进行开发是很困难的。也正因如此,大量的Ajax 运行时框架涌现出来。本文将概览这一领域,并提供一种用于细分不同框架并理解它们之间的相似性和差异的方法。
Ajax框架领域巡游
Ajax运行时框架形式多样,并具有各种不同的目标。一些简单的框架意在隐藏浏览器接口的差异,提供一种公共的API来发送和接收服务器消息;其他一些则更多地关注于UI 小部件和/或特殊可视化效果。还有一些框架则希望二者兼顾。我发现了一种比较这些框架的有用工具,即在不同的轴上查看相关它们,如图1所示。您也可以提出许多的指标,但本文只关注下图中列出的四个方面。我将依次对这些方面进行讨论。请紧记,我所描述的各种差异只是概述,它们是通用规则,您总是能在其中发现例外情况。

图1. Ajax轴
开源框架与商业框架的对比
只要是Java EE世界中的人,就不会对开源框架与商业框架的区别感到陌生。商业框架往往更成熟些,因为商业产品不仅是供应商公司使命的组成部分,也是支配拥有方组织全部注意力的地方。供应商一般都会有力地承诺向后兼容各版本。这些商业产品通常会被设计为综合性、端到端的解决方案。它们的特征是具有较好的文档和商业品质的支持。
开源框架一般来说并不稳定。它们可能在某些开发人员社区关注的领域中非常出色,但在某些不受关注的领域中就相对弱一些。对某一特性的关注取决于对其作出贡献的开发人员的需求。需要注意它们的支持和文档,如果决定在项目中采用某个开源框架,您需要确认据以提供此框架下的许可符合您的使用计划。如果您的应用程序将发布给客户而不是严格限制在组织内部使用,那么就需要确认是否有权重新发布该应用程序需要的任一框架所属工件。
另一方面,由于开源框架通常采用邀请社区贡献的模式,因此向开源框架添加您认为缺少的功能会比向商业产品添加更容易。如果您选择的是具有活跃社区背景的开源框架,那么其支持也会非常出色。
综合框架与独立组件的对比
Ajax运行时组件产品能运行广泛的内容,从在Web上发现且可剪切并粘贴到您自己的应用程序中的代码片断到综合性的框架。在代码片段的水平之上即为单独的JavaScript组件,这些组件表示针对具体用途的API。这些表示UI小部件中的一些(比如Dojo Button)会出现在Web页面上,另外一些则是用来解决较低层面、与管道技术相关的问题,比如与服务器通信或操纵浏览器DOM的问题(比如原型API)
综合框架就是这些封装对象的一个集合,它意在成为某个Ajax开发项目的完整解决方案。许多项目都假设它们“拥有”运行Ajax的页面——实际上,它们往往不能很容易地接受与外部资源组件共享页面的观点。
沿着这条轴线进行选择通常与应用程序的使用年限有关。对于新应用程序来说,应对综合包作出的假设一般较为轻松。而要对已有Web应用程序作出增量式改进,集成代码片断或对象通常(尽管不总是)更为简单。由于在较低的层次上操作,代码片断或独立组件可能需要更多的编程。综合框架作出的假设使它们更难彼此集成,也更难在门户中使用(因为有时它们的假设与门户容器的假设冲突)。
声明式与过程式的对比
声明式与过程式的区别体现在框架所提供用于制作Web页面的编程模型中。声明式旨在提供一种使开发人员可以描述页面上的UI布局及其关系的语言,这使得框架仅通过应用程序开发人员提供的描述即可知道如何处理在UI小部件间传递的事件。过程式框架提供了编程语言API,程序员提供处理UI事件的过程式代码。
在下面的示例1中,可以看到通过ICESoft框架完成的一个数据表的描述式布局的开始部分。所展示的列是动态数据和命令链接的显示,用于两者的数据绑定将检索数据,并将命令传递给引用JSF backing bean的服务器,它是在JSF表达式语言中指定的。
<ice:datatable>
<ice:column>
<ice:commandLink actionListener="#{catalog.selectBook}">
<ice:outputText value="#{book.title}" />
</ice:commandLink>
</ice:column>
...
示例1.声明式布局和事件处理 ICEFaces
在示例2中,我使用了Dojo这种更倾向于过程式的框架来处理JavaScript中的按钮事件,并且指定另外一个JavaScript函数onServerResponse(),在我请求的服务器数据抵达时,此函数将被调用。
<script>
function helloPressed()
{
dojo.io.bind({
url: 'response.txt',
handler: onServerResponse
});}
...
</script>
<button dojoType="Button2" widgetId="helloButton">
Hello World!
</button>
示例2.过程式事件处理:Dojo
客户端为中心与服务器为中心的对比
客户端为中心与服务器为中心的差异也与编程模型相关,这也是最有意思的差异之一。早期的运行时框架几乎都关注客户端:Web应用程序的Ajax部分在浏览器中执行,并与独立于Ajax框架的服务器端组件通信。近来,一些框架开始提供使用服务器端语言(就本文而言,也就是Java)的应用编程模型,并在不同程度上模糊服务器与浏览器环境之间的显著差异。
如下图2所示,在服务器为中心的模型中,应用程序员开发整个应用程序的服务器端代码。当然,程序运行时还需要DHTML和JavaScript,但框架未将这些内容公开给程序员。框架提供服务器端和客户端Ajax引擎。服务器端引擎生成浏览器需要的HTML和 JavaScript代码,还有一个客户端引擎,这个客户端引擎提供了所生成代码使用的API,用于操纵浏览器DOM、接收事件以及将事件推回服务器端引擎,服务器端引擎又会就事件与应用程序进行通信。
通常,一个服务器为中心的框架会在连接的服务器和浏览器端保持小部件DOM表示,并通过在连接中来回发送delta来保持同步。当然,这会消耗一些服务器的内存,但这使得在用户消失一会后再回来并希望从离开处继续工作时,服务器端能够很轻松地保持和恢复Ajax会话状态。
另一方面,一个客户端为中心的框架则需要应用程序员编写应用程序的服务器端程序,以及浏览器中运行的那部分代码。客户端代码与Ajax引擎一起发送到浏览器,Ajax引擎在DOM和应用程序代码之间执行仲裁功能,这与它在以服务器为中心的模型中相同。应用程序代码通过调用引擎API发起对服务器的请求。

图2.服务器为中心与客户端为中心的框架架构
图3进一步细化了这条轴线。表中两个客户端列的差异主要与框架期望在哪个层完成编程相关。最右边的的条目实际上是JavaScript库,它通常比UI更加注重管道技术。使用这些内容的UI布局可以用JavaScript代码或标准HTML来表示。左边第二列是更高层次的框架,实际上它包括一个Ajax呈现引擎。这一切要求用户以某种特定于框架的语言描写小部件树,引擎将解析并使用该树来构造最终用户实际看到并使用的浏览器DOM。
在表的服务器端,差异并不大。使用右列框架编写的应用程序看起来就像是Web应用程序:使用标记表示UI布局,布局标记中未使用描述式术语表示事件处理,而是使用Java编写。该列中所列出的框架将JSF作为编程模型提供,数据绑定以标准方式工作,还使用了JSF表达式语言和managed backing bean。当然,当应用程序在浏览器中运行时还需要JavaScript,但框架将其完全封装,使之对于应用程序员不可见。
最左列中的框架程序看起来根本不像Web应用程序。它们提供的Java API看起来更像Swimg或SWT,但在浏览器中而不是桌面上运行。开发人员实例化Java对象,并将其彼此嵌套,以这种方法来构造UI。所有的事件都是在Java中处理的。这里再一次地涉及了JavaScript,但为公开给程序员。由于该模型是无需标记的Web编程,因此它最有可能在Web应用程序开发中实现突破。有时,提供这些框架的目的设置是甚至将最终应用程序作为Web应用程序在浏览器中运行,或者作为一个完全独立于浏览器的桌面应用程序方式运行。

图3. 服务器为中心与客户端为中心框架表
在上述两种以服务器为中心的模型中,如果程序员需要使用框架未提供的功能,可以添加新的小部件,并且在该情况下可以使用JavaScript进行编程。但是添加新的小部件并不是框架为大多数客户端预设的功能,实际上,这会被视为一个异常而不是规则。
是不是这一切都意味着远离浏览器而趋向服务器呢?某类应用程序很适合服务器为中心的框架。比如,像旅游类Web站点这种数据条目型应用程序将会发现,以服务器为中心的框架足以满足其需求。类SWT API是一种非常有趣的替代选择。而在可预见的未来,对于那些封装的小部件中未提供、需要付出特殊的努力和大量快速事件处理的应用程序而言,客户端为中心的框架则更有吸引力。
一些具体的框架
接下来我们来看看一些具体框架,将它们标注在轴上。当某个框架明确地落在某条轴线的端点时,将在端点处用一个圈表示它。当其坐标不是很明确时,将使用一个框条来表示它的位置,并给出进一步解释。
Prototype
Prototype 是JavaScript函数的一个低级库。它主要关注掩盖不同浏览器内的JavaScript实现间差异这样的问题,为开发人员提供导航和操纵DOM的高级工具,以及对XMLHttpRequestdui对象不依赖于浏览器的访问。许多更为关注小部件的框架是构建在Prototype的基础之上的:OpenRico 和 Scriptaculous 是开源框架的代表,而商业JSF框架则包含Prototype和Scriptaculous。

图4.原型
Direct Web Remoting
Direct Web Remoting(DWR)是一个包,利用它可以在浏览器和Java Web服务器(如图5所示)之间轻松封送数据。它在客户端到服务器的管道中隐藏了浏览器差异,但将UI问题留给程序员处理。它是免费、开源的,并且在编程模型轴线上的位置很有趣:应用程序员定义服务端Java类,随后框架生成在浏览器端表示相应数据结构的JavaScript类。从程序员对Java类进行注释来生成封送对象这个角度来讲,DWR具有大部分过程式和少量的声明式特征。DWR在客户端和服务器上都有API。

图5. DWR
Dojo
图6展示了 Dojo 的特性。它是一个以客户端为中心的开源框架,某些人将它作为一个综合框架使用,但另外一些人则只在最底层使用它的管道功能而不使用UI组件。其API大部分属于过程式。

图6. Dojo
Backbase
图7展示了 Backbase,这是一种商业框架,在其Community Edition中提供了以客户端中心的版本,在其Java Server Edition中提供了以服务器为中心的版本。它要求应用程序员声明性地指定应用程序的布局和行为(虽然它也可容纳过程式代码),其小部件集非常全面。

图7. Backbase
Google Web Toolkit
Google WebToolkit(GWT)是一种综合框架(见图8)。它的编程模型是以服务器为中心和过程式的,它的API很像SWT。GWT有一个非常有趣的架构:可以在随框架发布的“托管Web浏览器”工具中调试Java应用程序代码。如果希望在实际的浏览器中运行应用程序,可以使用该框架的编译器将打算在浏览器中运行的应用程序部分转换成JavaScript,然后将它插入Web页面。框架的运行时部分是免费、开源的;随框架一起发布的两个开发工具(托管Web浏览器和编译器)代码是闭源,但随运行时一起免费发布。

图 8.Google Web Toolkit
工具考虑事项
客户端和服务器端框架最大的差别在于工具需求不同。客户端为中心的框架需要JavaScript和面向浏览器的工具:一个JavaScript编辑器、调试器、验证器、一个浏览器DOM查看器、消息跟踪等等。这些工具中有两个最有前途,一个是 Mozilla Foundation,它提供一个DOM查看器、一个JavaScript调试器和大量可通过Internet免费获取的扩展插件;另外一个是 Eclipse Ajax Tooling Framework(ATF) 项目,在本文撰写之时已经可以发布试用版。ATF整合了Mozilla工具,并且新增了一个验证器和编辑器。
在服务器端,由于框架对开发人员隐藏了浏览器编程,因此可以使用与传统Web应用程序相同的Eclipse Java和JSP工具。
所有这些工具中都有一个显而易见的遗漏之处,即它们都缺少支持可视化页面构建的工具。但两项最新的开发显示,这一情况很快就会得到改变。我将简要介绍几个新的基于Eclipse的工具的例子,这些工具使用指向编程模型的服务器端的运行时。由于这些运行时提供了一些相对成熟的已有工具的编程模型,因此生成功能页面构建工具所需的工作量少于只有少量工具的客户端为中心的框架。
第一种是JSF的BEA Workshop Studio,还有少量代码,以对其加以调整,使之适合特定面向JSFAjax的运行时。第二个例子是GWT Designer,它是Instantiations公司最近发布的一个版本,提供Google Web Toolkit页面构建工具。
BEA Workshop Studio
图9展示的是 BEA Workshop Studio 的一个原型版本,这是一个利用与ICEFaces相集成的Workshop Studio来可视化地构建页面的工具,它是一个来自 ICESoft. 的商业Ajax框架。由于ICEFaces提供了一个JSF编程模型,因此可以轻松调整它,使之适合已有的JSF工具。
视图右侧包含页面布局的Design和Source视图。该工具完全支持两种方式的编辑:在Source窗格中作出的更改会立即体现在Design窗格中,反之亦然。
Tag Libraries选项板位于窗口的左下方。在选项板中单击某个ICEFaces标记即可将其添加到源文件的当前光标位置处,从而也会添加到Design视图中。选项板上方的Smart Editor了解各种标记的所有相关属性,可以帮助用户将正确的属性绑定到JSF backing bean。

图 9. Workshop Studio JSF Tooling
GWT Desiner
Instantiations 公司最近发布了一个称为 GWT Designer 的产品,它提供在Eclipse中为Google Web Toolkit构建页面的功能。由于GWT的编程模型与SWT或Swing雷同——即通过构建Java对象并将其添加到容器对象中来设计UI布局,并且由于Instantiations公司已经提供了一个针对Swing和SWT的名为WindowsBuilder Pro的功能非常丰富的页面构建产品,因此它们有着设计顶尖GWT Desinger的牢固基础。在图10中,可以看到该工具的Design窗格:右边是设计界面,中间是小部件选项板,左上方是小部件树视图,还有一个编辑器,所有选定的小部件的属性都可在左下方窗格的属性单中编辑。同样地,该工具也保持Source和Design视图同步,用户在源码中所做的任何编辑都将体现在Design窗格中。由于GWT的编程模型是纯Java的,因此只使用基本Eclipse安装(无需web工具)即可运行该设计器工具,并且平台中已有的Java工具提供完全的错误发现、类型系统导航和重构等功能。

图10. Instantiations GWT Designer
结束语
Ajax运行时框架空间目前陷入了功能过于丰富的窘境。可供选择的选项过多,令人感到困惑。它的相关工具也是如此,但对以客户端为中心的框架来说,在许多情况下,这些功能都不如运行时工具先进。
在选择时需要进行多方面的考虑:给定的编程模型是否适合即将使用它的开发团队、可用工具、许可证、成本、文档和支持等。无疑,在确定之前,需要反复加以衡量。本文试图指导读者了解如何探索空间,以及用于理解框架比较方式的工具,还观察了某些趋势——虽然我非常不愿意去猜测它们最终将走向何方。:-)
参考资料
| 作者简介 |
|
Gary Horen 是BEA Workshop小组的Ajax and Languages 项目经理。 |
作者其它文章
|