日期:2010-08-13  浏览次数:20580 次

  摘要

  门户应用程序非常适用于从多个源提取信息以及为包含门户Web应用程序的portlet提供应用服务。对于用户,portlet应用程序是独立的实体,类似于桌面上的窗口应用程序。如果在一个窗口应用程序中执行一项操作会导致其他所有应用程序中的内容被刷新,那又会怎么样呢?这就是当前大多数门户的情况。在一个portlet中通过页面流进行转移会导致整个Web页面被刷新,包括该页面上的其他所有portlet。

  为了避免出现这种有时不希望有的行为,Web开发人员采用了所谓Ajax-风格的编程方法。Ajax即异步Java和XML(Asynchronous Java and XML),它是一个技术的集合,包括用于创建交互式Web应用程序的XHTML、CSS、JavaScript、DOM和XmlHttpRequest对象。本文将说明在BEA WebLogic Portal环境中使用Ajax编程方法的基本原理,并提供了一些最佳实践和建议,以避免新手Ajax程序员经常会犯的许多错误。

  Ajax简介

  考虑一个基于一些用户标准(比如街道地址、城市和州,)来绘制街道地图的Web应用程序。这类应用程序在用户界面中已经存在很多年了,并且很少有所改变。用户输入一个地址,然后单击一个按钮,页面中心就会显示周边区域的地图。用户通常需要缩小和放大以更清楚地显示周围区域,或者需要把地图向左或向右稍作移动,以找到一些能够帮助他们进行定位的主要街道或地界标。访问maps.yahoo.com或mapquest.com,便可以获得这种体验。来吧,试试这个地址:100 East Wacker Drive Chicago, IL

  最终,您将看到一幅芝加哥市区的地图,中心是Wacker和Michigan大街。在右方,您将看到一系列缩放级别,您可以从中选择一个。当选定一个缩放级别之后,会出现什么情况呢?整个页面将会刷新,这会花费相当长一段时间。现在,当您把地图向左或向右移动时,又会出现什么情况呢?您不可避免地会刷新整个页面,而整个地图需要再次下载。页面大小通常是75到100k,而平均的返回时间大约是3到10秒钟,这取决于您的网络连接速度。

  现在使用Google Maps进行同样的尝试,这是一个完全使用Ajax技术的站点。输入地址,然后单击Search。页面将完全显示出来。现在进行缩放。注意,地图之外的页面内容不会刷新。下面列出了这背后所发生的事情:

  • 用户单击缩放控件。
  • 缩放控件调用一个JavaScript方法。
  • JavaScript方法调用服务器来请求新的地图信息。
  • 服务器创建新的图像,然后将其发回给浏览器。
  • 浏览器使用新的图像数据替换现有的图像数据。
  • 用户在旧图像的位置看到新图像。

  注意,地图上没有指示东西南北的箭头。用户如何与地图进行交互呢?只需像在一个滚动窗口中那样进行拖拉即可。试着单击地图的中心,然后把地图向左方拖动。注意拖动地图时地图是如何响应的!下面列出这背后所发生的事情:

  • 用户把地图向左方拖动。
  • Web页面使用它所下载的图像信息,而用户等待着页面根据客户端已经存在的数据重新绘制地图。
  • 如果预先没有检索到图像数据,浏览器将从服务器获得它所需要的附加信息(新出现的地图区域)。
  • 新的数据被添加至现有数据,并在浏览器中重新绘制出来。
  • 用户看见地图向右方滚动,就像是一幅真正的大图那样。

  下面是使用Ajax技术所带来的好处:

  • 客户端与服务器之间传输的数据量大大减少。
  • 可感知的系统响应时间大幅度缩短。
  • 由于反馈及时,用户感觉对应用程序的控制更加得心应手。
  • 用户喜欢这个站点,因为使用它可以提高他们的工作效率。
  • 用户将会再次访问站点,这样其竞争对手的客户就会减少。

  上面对于Ajax风格的用户界面的演示令人印象深刻。(如果在使用Google Maps数天之后,您还不相信其竞争对手已经恼羞成怒,那么您就不必阅读本文下面的内容了。)

  有关Ajax的完整介绍,请阅读An Introduction to Ajax(中文版,dev2dev,2005年11月)。

  Ajax所解决的门户问题

  考虑那些大量使用Java applet而且希望利用其现有资产创建门户的潜在客户。把现有applet和其他页面流包装到portlet容器中是一件很简单的事情,但是也要考虑到进行门户测试时会出现哪些问题。例如,某个porlet中的一个动作会导致刷新以及随后的重新加载,并重新初始化页面上其他所有基于applet的portlet。如果所讨论的applet具有后端连接,那么portlet的重新初始化将导致服务器丢弃现有连接,然后强制applet重新进行连接,这不仅加重了服务器的负担,而且会使门户用户看到几秒钟的“静止时间”,在这段时间内,基于applet的portlet必须保持灰色,一直到它们完成初始化为止。

  这显然是一个潜在的瑕疵。告诉客户们重写所有的applet,因为基于JSP的应用程序并非有用的响应,尤其是对于已经在现有资产中投入大量资源的客户来说。此外,门户必须帮助客户包装现有的应用程序,而不是强迫他们重写整个系统。

  我们需要一种让单个portlet在不引起页面刷新的情况下进行操作或获得新数据的方法。虽然这显然存在一些不利之处(我将在本文后面讨论这些),但是在这种情况下,把避免页面刷新作为使用门户的进入屏障是完全有必要的。

  注:对于这个问题,一个可行的解决方案是iframes,也就是inline frames,一种基于浏览器的机制,它可以使屏幕的一块区域变为独立的实体,当页面重新加载时它不会刷新。使用类似于Ajax编程中所使用的技术,我们可以使用XML-RPC进行服务器调用,从而获取数据并将其加载到DOM文档中。Apple的开发者Web站点上有一篇文章非常好地总结了这种方法的优点和缺点。我确信,关于为什么iframes更好或Ajax更好,双方的支持者已经进行过精彩的辩论,但是Ajax已经流行开来,而iframes则没有。因此,本文只介绍了Ajax,而没有就iframes进行讨论。

  用例

  在下列情形下,Ajax技术很有用处:

  • 门户中使用了一个或多个基于applet的portlet。
    例子:参见前面内容中描述的场景。
  • portlet需要定期刷新其数据或重绘其内容。
    例子:一个带有股票价值表的可执行面板,这些值每分钟都要更新。
  • 使用Portlet间通信(Inter- Communication,IPC)而不能刷新整个Web页面。
    例子:一个列出股票名称的portlet需要更新另一个用于简要描述这些股票的当前状态(比如股票的当前价格、最高价格和最低价格)的portlet。
  • 页面包含大量通常为静态的数据,这样页面操作只需要置换少量数据。
    例子:Google地图。
  • 一个portlet需要基于在此portlet中的其他地方所做的选择来检索一个有限的数据集。
    例子:一个表单有3个组合框:State、City和ZIP。当用户选择一个州时,该州所有的城市名称都将出现在City组合框中。然后,用户从City组合框中选择一个城市,接着ZIP组合框中就会显示该城市所有有效的邮政编码。

  示例架构

  Ajax技术的核心是Web浏览器对一些负责提供信息的Web服务的调用。如何为该解决方案设计架构呢?有3种值得考虑的架构。第一种架构使用Web浏览器作为集成点,出于随之而来的安全考虑和浏览器方面的问题,该架构存在问题。第二种解决方案使用代理来获取分布的资源,这消除了安全问题,但是添加了一个单点故障。第三种架构使用企业服务总线(enterprise service bus,ESB)来消除单点故障,并为Web服务和Ajax技术的蓬勃发展提供了最适宜的环境。

  以浏览器为中心

  在以浏览器为中心的架构中,Web浏览器成为联系远程系统的中心点,如图1所示。数据从各个远程系统中获得,然后在浏览器处的JavaScript中进行整理和排序。

Figure 1
图 1.以浏览器为中心的架构

  这种架构是最自然的设计,它具有多处设计缺陷:

  • JavaScri