级别: 中级 Richard Gornitsky (mailto:rsgornit@us.ibm.com?subject=用于快速将 Web 应用程序集成到 WebSphere Portal 中的选项&cc=debcot@us.ibm.com), 高级 IT 架构师, IBM John Boezeman (mailto:boezemant@us.ibm.com?subject=用于快速将 Web 应用程序集成到 WebSphere Portal 中的选项&cc=debcot@us.ibm.com), 高级软件工程师, IBM
2006 年 9 月 04 日
本文说明了多种用于快速将 Web 应用程序集成到在 WebSphere Portal 下运行的门户中的技术。
引言 各个公司都希望能够快速将其多个不同的网站聚合到单个用户界面中,也希望提供具有一致外观且支持单点登录(Single Sign-On,SSO)的站点。他们很快就认识到门户可实现此目标。不过,他们的门户设计人员和开发人员面临的最大挑战之一是,要确定用于将现有 Web 应用程序集成到门户中的最有效方法。 理想的情况下,应该通过将表示层移植到自主开发的 Portlet 来集成这些 Web 应用程序。通过此方法可利用 WebSphere Portal 用于提供一致外观的功能,还能利用其他功能(如安全性、个性化、协作 Portlet、内容/文档管理、搜索、可伸缩性/可用性功能等)和各种设备支持。 不过,自定义开发工作有时候可能会超出用户的预算。幸运的是,WebSphere Portal 提供了多种机制,可以用于将 Web 应用程序集成到门户中。 本文讨论了其中的几种机制。您可以采用以下方法:
- 安装并使用即时可用的基于目录的全功能 Portlet。这是最便于实现的方法;不过,此方法灵活性较差,因为 Portlet 自定义仅限于配置选项。我们不打算讨论此备选方案。
- 使用 IBM Web Page Portlet 或创建自己的自定义 iFrame Portlet 来通过 iFrame 集成现有应用程序。
- 创建 Web Clipping Portlet,以标识和提取在 Portlet 中显示的 HTML 文档特定部分。iFrame Portlet 和 Web Clipping Portlet 都用于前端 Web 应用程序,且不需要使用任何其他工具。这些 Portlet 的配置非常简单;不过它们并不是万能的。在本文稍后,我们将说明其中的一些限制,以及如何开发自定义 iFrame Portlet 来绕过这些限制。
- 使用 IBM Rational® Application Developer、Rational Software Architect 或其他帮助构建 Portlet 的工具来开发自己的自定义 Portlet。
- 使用 IBM WebSphere Portlet Factory,这是 IBM 新推出的产品,可帮助进行 Portlet 开发。它提供了很多内置向导来自动为后端系统生成 Portlet。在很多情况下,您都不需要编写任何代码。
使用 Web Page Portlet 创建 iFrame IBM Web Page Portlet 是一个流行的快速集成工具,可以在 WebSphere Portal 的 installableApps 目录中找到此工具,也可以从 IBM WebSphere Portal catalog下载。 Web Page Portlet 将 iFrame 显示为 Portlet。其中包括以下支持:
- 设置 iFrame 的大小。
- 对相同域上的站点进行身份验证。如果所链接的站点要求基本身份验证或基于表单的身份验证,则可能需要使用此功能。Web Page Portlet 身份验证仅在 iFrame 站点与门户位于同一个域时才会工作。
- 使用来自凭据库的信息进行身份验证。
可以方便地配置 Web Page Portlet 和支持快速将多个网站集成到门户中。它非常适合进行概念验证;不过,在将其应用到生产中时必须非常小心。从门户的角度而言,此 iFrame 是门户页上的一个保留方框,门户不能控制其内容或格式。 决定在门户中使用 iFrame 时需要考虑的一些问题:
- 超时是一个非常麻烦的方面,因为 iFrame 或门户都可能在其他元素前出现超时。
- 目前的浏览器中的跨站点脚本(Cross-Site-Scripting,CSS)限制会阻止 iFrame 内的 JavaScript 访问父窗口或其他 iFrame 中的变量或遍历其中的 DOM。当二者位于同一个域且使用相同协议(HTTP 或 HTTPS)时例外。此情况会导致很多基于 iFrame 且依赖于 JavaScript(很多情况下都是如此)的应用程序失败。当出现 CSS 问题时,变量将为空,从而导致 JavaScript 失败或停止执行。此情况使得调试工作变得非常困难。
- 来自 iFrame 的链接会引用 JavaScript
top 变量或 navigator ,从而可以让用户访问 iFrame 外甚至门户外的内容。使用此类变量可能会导致整个浏览器窗口进入其他位置,而不会将其限制在 iFrame 的范围内。 - iFrame 并不会对状态进行维护;因此,当用户与 iFrame 中的内容交互时,可能会遇到意外的行为。例如,假定您在页面上的某个 Portlet 中使用 iFrame,而该 Portlet 中“包括”外部站点上的一个应用程序。用户将采用以下方式与外部站点交互:单击链接并在新页面上填写表单;切换到不同的门户页;然后再切换回包含 iFrame Portlet 的页面。用户将看到初始 外部站点页,而不是进行交互时离开的表单页。只有目标外部站点使用会话 Cookie 等普通 Web 技术来处理自己的状态管理时,用户才会看到“通常”的行为。在此情况下,当用户返回 iFrame 页时,外部站点将显示表单页,而不是初始页。
- iFrames 可能会导致很难在门户中控制和提供一致的外观。完整网页的 iFrame 通常包含页 Header 和导航信息,而这并不是 Portlet 中所希望的方式。完整的网页通常设计为适合全屏显示,通常不会将 Portlet 窗口内的滚动条(特别是水平滚动条)视为良好的用户界面 (UI) 设计。图 1 显示了这些 UI 问题。IBM 网站嵌入在页面右侧底部的 iFrame 内。其中的外观并不一致,且未集成导航。
- iFrames 无法利用 WebSphere Portal 的功能。例如,iFrames 和 Web 剪辑不支持 Portlet 消息传递或协作 Portlet。它们无法利用门户的个性化引擎、流程集成或很多内容管理功能。
图 1. 通过 iFrame 集成了 ibm.com 网站(右下角)的门户页
![通过 iFrame 集成了 ibm.com 网站的门户页](https://i-blog.csdnimg.cn/blog_migrate/e7b001a3a4a5a8712e9c0eb8cb3306eb.png)
创建自定义 iFrame Portlet 假定您希望使用 iFrame,但要提供 Web Page Portlet 之外的其他功能。您可以将 iFrame 嵌入到 Portlet JSP 中并对 iFrame 名称进行编码(使用命名空间),从而编写自己的 iFrame Portlet。 此部分说明了决定编写自定义 iFrame Portlet 时需要处理的一些问题。 防止名称冲突 必须对 iFrame 名称进行编码,以防止在页面上存在 Portlet 的多个实例时出现冲突。使用命名空间对此名称进行编码,如清单 1 中所示。 清单 1. 使用命名空间对 iFrame 名称进行编码
<iframe name="<portletAPI:encodeNamespace value='myapp_IFrame’ />"
width="100" height="100"
href="http://www.somesite.com/app.html"/> |
处理会话超时 当向 Portlet 添加 iFrame 时,必须对会话超时的可能性进行管理。如果用户花费太多的时间在 iFrame 内进行交互,门户会话可能会超时,具体取决于为门户服务器会话设置的超时值。 可以使用隐藏 iFrame 或 AJAX 在 Portlet 内刷新门户页,从而解决此问题。 清单 2 显示了如何在 Portlet 内使用隐藏 iFrame 刷新页面 清单 2. 使用隐藏 iFrame 刷新页面
<script>
var wps_PortalTimer= setInterval("wps_PokeTheSession();", 1740000);
function wps_PokeTheSession()
{
if ( window.frames['wps_BackgroundRefresher'] )
{
window.frames['wps_BackgroundRefresher'].location=document.location;
//Now you can either throw away the iframe contents after it loads,
//or you can update the current DOM with the new content for the portlets.
}
}
</script>
<iframe name="wps_BackgroundRefresher" width="0" id="wps_BackgroundRefresher" /> |
清单 3 显示了相应的 AJAX 方法,该方法将使用 XMLHttpRequest 调用在 Portlet 内刷新门户页。 清单 3. 使用隐藏 AJAX 刷新页面
<script>
var wps_PortalTimer= setInterval("wps_PokeTheSession();", 1740000);
var wps_ajaxRequest;
function wps_ProcessRequest()
{
if (wps_ajaxRequest.readyState == 4)
{
//Now you can either throw away the contents,
//or you can update the current DOM with the new content
//for the portlets.
}
}
function wps_PokeTheSession()
{
// Mozilla way
if (window.XMLHttpRequest)
{
wps_ajaxRequest = new XMLHttpRequest();
wps_ajaxRequest.onreadystatechange = wps_ProcessRequest;
wps_ajaxRequest.open("GET", document.location, true);
wps_ajaxRequest.send(null);
// IE way
}
else if (window.ActiveXObject)
{
wps_ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP");
if (wps_ajaxRequest)
{
wps_ajaxRequest.onreadystatechange = wps_ProcessRequest;
wps_ajaxRequest.open("GET", document.location, true);
wps_ajaxRequest.send();
}
}
}
</script> |
同样,对于 iFrames Portlet,需要对所有相应内容使用命名空间。即,对每个 JavaScript 变量、JavaScript 函数名称、iFrame 名称和 iFrame ID 都要使用 encodeNamespace Portlet 标记。例如: var <portletAPI:encodeNamespace value=' wps_PortalTimer ' /> = setInterval("<portletAPI:encodeNamespace value=' wps_PokeTheSession ' /> ();", 1740000); 域外的身份验证 对于涉及到域外的 iFrame 的身份验证,目前并没有真正的解决方案可用,因为浏览器会尝试保护用户。出于安全考虑,很多浏览器都不允许 iFrame 或 XMLHttpRequest 访问主浏览器请求域之外的其他域。因此,您需要确保 iFrame 所嵌入到的应用程序与门户服务器属于相同的域。 如果站点要求身份验证,则必须对其他应用程序进行自己的自定义表单身份验证或基本身份验证。如果应用程序使用 Header,则在生成 iFrame 时,代码可以读取 HTTP Header 并将其转发到后端应用程序。Cookie 转发也是如此。 状态管理 使用 iFrame Portlet 时,浏览器的“后退”、“前进”和“刷新”按钮会导致操作不一致。如果用户单击“重载”/“刷新”按钮,将重新生成整个浏览器页,从而会丢失所有 JavaScript 状态信息。为了解决此问题,可以使用众多持久性方法中的一种,如 Cookie、表单字段等。另外,由于会重新生成整个页面,因此主题将使用原始 URL 创建 iFrame。如果此站点不使用 Cookie 或其他方法维护状态,iFrame 生成操作还需要重新生成目标信息。 对于浏览器的“后退”按钮,如果 iFrame 的状态发生更改而更新浏览历史,则可能会正常工作。而将给用户带来困扰的是,当使用 WebSphere Portal 和 iFrame 时,浏览器历史可能不能按照预期的方式进行显示。我们的经验表明,即使是同一门户中的两个用户也可能期望得到不同的结果。 使用 Web Clipping Portlet 将 Web 应用程序集成到门户中的另一个解决方案是使用 IBM Web Clipping Portlet 创建自己的剪辑 Portlet(也称为 Web Clipper)。可以使用 Web Clipping Editor 创建 Web Clipper,如图 2 中所示。要使用 Web Clipping Editor,请打开 WebSphere Portal Administrative 页,然后展开 Portlet Management。 图 2. Web Clipping Editor
![Web Clipping Editor](https://i-blog.csdnimg.cn/blog_migrate/3c66c3d7404a113ed7ae3e6c5f8c8565.png)
可以使用 Web Clipper 在 Portlet 中显示文档的特定部分。还可以使用其进行以下工作:
- 添加参数来指定额外的 Header
- 使用 URL 重写
- 访问防火墙后的内容
- 将特定 Cookie 从客户机-门户对话复制到门户-原始服务器对话中。
- 指定缓存超时
- 在页面上启用其他 Portlet,以重置 Web Clipping Portlet 状态
Web Clipping Portlet 具有以下限制:
- 有些站点超出了页面尾部。虽然 Web Clipping Editor 设计用于处理各种网站编码技术,但并不能处理出现的所有情况。如果遇到了其设计能力无法处理的网站,结果可能并不会是您所预期的。如果一个页面上有两个 Web Clipping Portlet,JavaScript 名称可能会冲突。另外,所剪辑内容和另一个 Portlet 及主题间可能出现 JavaScript 名称和命名空间冲突。
- Web Clipping Portlet 已得到增强,在处理 JavaScript 方面更为可靠和稳定。不过,存在外部站点 JavaScript 会导致意外行为的情况。例如,当使用相对 URL 进行 JavaScript 编码时,可能会由于未修改 JavaScript 内的 URL 而遇到问题。当站点对使用 DHTML 的页面结构的特定层次或浏览器特定功能具有依赖性时,也会出现不可预见的结果。
- 来自 Web Clipper 的链接可能会存在行为不规范的情况,从而可能会将用户带到 iFrame 甚至门户外的位置。例如,应用程序可能存在将每个 URL 重写到 Clipper Portlet 时未检测到的链接。
- HTML 分析器希望接收到格式正确的 HTML。格式存在问题的 HTML 可能会导致显示意外的结果。
与 Web Page Portlet 相比,Web Clipping Portlet 在处理外部站点方面成熟得多。它能更好地处理 JavaScript,且支持反向代理,因此用户能从防火墙后访问内容;此外,它的身份验证机制也更为成熟。不过,在使用 Web Cliping Portlet 时可能遇到一些与 Portlet 技术或 WebSphere Portal 完全无关的问题。 Web Clipping Portlet 直接从外部站点接收标记和 JavaScript,它必须对代码进行调整,以便能够在整个聚合页面上共存。WebSphere Portal 无法控制来自外部站点的代码的质量,也不能保证与聚合到页面上的其他外部站点代码的兼容性。因此,Web Clipping Portlet 的灵活性完全依赖于所剪辑的外部站点代码的质量。它最初的时候可能很可靠;不过,如果使用格式存在问题的 HTML、与页面上的另一个外部站点具有相同名称的 JavaScript 变量或包含相对 URL 的 JavaScript 对外部站点进行了更新,则 Portlet 可能生成不一致的结果。
IBM WebSphere Portlet Factory 一致地确保聚合和呈现时聚合标记的稳健性、可伸缩性、准确性和可靠性的唯一方法是,直接从 Portlet 生成。当然,这意味着必须编写自定义 Portlet。 现在编写自定义 Portlet 的过程已经变得更为简单了。IBM Rational Application Developer(或 Rational Software Architect)提供了多个向导类帮助您构造 Portlet。此外,IBM 还在今年推出了 WebSphere Portlet Factory,提供了一个快速应用程序开发备选方案来帮助开发人员快速开发 Portlet。可以使用 Rational Application Developer 或 Eclipse 插件 WebSphere Portlet Factory Designer 来创建 WebSphere Portlet Factory Portlet。 WebSphere Portlet Factory Portlet Development 范式与标准 Portlet 开发范式不同。它存在一个学习过程;掌握了这种方法后,就可以快速开发和测试复杂的 Portlet。另外,此方法仅需要很少的 J2EE 知识。 通过使用 WebSphere Portlet Factory Designer 工具,可以通过将预先构建的组件(称为“构建块”)快速组合到一起来构建组合应用程序。可以使用标准构建块(Portlet Factory 提供了 70 个即时可用的构建块)或编写自己的构建块。可以将构建块组装为模型,就像将 Portlet 组装为组合应用程序一样。在运行时,此模型将生成应用程序代码,包括 JSP、Java 类和 XML 文档。您所进行的工作实际上就是捕获和自动构建动态 Portlet 的流程。模型打包为 WAR 文件,因此,从 WebSphere Portal 的角度而言,它就是一个 Portlet 应用程序。 WebSphere Portlet Factory 提供了对 JSR 168、WSRP、单点登录集成、凭据、Portlet 到 Portlet 通信等的全面支持,实现了与 SAP、数据库、Peoplesoft、Domino、Seibel、Excel 工作表等的无缝集成。
结束语 有很多解决方案支持快速将 Web 应用程序集成到 WebSphere Portal 中。这既包括快速但并非最佳的 iFrame,也包括 Web Clipping Portlet,还包括新 IBM WebSphere Portlet Factory。每个解决方案都有自己的优点和缺陷。iFrame 是一个很有价值的工具,但需要注意它们的限制,并要事先进行计划。
致谢 作者感谢 Scott DeWitt 和 Usman Memon 为撰写本文提供的帮助。 |