使用Eclipse plus Pluto开发你的第一个与JSR168兼容的Portlet(四)

来源:互联网 发布:linux启动电池 编辑:程序博客网 时间:2024/05/10 01:19

By Terry.li

SpiritSeekerS@sqatester.com

 

 

本文使用本系列中Part1搭建的开发环境,如果没有搭建好开发环境,请参考Portlet应用开发Part1进行开发环境的搭建.Part1中我们已经介绍了PortletGenericPortlet. 从形式上来看, PortletServlet非常相似, 但是从requestresponse对象的具体特点及功能来说, 又有所不同. 本部分主要描述了PortletRequestResponse对象的特点及其与ServletRequestResponse对象的不同点.

 

l         PortletRequest 对象

Portlet中的RequestServletRequest一样接受Client端发送的Request, 但是与Servlet不同, PortletRequest分为Action RequestRender Request两种类型,因此Portlet接口中定义了两种方法用来处理不同的Request. 分别是processAction(ActionRequest request,ActionResponse response) render(RenderRequest request,RenderResponse response),分别用以处理Action RequestRender Request. 某种意义上来讲,render方法类似Servlet中的service方法,doView,doEdit,doHelp方法又类似doGet,doPost方法,如下图:

 

 

1.            RenderRequestActionRequest有什么不同呢?
对于Portlet来说PortletRequest分为ActionRequestRenderRequest两种,分别是由renderURLactionURL来触发的.可以这样理解, renderURLactionURL的一种优化形式.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的实现将内部状态编码到URLQuery字符串中.

 

 

使用renderURL:

<%

PortletURL pu=renderResponse.createRenderURL();

pu.setParameter("PAGE",Number);

%>

<a href=”<%=pu%>”>下一页</a>

 

2.     renderURLactionURL的处理方式有什么不同?

当客户端request是由一个renderURL触发时,Portlet/Portlet Container会调用Portal页面中所有Portletrender方法. 如下:

 

renderURL

/       |           /

                                                              render      render  render  

 

 

当客户端request一个actionURL触发时, Portlet/Portlet Container会先调用目标PortletprocessAction()方法, processAction方法处理完毕后,再分别调用Portal页面中所有Portletrender方法.如下:

                          actionURL

                                 | 

                                processAction

                                /        |         /

                        render     render     render

 

由于以上原因,所以使用renderURL要比使用actionURLperformance来的好.

 

3.     RenderRequestActionRequestparameter参数作用范围有什么不同?

当客户端request一个actionURL触发时,比如一个form表单的提交,所有的Parameterget操作必须在processAction方法中进行. 例如:

 

JSPform表单页面:

<%

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所对应的值,因为我们知道,当目标portletprocessAction方法运行完后,Portlet Container将调用Portal页面中所有Portletrender方法.但是实际上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表单的递交. 详细请参考PortletRequest 对象部分. 或者也可以使用Tag. 它同样也可以生成一个PortletURL, 如下:

 

… …

<!-- 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生成/更新Portletweb.xml,  将所有配置及相关文件部署后, 启动Tomcat.

 

 

 

Browser中加载如下页面: Http://localhost:8080/pluto/portal , 可以看到如下的页面(:4-1)

 

:4-1

 

 

单击PortletRequest Example Page后可以看到如下Portlet 页面(4-2)

 

:4-2

 

 

 

单击 GetActionByJava , 得到如下(:4-3):

 

    :4-3

 

单击 GetActionByTag , 将跳转到edit mode, 如下(:4-4):

 

         :4-4

 

l          PortletResponse 对象
Request对象类似,Response对象也有两种:分别是ActionResponseRenderResponse, 分别封装了对应ActionRequestRenderRequest对象返回的所有信息。例如,重定向,windows state,portlet mode等的信息。其中他们的父类,PortletResponse拥有setPropertyaddProperty方法,用以传递提供商指定的信息给portal/portlet container

1
ActionResponseRenderResponse有什么不同?

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)
设定PortletTitle , 但必须先于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&gt;Preferences&gt;Java&gt;Code Generation&gt;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通过EclipsePlugin直接生成,所以没有列出配置文件, 请参考本系列中的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

·   ApacheWSRP实现
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)
 
原创粉丝点击