引言 已经开发和交付了为数众多的 Portlet这些 Portlet 可以安装在 WebSphere Portal 中除了包含在 WebSphere Portal 中的内部 Portlet 以外企业应用程序供应商为了提供对他们的系统的访问也开发了许多的 Portlet单个开发人员为了执行特定的门户功能或者为了提供针对特定问题的解决方案也纷纷推出了许多的 Portlet单单通过 WebSphere 门户目录就已经可以找到成百上千的 Portlet 可供使用这些 Portlet 涵盖了各种各样的应用程序和行业通常门户将使用一个或多个现有的 Portlet 来提供特定的功能并加速开发过程在某些情况下由于安全性控制或不公开的接口的缘故从门户访问特定于厂商的企业应用程序的惟一途径就是使用现有的 Portlet 虽然 Portlet 一般会通过配置提供一些自定义功能但通常这是很有限的在将现有的 Portlet 用于门户之前有时还需要其他的自定义功能包括简单的自定义(如提供与门户的其他部分更一致的外观)和复杂的自定义(如添加新的功能)我们来考虑一个现有的文件上传 Portlet我们可能需要加入一种常规算法来检查待上传的文件内容如果文件内容不合适那么在它抵达后台系统之前会被拒绝对于一个提供实时世界新闻的现有新闻频道 Portlet它可能只关注特定地区或特定主题的新闻而不应该显示其他的新闻在很多情况下门户范围的性能调优可能需要在门户的每一个 Portlet 中添加其他的逻辑以便测量执行时间 有多种方法可以修改和自定义现有的 Portlet最常用的方法就是面向对象的继承它使你能够从现有的 Portlet 派生新的 Portlet 以便添加新的功能因为 Portlet 的核心是一个或多个 Java 类这种方法的主要缺点是 首先新的 Portlet 要想能够自定义就必须从现有的 Portlet 创建 其次因为 Portlet 应用程序是作为 web 应用程序档案文件(WAR)交付的所以新的 Portlet 不能直接引用现有的 Portlet 的 WAR 中的类WAR 中 的所有类及其依赖性都必须先解包然后再重新打包到新的 Portlet 的 WAR 中 另外调用 Portlet 方法(如 service 和 actionPerformed)时还必须谨慎以防它将只被容器调用 与基于继承的自定义相比WebSphere Portlet 过滤器技术提供了一种更容易且更好的方法来重用和自定义现有的 Portlet Portlet 过滤器是一个(或多个)可重用的 Java 类可以通过一种标准的方式来声明性地添加或删除而无需对它所修改的现有 Portlet 或 Portlet 组进行更改 过滤器并不是一个 Portlet过滤器不创建对请求的响应但是它截取和修改请求(在请求传送到目标 Portlet 以进行处理之前)及响应(在响应聚集到门户页面之前) 过滤器并没有绑定到任何特定的 Portlet因此它的生命周期不依赖于任何单个 Portlet这就意味着一旦过滤器初始化完毕它就能够动态地应用到所有的可应用 Portlet而无需进一步的初始化 另外由于过滤器独立于任何 Portlet所以现有的 Portlet 或 Portlet 的 WAR 几乎不需要创建过滤器 WebSphere 代码转换和机器翻译是基于 Portlet 过滤器技术关于 WebSphere 代码转换和翻译的详细描述可以在版本 的 WebSphere portal 信息中心中找到而相关的文章列表请见参考资料部分 本文介绍了 WebSphere Portlet 过滤器的基础知识Portlet 过滤器和 Servlet 过滤器的不同之处以及如何开发和使用 Portlet 过滤器来自定义 Portlet另外还将解决各种开发问题以帮助简化其使用一种称为文件内容过滤器(File Content Filter)的过滤器为现有的文件上传 Portlet 添加了细粒度的文件控制机制本文就是以它为例来说明 Portlet 过滤器的使用的 您可以找到一些适用于 WebSphere Portal 的文件上传 Portlet在 WebSphere Portal 中 Portal Document Manager(PDM)Portlet 和 Portlet Installation Portlet 都是缺省安装的更有许多是在 WebSphere Portal Catalog 中列出的本文以 PDM Portlet(PDM)为例来说明文件内容过滤器的使用在 WebSphere Portal V 中PDM Portlet 在缺省状态下自动安装在 My Portal 中的 Document 页面内它给门户的用户提供了简单实时的文档查看和解决方案PDM 让用户具有编辑者(Editor)的权限使得他们几乎可以上传任何类型的文件然而对于许多组织来说这种功能的需求可能远远比 PDM Portlet 提供的标准行为复杂得多例如文件控制机制可以用于控制能够上传的文件的类型记录上传的文件和它们的属性报告上传成功或失败的状态等等本文中的文件内容过滤器将修改 PDM Portlet 的行为这样就只有某些类型的文件被允许上传 Portlet 过滤器与 Servlet 过滤器 如果您熟悉 Servlet 过滤器(请参阅 Java Servlet 规范以获得详细信息)从已经阅读的资料中您可能已经注意到了 Portlet 过滤器和 Servlet 过滤器的相似性实际上它们之所以是相似的是因为二者都可以声明性地嵌入从而截获并修改请求和响应但是理解它们之间存在着很大的不同是非常重要的在一定程度上它们之间的差异是与 Servlet 和 Portlet 之间的差异相联系的Servlet 过滤器是一个门户级过滤器它可以修改由一些小的部分(来自页面上所有 Portlet 的响应)集合而成的整个门户页面而 Portlet 过滤器只能用于那些小的部分Servlet 过滤器(如果已经安装的话)是接收和修改客户端请求的第一个组件同时也是修改对客户端的响应的最后一个组件(请参见图 ) 图 带有 Servlet 过滤器和 Portlet 过滤器的客户端请求事件序列 如图 所示 Servlet 请求(步骤 )在分派给一个或多个 Portlet 请求(步骤 )之前首先通过一个 Servlet 过滤器链进行处理(步骤 )在结果集聚到一起(步骤 和 )之前Portlet 请求进一步转发到 Portlet 过滤器链进行处理(步骤)接着将集聚的结果发送回 Servlet 过滤器进行处理之后将集聚的结果最终显示给用户(步骤 ) 一个过滤器链包含一个或多个过滤器在一个过滤器完成处理之后新的请求和响应将传送到链上的下一个过滤器链上的最后一个过滤器调用目标资源(Servlet 或 Portlet) 与 Servlet 过滤器一样Portlet 过滤器也是 WebSphere portal 体系结构中的一个可选的组件因此在解决实际的问题时可以使用一种类型的过滤器也可以同时使用两种类型的过滤器还可以不使用过滤器例如Servlet 过滤器可以用于压缩和加密整个门户页面而 Portlet 过滤器可能更适合只压缩和加密门户页面的一部分在 WebSphere Portal Transcoding Technology(请参见参考资料)中Portlet 级代码转换使用 Portlet 过滤器来进行内容转换标记转换和注解等等而门户级代码转换使用 Servlet 过滤器(或门户过滤器在 WebSphere portal 中是这样称呼的)来提供 Deck 片段 Portlet 过滤器的支持和开发 Portlet 过滤器的支持类定义在 WebSphere portal 的 comibmwpspepclegacycmpf 包中PortletFilter 接口提供了三个方法来管理 Portlet 的生命周期 void init(PortletFilterConfig config) 容器调用一次这个方法来准备用于服务的过滤器对象 PortletFilterConfig(config) 使得过滤器能够访问配置参数以及对门户上下文的引用 void destroy() 这个方法是在将过滤器从服务移除之后调用的这个方法使得过滤器能够清除任何存放的资源 void doFilter(PortletFilterMethod method PortletRequest request PortletResponse response PortletFilterChain filterChain) 这个方法执行实际的过滤工作这个方法使得过滤器能够检查和修改请求和响应或者完全跳过请求的处理第一个参数(method)是过滤器能够调用的请求方法的类型(如 SERVICE 或 ACTIONEVENT)最后 的参数(filterChain)包含一个已经注册且正在运行的过滤器的列表 包中的 PortletFilterAdapter 类为 PortletFilter 接口提供了一个缺省的实现根据作为 doFilter 方法中的第一个参数传送的请求方法的类型可以将 doFilter 方法的缺省实现委托给一组 do 方法(doServicedoTitledoActionEventdoMessageEventdoLogindoBeginPage 和 doEndPage)do 方法的缺省实现做的惟一一件事情就是将最初的请求和响应发送到链上的下一个过滤器或目标 Portlet过滤器的每个 do 方法都是在目标 Portlet 的对应方法调用之前调用的表 列出了每个过滤器方法和目标 Portlet 方法之间的映射 表 Portlet 和 Portlet 过滤器方法 自定义的 Portlet 过滤器应该扩展 PortletFilterAdapter 类并且覆盖表 中所列的一个或多个方法举例来说如果自定义过滤器仅支持 Portlet VIEW 并且修改输出那么就只需要覆盖 doService 方法然而如果过滤器支持 Portlet ActionEvent 并且修改输出那么 doService 和 doActionEvent 都应该被覆盖(请参见下一部分以获得详细信息)WebSphere Portal 提供了三个便利的包装类 PortletRequestWrapper(用于 PortletRequest) PortletResponseWrapper(用于 PortletResponse) ClientWrapper(用于客户端接口) 包装类应该用于创建自定义请求响应和客户端类这样就可以容易地添加新的功能而不必实现整个接口了 图 带有 Portlet 过滤器的服务请求的请求 |