首页 文章 J2EE综合 WebSphere Portal V6.1 中的新增功能:JSR 286 功能

邮件订阅

WebSphere Portal V6.1 中的新增功能:JSR 286 功能 E-mail
用户评价: / 1
好 
作者:Administrator   
2008-12-01 00:06

在本系列文章的第 1 部分“Java Portlet Specification V2.0 (JSR 286) 中的新增功能”中,我们研究了 Java Portlet Specification, JSR 286 的第二版带来的新编程功能。您已经了解了这些扩展如何使得 Portlet 程序员能够解决新用例,尤其是在独立开发的 Portlet 之间的协作和对流行的 AJAX 技术的改进的支持方面。

在本系列的这个第二部分中,我们将带您了解这些新功能在 IBM WebSphere Portal V6.1 中是如何公开的。

事件支持

我们将考虑的第一个 JSR 286 功能是 Portlet 事件。正如本系列的第一部分所述,Portlet 事件表示松散耦合的发布和订阅通信模型,其中某个 Portlet 发出事件,然后运行在门户中的代理组件将该事件中继到其他相关 Portlet。

Portlet 间通信一直是非常重要的用例,因此 WebSphere Portal 在多个版本中都提供了用于在 Poerlet 之间进行代理信息交换的非常相似的通信机制:WebSphere Portal 协作 Portlet 功能,也称为属性代理。对于 JSR 286 的 Portlet 事件支持,相同的发布和订阅基础结构已经得到扩展,现在支持新的标准化应用程序编程接口(application programming interface,API)。

连接 Portlet

从管理的角度看,连接基于 JSR 168 的协作 Portlet 与连接带事件支持的 JSR 286 Portlet之间没有任何区别:两者都是使用连接管理来完成的,其中的连接定义为从一个 Portlet 的已发布信息(某个发布事件)指向另一个 Portlet 中的处理逻辑(某个处理)。当然,连接工具需要了解 Portlet 能够发布和接收的事件类型。因此,您必须按照 Java Portlet Specification 的建议,在 Portlet 的 portlet.xml 部署描述符中声明该 Portlet 支持的所有事件。否则,您将不能在 WebSphere Portal V6.1 中连接 Portlet,并且 Portlet 将无法通信。

您应该为声明的所有事件提供用户可读的显示名称,以便连接工具能够以用户友好的方式显示连接源和目标:JSR 286 添加了在某个 WAR 文件中的所有 Portlet 之间共享的特定于语言的信息;因此,除了 JSR 168 Portlet 资源包之外,新标准还定义了一个应用程序资源包,其中存储了诸如这些事件显示名称等可转换信息。

本文提供的示例 Portlet 演示了如何在部署描述符中定义事件,并在代码和资源包中引用它们,以说明各个部分如何正确地组合在一起。

WebSphere Portal 目前不支持通过简单地将 Portlet 放在同一个页面上来实现 Portlet 的动态相互联系;仅当定义了匹配的连接时,才会在 Portlet 之间交换事件。通常,页面由管理员设置,包括页面上的 Portlet 的连接。拥有适当权限的用户可以向页面的私有视图添加 Portlet,同时还可以设置不适用于其他用户的私有连接。

图 1 是带有两个连接在一起的示例 Portlet 的 Portlet 连接工具的屏幕快照。


图 1. Portlet 连接工具
Portlet 连接工具

显式的连接模型使管理员可以完全控制 WebSphere Portal 中部署的 Portlet 如何通信。特别是,此模型使您可以将目标事件定义为全局的(在所有页面中可见),并建立在不同页面上的 Portlet 之间进行协作的跨页面连接。来自一个 Portlet 的事件可以通过多个页面内和跨页面连接进行传播。可以使用页面切换标记来对其中一个跨页面连接进行标记,以便在事件处理完成以后,可以将浏览器重定向到目标页面。

连接是页面的数据模型的一部分,这意味着页面上的管理功能和 API 还包括所包含的连接:诸如 XmlAccess 等配置管理工具或新版本 6.1 的站点管理工具可以随同页面一起导出和导入连接。WebSphere Portal 应用程序模板允许您创建具有给定设置的 Portlet、页面和业务组件的多个实例,它可以作为应用程序实例的一部分使用通信 Portlet 来设置连接。最后,用于读取模型信息的公共模型系统编程接口(system programming interface,SPI)、公共控制器 SPI 和模型 Atom Feed 基础结构(两者均为 6.1 版的新功能)支持读取和修改页面的连接结构。

事件有效负载和互操作性

JSR 286 规范允许 Portlet 作为事件有效负载发送和接收复杂 Java 对象,前提是这些有效负载是 Java 和 JAXB XML 可序列化的。这种许可允许跨类加载器甚至事件服务器传输复杂对象,例如在与遵循 Web Services for Remote Portlets (WSRP) 2.0 协议的远程 Portlet 通信的时候。WebSphere Portal 6.1 支持 WSRP 2.0,并允许本地和远程 Portlet 之间的完全互操作性和事件传播。

XML 序列化机制(基于 JAXB 2.0)还用于在不同类加载器之间转换复杂对象。当在 Portlet WAR 文件中对自定义有效负载类型打包时,通常就会出现这种序列化情况,因为每个 Web 模块是在各自的类加载器中进行部署的。XML 序列化会带来性能开销;因此,WebSphere Portal 尝试尽可能传递直接对象引用。您可以通过在公共类加载器中部署共享有效负载类来利用此功能,例如通过使用 WebSphere Application Server 共享库概念,以便消除对序列化的需要并获得最佳的性能。

一般来讲,您应该使用简单 Java 类型(通常为 String)作为事件有效负载,因为即使 Portlet 最初不是一起开发的,此方法也可以最大化互连 Portlet 的可能性。对于独立部署的 Portlet,复杂的事件有效负载类很少是兼容的。

您应该通过声明兼容的事件名称或别名来改进 Portlet 的互操作性。事件名称通常不仅描述了所交换的数据,而且还描述了创建或需要该数据的活动。例如,某个日历 Portlet 可能对接受日期作为输入的特定 show_week_for_date 处理事件做出反应。为了将来自另一个 Portlet 的输入连接到此活动,另一个 Portlet 需要在同一个特定于 Portlet 的命名空间中产生一个 show_week_for_date 发布事件;在产生日期的订单处理 Portlet(举例而言)上下文中,此事件名称可能没有多大的意义。为此,JSR 286 支持使用事件的别名。例如,订单处理 Portlet 可以声明一个 order_added_for_date 发布事件,其别名为 show_week_for_date 和 show_month_for_date,以便用户能够将订单选择事件连接到日历中的不同操作。

但是,此方法仍然意味着两个 Portlet 设计的相对紧密的耦合。为了最大化互操作性,对于每个仅描述其预期或产生的数据类型的事件,您应该为其声明一个别名,换句话说,这就是最低兼容性要求。例如,您可以声明如清单 1 所示的日历 Portlet 处理事件。


清单 1. 日历 Portlet 处理事件
<event-definition
xmlns:cal=”http://www.acme.com/portlets/calendar”
  xmlns:xsd=”http://www.w3.org/2001/XMLSchema”>
  <qname>cal:show_week_for_date</qname> 
  <alias>xsd:date</alias>
  <value-type> java.util.Date</value-type>
</event-definition>
  

使用别名名称,即使两个连接的 Portlet 是独立地开发的,show_week_for_date 事件也可由产生日期的任何源触发。

新订单已添加,并且日期已发送到日历。请参见图 2。


图 2. 事件示例
事件示例

WebSphere Portal 中由用户控制的事件传播

JSR 286 事件传播机制描述每当某个 Portlet 发布了事件时的自动化 Portlet 交互。Portlet 生命周期的事件阶段不允许任何类型的用户交互。WebSphere Portal 使用 Portlet 间通信机制扩展了此模型,在该机制中,信息的传播由用户显式地控制:我们将此机制称为 Click-to-Action 模型。

其基本思想在于,与在操作阶段中发布事件不同,Portlet 可以使用特殊 HTML 构造将事件信息嵌入到标记中,以支持实时文本形式的事件源。然后此事件源可以变为浏览器中的活动热点:在单击时,该事件源动态地将页面上的所有匹配处理目标收集到向用户显示的菜单中。然后用户可以为所执行的信息选择处理操作。请参见图 3。


图 3. 用于在订单 Portlet 中交付日期实时文本的上下文菜单
用于在订单 Portlet 中交付日期实时文本的上下文菜单

此模型中用于提供事件源的机制与 JSR 286 不同(语义 HTML 标记而不是 Java 调用),但是 JSR 286 事件处理很适合在此模型中作为处理目标。因此,定义处理事件的 JSR 286 Portlet 在 WebSphere Portal V6.1 中作为 Click-to-Action 目标自动变得可用。您可以通过在 Portlet 中提供 JSR 286 源事件和实时文本标记来容易地组合这两种编程模型。请注意,由于 Click-to-Action 完全基于 HTML 标记,因此可将其用于在门户页面上表示为标记的所有类型的组件之间的通信。例如,您可以在页面上显示的内容管理信息中为事件源添加标记,然后在同一个页面上的 JSR 286 Portlet 上发送该信息。有关 Click-to-Action 支持的更多信息,请参见 WebSphere Portal V6.1 信息中心

最后,我们希望指出的是,WebSphere Portal 中的 JSR 286 事件支持完全可与我们前面已提到过的早期版本中的协作 Portlet 功能互操作。协作 JSR 168 Portlet 可以发送由 JSR 286 Portlet 作为处理事件接收的信息,并且 JSR 286 Portlet 可以发布使用协作 Portlet 模型传播到 Portlet 的事件。这种互操作性允许将带有协作 Portlet 的现有系统顺利迁移或扩展到新的 Portlet 标准,从而保护客户的投资。





回页首


公共呈现参数

除了 Portlet 事件以外,公共呈现参数代表 Portlet 之间的替代协作方法。尽管两种机制都允许在 Portlet 之间交换信息,但它们在几个方面存在差异。我们首先研究公共呈现参数的技术细节及其在 WebSphere Portal 中的实现,然后我们将提供指导原则以帮助您选择用于 Portlet 通信的最适当技术。

使用公共呈现参数

正如在本文的第一部分所指出的,从编程的角度看,公共呈现参数的处理几乎与普通(私有)呈现参数的处理完全相同:Portlet 可以使用 JSR 168 为私有呈现参数引入的相同 API 方法来设置和读取此参数。从程序员的角度看,重要的区别在于,公共呈现参数是在 portlet.xml 部署描述符中声明的,因此成为了 Portlet 的外部接口。请参见清单 2。


清单 2. 公共呈现参数
	<public-render-parameter
	xmlns:dm=”http://www.acme.com/portlets/doc-mgmt”>
		<identifier>selected-doc</identifier>
		<qname>dm:doc</qname>
	</public-render-parameter>

这个 portlet.xml 片段声明该 Portlet 代码使用一个具有特定于该 Portlet 的标识符 selected-doc 的呈现参数,并且此呈现参数可在全局(并且我们希望是唯一的)名称 http://www.acme.com/portlets/doc-mgmt:doc 下在外部进行共享。如果第二个 Portlet 也声明了一个全局名称为 http://www.acme.com/portlets/doc-mgmt:doc 的公共呈现参数(无论它使用的特定于该 Portlet 的标识符是什么),则它现在可以共享此呈现参数的值。请注意,WebSphere Portal V6.1 将存储 URL 中您已在 portlet.xml 中声明的命名空间和 Qname,因此您应该将这些内容保持尽可能简短。

WebSphere Portal V6.1 不需要任何管理任务来为了共享公共参数而对两个 Portlet 进行设置。它们均使用相同全局名称这一简单事实就足够了;只需将两个 Portlet 放在一个页面上,它们就会开始交互。

实际上,协作甚至可以跨页面进行。缺省情况下,Portlet 设置的所有公共呈现参数都放在全局范围中。该事实意味着,您可以与一个使用公共参数的 Portlet 交互,然后切换到不同页面上正在使用相同公共参数的另一个 Portlet。当您第一次查看第二个 Portlet 时,可以看到它立即用第一个 Portlet 提供的信息完成了设置。如果您拥有多个 Portlet(甚至在不同的页面上),这些 Portlet 全都可以显示与某个全局键(例如客户 ID)相关的信息,则此方法使得公共呈现参数成为此类场景的理想工具。通过在所有 Portlet 中将此全局键视为公共呈现参数,这些 Portlet 将自动进行协作。

限制公共呈现参数的共享范围

显而易见,在某些情况下,这种全局信息共享并不是所需的。一种常见的示例情况是您在单独的页面上有两对协作 Portlet,例如一个导航器和一个查看器。您希望第一个页面上的导航器控制同一个页面上的查看器,但是不影响另一个页面上的查看器。在 WebSphere Portal V6.1 中,您可以通过将公共参数的共享范围限制到某个页面来控制此行为。为此,请转到该页面的 Edit page settings,并将 param.sharing.scope(在 Advanced options - I want to set parameters 下面)设置为某个非空值,例如 scope1。放在该页面上的所有 Portlet 现在将对它们声明的呈现参数使用自己的共享值,因此它们仍然可以共享信息,但是它们不能影响其他页面上的 Portlet。请参见图 4。


图 4. public.param.scope 页面设置
public.param.scope 页面设置

当您将另一个页面的页面设置设置为相同的值 scope1 时,该页面也成为了相同共享范围的一部分。一般来讲,当且仅当满足以下条件时,两个 Portlet 才共享某个公共呈现参数的值:

  • 它们在 portlet.xml 部署描述符中使用相同的全局名称声明该参数。
  • 它们被放在同一个页面或具有相同 param.sharing.scope 设置值的页面上。

我们在开头看到的全局共享范围是该页面设置为空时的特殊情况。

使用公共呈现参数的 Web 行为支持

Java Portlet Specification 1.0 中的呈现参数的基本思想是为 Portlet 提供一个 API,Portlet 可以在其中存储有关其内部导航状态的信息,并允许门户将此信息放在 URL 中。此概念意味着呈现参数可以在 Portlet 中为诸如书签和返回按钮等浏览器操作提供预期的用户行为。如果将 Portlet 内部导航状态表示为呈现参数,则门户页面的每个 URL 将正确地恢复该状态,例如用户选择。此外,HTTP 代理缓存可以根据 URL 正确地缓存相同门户页面的不同状态。

WebSphere Portal 自从 5.1 版以来就已支持此类可加入书签的丰富 URL,后来在 6.1 版中,公共呈现参数也成了此 URL 信息的一部分。例如,它们将作为门户书签的一部分进行存储。事实上,WebSphere Portal 中的任何 URL 都可以包含公共呈现参数,并且您可以使用特定于产品的 URL 生成功能(例如 UrlGeneration JSP 标记)设置 Portlet 的公共呈现参数。

使用公共呈现参数还是使用 Portlet 事件

正如我们从前面的讨论中看到的,可以将公共呈现参数视为对 Portlet 事件的较轻量级的通信替代方法。下面的列表将各自的功能进行了对比,以帮助您决定哪一种机制更适合您的用例。

公共呈现参数具有以下特性:

  • 它们通常不需要显式的编码,而是只需在 portlet.xml 部署描述符中进行声明。
  • 它们仅限于简单字符串值。
  • 它们不需要显式的管理来设置协作。
  • 它们不会随着共享信息的 Portlet 数量的增长而导致性能开销。
  • 它们通过 URL 更改进行更新,例如跳转到某个书签。
  • 可以在门户主题和皮肤中编码的链接中对它们进行设置。
  • 可以在使用特定于产品的 API 创建的链接上对它们进行设置,这样的链接从一个 Portlet 指向不同页面上的另一个 Portlet。

Portlet 事件具有以下特性:

  • 需要显式的 Portlet 代码来发送和接收它们。
  • 它们可以包含复杂信息。
  • 它们允许通过在 Portlet 之间设置不同类型的连接(页面内或跨页面,公共或私有)实现细粒度的控制。
  • 它们可以触发具有不同信息的级联更新。例如,Portlet A 可以将事件 X 发送到 Portlet B,后者又将不同的事件 Y 发送到 Portlet C。
  • 它们随着通信链接数量的增长而导致增加处理开销。
  • 它们必须由某个显式的用户交互(通常是通过单击 Portlet 中的某个操作链接)发起,并且不能在第一次跳转到某个页面时将它们用于设置协作视图。
  • 它们可以与 WebSphere Portal 提供的协作 Portlet 通信功能互操作。

两种机制都允许您将数据交互与某个页面切换耦合在一起。对于事件,正如前面所解释的,您可以定义页面切换跨页面连接。对于公共呈现参数,您可以在一个 Portlet 中使用特定于产品的 API 生成指向不同页面上的另一个 Portlet 的链接,并为该目标设置公共呈现参数。

当然,您甚至可以组合使用两种技术;例如,您可以在 Portlet 中声明一个设置呈现参数的处理事件,同时将此参数设置为公共参数,以便能够通过两种方式接收信息。

此讨论应该有助于您确定哪一种功能更适合给定的用例。根据一般经验,应该在可使用公共呈现参数的场合使用公共呈现参数,并对呈现参数不足够的较复杂情况使用 Portlet 事件。





回页首


其他 JSR 286 功能

我们现在已介绍了 JSR 286 引入的 Portlet 协作功能。这些功能是该规范中最新颖的内容;这些功能还依赖于门户实现,后者负责在 Portlet 之间代理信息。

JSR 286 中的大多数其他新的编程特性(如 Portlet 筛选器)已在该规范中进行了详细的定义,并且不依赖特定的门户实现,因此就不需要讨论特定于 WebSphere Portal 的主题了。

在下面几个部分中,我们将介绍有关各个新的 JSR 286 功能的一些明确详细信息,当您在 WebSphere Portal V6.1 上进行 JSR 286 Portlet 编程时,了解这些信息是有帮助的。

资源服务

资源服务为您提供了对 HTTP 协议的所有方面的完全控制。WebSphere Portal 将您在资源响应上指定的所有响应属性作为 HTTP 标头写出,因此您可以控制所提供的内容的语言、内容类型和其他信息。另一面在于,与普通页面请求相反,门户不为响应提供任何缺省标头信息;所有信息都必须在资源服务过程中显式地进行设置。

WebSphere Portal 实现了由该规范定义的不同缓存级别 PAGE、PORTLET 和 FULL。正如前面指出的,WebSphere Portal 使用编码了页面的完整导航状态的丰富 URL。具有缺省 PAGE 缓存能力的资源 URL 包含大量有关门户中的其他组件的特定信息,在许多情况下,资源请求中不需要这些信息。

如果希望对资源请求利用 HTTP 缓存,请确保将资源 URL 缓存能力设置为处理该资源请求所必需的最高级别(最少的信息),以生成一致的 URL 并改进 HTTP 缓存能力。此外,要使资源请求可缓存,您需要在响应上显式设置缓存控制信息,以便门户能够生成缓存标头。与普通呈现请求不同,portlet.xml 部署描述符中的缺省缓存信息不适用于资源请求。

Cookie 处理

JSR 286 添加了用于针对 Portlet 请求和响应读取和写入 Cookie 属性的 API 方法,但是门户实现可以自由决定有关如何存储和处理这些 Cooie 的细节。WebSphere Portal 直接将 Cookie 属性转换为实际的 HTTP Cookie。如果您不显式指定 CooKie 路径,则会将其缺省设置为门户的 URL 上下文,因此后续的门户请求可以正确地接收回 Cookie,但是相同服务器上的其他 Web 应用程序则不能。

Cookie 不在某个命名空间中,因此可以在 Portlet 之间共享,如果需要的话,还可以与其他 Web 应用程序共享。因此 Cookie 提供了Portlet 之间的替代协作机制,这在某些情况下可能非常有用。由某个 Portlet 设置的新 Cookie 对相同客户端请求的后续生命周期阶段中的所有 Portlet 可见,除非客户端决定丢弃它们,否则在后续请求中也可见。

WebSphere Portal V6.1 目前不支持在呈现阶段中设置 Cookie。当客户端响应已经在呈现阶段中提交时,这些 Cookie 未传输到客户端,从而在后续的请求中丢失。

容器运行时选项

容器运行时选项允许 Portlet 从门户和 Portlet 容器请求特定的运行时行为。WebSphere Portal V6.1 支持以下容器运行时选项:

  • javax.portlet.escapeXml(由 JSR 286 定义),用于避免 JSP 标记生成的 URL 的缺省 XML 转义。
  • javax.portlet.actionScopedRequestAttributes(由 JSR 286 定义),用于跨请求边界保留 Portlet 请求属性。
  • com.ibm.portal.public.session(特定于产品),用于指示某个 Portlet 需要会话才能正确操作。它请求门户在每当包含该 Portlet 的页面被访问时,即使不存在任何用户登录,也要创建会话 Cookie。

有些代码不是非常适合 Portlet 规范的概念,但是仍然应该在 WebSphere Portal 中受到支持,上述所有这些运行时选项就表示此类代码的变通办法。在频繁使用的门户上,使用后两个运行时选项还会导致性能下降。因此,应该尽量避免使用这些运行时选项,并且最好以使得这些选项变得不必要的方式编写代码。

URL 流支持

对于使用 JSR 168 API 的 URL 生成,Portlet 始终必须在将 URL 对象写入到标记中之前,使用 PortletURL.toString() 方法将其转换为字符串。由于 WebSphere Portal 中的 URL 的丰富性质和相当大的大小,此字符串转换会负面影响创建大量 URL 的 Portlet 的性能。

JSR 286 添加了 write() 方法,允许您将 URL 对象直接流向响应写出程序,从而避免创建临时字符串对象。应该使用此方法来写出 URL。与 toString() 方法不同,此方法还自动提供 XML 和 HTML 规范所要求的 URL 的正确 XML 转义。类似的注意事项同样适用于 JavaServer? Pages 中的 Portlet URL 标记:直接写出 URL 的标记语法优先于在临时字符串变量中存储生成的 URL 的标记语法。

局限性

尽管 WebSphere Portal V6.1 提供了 JSR 286 的完全兼容的实现,并支持所有的主要功能,但是该标准的一些可选方面不受支持。有关详细信息,请参考 WebSphere Portal 信息中心。





回页首


远程 Portlet 支持

与 Java Portlet API 的第一个版本一样,JSR 286 规范是在与定义 Web Services for Remote Portlets (WSRP) 标准的 OASIS 委员会的密切协作下开发的。因此,两个规范紧密一致,并表示相同的编程模型,只不过针对不同的协议。JSR 286 定义了本地 Portlet 如何与基于 Java 的门户交互;WSRP 2.0 定义了远程 Portlet 如何与支持基于 SOAP 的 Web 服务的门户交互。

WebSphere Portal V6.1 组合了对这两个规范的支持。因此,JSR 286 的主要编程特性——尤其是 Portlet 协作和资源服务——也适用于远程 Portlet。例如,这意味着您可以在一个门户安装上部署某个 JSR 286 Portlet,然后从不同的门户安装远程地使用它,并且它将像在本地安装的那样继续工作。





回页首


结束语

通过对 JSR 286 的支持,最重要的是通过支持用于 Portlet 间通信的通用标准化机制,新的 WebSphere Portal 版本提供了一系列新特性,使得 Portlet 编程功能更加强大。该规范有意将这些新功能的某些方面留给特定于产品的实现去自由决定。预留的这种余地特别适合于 Portlet 间通信。该规范清楚地定义了如何编写 Portlet 程序来交换信息,但它没有定义该信息交换何时在门户环境中实际地进行,或者必须通过哪种途径来连接 Portlet 以控制该信息交换。

在本文的第二部分中,我们研究了该新标准的这些特定于产品的方面是如何在 WebSphere Portal V6.1 中进行处理,以及新功能如何与该标准以外的产品功能集成,例如 Click-to-Action 或高级 URL 生成。与第一部分相结合,本文为您提供了在新的门户项目中利用新的 Portlet 编程功能所需要的所有信息。






回页首


下载

名字大小下载方法
dummyOrders.war9KBHTTP
dummyCalendar.war11KBHTTP
关于下载方法的信息


最后更新于: 2008-12-01 00:06
 

欢迎转载

本站文章欢迎转载,但请注明出处(http://www.javajia.com,Java家)

其他相关文章