第三节 Portal的对象
JSR168给Portal定义了几个特别的对象,用来操作Portal特有的信息。这些对象跟Servlet的对象有点类似,又有点不同。这些对象都封装在{PORTAL_HOME}/common/lib/ext/portlet.jar包中,具体支持实现要视Portal服务器而定。
3.3.1 Request对象
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
PortletRequest分为RenderRequest和ActionRequest两种,分别由renderURL和actionURL来触发。renderURL是actionURL的一种优化。Portlet的开发过程中尽量使用renderURL而避免actionURL。actionURL适用于有确实的Action(行为)的情况下。比如说,表单form提交后Persistent状态的改变、session的改变、perference的修改等等。renderURL通常用来处理Portlet的导航。举个例子:
使用actionURL:
<%
PortletURL pu = renderResponse.createActionURL();
pu.setParameter("ACTION","LOGIN");
%>
说明:表单提交最好使用Post方法而不是Get方法,因为某些Portal服务器可能会将内部状态编码到URL的Query字符串中。
使用renderURL:
<%
PortletURL pu=renderResponse.createRenderURL();
Pu.setParameter("PAGE",Number);
%>
下一页
②、renderURL和actionURL的处理方式
当客户端请求是由一个renderURL触发的时候,Portal服务器会调用该Portal页面所有Portlet的render方法。
而当客户端请求是由一个actionURL触发的时候,Portal服务器会先按用该页面所有Portlet的processAction方法再调用render方法。所以,要明确自己到底使用那种URL来出发客户端请求。
③、RenderRequest和ActionRequest的parameter参数作用范围
当客户端请求由一个actionRequest触发时,所有parameter参数的取得都必须在processAction方法中进行。比如:
public void processAction(ActionRequest req,ActionResponse res){
String str = req.getParameter("ACTION");
//response.setRenderParameter("ACTION",action);
}
public void doView(ActionRequest req,ActionResponse res){
String str = req.getParameter("ACTION");
}
如上processAction方法中,getParameter方法将能成功得到表单中的参数ACTION所对应的值,因为我们知道,当目标Portlet的processAction方法运行完后,Portlet Container将调用Portal页面中所有Portlet的render方法.但是实际上doView方法中使用getParameter不会得到任何值.但是如果把processAction方法中注释了的一行解除注释的话,你就可以在doView方法中的得到参数ACTION对应的值. 这说明action request的参数,render方法中不可以直接取到.必须使用了setRenderParameter方法,再次传递一次.
3.3.2 Response对象
与Request对象一样,Response对象也有两种:RenderResponse和ActionResponse,分别用来封装对应的RenderRequest和ActionRequest的返回信息,比如重定向、窗口状态、Portlet模式等。他们两者的父类PortletResponse拥有serPorperty和getPorperty两个方法,用来传递信息给Portal容器。
ActionResponse主要用来处理以下功能:
a、 重定向
b、 改变窗口状态、Portlet模式
c、 传递parameter参数到RenderRequest中去
RenderResponse主要用来提供以下功能:
a、 设置ContentType
b、 得到OutputStream和Writer对象,用来输出页面内容
c、 Buffering缓冲
d、 设定Portlet的标题,但是必须在Portlet输出前调用,否则将被忽略
3.3.3 P ortletConfig对象
和ServletConfig对象类似,PortletConfig对象提供对Portlet初始化信息以及PortletContext对象存取的方法。
和ServletConfig对象不同的是,PortletConfig对象提供对Portlet的标题等资源的I18N支持,可以通过设定不同的Resource Bundle文件以提供多种语言支持。
3.3.4 Session对象
由于容器不同,Portal的Session对象与Servlet的Session对象略有不同。
由于Portlet处于Portal服务器的缘故,Portlet的Session分为Application Scope和Portlet Scope。两者的区别在于:
①、Application Scope范围的Session中保存的对象,对于同一个Portlet应用范围内的所有Portlet都是可用的。
②、Portlet Scope范围的Session中保存的对象,只对本Portlet可用,其他Portlet即使在同一个应用中,也不可用。
但是对于Portlet应用来说,可以通过HttpSession来访问。毕竟Portlet应用也是Web应用。在使用Session对象的时候,最好能明确指出使用的是那个Scope范围的Session。比如:
NORMAL" PortletMode="view" var="pu1">
NORMAL" PortletMode="view" var="pu2">
这个JSP创建了两个ActionURL,分别产生了两种PortletSession对象。
PortletSession ps = req.getPortletSession();
if(ps.getAttribute("PortletSession.AS",PortletSession.APPLICATION_SCOPE)!=null){
app=ps.getAttribute("PortletSession.AS",PortletSession.APPLICATION_SCOPE).
toString();
}
if(ps.getAttribute("PortletSession.PS",PortletSession.PORTLET_SCOPE)!=null){
Portlet=ps.getAttribute("PortletSession.PS",PortletSession.PORTLET_SCOPE).
toString();
}
以上代码根据需要取得不同Scope范围的Session对象值。
同一个应用下,可以直接通过ServletSession取得PortletSession.APPLICATION_SCOPE范围下的Session对象值。
HttpSession se = request.getSession();
if(se.getAttribute("PortletSession.AS")!=null){
app=se.getAttribute("PortletSession.AS");
}
3.3.5 P reference对象
Preference对象被设计用来实现用户的个性化设置,可以帮助用户对Portlet进行符合用户需求的显示定制和行为定制,可以替代部分的数据库功能。需要指出的是,Preference对象只是用来存取简单的配置信息,并不能完全替代数据库应用。
Preference对象对于配置信息采用键-值的形式存取,用户可以将需要的信息暂时保存在Preference中。
PortletPreference p= req.getPortletPreferences();
p.setValue("educhina.username","educhina");
p.store();
Preference对象用来存取用户的个性化信息,所以不同用户的Preference对象不能共享,这点跟Session不同。
可以在Portlet.xml中配置Preference信息,如下:
educhina 。username
educhina
true
另外,还可以配套使用PreferencesValidator对象,对Portlet的Preference在存储之前进行验证,以确保Preference的正确性。
具体规范可以参照http://java.sun.com/xml/ns/Portlet/Portlet-app_1_0.xsd 的 部分。