使用Eclipse plus Pluto开发你的第一个与JSR168兼容的Portlet(四)
来源:互联网 发布:linux启动电池 编辑:程序博客网 时间:2024/05/10 01:19
By Terry.li
SpiritSeekerS@sqatester.com
本文使用本系列中Part1搭建的开发环境,如果没有搭建好开发环境,请参考Portlet应用开发Part1进行开发环境的搭建.在Part1中我们已经介绍了Portlet的GenericPortlet类. 从形式上来看, Portlet与Servlet非常相似, 但是从request和response对象的具体特点及功能来说, 又有所不同. 本部分主要描述了Portlet的Request和Response对象的特点及其与Servlet的Request和Response对象的不同点.
l 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方法,如下图:
1. RenderRequest和ActionRequest有什么不同呢?
对于Portlet来说PortletRequest分为ActionRequest和RenderRequest两种,分别是由renderURL和actionURL来触发的.可以这样理解, renderURL是actionURL的一种优化形式.Portlet开发过程中尽可能使用renderURL而避免使用actionURL. actionURL适用于有确实的Action(行为)的情况下. 比如说, form表单的递交. Persistent状态的改变,session的操作,preference的修改,这种情况下使用actionURL,而不使用renderURL, renderURL通常用来操作portlet内容的导航.
以下是两个例子:
使用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>
2. renderURL和actionURL的处理方式有什么不同?
当客户端request是由一个renderURL触发时,Portlet/Portlet Container会调用Portal页面中所有Portlet的render方法. 如下:
renderURL
/ | /
render render render
而当客户端request一个actionURL触发时, Portlet/Portlet Container会先调用目标Portlet的processAction()方法, 当processAction方法处理完毕后,再分别调用Portal页面中所有Portlet的render方法.如下:
actionURL
|
processAction
/ | /
render render render
由于以上原因,所以使用renderURL要比使用actionURL的performance来的好.
3. 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.
在Browser中加载如下页面: Http://localhost:8080/pluto/portal , 可以看到如下的页面(图:4-1)
图:4-1
单击PortletRequest Example Page后可以看到如下Portlet 页面(图4-2)
图:4-2
单击 GetActionByJava 后, 得到如下(图:4-3):
单击 GetActionByTag 后, 将跳转到edit mode, 如下(图:4-4):
图:4-4
l 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的输出递交前来调用,否则将会被忽略。(注:目前的pluto没有实现,如果调用不会修改title)
l A example
… …
public void doView(RenderRequest request, RenderResponse response)
throws PortletException, IOException
{
response.setContentType("text/html");
PrintWriter pw=response.getWriter();
pw.print(“Hello, Portlet”);
… …
· 源代码及Portlet相关配置文件
A. Portlet (PortletRequestExample.java)
package portlets.portletrequest;
/**
* @author terry
*
* To change the template for this generated type comment go to
* Window>Preferences>Java>Code Generation>Code and Comments
*/
import javax.portlet.*;
import java.io.IOException;
public class PortletRequestExample extends GenericPortlet{
public void doView(RenderRequest request, RenderResponse response)
throws PortletException, IOException
{
response.setContentType("text/html");
String jspName = getPortletConfig().getInitParameter("view");
PortletRequestDispatcher rd =
getPortletContext().getRequestDispatcher(jspName);
rd.include(request, response);
}
public void doEdit(RenderRequest request, RenderResponse response)
throws PortletException, IOException
{
response.setContentType("text/html");
String jspName = getPortletConfig().getInitParameter("edit");
PortletRequestDispatcher rd =
getPortletContext().getRequestDispatcher(jspName);
rd.include(request, response);
}
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);
}
}
B. JSP (view_portletrequest.jsp)
<%@ page session="false" %>
<%@ page import="javax.portlet.*"%>
<%@ page import="java.util.*"%>
<%@ taglib uri='/WEB-INF/tld/portlet.tld' prefix='portlet'%>
<portlet:defineObjects/>
<BR>
<h3>Request Example</h3>
<!-- 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>
<!-- 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>
<%
String getaction="";
if(request.getParameter("ACTION")!=null){
getaction=request.getParameter("ACTION");
}
%>
ACTION: <B><%=getaction%></B>
<BR><BR>
Current Portlet Mode: <B><big><%=renderRequest.getPortletMode()%></big></font></B><br>
C. JSP (edit_portletrequest.jsp)
<%@ page session="false" %>
<%@ page import="javax.portlet.*"%>
<%@ page import="java.util.*"%>
<%@ taglib uri='/WEB-INF/tld/portlet.tld' prefix='portlet'%>
<portlet:defineObjects/>
<BR>
<h3>Request Example</h3>
<%
String getaction="";
if(request.getParameter("ACTION")!=null){
getaction=request.getParameter("ACTION");
}
%>
ACTION: <B><%=getaction%></B>
<BR><BR>
Current Portlet Mode: <big><B><%=renderRequest.getPortletMode()%></font></big></B><br>
D. Portlet.xml
… …
<!-- PortletRequest Example -->
<portlet>
<description>PortletRequest Example</description>
<portlet-name>PortletRequestExample</portlet-name>
<display-name>PortletRequest Example</display-name>
<portlet-class>portlets.portletrequest.PortletRequestExample</portlet-class>
<init-param>
<name>view</name>
<value>/fragments/portletrequest/view_portletrequest.jsp</value>
</init-param>
<init-param>
<name>edit</name>
<value>/fragments/portletrequest/edit_portletrequest.jsp</value>
</init-param>
<expiration-cache>-1</expiration-cache>
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>VIEW</portlet-mode>
<portlet-mode>EDIT</portlet-mode>
</supports>
<supported-locale>en</supported-locale>
<portlet-info>
<title>PortletRequest Example</title>
<short-title>PortletRequest</short-title>
<keywords>PortletRequest</keywords>
</portlet-info>
</portlet>
… …
E. portletentityregistry.xml
<?xml version="1.0" encoding="UTF-8"?>
<portlet-entity-registry>
<application id="10">
<definition-id>portlets</definition-id>
… …
<portlet id="30">
<definition-id>portlets.PortletRequestExample</definition-id>
</portlet>
… …
</application>
</portlet-entity-registry>
F. pageregistry.xml
<?xml version="1.0"?>
<portal>
<fragment name="navigation" class="org.apache.pluto.portalImpl.aggregation.navigation.TabNavigation">
</fragment>
… …
<!-- PortletRequest Example Page -->
<fragment name="portletrequestpage" type="page">
<navigation>
<title>PortletRequest Example Page</title>
<description>PortletConfig Example Page</description>
</navigation>
<fragment name="row1" type="row">
<fragment name="col1" type="column">
<fragment name="p1" type="portlet">
<property name="portlet" value="10.30"/>
</fragment>
</fragment>
</fragment>
</fragment>
… …
</portal>
注: web.xml文件可以从portlet.xml通过Eclipse的Plugin直接生成,所以没有列出配置文件, 请参考本系列中的Part1.
资源:
· Pluto
http://jakarta.apache.org/pluto
· Pluto Mail List
http://news.gmane.org/gmane.comp.jakarta.pluto.user
· WSRP Spec1.0
http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=wsrp
· Apache的WSRP实现
http://ws.apache.org/wsrp4j/
· Apache’s Portal, JetSpeed:
http://jakarta.apache.org/jetspeed/site/index.html
· JSR 168:
http://www.jcp.org/en/jsr/detail?id=168
· "Portlet 规范介绍" By Stefan Hepper 和 Stephan Hesmer
- Part 1: Get your feet wet with the specification's underlying terms and concepts (August 2003)
- Part 2: The Portlet API's reference implementation reveals its secrets (September 2003)
- 使用Eclipse plus Pluto开发你的第一个与JSR168兼容的Portlet(四)
- 使用Eclipse plus Pluto开发你的第一个与JSR168兼容的Portlet(一)
- 使用Eclipse plus Pluto开发你的第一个与JSR168兼容的Portlet(二)
- 使用Eclipse plus Pluto开发你的第一个与JSR168兼容的Portlet(三)
- Struts2 JSR168 Portlet的开发
- Eclipse 中使用Pluto开发portlet
- 在RAD7中开发JSR168 Portlet (四)
- 使用Eclipse开发的第一个应用程序
- SharePoint使用BCS开发你第一个应用程序(四)
- 在RAD7中开发JSR168 Portlet (一)
- 在RAD7中开发JSR168 Portlet (二)
- 在RAD7中开发JSR168 Portlet (三)
- Java Portlet规范的参考实现-Pluto项目介绍(1)
- 在RAD7中开发JSR168 Portlet
- LifeRay的portlet开发(使用Netbeans)
- 使用Pluto+Tomcat 开发遇到的问题和总结 (1)
- 使用Pluto+Tomcat 开发遇到的问题和总结 (2)
- 使用COCOS2D-JS开发你的第一个游戏
- 为MySQL数据库添加新用户
- 使用Eclipse plus Pluto开发你的第一个与JSR168兼容的Portlet(三)
- 我读《代码大全》
- 如何干净地清除电脑中的木马病毒
- 专家教你避免办公电脑综合症
- 使用Eclipse plus Pluto开发你的第一个与JSR168兼容的Portlet(四)
- 自动记录上次登陆成功的用户信息
- 群雄逐鹿-纷乱的PC平台之争(2)
- 群雄逐鹿-纷乱的PC平台之争(3)
- 导师送给我的15条人生建议
- 彻底解决Java中中文拼音的排序问题
- Linux内核编程
- GB2312, GBK, UCS2, UTF-8
- oracle应用程序实现打包