龙盟编程博客 | 无障碍搜索 | 云盘搜索神器
快速搜索
主页 > web编程 > Javascript编程 >

Weblogic Portal中实现AJAX编程之架构(1)(2)

时间:2013-03-06 14:58来源:未知 作者:admin 点击:
分享到:
企业服务总线 图3与前面的两幅图又有所不同,因为企业服务总线(ESB)架构是一种逻辑架构。服务可以位于网络上的任意位置,数据源可以被抽象到(可
企业服务总线
图3与前面的两幅图又有所不同,因为企业服务总线(ESB)架构是一种逻辑架构。服务可以位于网络上的任意位置,数据源可以被抽象到(可插入到ESB中的)服务中。ESB为后端系统开发人员处理了他们通常必须做的工作,比如服务身份验证、数据转换、协议转换和可靠性特征。ESB可以扩展到带有硬件负载平衡器的计算机集群上,这提供了代理服务架构所具有的优点。


Figure 3
图 3.企业服务总线

为了说明在门户中对Ajax应用程序使用ESB的优点,考虑对于每次Ajax调用都要引用一个Web服务的情况。对于小型门户来说,Web服务的数量可能相对较少,譬如说几十个。但是随着门户的增长,将会引入更多的Web服务。大量Web服务的添加与Ajax没有关系,但是与SOA的实现有着密切的联系。这是一个ESB的经典用例。尽管从严格意义上来说,它对于Ajax实现的操作不是必要的,但是它还是带来了几个好处:

  • ESB消除了对ProxyServlet类(稍后将会介绍)的需求,因为代理服务更好地完成了同样的工作。
  • ESB支持监控和管理单个Web服务,同时无需在每个Web服务中增加额外的代码。这包括监控服务水平协议(SLA)和报告违反情况。
  • ESB可以保护Ajax代码不会被外部提供者修改。如果外部提供者以一种无需修改门户用户界面但需要修改Ajax调用代码的方式修改了WSDL,那么就有可能在ESB的代理服务中修改配置,而不用修改Ajax代码。为什么这样做比修改Ajax代码更好呢?我认为,在ESB中代理服务的配置中进行小的改动比起在JavaScript中对每个到相关服务的引用进行修改更不容易出错。此外,对于同样的信息(比如股票报价查询)还可以使用多个外部提供者,但是每个提供者具有不同的调用接口并返回XML。如果某个提供者出现故障或者只是为了进行负载平衡,使用多个提供者就很有利了。在ESB中可以轻松实现这一点,但是在JavaScript中这几乎是不可能的。

在这里的例子中,我之所以使用了以浏览器为中心的架构和代理服务架构,是因为作为例子来说,它们比较简单,但是我希望能够使您相信,Ajax是体现ESB优点的非常不错的方式。
对门户使用的影响
当在门户内采用Ajax编程方法时,出现了几个问题。这些问题中的大多数与门户的生命周期以及如何/何时挑选用户信息有关。具体来说,门户要使用诸如用户在哪里单击之类的信息来决定向其显示何种类型的相关信息。WebLogic Portal具有一种叫做campaign的特性,它允许门户设计人员基于用户个人信息指定对用户的有目的广告宣传。用户个人信息中包括用户的页面历史,即,用户过去点击过的页面。门户在页面刷新时收集这类信息,所以如果用户从未刷新页面,门户就无法(容易地)自动收集用户信息。
考虑Ajax编程可能对门户产生的以下副作用:

  • 不可跟踪性使campaign得不到有效使用(参见上面的内容)。
  • 页面刷新重置了DOM树,所以当用户最终刷新页面时,所有对使用Ajax修改过的portlet的更新都会丢失。对portlet内容的修改将会丢失,还原为初始的页面状态。
  • JSP中的所有JavaScript都是整个页面共用的。考虑一个包含在每个portlet中的JavaScript片断。当呈现最终的HTML页面时,JavaScript片断将在包含它的每个portlet中重复使用。类似地,如果已经将两个portlet嵌入了JavaScript,而且每个portlet的脚本都有一个名为getData()的方法,那么最终的HTML页面将会有两个不同的getData()函数定义。调用该函数时很可能导致调用不正确的方法。如果有两个名为isOK()的变量,也会出现同样的情况。

使用适当的编码风格可以防止这些问题的发生,比如给所有变量和函数取独有的名称,或者使用cookies来保存portlet中使用的当前数据。
一种最佳实践是在所有脚本中使用独有的变量和函数名称,具体做法是在每个变量和函数的名称前加上包含它们的portlet的名称。
浏览器战争尚未结束,专有浏览器和基于标准的浏览器之间的战争仍在延续。Ajax相当有趣的一点是,其中有一半是标准(XHTML、XSLT、JavaScript/ECMAScript、DOM和Web services)驱动的。但是其核心技术――XmlHttpRequest对象――来自微软。
下面列出了在进行跨浏览器的Ajax编程时要注意的一些重要的常见错误,以及如何避免这些陷阱。

安全性
XmlHttpRequest对象直接把浏览器连接到一台远程主机,要么是加载页面的Web服务器,要么是从另一个完全不同的服务器。正如您所想像的,这里为恶意软件提供了大量的机会。例如,一段恶意的JavaScript可能等着用户输入口令字段,然后把口令传递给一个远程浏览器,而用户却不知道,甚至还没有单击页面上的提交按钮。如果把口令换为信用卡号码,事情就变得更加有趣了。
为了避免这种风险,Mozilla拒绝到为Web页面提供服务的主机之外的任意主机的连接。用户不会看到错误消息,因为它根本就不会运行!
Internet Explorer (IE)采用另一种方法。当要求连接到远程主机时,将使用一个对话框通知用户,而用户可以决定执行什么操作。但是要注意,该对话框不会告诉用户要连接到哪个站点,所以用户缺乏可以用于做出决策的信息。

Figure 4
图 4. 没有有用的信息

这个问题的解决方案是使用一个Java servlet作为到Web服务的代理。该servlet获得所有的参数,并把它们传递给远程服务,接着将响应返回给Web站点。通过让servlet运行在创建Web页面的Web服务器上,Mozilla就会认为服务是本地的。注意,这是企业服务总线(比如AquaLogic Service Bus)的一个绝好用例。
使用XmlHttpRequest对象
包含XmlHttpRequest对象的XmlHttp库最初是随Internet Explorer 4一起发行的ActiveX控件。Mozilla包含一个兼容的函数库,所以没有什么好担心的。我仍然推荐使用一个开源库,比如Sarissa或DWR。然而,它们在将XML数据传递到对象的方式上存在着细微的区别。
更新DOM节点
Mozilla和IE之间最令人恼火的区别就是Web页面中对DOM(Document Object Model,文档对象模型)的处理。大多数函数的工作方式是一样的(至少在DOM Level 2上),但是仍然有很多值得注意的地方。下面给出两个例子。
innerHtml与innerText的使用
当使用新的动态内容更新标签时,IE用户有两个选择:可以更新节点的innerText或innerHTML。二者的区别很细微,但是却能在信息的显示方面造成很大的差别,尤其是当要显示的文本是XML格式或者包含HTML实体(比如尖括号或&符号)时。使用innerHTML时假定内容与标签是一起放入的(不管内容是什么)。假设我们试着把以下文本放入一个节点中:

var txt = This is a test 
document.getElementById('mydivtext').innerText = txt; 
document.getElementById('mydivhtml').innerHTML = txt;

部分在浏览器中看起来如下:

This is a test

部分看起来则是下面这样:

This is a test

基本上,innerText节点对输入字符串进行转义,这样显示在用户面前的就是内容原来的样子。但是Mozilla在DOM节点上不支持innerText属性,所以更好的方法是用户亲自对文本进行转义,并始终使用innerHTML。Sarissa有一个帮助器函数用于实现这一项功能:

document.getElementById('mydivtext').innerHTML = 
Sarissa.escape("This is a test")

我们将得到同样的结果,如下:

document.getElementById('mydivtext').innerText = 
"This is a test")

在门户中使用独有名称
当某个门户页面由WebLogic Portal(或任何门户)进行解析时,每个portlet均作为完整的Web页面放在HTML文档中,包括标签(有时甚至包括标签)。因此,如果在每个portlet中始终以相同的ID来命名标签(理论上来说,这似乎是使编程标准化的一种良好方法),那么将获得不正确的结果。考虑如果有两个ID为“result_data”的元素,那么解析后的门户页面将会是什么样子。

// Outer portal shell 
 
// First portlet 
... 

      





 
精彩图集

赞助商链接