- 浏览: 25516 次
- 性别:
- 来自: 大连
文章分类
最新评论
WebSphere Portal
Portlet API
本节提供了 Portlet API 的简要描述。
<!-- from Portlet Container SDD -->
概述
<!-- definition of portlet -->
Portlet 是可以提供对基于 Web 的内容、应用程序和其它资源访问的可重用组件。可通过 portlet 访问 Web 页面、web 服务、应用程序和成为企业组合的内容供给。公司可以创建他们自己的 portlet 或从第三方 portlet 目录中选择 portlet。portlet 是打算被组装成更大的门户网站页面,其中同一 portlet 的多个实例为每个用户显示不同的数据。<!-- example??? -->
<!-- p>For detailed information about the classes and methods in the Portlet API, see the <a href="../../../Javadoc/WPS/index.html" target="_blank">Javadoc</a> . </p -->
从用户的角度来看,portlet 是门户网站站点中提供特定服务或信息(例如,提供日历和新闻)的窗口。从开发者的角度来看,portlet 是可插入的模块,它们被设计成在 Portal Server 的 portlet 容器中运行。
portlet 容器提供了一个运行时环境,在这个环境中实例化、使用和最终破坏 portlet。portlet 依靠门户网站基础结构来访问用户概要文件信息、参与在窗口和操作事件中、与其它 portlet 通信、访问远程内容、查找凭证以及存储持久数据。Portlet API 提供了这些功能的标准接口。portlet 容器不是一个类似于 servlet 容器的独立容器。它是以 servlet 容器上的瘦层的方式实现的,并重用 servlet 容器提供的功能。
IBM 正在与其它公司一同致力于 Portlet API 的标准化,使 portlet 能在实现此规范的 Portal Server 之间协同使用。WebSphere Portal 版本 4.1 中提供的 Portlet API 是迈向 Portlet API 标准化的第一步。要获取有关 portlet 规范的更多信息,请参阅
http://jcp.org/jsr/detail/168.jsp
Portlet 和 Servlet API
<!-- By extending <code>HTTPServlet</code>, -->
抽象 Portlet
类是 Portlet API 的核心抽象。Portlet
类扩展 Servlet API 的 HTTPServlet
。所有 portlet 间接地扩展此抽象类,且从 HttpServlet
继承,如下所示:
... +--javax.servlet.http.HttpServlet
|
+--org.apache.jetspeed.portlet.Portlet
|
+--org.apache.jetspeed.portlet.PortletAdapter
|
+--com.myCompany.myApplication.myPortlet
|
因此,portlet 是特殊类型的 servlet。这种类型的 servlet 的特性使它们能容易地插入并在 Portal Server 中运行。与 servlet 不同,portlet 无法直接发送重定向或错误到浏览器、转发请求或者写专用标记到输出流。portlet 容器依赖于 WebSphere Application Server 实现的 J2EE 体系结构。结果是,portlet 按类似于 J2EE Web 应用程序的方式封装,并按类似于 servlet 的方式部署。
总之,与 servlet 相比,可更动态地管理 portlet。可在不启动和重新启动 Portal Server 的情况下,应用以下更新:
- 可使用门户网站管理用户界面安装和除去由多个 portlet 组成的 portlet 应用程序。
- portlet 的设置可由有适当访问权的管理员更改
- 可使用管理 portlet 动态创建和删除 portlet。例如,一旦管理员创建新的裁剪,裁剪 portlet 就可用于创建新的 portlet 实例。
portlet 容器依赖于 WebSphere Application Server 实现的 J2EE 体系结构。结果是,portlet 按类似于 J2EE Web 应用程序的方式封装在 WAR 文件中,并按类似于 servlet 的方式部署。与其它 servlet 相似,要使用 servlet 部署描述符(web.xml )把 portlet 定义到应用程序服务器。这个文件定义 portlet 的类文件和只读初始化参数。
以下图显示部署了它的 WAR 文件之后的 portlet。对于 Portal Server 上部署的每个 portlet,它在应用程序服务器上创建一个 servlet 或者 portlet 类实例 。
<!-- width="516" height="447" -->
初始化参数是由 portlet 开发者设置的,并可由 portlet 使用 PortletConfig 对象读取。servlet 部署描述符可以包含多个 Web 应用程序,每个 Web 应用程序由 <servlet> 元素定义。此外,每个 servlet 定义可以指向相同的 portlet 类文件,因此可为每个 portlet 类实例使用不同的初始化参数创建不同的 PortletConfig 对象。要获取更多信息,请参阅 Web 应用程序部署描述符 。
portlet 部署描述符
除了 servlet 描述符之外,portlet 还必须提供 portlet 部署描述符(portlet.xml ) 以定义 portlet 对于 Portal Server 的能力。此信息包含特定于特定 portlet 或 portlet 应用程序的配置参数,以及所有 portlet 所提供的一般信息(如 portlet 支持的标记类型)。 Portal Server 使用该信息为 portlet 提供服务。例如,如果 portlet 在 portlet 部署描述符中对帮助和编辑方式注册其支持,则 Portal Server 将输出图标从而允许用户调用 portlet 的帮助和编辑页面。
以下是带有最少标记的示例 portlet 部署描述符。
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE portlet-app-def PUBLIC "-//IBM//DTD Portlet Application 1.1//EN" "portlet_1.1.dtd"> <portlet-app-def> <portlet-app uid="com.myCompany.myPortletApp.54321"> <portlet-app-name>My portlet application</portlet-app-name> <portlet id="Portlet_1" href="WEB-INF/web.xml#Servlet_1"> <portlet-name>My portlet</portlet-name> <supports> <markup name="html"> <view output="fragment"/> </markup> </supports> </portlet> </portlet-app> <concrete-portlet-app uid="com.myCompany.myConcretePortletApp.54321"> <portlet-app-name>My concrete portlet application</portlet-app-name> <concrete-portlet href="#Portlet_1"> <portlet-name>My concrete portlet</portlet-name> <default-locale>en</default-locale> <language locale="en_US"> <title>My portlet</title> </language> </concrete-portlet> </concrete-portlet-app> </portlet-app-def>
要获取包含每个标记的描述的详细信息,请参阅部署描述符 。
Portlet 概念
下图显示创建 portlet,在页面上放置 portlet 和用户访问 portlet 时 portlet 的不同变化。注意,前两个步骤涉及使用持久数据。但对于第三个步骤,数据只在会话持续时间期间可用。
门户网站管理员使用管理界面来部署新的 portlet 应用程序 WAR 文件或安装 portlet 的副本。这两个操作都创建具体 portlet ,这是由单个 PortletSettings 对象参数化的 portlet。每个 portlet 可能具有多个具体 portlet。PortletSettings 是具有读/写访问权,并是持久的。PortletSettings 包含最初在 portlet 部署描述符中定义的配置参数。
使用具体 portlet 能在不创建另外的 portlet 类实例的情况下,运行许多 portlet 不同配置的实例。在单个 portlet 的生命周期期间,可创建和破坏许多具体 portlet。无明确代表具体 portlet 的对象。可在许多用户之间共享同一个具体 portlet。
用户或管理员把 portlet 放到页面上。这创建具体 portlet 实例 ,这是由单个 PortletData 对象参数化的具体 portlet。每个具体 portlet 可能具有多个具体 portlet 实例。PortletData 存储已添加到页面的 portlet 的持久信息。例如,用户可以编辑股票报价 portlet,并可保存股票符号的列表以供公司跟踪。
PortletData 的作用域取决于具体 portlet 所在的页面的作用域。
- 如果管理员把具体 portlet 放到组页面,则 PortletData 对象包含为用户的组存储的数据。
- 如果具体 portlet 放在用户的页面上,PortletData 包含那个用户的数据。
用户访问包含 portlet 的页面时,会创建用户 portlet 实例 。用户登录门户网站时,Portal Server 会为每个用户的 portlet 创建 PortletSession 。PortletSession 参数化的具体 portlet 实例称为用户 portlet 实例 。每个具体 portlet 实例可能具有多个用户 portlet 实例。
用户 portlet 实例是由单个 PortletSession 参数化的具体 portlet 实例。每个具体 portlet 实例可能具有多个用户 portlet 实例。PortletSession 存储与单次使用 portlet 相关的瞬时信息。
Portlet 应用程序
Portlet 应用程序提供了封装一组共享相同的上下文的 portlet 的方法。上下文包含所有资源,例如,图像、属性文件和类。所有 portlet 必须封装为 portlet 应用程序的一部分。
具体 Portlet 应用程序
具体 portlet 应用程序是由单个 PortletApplicationSettings 对象参数化的 portlet 应用程序。对于每个 portlet 应用程序,可能具有多个具体 portlet 应用程序。PortletApplicationSettings 是具有读/写访问权,并是持久的。无明确代表具体 portlet 应用程序的对象。
具体 portlet 应用程序至少包含一个来自 portlet 应用程序的具体 portlet,但是无需全部包含它们。
Portlet 应用程序自己不提供代码,但是形成 portlet 的逻辑组。除了这更多的逻辑收益之外,同一 portlet 应用程序的 portlet 也可交换消息。
Portlet 方式
portlet 方式允许 portlet 显示不同的用户界面,这取决于 portlet 所需的任务。在 WebSphere Portal 中,portlet 有三种显示方式,可通过 portlet 标题栏上的图标来调用。Portlet 对显示方式的支持在 portlet 部署描述符 中定义。portlet 容器在 Portlet.Mode 对象中维护 portlet 方式。通过 Portlet API 提供下列方式:
Portlet API 为 portlet 提供方法来确定当前或前一个方式。所有 portlet 都必须支持视图方式。portlet 容器为用户提供控件从而使用户在其门户网站页面上能与 portlet 交互。单击其中一个控件能更改 portlet 的方式或状态。下面显示 portlet 在视图方式下的空白标题栏。
此标题栏显示编辑、帮助、最小化和最大化图标。单击铅笔图标使 portlet 处于编辑方式。
portlet 状态
portlet 状态允许用户更改在门户网站中怎样显示 portlet 窗口。在浏览器中,用户用标题栏中的图标调用这些状态,这与 Windows 应用程序的操作方法是相同的。portlet 状态用布尔值在 PortletWindow.State 对象中维护。
- 正常 当最初在门户网站页面上构建 portlet 时,它以正常状态显示——与其它 portlet 一起排列在页面上。
- 最大化 当最大化 portlet 时,它显示为门户网站的整个主体,替换了其它门户网站的视图。
- 最小化 当最小化 portlet 时,仅显示门户网站页面上的 portlet 标题栏。
Portlet API 为 portlet 提供方法来确定当前状态。
Portlet API 的元素
本节描述 Portlet API 的基本接口、类和方法。下图显示 Portlet API 中许多公共对象的结构图。
-
Portlet
由 PortletAdapter 扩展
- service()1
PortletResponse
- createURI() PortletURI
- service()1
PortletRequest
- getPortletSettings() PortletSettings
- getPortletApplicationSettings PortletApplicationSettings
- getMode() Portlet.Mode
- getClient() Client
- getData() PortletData
- getWindow() PortletWindow
- getWindowState() PortletWindow.State
- getPortletSession() PortletSession
- getUser() User
- getPortletSettings() PortletSettings
- getPortletConfig() PortletConfig
- getContext() PortletContext
- getLog() PortletLog
- getService() PortletService
- getContext() PortletContext
- service()1
PortletResponse
1
PortletRequest
和 PortletResponse
由 PortletAdapter 的帮助器方法(例如 doView())传递。
Portlet 类
抽象 Portlet
类是 Portlet API 的核心抽象。所有 portlet 通过扩展抽象类的子类之一(例如 PortletAdapter
)来扩展该抽象类,这提供有助于开发者的方法。
Portlet 生命周期
portlet 容器在 portlet 的生命周期期间调用抽象 portlet 的以下方法2 :
PortletSettings
实例化。2 这代表所有 portlet 上调用的方法。为实现侦听器 的 portlet 调用其它方法。请参阅侦听器生命周期 以获取更多信息。
getLastModified()
除了在 portlet 生命周期期间调用的方法外,portlet 容器为每个 portlet 请求调用 getLastModified() 方法。该方法返回 portlet 内容的更改的最后时间(以毫秒计),该时间在当前时间和 1970 年 1 月 1 日午夜之间 UTC(java.lang.System.currentTimeMillis())或为负值(如果时间未知)。要获取有关何时使用 getLastModified() 的更多信息,请参阅刷新 portlet 高速缓存 。
帮助器类
portlet 不直接扩展抽象 Portlet
类,而是扩展 PortletAdapter
或任何其它帮助器类依次扩展 Portlet
。扩展这些类之一,有助于保护 portlet 免受抽象 Portlet
类的更改。此外,它保存必须实现所有 Portlet
接口的方法,即使 portlet 不需要全部使用它们。使用 PortletAdapter
类,只需覆盖真正需要的方法。
在它的 service() 方法中,PortletAdapter
类调用对应于 portlet 方式
的方法。扩展该类的 portlet 能覆盖 doView()、doEdit()、和 doHelp() 方法,而不必测试该方法或编写特定的 service() 方法。
此外,PortletAdapter
使 portlet 能在具体 portlet 中存储变量。具体 portlet 变量与 Java 实例变量是不同的,因为它们绑定到 portlet 类或非具体 portlet。PortletAdapater
提供 setVariable()、getVariable() 和 removeVariable() 方法和具体 portlet 变量一起使用。
核心对象
以下对象是 portlet 最常用的:
这些对象的每一个是它在 Servlet API 中的副本的扩展。
PortletRequest
PortletRequest
对象通过 login()
、beginPage()
、endPage()
和 service()
方法传递给 portlet,为 portlet 提供请求特定的数据并使其能访问以下所列的进一步重要信息。
Client
对象封装赖于请求的信息(有关特定请求的用户代理程序)。来自 Client
的信息包含用户代理程序的制造商或客户机支持的标记类型。使用 getClient() 方法从 PortletRequest
抽取 Client
。能从 Client
获取以下信息:
Text/html | html |
Text/vnd.wap.wml | wml |
Text/html | chtml |
Capability
对象比标记类型包含更多的详细信息(有关客户机能支持什么),如 HTML、Javascript 或 WML 表的级别。PortletData
对象中为实例存储该首选项。PortletSettings
对象中为具体 portlet 存储该首选项。PortletResponse
响应对象封装从服务器返回到客户机的信息。PortletResponse
通过 beginPage()
、endPage()
和 service()
方法传递,portlet 可以使用它返回 portlet 输出(通过使用PrintWriter
)。响应还包含创建 PortletURI
对象的方法或使用 portlet 的名称空间限制 portlet 标记。
使用下列方法之一来创建 PortletURI:
PortletURI
对象PortletURI
对象portletURI
,指向 portlet 的呼叫器。例如,createReturnURI() 能用于在编辑方式中创建后退按钮。每个 portlet 在其本身的唯一名称空间中运行。portlet 使用 encodeNamespace() 方法把属性 带至 portlet 输出以避免名称与其它 portlet 冲突。属性能包含参数名称、全局变量或 JavaScript 函数名。
PortletURI
PortletURI
对象包含指向 portlet 实例的 URI,并能通过添加特定 portlet 的参数或通过附加操作进一步扩展。
操作是特定 portlet 的活动,但在调用 portlet service() 方法之前,它需要以入站请求的结果来执行。例如,当用户在 portlet 编辑方式中输入数据并单击保存 按钮时,在下一个标记生成前,portlet 需要处理已记入的数据。这能通过将保存操作添加到 URI(代表保存 按钮)来完成。
完整的 URI 可转换为可以嵌入标记的字符串。
PortletSession
PortletSession 保存 portlet 的具体 portlet 实例的特定用户数据,创建 portlet 用户实例。具体 portlet 实例之间的不同仅在于存储在它们的 PortletData
中的数据。Portlet 用户实例之间的不同仅在于存储在它们的 PortletSession
中的瞬时数据。任何持久数据必须使用 PortletData
存储。存储在 portlet 的实例变量中的信息通过读和写访问在所有具体 portlet 实例(甚至所有具体 portlet)之间共享。确保未对特定用户的数据使用实例属性。
另一方面,必须谨慎对待 portlet 把什么添加到会话,特别是如果 portlet 曾运行在群集环境中,该环境是共享数据库串行化会话的地方。任何存储在会话中的东西必须也能串行化。
与 HttpSession
相似,PortletSession
在匿名页面上不可用。登录期间,将会为页面上的每个 portlet 自动创建 PortletSession
。要获取 PortletSession
,必须使用 getSession() 方法(在 PortletRequest
可用的)。该方法返回当前会话,或者如果没有当前会话,且给定参数“creat”创建是 true
,它将创建一个并返回它。
侦听器
Portlet API 提供了侦听器,它可为 portlet 添加更多的功能。要启用侦听器的功能,portlet 必须实现以下接口之一。
- PortletSessionListener
- PortletPageListener
- PortletTitleListener
- PortletSettingsAttributesListener
- PortletApplicationSettingsAttributesListener
PortletSessionListener
除了存在于每个出现在页面上的 portlet 的具体 portlet 实例之外,portlet 可能还有更细小的颗粒度。PortletSessionListener
使 portlet 能识别用户 portlet 实例的生命周期:
-
login()
在用户登录到门户网站之后,每个 portlet 为用户创建了会话。具体 portlet 实例和用户会话的组合创建了用户 portlet 实例。用户实例的启动是由门户网站调用 portlet 上的 login() 方法来发信号的。此方法允许 portlet 初始化用户的 porlet 会话实例,例如,以便在会话中存储属性。
-
logout()
当用户结束与门户网站的会话时,Portal Server 调用 logout() 方法来通知 portlet 用户的会话实例正在终止。然后,portlet 将清除 portlet 用户实例的任何资源。
PortletPageListener
portlet 没有用于写入从页面上所有 portlet 的输出次序的控制或意识。PortletPageListener
允许 portlet 在页面的开始和结束插入标记。
-
beginPage()
在每个页面的开始和 调用页面上任何 portlet 的任何 service() 方法前,为驻留在页面的每个 portlet 调用 beginPage() 方法。和 service() 方法相似,不是按保证的次序为页面上的每个 portlet 调用 the beginPage() 方法,可能是按每个请求的不同次序调用。该方法允许 portlet 输出对所有 portlet 的 service() 方法可见的,或甚至可以设置 cookies 或头的 Javascript。
-
endPage()
在每个页面的结束和调用页面上所有 portlet 的 service() 方法后,为驻留在页面上的每个 portlet 调用 endPage() 方法。与 service() 方法相似,不是按保证的次序调用 endPage() 方法,可能是按每个请求的的不同次序调用。例如,portlet 可以把需要在页面所有其它元素写好之后发生的 Javascript 插入到页面的结束处。
侦听器生命周期
当实现 PortletSesssionListener 和 PortletPageListener 时,生命周期期间在 portlet 上调用下列方法。
-
init()
非具体 portlet 和
PortletConfig
一起初始化。 -
initConcrete()
具体 portlet 和
PortletSettings
一起初始化。 -
login()
用户 portlet 实例和
PortletSession
一起初始化。 - beginPage() portlet 可能在每个请求的每个页面开始处对输出进行输出。
- service() portlet 可能在每个请求的 portlet 窗口中对输出进行输出。
- endPage() portlet 可能在每个请求的每个页面结束处对输出进行输出。
- logout() 破坏用户 portlet 实例。
- destroyConcrete() 破坏具体 portlet。
- destroy() 破坏非具体 portlet。
PortletTitleListener
如标题栏中显示的,PortletTitleListener 接口用于允许基于条件(例如,用于访问门户网站的设备类型)或用户输入(例如,用户在编辑页面上进行设置的首选项)来更改 portlet 标题。如果没有实现侦听器,portlet 显示 portlet 部署描述符 的 <title> 元素(<language> 下) 上指定的标题。
PortletSettingsAttributesListener
该接口侦听 PortletSettings 属性的更改,与管理员配置具体 portlet 时相似。
PortletApplicationSettingsAttributesListener
该接口侦听 PortletApplicationSettings 属性的更改,与管理员配置具体 portlet 应用程序时相似。
配置对象
portlet 使用下列对象检索和存储数据,这取决于如何使用数据:
PortletConfig
PortletConfig
将其初始化配置给提供非具体 portlet。配置拥有 portlet 类的信息。该信息对于从 portlet 派生的每个具体 portlet 都生效。
portle 的配置首先从其 servlet 部署描述符读取。该信息由 portlet 开发者定义。配置是只读的,并且 portlet 无法对它更改。
在抽象 Portlet
的 init() 方法中把 PortletConfig
传递给 portlet,并使用 getInitParameters() 将其用于访问特定 portlet 配置参数。PortletConfig
参数是整个非具体 portlet 生命周期可用的名称/值对。非具体 portlet 的参数由 servlet 部署描述符中 <init-param> 标记定义。
PortletSettings
PortletSettings
对象将其动态配置提供给具体 portlet。配置拥有具体 portlet 的信息。该信息对于具体 portlet 的每个具体 portlet 的实例都有效。
具体 portlet 的配置首先从 portlet 部署描述符读取。该配置是只读的并且仅当 portlet 在配置方式 下可以由 portlet 来写。该信息通常由门户网站管理员来维护,并且当 Portal Server 运行时可能会被更改。一个请求期间,portlet 能获取、设置和除去属性。要提交更改,必须调用 store() 方法。
PortletSettings
对象可以被 PortletRequest
可用的 getPortletSettings() 方法访问。通常,它用于使用 getAttribute() 来访问特定 portlet 配置参数。属性是整个具体 portlet 生命周期可用的名称/值对。具体 portlet 属性由 portlet 部署描述符
中的 <config-param> 标记定义。
PortletApplicationSettings
PortletApplicationSettings
对象将其动态配置提供给具体 portlet 应用程序。配置拥有应用程序中包含的所有具体 portlet 共享的 portlet 应用程序的信息。
具体 portlet 应用程序的配置首先从 portlet 部署描述符读取。该配置是只读的并且仅当 portlet 在配置方式 下可以由 portlet 来写。该信息通常由门户网站管理员来维护,并且当 Portal Server 运行时可能会被更改。一个请求期间,应用程序中的 portlet 可以获取、设置和除去属性。要提交更改,必须调用 store() 方法。
PortletApplicationSettings
可以被 PortletSettings
对象可用的 getApplicationSettings() 方法访问。它用于使用 getAttribute() 来访问特定 portlet
配置参数。属性是整个具体 portlet 应用程序生命周期可用的名称/值对。具体 portlet 应用程序属性由 portlet
部署描述符中的 <context-param> 标记定义。
PortletData
PortletData
拥有具体 portlet 实例的数据。页面上每个发生具有一个具体 portlet 实例。PortletData
包含有关具体 portlet 实例的持久信息,而 PortletSession
仅包含用户 portlet 实例的瞬时数据。
页面上 portlet 的每个发生有一个具体 portlet 实例。页面可以由单个用户拥有(个人主页)或单个用户组拥有(组页面)。PortletData
在个人主页上包含特定用户数据,在组页面上包含特定组数据。
PortletData
对象将属性存储为名称/值对。一个请求期间,portlet 能获取、设置和除去属性。要提交更改,必须调用 store() 方法。数据是只读的并且仅当 portlet 在编辑方式
下可以由 portlet 来写。
杂项对象
下列对象由 portlet 使用:
PortletContext
PortletContext
接口定义每个 portlet 运行在其中的 portlet 容器的 portlet 视图。PortletContext
还允许 portlet 访问其可用的资源。例如,使用上下文,portlet 可以访问 portlet 日志,访问 portlet 对应用程序中所有 portlet 是公共的上下文参数,获取资源的 URL 引用或访问 portlet 服务
。
以下描述了有关 PortletContext
的非常重要的详细信息。
PortletContext
,portlet 才可以装入或包含位于 portlet 应用程序作用域中的资源。可用的方法有 include() 和 getResourceAsStream()。include() 方法通常用于为输出调用 JSP。PortletLog
对象提供 portlet 记录信息、警告或错误消息的能力。日志由 portlet 容器维护。启用或不启用记录日志是由 portlet 容器来判断的。要获取更多的信息,请参阅消息和跟踪记录日志
。
该对象还可以从 PortletAdapter 类的 getPortletLog() 得到。
PortletWindow
PortletWindow
对象代表封装 portlet 的窗口。例如,在一个 HTML 页面上,portlet 窗口通常可以作为表单元输出。portlet 窗口能在其各种窗口控件的操作上发送事件,如用户单击最小化或关闭时那样。portlet,能就其当前状态
依次询问窗口。例如,portlet 可能不同地输出其内容,这取决于它的窗口是否为最大化或否。使用 PortletRequest
对象的 getWindow() 方法,PortletWindow 可用。
User
User
接口包含访问诸如用户全名或用户名的用户属性的方法。
Portlet 事件
portlet 事件包含了关于 portlet 可能需要响应的事件的信息。例如,当用户单击链接或按钮时,将生成操作事件。要接收事件的通知,portlet 必须在 portlet 类中实现事件侦听器。
- 操作事件 :当 HTTP 请求通过与操作关联的 portlet 容器接收时生成(如在用户单击链接时)。
- 消息事件 :当 portlet 应用程序中的另一个 portlet 发送消息时生成。
- 窗口事件 :当用户更改 portlet 窗口的状态时生成。
在生成事件要求的新的内容之前(并且因此 portlet),portlet 容器将所有事件发送到各自的事件侦听器。侦听器在处理事件的时候应该发现需要生成另一个事件吗?那个事件将由 portlet 容器队列和并在时间点发送即在 portlet 容器的判断。仅保证将它发送并在内容产生阶段前发生。
一旦内容产生阶段开始,将不发送进一步的事件。例如,无法从 beginPage()、service() 和 endPage() 方法中发送消息。结果消息事件将不会被发送和实质上废弃。
直接在 portlet 类中实现事件侦听器。侦听器可以使用 PortletRequest
或 PortletSession
属性从事件和响应访问 PortletRequest
。
操作事件
当接收与 PortletAction
关联的 HTTP 请求时,发送 ActionEvent
到 portlet。要接收操作事件,portlet 类必须实现 ActionListener
接口和带有 PortletAction
类型的对象。PortletAction
链接到使用 PortletURI
类及其 addAction() 方法引用操作的 URI。ActionEvent
可以用于获取相关联的 PortletAction
和 PortletRequest
。
通常,PortletAction
与 HTTP 引用或 HTML 表单中的按钮链接。然后所点击的链接的 ActionEvent
把关联的 PortletAction
传送回 portlet,其能依次实现基于用户操作的不同的处理路径。portlet 操作能传送任何信息。然而,它不应该存储请求、响应或会话对象。该信息是操作事件的一部分,并将发送到注册了的侦听器。
以下显示 JSP 如何使用 URI,包括 PortletAction。当用户单击“添加”按钮,一个新的 HTTP 请求被发送到表单的操作 URL。
<FORM method='POST' action='<%=editBean.getAddURI()%>'> Name: <INPUT name='bookmark.name'><br> URL: <INPUT name='bookmark.url'><br> <INPUT type='submit' name='addButton' value='Add'><br> </FORM>
以下显示 ActionListener 如何区分操作。
public void actionPerformed(ActionEvent event) { PortletAction _action = event.getAction(); if (_action instanceof DefaultPortletAction) { ... DefaultPortletAction action = (DefaultPortletAction)_action; if (action.getName().equals("add")) { ...
请参阅使用持久性 获得代码示例,显示如何为 portlet 添加操作 并创建 ActionListener 。
DefaultPortletAction
Portlet API 提供给 DefaultPortletAction 类缺省参数,portlet 可以使用它实现 PortletAction
对象。可以基于 DefaultPortletAction 创建 PortletAction,或使用它来实现您自己的 PortletAction。以下显示如何创建 DefaultPortletAction:
DefaultPortletAction addAction = new DefaultPortletAction("add");
下列显示如何把 PortletAction 包含到 URI:
PortletURI addURI = response.createURI(); DefaultPortletAction addAction = new DefaultPortletAction("add"); addURI.addAction(addAction);
窗口事件
无论何时用户单击其中一个更改窗口状态的控制按钮,如最大化、最小化或恢复,WindowEvent
由 portlet 容器发送。例如,当用户最大化将以其正常状态显示的 portlet 时,可以使用 WindowEvent
显示更多信息。要接收窗口事件,必须在 portlet 类实现 WindowListener
接口。
Portlet API 提供 WindowAdapter
类,该类实现 WindowListener
的空的方法。通过扩展 WindowAdapter
,portlet 开发者仅需要实现那些 portlet 所需的回调方法。没有 WindowAdapter
,必须实现所有回调方法,即使方法为空也一样。请参阅刷新 portlet 高速缓存
以获取 WindowListener
的示例。
消息事件
如果收件人 portlet 是同一个 portlet 应用程序的成员并且作为正在发送的 portlet 放置在相同的页面上,则消息事件能从一个 portlet 发送到其它 portlet。此外,DefaultPortletMessage
可以跨越 portlet 应用程序边界并被发送到页面的所有 portlet。仅当 portlet 处于 portlet 容器的事件处理周期中时,MessageEvent
才能被活动地发送到其它 portlet,否则将抛弃异常。有两种不同类型的消息:
- 单地址信息:通过指定 send() 方法上的 portlet 名称,将消息发送到特定的 portlet。
- 广播消息:页面上发送到所有 portlet 的消息。
当一个 portlet 的更改反映到另一个 portlet 时,消息事件是有用的。必须实现带有 PortletMessage
类型的对象,该对象通过 MessageEvent
传递。portlet 接收消息必须实现 MessageListener
接口和带有 PortletMessage
类型的对象。<!-- has to be implemented which will be passed via the MessageEvent. -->
要获得 portlet 如何能在相互之间发送消息的示例,请参阅 portlet 消息传递 。
PortletService
要使 portlet 通过动态的发现能使用可插入的服务,Portlet API 提供 PortletService 接口。PortletService 从 PortletContext.getService() 方法访问,查找适当的工厂获得服务,创建服务并将它返回到 portlet。
通过不同供应商可以实现各种服务,例如,SearchService、LocationService、ContentAccessService 或 MailService。Portlet API 提供 ContentAccessService 。
创建您自己的 portlet 服务
编写 portlet 服务包含四个步骤:
如果要对照现有接口实现您的服务,步骤 1 不是必需的。如果要重用现有的服务工厂,此情况也适用于步骤 3。
定义接口
定义 portlet 服务接口需要与定义任何公用 API 接口相同的严密的注意事项。portlet 服务接口仅必须扩展定义在 org.apache.jetspeed.portlet.service
软件包中的 PortletService
接口,该接口作为标志进行服务,与 Java API 的 Serializable
接口相似。
下面是一个 HelloWorldService
示例接口。
package my.portlet.service; import org.apache.jetspeed.portlet.service.*; public interface HelloWorldService extends PortletService { // my service's method public String sayIt(); }
编写服务实现
服务实现必须实现 org.apache.jetspeed.portlet.service.spi
软件包的 PortletServiceProvider
接口,这样除了服务接口之外,还可以使用 portlet 服务生命周期方法。例如,init 方法的 PortletServiceConfig
参数允许您访问服务的配置。(请参阅注册服务
以获取更多的信息。
package my.portlet.service.impl; import org.apache.jetspeed.portlet.service.*; import org.apache.jetspeed.portlet.service.spi.*; public class HelloWorldServiceImpl implements HelloWorldService, PortletServiceProvider { private String it = null; public void destroy() { // do nothing - no resources in use } public void init(PortletServiceConfig config) { it = config.getInitParameter("MY_MESSAGE"); if (it == null) it = "Hello world!!!"; } public String sayIt() { return it; } }
编写服务的工厂
通常,不必编写您自己的工厂,因为在 org.apache.jetspeed.portletcontainer.service
软件包中有两个与 Portal Server 一起提供的类属工厂。PortletServiceDefaultFactory
总是返回给定的服务的新实例,PortletServiceCacheFactory
总是返回与给定的服务相同的实例。可以使用这些工厂中的一个而不是作为单个实现服务。工厂必须实现 org.apache.jetspeed.portlet.service.spi
软件包的 PortletServiceFactory
接口。
下面是 HelloWorldService 的工厂类:
package my.portlet.service.factory; import org.apache.jetspeed.portlet.service.*; import org.apache.jetspeed.portlet.service.spi.*; public class HelloWorldServiceFactory implements PortletServiceFactory { PortletServiceProvider psp = null; public PortletService createPortletService(Class service, Properties serviceProperties, ServletConfig servletConfig) throws PortletServiceUnavailableException { if (psp != null) { return psp; } else { psp = new HelloWorldServiceImpl(); psp.init(new PortletServiceConfigImpl( service, serviceProperties, servletConfig)); return psp; } } }
注册服务
要把服务插入 Portal Server,相应的类文件必须复制到 was_root /lib/app 。然后必须更改 wp_root /app/wps.ear/wps.war/WEB-INF/conf 目录中的 PortletServices.properties 文件:
- 把实现作为相应的服务类型注册
- 为实现注册工厂
- 为实现提供配置参数
# PortletServices.properties org.apache.jetspeed.portlet.service.default.factory = org.apache.jetspeed.portletcontainer.service.PortletServiceDefaultFactory ... my.portlet.service.HelloWorldService = my.portlet.service.impl.HelloWorldServiceImpl my.portlet.service.impl.HelloWorldServiceImpl.factory = my.portlet.service.factory.HelloWorldServiceFactory my.portlet.service.impl.HelloWorldServiceImpl.MY_MESSAGE = Hello World (properties)! ...
内容访问服务
能通过不同的供应商(例如,SearchService 或 MailService)实现各种服务。通常当必须使用代理时,Portlet API 提供从内部网外的源检索内容的 ContentAccessService
。该服务允许 portlet 从远程 web 站点或门户网站 Web 应用程序中的 JSP 和 servlet 访问内容。(相反,PortletContext.include 方法仅能包含 portlet 应用程序的本地 JSP。)
import org.apache.jetspeed.portlet.service.ContentAccessService; . . . ContentAccessService service = (ContentAccessService)portletContext.getService(ContentAccessService.class); //get a URL URL url = service.getURL("http://www.ibm.com", request, response); //include the content of a web site into the portlet service.include("http://www.ibm.com", request, response); //include a JSP or servlet belonging to the portal web application service.include("/templates/weather.jsp", request, response); . . .
提示: 直接访问因特网资源的缺点是,仅仅简单的将内容拿取并编写到 portlet 的输出。这意味着将断开所有与其它页面或图像相关的链接。通过分析内容或使用一些增强了的浏览器 portlet 能解决这些问题。
ContentAccessService
还可以打开与远程应用程序的 SSL 连接。除了在 URL 中为 include() 方法指定安全协议(HTTPS)之外,代码与非安全连接的代码相同(请参阅示例:ContentAccessService
)。然而,,请参阅 PortletServices.properties
,必须如门户网站配置
中所描述的来配置门户网站以支持 SSL。
源文件地址:http://ssconnect.sscoop.com/wps/doc/zh/InfoCenter/wps/wpspapi.html
发表评论
文章已被作者锁定,不允许评论。
-
o-o
2009-08-13 18:23 52好久没上网了,最近学到不少关于liferay的东西,算是没白忙 ... -
liferay 中文参数乱码问题
2009-06-28 14:30 1571昨天遇到页面中文传到action再取出来是乱码问题,直到现在才 ... -
liferay configuration.jsp 添加tabs
2009-05-21 17:56 1749configuration.jsp与普通的页面加tabs有区别 ... -
liferay upload(二)
2009-05-20 09:43 1266上一篇文章写了如果显示出upload组件,下面代码为点击sav ... -
Liferay upload(一)
2009-05-15 18:39 17871.jsp: <script type=&qu ... -
Liferay中使用fckeditor liferay-ui:input-editor
2009-05-15 11:02 2546做liferay-ui:input-editor标 ... -
liferay plugin下使用Language.properties
2009-05-09 13:38 1589一般用plugin开发portlet,使用资源文件的方法是: ... -
liferay Selenium Test
2009-04-28 11:27 11231.在liferay的源码中找到路径:portal-web\t ... -
Portlet API--WebSphere Portal (二)
2009-04-28 10:08 1161部署描述符 portlet 应用程序的 WAR 文件必 ... -
liferay sdk5.1.0 创建StrutsPortlet
2009-04-15 12:44 10181.在sdk5.1.0下的portlets下执行create ... -
liferay5.2.2 更改tomcat链接数据库
2009-04-10 13:10 1398今天第一次用liferay的5.2.2版本,并且也是第一次使用 ... -
liferay 环境搭建
2009-03-24 13:30 1036liferay环境搭建: 1.下载apache-ant-1. ... -
liferay 权限配置
2009-03-24 13:25 15991.ext环境下配置权限: 在src的portal- ... -
liferay Journal Preview
2009-03-24 13:14 11051.实现Journal的Preview功能 2. 重写J ...
相关推荐
portlet-api.jar portlet-api.jar portlet-api.jar
portlet-api-2.0.jar,javax.portlet.*
portlet-api-1.0.jar,portlet的API,portlet.jar文件
pluto-2.0.3部署到tomcat-7.0.52例子,同时提供开发使用的portlet-api-2.0.jar
portlet-api-3.0.0.jar,
比较-JSR-168-Java-Portlet-规范与-IBM-Portlet-API.docx
IBM WebSphere Portal API Portlet v6.0 help
spring-webmvc-portlet-3.2.7.RELEASE.jarspring-webmvc-portlet-3.2.7.RELEASE.jarspring-webmvc-portlet-3.2.7.RELEASE.jarspring-webmvc-portlet-3.2.7.RELEASE.jar
jar包,官方版本,自测可用
spring-webmvc-portlet-3.0.2.RELEASE
PHP Portlet是一个以Java 5 JSR168 Portlet规范为灵感PHP 5语言开发Portlet的API。
portlet 2.0 api,JSR286下的portlet 2.0 api java类接口,有兴趣的可以下。
开发Portlet的JSR-170标准手册跟帮助文档
开发Portlet的JSR-168标准手册跟帮助文档。
portlet-util-2.1.0.jar,portlet-util-2.1.0.jar,portlet-util-2.1.0.jar
用jdbc插件开发开发liferay-portal
IBM WebSphere Portal 由用于构建和管理安全的企业对企业(B2B)、企业对客户(B2C)和企业对雇员(B2E)门户网站的中间件、应用程序(称为 portlet)和开发工具组成。WebSphere Portal 的基本产品提供个性化、web ...
8、WEBSPHERE PORTAL调整PORTLET之间的间隙 102 9、PORTAL6.1.0.1配置扩展属性 105 10、内容链接(同服务器或同站区) 120 11、内容链接(不同服务器或不同站区) 120 12、草稿内容阶段的判断、操作和获取(API) 121 ...
Liferay 的 Control-Panel、Portlet DTD 5.2 和 MVC Portlet。
中文英文的liferay-portlet-development-guide;主要是里面有中文翻译好的,免去你翻译的烦恼。