2.
portlet
技术。
2. 1
什么是
portlal
。
Portal
是基于
WEB
的应用程序
,
一个信息平台
,
它将不同来源的各种资源进行整合并集中展现给客户
.
通常其有如下三个特点
:
a.P
ersonalization (
个性化
)
b.
Single sign on
(
单点登陆
)
c.
Content aggregation (
内容聚合
)
2. 2
什么是
portlet
。
Portlet
是一种基于
WEB
组件的
JAVA
技术
,
由
Portlet Container
进行管理
.
处理请求并动态返回页面
,
可以作为
Portal
的可
即插即用
的界面组件
.
2. 2
什么是
Portlet Container
。
Portlet Container
用来管理
Portlet
的生命周期并且提供其运行所需要的必要环境
.
并且给
Portlet Preferences
提供持久性
(
Persistent
)
存取服务
.
但是其不支持
Portlet
的
aggregation(
内容聚合
).
内容聚合
由
Portal
组件提供
.
这个概念需要弄清楚
.
2. 2
什么是
WSRP?
WSRP
是
OASIS Web Service for Remote Portlets
的缩写
. WSRP
是
Web service
的一种新的商业应用
,
一种新的标准
,
主要用来简化
Portal
对于各种资源或者程序整合的复杂性
,
可以避免编程带来的整合麻烦和问题
.
而且
Portal
的管理员可以从海量的
WSRP
服务中选择需要的功能用以整和到目前使用的
Portal
中
.
它有三种
Roles:
1) Producer ->
提供
Portlet
2) Consumer ->
使用
Portlet
3) End User ->
最终用户
它的特点在于
Producer
将
Consumer
所需要的信息通过
WSRP
返回给
Consumer,
这些信息是相对的标记
Fragment(
片段
),
例如
HTML,XHTML
等
,
直接可以镶入用户的
Page
中
,
而不用象
Web service
一样需要单独开发用户端接口
.
3.
开发环境部署
配置开发环境
Step1 :
解压
eclipse-SDK-3.2-win32.zip
Step2 :
解压
org.eclipsefan.pluto.ui_1.0.0.zip ,
并将其拷入
eclipse/plugins
目录
下
,
如下
: eclipse/plugins/org.eclipsefan.pluto.ui_1.0.0/
/Icon
/Lib
/Source
/Webapp
Step3
:
解压
tomat5.5
到一目录
.
并且配置好
Tomcat
服务器
.
配置完成
.
a.
使用
Portlet Wizard
来创建
Portal
1)
选择
File > New > Project… > Portal > Pluto Portal application,
单击
Next
,
如图
:
2)
指定
Project
名称
(
如图
1.3),
这里使用
pluto
,
然后单击
Next
3)
指定
Tomcat
路径
,
单击
Finish
.
之后
eclipse
会将
Pluto
安装到
tomcat
上
,
并且自动配置好环境
b
.
创建
Portlets Application
b.
最后生成的工程如图
并
通过
portlet.xml
生成
/
更新
web.xml
4
.
portlet
技术验证。
4. 1
doView
(
…
),
doEdit(
…)
,
doHelp(
…)
与
Servlet
非常类似
,
Portlet
扩展自
GenericPortlet .
import
javax.portlet.*;
public
class
Textportlet
extends GenericPortlet
其三个方法对应了
Portlet
标题栏中的三个链接
(View, Edit, Help)
所执行的功能
.
public
void doView(
…)
public
void doEdit(
…)
public
void doHelp(
…)
三个方法分别调用了三个
JSP
文件
,
用以生成
Portlet fragment
,
同样也可以调用
Servlet
产生
Portlet fragment
,
或者不调用
JSP
或者
Servlet,
直接在方法中得到
PrintWriter,
用最简单的
pw.println(…)
打印出内容
,
类似
Servlet,
如下
:
PrintWriter pw=renderResponse.getWriter();
pw.println(
"
Hello, Portlet!
"
);
与Servlet应用类似,也可以使用
getInitParameter(String s)方法,得到配置文件中Portlet的初始值. 只不过Servlet使用web.xml,而Portlet 使用portlet.xml文件.
4.2
Portal
的设定
Tomcat
中
Webapps
目录
:
其中
pluto
是
portal
所在目录
,
用以配置
Portal Page
的两个文件分别是
pageregistry.xml
和
portletentityregistry.xml
其中
pageregistry.xml
用来在
Portal
中配置
Portal Page,
而
portletentityregistry.xml
用来在
Page
中配置
Portlet.
4.2.1
配置同一行中的两个
Portlet
<?xml version="1.0"?>
<portal>
<fragment name="navigation" class="org.apache.pluto.portalImpl.aggregation.navigation.TabNavigation">
</fragment>
<fragment name="sample" type="page">
<navigation>
<title>Sample Portlet</title>
<description>Basic page to show the simple portlet</description>
</navigation>
<fragment name="row" type="row">
<fragment name="col1" type="column">
<fragment name="p1" type="portlet">
<property name="portlet" value="1.1"/>
</fragment>
<fragment name="p2" type="portlet">
<property name="portlet" value="1.1"/>
</fragment>
</fragment>
</fragment>
</fragment>
</portal>
4.2.2
配置同一列中的两个
Portlet
<?xml version="1.0"?>
<portal>
<fragment name="navigation" class="org.apache.pluto.portalImpl.aggregation.navigation.TabNavigation">
</fragment>
<fragment name="sample" type="page">
<navigation>
<title>Sample Portlet</title>
<description>Basic page to show the simple portlet</description>
</navigation>
<fragment name="row1" type="row">
<fragment name="col1" type="column">
<fragment name="p1" type="portlet">
<property name="portlet" value="1.1"/>
</fragment>
</fragment>
</fragment>
<fragment name="row2" type="row">
<fragment name="col1" type="column">
<fragment name="p1" type="portlet">
<property name="portlet" value="1.1"/>
</fragment>
</fragment>
</fragment>
</fragment>
</portal>
4.3 Portlet Modes
和
Portlet window state
s
·
Portlet
模式
(Portlet Mode)
是
Portlet
提供的用以区分
Portlet
所执行功能的一个概念
.
通常情况下其拥有以下几种模式
:
1. VIEW
2. EDIT
3. HELP
以上各模式分别对应
GenericPortlet
中的
doView(…) , doEdit(…) , doHelp(…)
方法
,
分别调用以上方法来产生各个模式中的
Fragment
内容
.
非常类似
Servlet
中的
doGet(…) , doPost(…)
方法
,
都是
Helper
方法
,
但是概念不同
.
Portlet
状态
(Portlet window states)
提供了对于
Portlet
窗口的控制功能
,
其中有如下三种最基本的状态
:
1.
Normal
2.
Maximized
3.
Minimized
Portlet
开发人员可以在处理
ActionRequest
(
以后的章节将讲述其概念
)
时使用代码实现
Portlet
模式
,
及其
Portlet
状态的转变
.
注
:
只能在处理
ActionRequest
时改变
Portlet Modes
和
Portlet Window state
以上
Portlet Modes
和
Portlet window states
都可以配置成
custom Portlet mode
和
custom portlet window state.
不同的地方在于对于
Mode
来说
,
定制化的
Mode
需要对
GenericPortlet
的
doDispatch
方法进行重写
(Overriding),
因为
GenericPortlet
类通过
render
方法按照不同的
Portlet Mode
将
request
分别分发给
doView,doEdit,doHelp
等辅助方法
.
如果需要定制的
Mode ,
必须重写
doDispatch
方法
.
同时如果使用
Portal
提供商的
Portlet Modes
或者
Portlet window States,
都必须在部署描述中添加相关的设定
4.4
PortletConfig
对象
·
PortletConfig
对象
和
ServletConfig
对象类似
, PortletConfig
对象提供
Portlet
初始的所需的参数及其对
PortletContext
对象存取提供相关方法
.
和
ServletConfig
不同处在于
, PortletConfig
对象提供对
Portlet Title Bar
资源的
I18N
支持
,
我们可以设定不同的
Resource Bundle
文件用以提供多语言的支持
,
如下
portlet.xml
文件
:
… …
<portlet-info>
<title>PortletConfig Example</title>
<short-title>PortletConfig</short-title>
<keywords>PortletConfig</keywords>
</portlet-info>
… …
以上
Portlet
描述文件中的设置用于显示
Portlet
的
Title Bar
文字
,
同样也可以使用
Resource Bundle
用以显示
Title Bar
文字
,
如下
:
… …
<resource-bundle>
portlets.portletconfig.portletconfigexample
</resource-bundle>
… …
4.5 Portlet
的
Request
和
Response
对象
Portlet的Request 对象
Portlet
中的
Request
与
Servlet
的
Request
一样接受
Client
端发送的
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
有什么不同呢?
对于
Portlet
来说
PortletRequest
分为
ActionRequest
和
RenderRequest
两种
,
分别是由
renderURL
和
actionURL
来触发的
.
可以这样理解
, renderURL
是
actionURL
的一种优化形式
.Portlet
开发过程中尽可能使用
renderURL
而避免使用
actionURL. actionURL
适用于有确实的
Action(
行为
)
的情况下
.
比如说
, form
表单的递交
. Persistent
状态的改变,
session
的操作,
preference
的修改
,
这种情况下使用
actionURL,
而不使用
renderURL, renderURL
通常用来操作
portlet
内容的导航.
a.
使用
actionURL:
<%
PortletURL pu=renderResponse.createActionURL();
pu.setParameter("ACTION","LOGIN");
…
%>
<form name="usrfrm" method="post" action="<%=pu.toString()%>">
注
: form
表单递交时,使用
HTTP post
方法,而不用
get
方法.因为某些
Portal/Portlet Container
的实现将内部状态编码到
URL
的
Query
字符串中.
使用
renderURL:
<%
PortletURL pu=renderResponse.createRenderURL();
pu.setParameter("PAGE",Number);
…
%>
<a href=”<%=pu%>”>
下一页
</a>
b.
renderURL
和
actionURL
的处理方式有什么不同?
当客户端
request
是由
一个
renderURL
触发
时,
Portlet/Portlet Container
会调用
Portal
页面中所有
Portlet
的
render
方法.
如下
:
renderURL
/ | /
renderrenderrender
而
当客户端
request
一个
actionURL
触发时
, Portlet/Portlet Container
会先调用目标
Portlet
的
processAction()
方法,
当
processAction
方法处理完毕后
,
再分别调用
Portal
页面中所有
Portlet
的
render
方法.如下
:
actionURL
|
processAction
/ | /
render render render
由于以上原因,所以使用
renderURL
要比使用
actionURL
的
performance
来的好
c. RenderRequest和ActionRequest的parameter参数作用范围有什么不同?
当客户端request一个actionURL触发时,比如一个form表单的提交,所有的Parameter的get操作必须在processAction方法中进行. 例如:
JSP
的
form
表单页面
:
<%
PortletURL pu=renderResponse.createActionURL();
pu.setParameter("ACTION","LOGIN");
…
%>
<form name="usrfrm" method="post" action="<%=pu.toString()%>">
…
Portlet
的处理:
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
方法中,
getParamter
方法将能成功得到表单中的参数
ACTION
所对应的值
,
因为我们知道,当目标
portlet
的
processAction
方法运行完后,
Portlet Container
将调用
Portal
页面中所有
Portlet
的
render
方法.但是实际上
doView
方法中使用
getParameter
不会得到任何值.但是如果把
processAction
方法中注释了的一行
uncomment
的话,你就可以在
doView
方法中的得到参数
ACTION
对应的值.
这说明
action request
的参数,
render
方法中不可以直接取到.必须使用了
setRenderParameter
方法,再次传递一次.
l
A case study
在这部分中
,
我们来做一个简单的
Portlet,
实现一个简单的
Form submit
功能
.
以下是代码片段
JSP(
view_portletrequest.jsp.jsp
):
… …
<!-- Use PortletURL Object//-->
<%
PortletURL pu1=renderResponse.createActionURL();
pu1.setParameter(
"ACTION"
,
"Use PortletURL Object"
);
pu1.setPortletMode(PortletMode.VIEW);
%>
<
table
width=100% border=0>
<
TR
><
TD
>1.
Use PortletURL object to get an ActionURL and set current portlet mode to view</TD></TR>
<
tr
><
td
>
<
form
name="usrfrm" method="post" action="
<%=
pu1.toString()
%>
">
<input type=submit name=bt1 value="GetActionByJava">
</
form
>
<
tr
><
td
>
</
table
>
… …
注
:
处理完
form
后将会将
PortletMode
设定为
VIEW
.
以上代码使用了
actionURL
因为是
form
表单的递交
.
详细请参考
Portlet
的
Request
对象
部分
.
或者也可以使用
Tag.
它同样也可以生成一个
Portlet
的
URL,
如下
:
… …
<!-- Use Portlet Tag //-->
<portlet:actionURL
windowState="maximized" portletMode="edit" var="pu2">
<portlet:
param
name="ACTION" value="Use Portlet Tag"/>
</portlet:actionURL>
<
BR
>
<
table
width=100% border=0>
<
TR
><
TD
>2.
Use Portlet Tag to get a ActionURL and and set current portlet mode to edit</TD></TR>
<
tr
><
td
>
<
form
name="usrfrm" method="post" action="
<%=
pu2
%>
">
<input type=submit name=bt2 value="GetActionByTag">
</
form
>
<
tr
><
td
>
</
table
>
… …
注
:
它在处理完
form
后将会将
PortletMode
设定为
EDIT
,
并且
Window state
会为最大化
.
Portlet(
PortletRequestExample
.java):
… …
public
void processAction(ActionRequest request, ActionResponse response)
throws PortletException, IOException
{
String action=request.getParameter("ACTION");
System.out.println("ACTION" + action);
if(action==null){
action="";
}
response.setRenderParameter("ACTION",action);
}
… …
JSP(
view_portletrequest.jsp)
… …
<%
String getaction=
""
;
if
(
request
.getParameter(
"ACTION"
)!=
null
){
getaction=
request
.getParameter(
"ACTION"
);
}
%>
<
B
>
ACTION
:
<%=
getaction
%>
</
B
>
… …
JSP(
edit_portletrequest.jsp.jsp)
… …
<%
String getaction=
""
;
if
(
request
.getParameter(
"ACTION"
)!=
null
){
getaction=
request
.getParameter(
"ACTION"
);
}
%>
<
B
>
ACTION
:
<%=
getaction
%>
</
B
>
… …
将以上源代码编译后
,
再通过
Eclipse
生成
/
更新
Portlet
的
web.xml
后
,
将所有配置及相关文件部署后
,
启动
Tomcat
单击
PortletRequest Example Page
后可以看到如下
Portlet
页面
单击
GetActionByJava
后
单击
GetActionByTag
后
,
将跳转到
edit modes
4.5.1
Portlet
的
Response
对象
.
与
Request
对象类似,
Response
对象也有两种:分别是
ActionResponse
和
RenderResponse,
分别封装了对应
ActionRequest
和
RenderRequest
对象返回的所有信息。例如,重定向,
windows state,portlet mode
等的信息。其中他们的父类,
PortletResponse
拥有
setProperty
和
addProperty
方法,用以传递提供商指定的信息给
portal/portlet container
1
。
ActionResponse
和
RenderResponse
有什么不同?
ActionResonse
可以用来处理以下相关功能:
1)
重定向
sendRedirect
方法用来进行帮助
portal/portlet-container
进行头信息,及其内容的设定
,
并且将
URL
重定向到用户指定的页面。
2)
改变
windows state, portlet mode
,我们在以前章节中介绍了
window state
和
portlet mode
概念
.
3)
传递
Parameter
参数到
RenderRequest
中去,如上面
request
部分中用到的例子。
RenderResponse
用来提供如下功能
(
和
Servlet
中的
Response
更相似
)
:
1)
设置
ContentType
2)
得到
Output Stream and Writer
对象,用来产生页面内容
3) Buffering
4)
设定
Portlet
的
Title ,
但必须先于
portlet
的输出递交前来调用,否则将会被忽略。
5.
资源
"Portlet
规范介绍
" By Stefan Hepper
和
Stephan Hesmer