JSR 286 Portlet 的新特性,第 2 部分: 资源服务、事件与共享呈现参数

关于本系列

本系列 专门针对具有 JSR 168 Portlet 开发基础,并且想了解 JSR 286 Portlet 新特性和开发流程的开发人员。在学完本系列后,您将了解到相对于 JSR 168 Portlet,JSR 286 Portlet 究竟提供了哪些增强功能, 以及这些新增特性在实际开发中的应用。

本系列的 第 1 部分 简单回顾了 JSR 168 Portlet, 并列出了 JSR 286 Portlet 的新增内容。第 2 部分和第 3 部分将通过在 Apache Pluto 2.0 平台上开发和部署 Portlet 应用程序, 向读者介绍 JSR 286 Portlet 新特性的使用方法

 

关于本文

本文将首先介绍 JSR 286 参考实现 Apache Pluto 2.0 平台的构建过程,然后通过在 Apache Pluto 2.0 平台上开发和部署 JSR 286 Portlet 应用程序, 向读者介绍 JSR 286 Portlet 资源服务和新增的交互功能:事件和共享呈现参数。

Portlet 过滤器和 Portlet 窗口方面应用程序的开发过程,将在第 3 部分进行详细介绍。

在示例应用程序的开发和部署中用到了下列产品:

  • Sun JDK 1.5
  • Apache Tomcat 6.x
  • Apache Pluto 2.0
  • Apache Maven 2.x
  • Eclipse Europa(Eclipse V3.3) for JavaEE Developers

阅读本文之前,您应当对 JSR 168 Portlet 有所了解,并阅读了本系列的 第 1 部分

 

准备工作

Apache Pluto 2.0 是 JSR 286 的参考实现,是实现了 Portlet 2.0 API 的 Portlet 容器,充当 Portlet 的运行时环境,与 web 应用服务器的 Servlet 容器的运行时环境支持 Servlet 的情形非常相似。Pluto 2.0 目前支持的 JSR 286 Portlet 新特性有资源服务、事件、Portlet 过滤器、共享呈现参数、 Portlet 窗口。

在本文中,我们将使用 Apache Pluto 2.0 开发测试我们的 JSR 286 Portlet 应用程序。以下操作均在 Windows XP 操作系统环境下进行。

1. 构建 JSR 286 Portlet 运行环境 Apache Pluto 2.0

Apache Pluto 2.0 目前还处于开发阶段,我们只能通过其源代码构建出一个支持 JSR 286 Portlet 标准的 Portlet 2.0 容器。

  1. 安装 Sun JDK 1.5 并设定环境变量

    该步骤一般读者都比较熟悉,不再拗述。需要注意的是,经过笔者测试,Pluto 2.0 源码工程只可以在 Sun JDK 1.5 下构建成功,笔者使用 Sun JDK 1.6 和 IBM JDK 1.5 均构建失败。

  2. 安装 Maven 2

    Pluto 源代码使用 Maven 2 进行项目管理和构建,我们必须首先安装该工具。

    http://maven.apache.org/ 上寻找 Maven 2 的最新版本压缩包,下载并解压,设定 Maven 2 的安装路径为 ${M2_HOME}。将 ${M2_HOME}/bin 目录加到系统的 PATH 环境变量中。

  3. 安装 Tomcat 6

    http://tomcat.apache.org/ 上寻找 Tomcat 6 的最新版本压缩包,下载并解压,设定安装路径为 ${TOMCAT_HOME}。

  4. 获取 Apache Pluto 2.0 源码

    使用 SVN 客户端从官方 SVN 服务器上获得源代码:

    清单 1. 使用 SVN 客户端从官方 SVN 服务器上获得源代码
                            
    svn checkout https://svn.apache.org/repos/asf/portals/pluto/trunk/ pluto2
  5. 使用 Maven 2 构建 Pluto 2.0

    编辑 ${M2_HOME}/conf 目录下的 settings.xml 文件,增加 <pluginGroups> 元素:

    清单 2. settings.xml 文件
                            
    <settings>
      ...
      <pluginGroups>
        <pluginGroup>org.apache.pluto</pluginGroup>
      </pluginGroups>
      ...
    </settings>
    

    打开 pluto2 目录下的 pom.xml 文件,找到

    清单 3. pom.xml 文件
                            
    ...
    <jaxb-impl.version>2.1.2</jaxb-impl.version>
    ...
    

    改为

    清单 4. pom.xml 文件
                            
    <jaxb-impl.version>2.1.3</jaxb-impl.version>
    

    命令行模式下进入 pluto2 目录,执行以下命令:

    清单 5.
                            
    D:/>cd pluto2
    D:/pluto2>mvn install
    D:/pluto2>mvn pluto:install -DinstallDir=${TOMCAT_HOME}
    

    如果您的 Tomcat 安装路径中存在空格,则需要用双引号把路径引起来:

    清单 6.
                            
    mvn pluto:install 
        -DinstallDir="C:/Program Files/Apache Software Foundation/Tomcat 6.0"
    

    从网上寻找 commons-logging-api-1.1.jar 文件,拷贝到 ${TOMCAT_HOME}/lib/ 目录下。

    至此,pluto2.0 的相关文件就被安装到 tomcat 相应目录下。

    编辑 ${TOMCAT_HOME}/conf/tomcat-users.xml 文件,添加角色 pluto,并在该角色下新增一个用户,以下为示例文件:

    清单 7. tomcat-users.xml 文件
                            
    <?xml version="1.0" encoding="UTF-8"?>
    <tomcat-users>
      <role rolename="role1"/>
      <role rolename="pluto"/>
      <role rolename="tomcat"/>
      <role rolename="manager"/>
      <user password="pluto" roles="pluto,manager" username="pluto"/>
      <user password="tomcat" roles="role1" username="role1"/>
      <user password="tomcat" roles="tomcat,role1" username="both"/>
      <user password="tomcat" roles="tomcat,pluto,manager" username="tomcat"/>
    </tomcat-users>
    
  6. 验证安装

    运行 ${TOMCAT_HOME}/bin/startup.bat,启动 tomcat 服务器。浏览器访问 URL http://localhost:8080/pluto/portal,如图 1 所示:

    图 1. Pluto 登录界面 Pluto 登录界面

    输入添加到 pluto 角色的用户名和密码,进入 Pluto 的 Portal 页面:

    图 2. Pluto Portal界面 Pluto Portal 界面

至此,JSR 286 Portlet 运行环境 Apache Pluto 2.0 搭建成功。

2. 使用 Eclipse Europa 建立开发环境

首先,需要从 Eclipse 官方网站 http://www.eclipse.org 下载 Eclipse Europa,针对不同的开发需求,有几种包可供下载。我们进行的是 J2EE Web 开发,所以注意要下载 Eclipse IDE for Java EE Developers。

启动 Eclipse,对 Eclipse 进行配置:

执行菜单项目 Window -> Preferences,打开 Preferences 对话框,选择 Server -> Installed Runtimes 项,如 图 3 所示:

图 3. Preferences 对话框 Preferences 对话框

点击 Add 按钮,将 Tomcat 6 添加为运行时,如 图 4、图 5 所示:

图 4. 选择运行时类型 选择运行时类型 图 5. 设定 Tomcat 安装路径 设定 Tomcat 安装路径

单击 Finish 结束配置,单击 OK 关闭 Preferences 对话框。

在 Eclipse 的 Servers 视图中单击鼠标右键,选择 New -> Server。如 图 6 所示:

图 6. 新建服务器 新建服务器

在弹出的窗口中选择目标运行服务器 Apache Tomcat 6.0 Server,运行时呈现 Apache Tomcat v6.0,如图7所示,点击 Finish。

图 7. 选择目标运行服务器 选择目标运行服务器

在 Servers 视图中双击刚刚新建的 Tomcat 服务器,打开服务器配置页面,如图 8 所示:

图 8. Tomcat 服务器配置页面 Tomcat 服务器配置页面

在 Server Locations 中选择 Use Tomcat Installation,Deploy Path选择 ${TOMCAT_HOME}/webapps,如图 9 所示。至此开发环境设置完毕。

必须设定 Deploy Path 为 Tomcat 安装目录下的 webapps 目录,否则使用 Eclipse 启动 Tomcat 后,Pluto 不能加载进来。
图 9. Tomcat 服务器配置 Tomcat 服务器配置

创建 JSR 286 Portlet 应用

下面,我们开始创建一系列程序来演示 JSR 286 Portlet 的新特性。主要分为以下六个部分:

  1. 使用 Eclipse 创建 Portlet Web 项目
  2. 资源服务
  3. 事件
  4. Portlet 过滤器
  5. 共享呈现参数
  6. Portlet 窗口

1. 使用 Eclipse 创建 Portlet Web 项目

新建项目,项目类型选择 Web->Dynamic Web Project,如图 10 所示:

图 10. 新建动态 Web 项目 新建动态 Web 项目

接下来,设置项目属性,项目名称 jsr286portlets, 目标运行时 Apache Tomcat V6.0,保留默认设置,点击 Finish,如 图 11 所示:

图 11. 设置项目属性 设置项目属性

生成项目结构如图 12:

图 12. 项目结构 项目结构

在 META-INF 下新建 context.xml 文件,内容如下:

清单 8. context.xml 文件

                
<Context crossContext="true" />

该文件为 Tomcat 的特有配置文件,根据 Pluto 的要求,该 Web 工程的上下文应该可以被其它 JavaEE 程序访问,所以 crossContext 参数设置为 true。

在 WEB-INF 下新建 portlet.xml 文件,内容如下:

清单 9. portlet.xml 文件

                
<?xml version="1.0" encoding="UTF-8"?>
<portlet-app
    xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd
            http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd"
    version="2.0">
   <!-- 在该位置填写portlet描述内容 -->
</portlet-app>

下面我们将在黑体部分填写 portlet 定义。

2. 资源服务

新增 Java 类 TestPortlet,实现了 javax.portlet.Portlet 和 javax.portlet.ResourceServingPortlet 接口:

清单 10. TestPortlet.java 文件

package com.ibm.samples.jsr286.portlets;



import ...



public class TestPortlet implements Portlet, ResourceServingPortlet {



    private PortletConfig portletConfig;



    public void init(PortletConfig portletConfig) throws PortletException {

        this.portletConfig = portletConfig;

    }



    public void destroy() {

    }



    public void processAction(ActionRequest actionRequest,

        ActionResponse actionResponse) throws PortletException, IOException {

    }



    public void render(RenderRequest renderRequest,

        RenderResponse renderResponse) throws PortletException, IOException {

        PortletRequestDispatcher portletRequestDispatcher = portletConfig

            .getPortletContext().getRequestDispatcher(

                "/WEB-INF/jsp/TestPortletView.jsp");

        portletRequestDispatcher.include(renderRequest, renderResponse);

    }



    public void serveResource(ResourceRequest resourceRequest,

        ResourceResponse resourceResponse) throws PortletException,

        IOException {

        PortletRequestDispatcher portletRequestDispatcher = portletConfig

            .getPortletContext().getRequestDispatcher(

                "/WEB-INF/jsp/TestPortletResource.jsp");

        portletRequestDispatcher.include(resourceRequest, resourceResponse);

    }

}

在 WEB-INF 目录下新建 jsp 目录,在 jsp 目录下新建 portlet 呈现阶段所显示的 jsp 文件 TestPortletView.jsp。

清单 11. TestPortletView.jsp 文件

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%>

<%@taglib prefix="portlet" uri="http://java.sun.com/portlet_2_0"%>

<portlet:defineObjects />

<table>

    <tr>

        <td><h1>Test portlet page.</h1></td>

    </tr>

    <tr>

        <td><a href="<portlet:resourceURL/>">Click me to request Resource URL</a></td>

    </tr>

</table>

在 jsp 目录下新建 portlet 资源服务所请求的 jsp 文件 TestPortletResource.jsp。

清单 12. TestPortletResource.jsp 文件

                
<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%>
<%@taglib prefix="portlet" uri="http://java.sun.com/portlet_2_0"%>
<portlet:defineObjects />
<table>
    <tr>
        <td><h1>Test portlet resource page.</h1></td>
    </tr>
</table>

编辑 portlet.xml 文件, 为 TestPortlet 增加一个 portlet 定义片断,该 TestPortlet 仅支持 View 模式。

清单 13. TestPortlet 定义片断

                
<portlet>
    <portlet-name>TestPortlet</portlet-name>
    <display-name>TestPortlet</display-name>
    <portlet-class>com.ibm.samples.jsr286.portlets.TestPortlet</portlet-class>
    <supports>
        <mime-type>text/html</mime-type>
        <portlet-mode>VIEW</portlet-mode>
    </supports>
    <portlet-info>
        <title>TestPortlet</title>
    </portlet-info>
</portlet>

编辑 web.xml 文件,增加 Pluto 所需的 servlet 定义及映射。读者请注意,该定义为 Pluto 2.0 Portlet 容器所需,不属于 JSR 286 标准的要求。

清单 14. Pluto 所需的 servlet 定义及映射片断

                
<servlet>
    <servlet-name>TestPortlet</servlet-name>
    <servlet-class>
        org.apache.pluto.core.PortletServlet
    </servlet-class>
    <init-param>
        <param-name>portlet-name</param-name>
        <param-value>TestPortlet</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>TestPortlet</servlet-name>
    <url-pattern>/PlutoInvoker/TestPortlet</url-pattern>
</servlet-mapping>

在 Eclipse 的 Servers 视图中,右键单击 Tomcat 服务器,点击 Add and Remove Projects,在弹出的对话框中将 jsr286portlets 项目添加到右侧栏目中,点击 Finish 确认,如图13:

图 13. 部署项目到服务器 部署项目到服务器

在 Servers 视图中启动服务器,Console 视图中输出 Tomcat 启动信息。

浏览器中输入相应 url 访问 pluto 的 portal 页面,登录,点击 Pluto Admin 导航栏,如图14:

图 14. Pluto 管理界面 Pluto 管理界面

使用该工具新建一个页面,如 "Test JSR 286 Portlet Page"。导航栏中马上新增一项 "Test JSR 286 Portlet Page",点击进入该页面可以见到目前该页面没有内容。

选择 jsr286portlets 应用程序中的 Portlet TestPortlet,选择上一步新建的页面,点击 Add Portlet 按钮,将 TestPortlet 布局到 "Test JSR 286 Portlet Page"页面。如图 15:

图 15. 布局 Portlet 到 Portal 页面 布局 Portlet 到 Portal 页面

进入"Test JSR 286 Portlet Page"页面,该页面新增了一个 Portlet TestPortlet,如图16:

图 16. TestPortlet 界面 TestPortlet 界面

注意到上图 portlet 的标题显示为 null, 这是由于 pluto 2.0 目前处于开发阶段,存在一些 bug,读者可不必理会。

点击超链接,进入所请求的资源页面,如图 17:

图 17. TestPortlet 资源界面 TestPortlet 资源界面

观察此页面,发现此页面只显示了 TestPortletResource.jsp 的内容,未经过 Portal 容器的修饰, 和直接请求一个 Servlet 或者 JSP 页面的效果是一样的。这就是 JSR 286 Portlet 资源服务的主要特性。对照此示例,读者可加深对 第 1 部分 相关内容的理解。

3. 事件

简单事件

新建 Java 类 TestSimpleEventSenderPortlet, 在该 Portlet 类的 processAction 方法中,发送一个简单事件,事件内容为一个字符串。

清单 15. TestSimpleEventSenderPortlet.java 文件

package com.ibm.samples.jsr286.portlets;



import ...



public class TestSimpleEventSenderPortlet implements Portlet {



    ...



    public void processAction(ActionRequest actionRequest,

            ActionResponse actionResponse) throws PortletException, IOException {

        actionResponse.setEvent("simple-event", "simple-event is sent by "

                + portletConfig.getPortletName());



    }



    public void render(RenderRequest renderRequest,

            RenderResponse renderResponse) throws PortletException, IOException {

        PortletRequestDispatcher portletRequestDispatcher = portletConfig

                .getPortletContext().getRequestDispatcher(

                        "/WEB-INF/jsp/TestSimpleEventSenderPortletView.jsp");

        portletRequestDispatcher.include(renderRequest, renderResponse);

    }

}

在 jsp 目录下新建 jsp 文件 TestSimpleEventSenderPortletView.jsp

清单 16. TestSimpleEventSenderPortletView.jsp 文件

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%>

<%@taglib prefix="portlet" uri="http://java.sun.com/portlet_2_0"%>

<portlet:defineObjects />

<form action="<portlet:actionURL/>">

<table>

    <tr>

        <td><h1>Test simple event sender portlet page.</h1></td>

    </tr>

    <tr>

        <td>

          <input type="submit" value="Click me to send simple event to other portlets">

        </td>

    </tr>

</table>

</form>

新建 Java 类 TestSimpleEventReceiverPortlet, 在该 Portlet 实现了 javax.portlet.EventPortlet 接口,可以响应事件。

清单 17. TestSimpleEventReceiverPortlet.java 文件

package com.ibm.samples.jsr286.portlets;



import ...



public class TestSimpleEventReceiverPortlet implements Portlet, EventPortlet {



    ...



    public void processAction(ActionRequest actionRequest,

            ActionResponse actionResponse) throws PortletException, IOException {

    }



    public void render(RenderRequest renderRequest,

            RenderResponse renderResponse) throws PortletException, IOException {

        PortletRequestDispatcher portletRequestDispatcher = portletConfig

                .getPortletContext().getRequestDispatcher(

                        "/WEB-INF/jsp/TestSimpleEventReceiverPortletView.jsp");

        portletRequestDispatcher.include(renderRequest, renderResponse);

    }



    public void processEvent(EventRequest eventRequest,

            EventResponse eventResponse) throws PortletException, IOException {

        Event event = eventRequest.getEvent();

        eventResponse.setRenderParameter("eventName", event.getName());

        eventResponse.setRenderParameter("eventValue", event.getValue().toString());

    }

}

在 jsp 目录下新建 jsp 文件 TestSimpleEventReceiverPortletView.jsp

清单 18. TestSimpleEventReceiverPortletView.jsp 文件

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%>

<%@taglib prefix="portlet" uri="http://java.sun.com/portlet_2_0"%>

<portlet:defineObjects />

<table>

    <tr>

        <td><h1>Test simple event receiver portlet page.</h1></td>

    </tr>

    <tr>

        <td><h2>Received simple event:</h2></td>

    </tr>

    <tr>

        <td>Event name:<%=renderRequest.getParameter("eventName")%></td>

    </tr>

    <tr>

        <td>Event value:<%=renderRequest.getParameter("eventValue")%></td>

    </tr>

</table>

在 portlet.xml 文件中新增 TestSimpleEventSenderPortlet 定义, 该 portlet 支持事件的发布,注意 supported-publishing-event 元素中定义所支持发布的事件名称为 simple-event。

清单 19. TestSimpleEventSenderPortlet 定义

<portlet>

    <portlet-name>TestSimpleEventSenderPortlet</portlet-name>

    <display-name>TestSimpleEventSenderPortlet</display-name>

    <portlet-class>

        com.ibm.samples.jsr286.portlets.TestSimpleEventSenderPortlet

    </portlet-class>

    <supports>

        <mime-type>text/html</mime-type>

        <portlet-mode>VIEW</portlet-mode>

    </supports>

    <portlet-info>

        <title>TestSimpleEventSenderPortlet</title>

    </portlet-info>

    <supported-publishing-event>

        <name>simple-event</name>

    </supported-publishing-event>

</portlet>

在 portlet.xml 文件中新增 TestSimpleEventReceiverPortlet 定义, 该 portlet 支持事件的响应处理,注意 supported-processing-event 元素中定义所支持处理的事件名称为 simple-event。

清单 20. TestSimpleEventReceiverPortlet 定义

<portlet>

    <portlet-name>TestSimpleEventReceiverPortlet</portlet-name>

    <display-name>TestSimpleEventReceiverPortlet</display-name>

    <portlet-class>

        com.ibm.samples.jsr286.portlets.TestSimpleEventReceiverPortlet

    </portlet-class>

    <supports>

        <mime-type>text/html</mime-type>

        <portlet-mode>VIEW</portlet-mode>

    </supports>

    <portlet-info>

        <title>TestSimpleEventReceiverPortlet</title>

    </portlet-info>

    <supported-processing-event>

        <name>simple-event</name>

    </supported-processing-event>

</portlet>

您还需要在 portlet.xml 文件中添加以下声明,定义 QName 默认的命名空间和事件定义,该事件类型为 java.lang.String。

清单 21. simple-event 定义

                
<default-namespace>http://cn.ibm.com/</default-namespace>
<event-definition>
    <name>simple-event</name>
    <value-type>java.lang.String</value-type>
</event-definition>

参照 TestPortlet 的定义,为 TestSimpleEventSenderPortlet 和 TestSimpleEventReceiverPortlet 在 web.xml 里添加 Pluto 所需的 servlet 定义及映射。

将 TestSimpleEventSenderPortlet 和 TestSimpleEventReceiverPortlet 部署到"Test JSR 286 Portlet Page"页面,如图 18 和 图 19。

图 18. 简单事件发布 portlet TestSimpleEventSenderPortlet 图 19. 简单事件响应 portlet TestSimpleEventReceiverPortlet

点击 TestSimpleEventSenderPortlet 中的按钮,TestSimpleEventReceiverPortlet 如图 20 所示:

图 20. 简单事件响应 TestSimpleEventReceiverPortlet

表明 TestSimpleEventReceiverPortlet 接收到了名为 simple-event 的事件,事件值为 "simple-event is sent by TestSimpleEventSenderPortlet"。

复合事件

定义一个 复合事件 Java 类 SampleComplexEvent, 该类是可序列化的,并且存在 int, String, Date 三种类型的属性。

清单 22. SampleComplexEvent.java 文件

package com.ibm.samples.jsr286.events;



import ...



public class SampleComplexEvent implements Serializable {



    private static final long serialVersionUID = -1447091586272283310L;



    private int intItem;



    private String strItem;



    private Date dateItem;



    //setters and getters

    ...

}

新建 Java 类 TestComplexEventSenderPortlet, 在该 Portlet 类的 processAction 方法中,发送一个复合事件,事件类型为 com.ibm.samples.jsr286.events.SampleComplexEvent。

清单 23. TestComplexEventSenderPortlet.java 文件

package com.ibm.samples.jsr286.portlets;



import ...



public class TestComplexEventSenderPortlet implements Portlet {



    ...



    public void processAction(ActionRequest actionRequest,

            ActionResponse actionResponse) throws PortletException, IOException {

        SampleComplexEvent event = new SampleComplexEvent();

        event.setIntItem(new Random().nextInt());

        event.setStrItem("complex-event is sent by "

                + portletConfig.getPortletName());

        event.setDateItem(new Date());

        actionResponse.setEvent("complex-event", event);



    }



    public void render(RenderRequest renderRequest,

            RenderResponse renderResponse) throws PortletException, IOException {

        PortletRequestDispatcher portletRequestDispatcher = portletConfig

                .getPortletContext().getRequestDispatcher(

                        "/WEB-INF/jsp/TestComplexEventSenderPortletView.jsp");

        portletRequestDispatcher.include(renderRequest, renderResponse);

    }

}

在 jsp 目录下新建 jsp 文件 TestComplexEventSenderPortletView.jsp, 内容同 清单 16. TestSimpleEventSenderPortletView.jsp 文件 类似。

新建 Java 类 TestComplexEventReceiverPortlet, 在该 Portlet 实现了 javax.portlet.EventPortlet 接口,可以响应复合事件。

清单 24. TestComplexEventReceiverPortlet.java 文件

package com.ibm.samples.jsr286.portlets;



import ...



public class TestComplexEventReceiverPortlet implements Portlet, EventPortlet {



    ...



    public void processAction(ActionRequest actionRequest,

            ActionResponse actionResponse) throws PortletException, IOException {

    }



    public void render(RenderRequest renderRequest,

            RenderResponse renderResponse) throws PortletException, IOException {

        PortletRequestDispatcher portletRequestDispatcher = portletConfig

                .getPortletContext().getRequestDispatcher(

                        "/WEB-INF/jsp/TestComplexEventReceiverPortletView.jsp");

        portletRequestDispatcher.include(renderRequest, renderResponse);

    }



    public void processEvent(EventRequest eventRequest,

            EventResponse eventResponse) throws PortletException, IOException {

        Event event = eventRequest.getEvent();

        eventResponse.setRenderParameter("eventName", event.getName());

        SampleComplexEvent eventValue = (SampleComplexEvent) event.getValue();

        eventResponse.setRenderParameter("intItem", Integer.toString(eventValue

                .getIntItem()));

        eventResponse.setRenderParameter("strItem", eventValue.getStrItem());

        eventResponse.setRenderParameter("dateItem", eventValue.getDateItem().toString());

    }

}

在 jsp 目录下新建 jsp 文件 TestComplexEventReceiverPortletView.jsp

清单 25. TestComplexEventReceiverPortletView.jsp 文件

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%>

<%@taglib prefix="portlet" uri="http://java.sun.com/portlet_2_0"%>

<portlet:defineObjects />

<table>

    <tr>

        <td><h1>Test complex event receiver portlet page.</h1></td>

    </tr>

    <tr>

        <td><h2>Received complex event:</h2></td>

    </tr>

    <tr>

        <td>Event name:<%=renderRequest.getParameter("eventName")%></td>

    </tr>

    <tr><td>Event value</td></tr>

    <tr>

        <td>Integer item:<%=renderRequest.getParameter("intItem")%></td>

    </tr>

    <tr>

        <td>String item:<%=renderRequest.getParameter("strItem")%></td>

    </tr>

    <tr>

        <td>Date item:<%=renderRequest.getParameter("dateItem")%></td>

    </tr>

</table>

请读者自行参照清单 19 和 清单 20 在 portlet.xml 文件中定义两个portlet TestComplexEventSenderPortlet 和 TestComplexEventReceiverPortlet, 使其分别支持发布和响应事件 complex-event。

在 portlet.xml 文件中添加以下声明,定义事件名称和类型,该事件类型为com.ibm.samples.jsr286.events.SampleComplexEvent,如清单 26 所示:

清单 26.

                
<event-definition>
    <name>complex-event</name>
    <value-type>com.ibm.samples.jsr286.events.SampleComplexEvent</value-type>
</event-definition>

参照 TestPortlet 的定义, 为 TestComplexEventSenderPortlet 和 TestComplexEventReceiverPortlet 在 web.xml 里添加 Pluto 所需的 servlet 定义及映射。

将 TestComplexEventSenderPortlet 和 TestComplexEventSenderPortlet 部署到"Test JSR 286 Portlet Page"页面,如图 21 和 图 22。

图 21. 复合事件发布 portlet TestComplexEventSenderPortlet 图 22. 复合事件响应 portlet TestComplexEventReceiverPortlet

点击 TestComplexEventSenderPortlet 中的按钮,TestComplexEventReceiverPortlet 如图 23 所示:

图 23. 复合事件响应 TestComplexEventReceiverPortlet

表明 TestComplexEventReceiverPortlet 接收到了名为 complex-event 的事件,事件值如图 23 所示。

4. 共享呈现参数

更改 TestPortletView.jsp 文件,在文件末尾增加表单和输入框接收输入参数,如清单 26 所示:

清单 26. 表单和共享呈现参数值输入框

...

<form action="<portlet:actionURL/>">

<table>

    <tr><td>Input public render parameter value:</td></tr>

    <tr>

        <td><input type="text" name="public-render-param"></td>

    </tr>

    <tr>

        <td><input type="submit" value="Submit"></td>

    </tr>

</table>

</form>

 

更改 TestPortlet 的 processAction 方法,将从输入框中得到的值传送到呈现阶段的请求参数中,如清单 27 所示:

清单 27. TestPortlet 的 processAction 方法

                
...
public void processAction(ActionRequest actionRequest,
        ActionResponse actionResponse) throws PortletException, IOException {
    String publicRenderParamValue = actionRequest.getParameter("public-render-param");
    actionResponse.setRenderParameter("public-render-param", publicRenderParamValue);
}
...

新建 portlet 类 TestPublicRenderParameterPortlet, 如清单 28 所示:

清单 28. TestPublicRenderParameterPortlet.java 文件

package com.ibm.samples.jsr286.portlets;



import ...



public class TestPublicRenderParameterPortlet implements Portlet {



    private PortletConfig portletConfig;



    public void init(PortletConfig portletConfig) throws PortletException {

        this.portletConfig = portletConfig;

    }



    public void destroy() {

    }

    

    public void processAction(ActionRequest actionRequest,

            ActionResponse actionResponse) throws PortletException, IOException {

    }



    public void render(RenderRequest renderRequest,

            RenderResponse renderResponse) throws PortletException, IOException {

        PortletRequestDispatcher portletRequestDispatcher = portletConfig

                .getPortletContext()

                .getRequestDispatcher(

                        "/WEB-INF/jsp/TestPublicRenderParameterPortletView.jsp");

        portletRequestDispatcher.include(renderRequest, renderResponse);

    }

}

 

TestPublicRenderParameterPortlet 呈现所需的 jsp 页面 TestPublicRenderParameterPortletView.jsp 如清单 29 所示:

清单 29. TestPublicRenderParameterPortletView.jsp 文件

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%>

<%@taglib prefix="portlet" uri="http://java.sun.com/portlet_2_0"%>

<portlet:defineObjects />

<table>

    <tr><td><h1>Test public render parameter test page.</h1></td></tr>

    <tr><td><h2>Received public render parameter value:</h2></td></tr>

    <tr>

        <td>Parameter value:<%=renderRequest.getParameter("public-render-param")%></td>

    </tr>

</table>

 

编辑 portlet.xml 文件, 在 TestPortlet 定义的尾端加入 清单 30 中 的内容,使得 portlet TestPortlet 支持共享呈现参数 public-render-param。

清单 30.

                
<portlet>
...
    <supported-public-render-parameter>
        public-render-param
    </supported-public-render-parameter>
</portlet>

在 portlet.xml 中增加 TestPublicRenderParameterPortlet 的定义,并加入清单 30 中的内容。

在 portlet.xml 末尾添加 清单 31 中的内容:

清单 31.

                
...
    <public-render-parameter>
        <identifier>public-render-param</identifier>
    </public-render-parameter>
</portlet-app>

为 TestPublicRenderParameterPortlet 在 web.xml 里添加 Pluto 所需的 servlet 定义及映射。

将 TestPortlet 和 TestPublicRenderParameterPortlet 部署到 "Test JSR 286 Portlet Page" 页面,如图 24 和 图 25。

图 24. 输入共享呈现参数值 输入共享呈现参数值 图 25. 显示共享呈现参数值的 portlet 显示共享呈现参数值的 portlet

在 TestPortlet 中输入参数值 testvalue, 提交表单,则在 TestPublicRenderParameterPortlet 呈现图 26 所示结果:

图 26. 显示共享呈现参数值 显示共享呈现参数值 

小结

本部分介绍了 JSR 286 Portlet 容器的参考实现 Apache Pluto 2.0 的构建过程,以及使用 Eclipse 和 Apache Pluto 2.0 进行 Portlet 开发的方法流程,并且通过示例代码介绍了JSR 286 Portlet 资源服务、事件交互和共享呈现参数的实际开发步骤。JSR 286 规范目前还处于草案阶段,而且相应的 Portlet 容器还处于不稳定版本的开发阶段,在具体的实验性开发过程中需要读者对 Portelt 容器本身的 Bug 加以注意。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值