Lifray Portlet
Portlet 的生命周期
一个Portlet有着良好的生命周期管理,定义了怎样装载,实例化和初始化,怎样响应来自客户端的请求及怎样送出服务。这个Portlet生命周期由Portlet接口的init,processAction,render和destroy方法来表达。
载入和实例化:Portlet 容器负责载入和实例化Portlet。当Portlet 容器运行Portlet 应用或者延迟到Portlet 需要服务使用者的请求时,Portlet 就会被载入并实例化。载入Portlet 类后,Portlet 类随即被实例化。
初始化:Portlet 类实例化后,Portlet 容器还需要初始化Portlet。以调用Portlet 去响应客户端的请求。Portlet 容器呼叫Portlet 接口中的init 方法初始化Portlet。扩展自PortletConfig的类可以取出定义在部署描述文件中的初始化参数,以及Resource Bundle。
初始化异常:在 Portlet 初始化期间,Portlet 可能会丟出 UnavailableException 或PortletException 异常。此时,Portlet 容器不能把 Portlet 置入已启动的服务,并且 Portlet容器必需释放这个 Portlet。 destory 方法不能被呼叫,因为初始化被认为执行失败。发生 失败后,Portlet 容器会尝试着重新实例化及初始化 Portlet。这个异常处理的规则是:由一个UnavailableException 指定一个不能执行的最小时间,当此异常发生时,Portlet 容器必需等到指定时间过去后才产生并且初始化一个新的 Portlet。在初始化过程中所丟出的 Runtime Exception 异常,被当作 PortletException 来处理。
Portlet标签
跟Servlet 一样,Portlet 也自定义了很多灵活的标签。通过这些标签,可以调用Portlet内部的参数比如renderResponse、renderRequest、PortletConfig 等,在JSP 中跟Portlet 通信。当然,在使用之前,除了要在web.xml 中声明标签库外,还要在JSP 的头部声明标签库调用:
defineObjects 标签
在使用Portlet 典型标签之前,要见声明<portlet:defineObjects/>,这样才可以使用其他的标签。defineObjects 中间不允许定义任何属性和包含任何内容。
renderURL 标签
属性 |
值类型 |
对应值 |
windowState |
String |
minimized normal maximized |
portletMode |
String |
view edit help |
var |
String |
|
secure |
String |
true false |
actionURL 标签
属性 |
值类型 |
对应值 |
windowState |
String |
minimized normal maximized |
portletMode |
String |
view edit help |
var |
String |
|
secure |
String |
true false |
param 标签
属性 |
值类型 |
name |
String |
用在renderURL 和actionURL 标签内部,用来在生成的URL 中增加参数和值。param标签不运行body 内容存在。
namespace标签
为目前的Portlet 产生一个唯一的Value,防止与其他Portlet 或者Portal 上面的Value 冲突。上述标签的具体属性及其约束, 请参阅${CATALINA_HOME}/liferay/WEB-INF/tld/liferay-portlet.tld
Portal 的对象
Portlet 中的Request 与Servlet 的Request 一样接受客户端发送的请求,但是与Servlet不同,Portlet 的Request 分为Action Request 及Render Request 两种类型,因此Portlet 接口中定义了两种方法用来处理不同的Request。分别是processAction(ActionRequest request,ActionResponse response) 和render(RenderRequest request,RenderResponse response),分别用以处理Action Request 和Render Request。某种意义上来讲,render 方法类似Servlet 中的service 方法,doView,doEdit,doHelp 方法又类似doGet,doPost 方法。
RenderRequest 和ActionRequest
如上processAction 方法中,getParameter 方法将能成功得到表单中的参数ACTION 所对应的值,因为我们知道,当目标Portlet 的processAction 方法运行完后,Portlet Container 将调用Portal 页面中所有Portlet 的render方法.但是实际上doView 方法中使用getParameter不会得到任何值.但是如果把processAction 方法中注释了的一行解除注释的话,你就可以在doView 方法中的得到参数ACTION 对应的值. 这说明action request 的参数,render方法中不可以直接取到.必须使用了setRenderParameter 方法,再次传递一次.
Response 对象
与Request 对象一样,Response 对象也有两种:RenderResponse 和ActionResponse,分别用来封装对应的RenderRequest 和ActionRequest 的返回信息,比如重定向、窗口状态、Portlet 模式等。他们两者的父类PortletResponse 拥有serPorperty 和getPorperty 两个方法,用来递信息给Portal 容器。
ActionResponse 主要用来处理以下功能:
a) 重定向
b) 改变窗口状态、Portlet 模式
c) 传递parameter 参数到RenderRequest 中去RenderResponse 主要用来提供以下功能:
d) 设置ContentType
e) 得到OutputStream 和Writer 对象,用来输出页面内容
f) Buffering 缓冲
g) 设定Portlet 的标题,但是必须在Portlet 输出前调用,否则将被忽略
PortletConfig 对象
和ServletConfig 对象类似, PortletConfig 对象提供对Portlet 初始化信息以及PortletContext 对象存取的方法。
和ServletConfig 对象不同的是,PortletConfig 对象提供对Portlet 的标题等资源的I18N支持,可以通过设定不同的Resource Bundle 文件以提供多种语言支持。
Session 对象
由于容器不同,Portal 的Session 对象与Servlet 的Session 对象略有不同。由于Portlet 处于Portal 服务器的缘故,Portlet 的Session 分为Application Scope 和PortletScope。
两者的区别在于:
①、 Application Scope 范围的Session 中保存的对象,对于同一个Portlet 应用范围内的所有Portlet 都是可用的。
②、 Portlet Scope 范围的Session 中保存的对象,只对本Portlet 可用,其他Portlet 即使在同一个应用中,也不可用。
Preference 对象
Preference 对象被设计用来实现用户的个性化设置,可以帮助用户对Portlet 进行符合用户需求的显示定制和行为定制,可以替代部分的数据库功能。需要指出的是,Preference 对象只是用来存取简单的配置信息,并不能完全替代数据库应用。
Preference 对象对于配置信息采用键-值的形式存取,用户可以将需要的信息暂时保存在Preference 中。Preference 对象用来存取用户的个性化信息,所以不同用户的Preference
对象不能共享,这点跟Session 不同。可以在Portlet.xml 中配置Preference 信息,如下:
<portlet-preferences>
<preference>
<name>educhina.username</name>
<value>educhina</value>
<read-only>true</read-only>
</preference>
</portlet-preferences>
<portlet-preferences>
<preference>
<name>educhina.username</name>
<value>educhina</value>
<read-only>true</read-only>
</preference>
</portlet-preferences>
另外,还可以配套使用PreferencesValidator 对象,对Portlet 的Preference 在存储之前进行验证,以确保Preference 的正确性。具体规范可以参照http://java.sun.com/xml/ns/Portlet/Portlet-app_1_0.xsd 的<complexTypename="preferenceType">部分。