为了查看如何使用 Pluto 作为 portlet 的 JSR 168 兼容性测试平台,需要一个 portlet 来进行测试。在此练习中,您将创建一个简单的 portlet,它根据用户的输入,把文本框中的内容转换为全是大写字符或全是小写字符
我们从查看清单 3 所示的 portlet.xml 文件开始。portlet.xml 文件是包含关于 WAR 文件中捆绑的 portlet 的配置细节的描述符文件。
清单 3. portlet.xml 文件
<?xml version="1.0" encoding="UTF-8"?>
<portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd"
version="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd
http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd"
id="com.ibm.changecase.ChangeCasePortlet">
<portlet>
<portlet-name>ChangeCase</portlet-name>
<display-name>Change Case Portlet</display-name>
<portlet-class>com.ibm.changecase.ChangeCasePortlet</portlet-class>
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>view</portlet-mode>
</supports>
<portlet-info>
<title>ChangeCasePortlet</title>
</portlet-info>
</portlet>
</portlet-app>
清单 3 中的 <portlet-app> 标记定义了 XML 模式定义和 portlet 应用程序 的 ID。一个 portlet 应用程序可以包含零个或多个 portlet。使用 <portlet> 标记来定义 portlet 应用程序中的单个 portlet:
<portlet-name> —— 提供一个名称,在内部或由程序使用该名称来引用 portlet。
<display-name> —— portlet 的缩写名,用来在 GUI 工具中显示 portlet 名称,它随 portlet 容器的不同而不同。
<portlet-class> —— 充当 portlet 控制器的类。
<supports> —— 这些标记定义 portlet 支持的 portlet 模式和 mime 类型。
<title> —— 可以在 portlet.xml 中定义 portlet 的首选标题。但是,如何使用该标题取决于 portlet 容器。
清单 4 显示的是 portlet.xml 中引用的 com.ibm.changecase.ChangeCasePortlet portlet 类。此类必须实现 javax.portlet.Portlet 接口,但幸运的是,您不必直接实现 Portlet 接口。JSR 168 为 javax.portlet.Portlet 接口定义了一个称为 javax.portlet.GenericPortlet 类的默认实现。com.ibm.changecase.ChangeCasePortlet 类继承 GenericPortlet 类。
清单 4. ChangeCasePortlet 类
package com.ibm.changecase;
import java.io.*;
import javax.portlet.*;
/**
*
* A sample portlet based on GenericPortlet
*
*/
public class ChangeCasePortlet extends GenericPortlet {
private static String VIEW_JSP = "/view.jsp";
protected void doView(RenderRequest request, RenderResponse response)
throws PortletException, IOException {
response.setContentType(request.getResponseContentType());
PortletContext context = getPortletConfig().getPortletContext();
context.getRequestDispatcher(VIEW_JSP).include(request, response);
}
public void processAction(ActionRequest request, ActionResponse response)
throws PortletException, java.io.IOException {
//Do Action Handling here.
}
}
注意重写 doView() 和 processAction() 方法的选择。每当出现 portlet 操作时都会调用 processAction() 方法。当用户处于 portlet 的视图模式时调用 doView() 方法。JSR 168 支持其他的模式,例如帮助模式和编辑模式。但是,如果回过头看一下 清单 3,在 <supports> 部分可以看到 portlet 只支持视图模式。
现在仔细地看一下清单 4 中的 doView() 方法。与 Java servlet 编码中一样,portlet 编码中也经常使用模型-视图-控制器 (MVC) 设计模式。因此,在 portlet 中,把表示的职责转交给了 view.jsp。或者,也可以使用 prinltn 逻辑在 doView() 方法中实现视图。
response.getWriter().println("<p>Hello World</p>()");
这种方法的问题是,图形用户界面的设计者需要具有 portlet 技术的知识来编写 doView() 方法。JSP 开发人员从复杂的 Java 开发中解放出来,能够集中精力开发前端界面。清单 5 显示的是 view.jsp:
清单 5. view.jsp
<%@ taglib uri="http://java.sun.com/portlet" prefix="portlet"%>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1" session="false"%>
<portlet:defineObjects />
<%String textBox = renderRequest.getParameter("textBox");
if (textBox == null)
textBox = "";
String caseString = renderRequest.getParameter("case");
boolean isUpperCase = true;
if ((caseString != null) && (caseString.equals("false"))) {
isUpperCase = false;
}
String errorMessage = renderRequest.getParameter("errorMessage");%>
<%if (errorMessage != null) {%>
<p><%=errorMessage%></p>
<%}%>
<FORM name="<portlet:namespace/>caseform" action="<portlet:actionURL/>">
<INPUT type="text" name="textBox" size="20" value="<%=textBox%>">
<p><INPUT type="radio" name="case" value="lowercase"
<%if (!isUpperCase) {%> checked="checked" <%}%>>To Lowercase</p>
<p><INPUT type="radio" name="case" value="uppercase"
<%if (isUpperCase) {%> checked="checked" <%}%>>To Uppercase</p>
<INPUT type="submit" name="<portlet:namespace/>submitCase"
value="Change Case"></FORM>
首先,注意在 view.jsp 中定义 portlet 标记库。这是 JSP 解析器识别 portlet 标记所必需的。您使用的第一个 portlet 标记是 <portlet:defineObjects/>。此标记允许访问 renderRequest、renderResponse 和 portletConfig 对象。使用 renderRequest 对象使您具有访问 requestParameters 的权利。portlet 类通过 request 参数向 view JSP 传递值。
接下来,在 view.jsp 中创建一个向 portlet 类发送表单数据的表单。为了发送表单数据,必须创建一个 actionURL,它使 ChangeCasePortlet portlet 类的 processAction() 方法被调用。使用 <portlet:actionURL/> 标记创建 actionURL。 注意,在 view.jsp 中将文本框和单选按钮的值设置为服务器传回 JSP 的值。因此,view.jsp 负责处理请求输入和显示 portlet 的响应。
单击表单的 Submit 按钮会调用 portlet 的 processAction() 方法,如清单 6 所示。processAction() 从 view.jsp 接收一个 ActionRequest 对象作为输入。
清单 6. processAction 方法
public void processAction(ActionRequest request, ActionResponse response)
throws PortletException, java.io.IOException {
String newCase = request.getParameter("case");
String textBox = request.getParameter("textBox");
String errorMessage = null;
boolean isUpperCase = true;
if ((newCase!=null) && (newCase.equals(ChangeCaseConstants.LOWER_CASE)))
isUpperCase = false;
else if ((newCase == null) || (newCase==ChangeCaseConstants.UPPER_CASE))
errorMessage = "Error no case selected! Select a case.";
if (textBox !=null) {
if (isUpperCase)
textBox = textBox.toUpperCase();
else
textBox = textBox.toLowerCase();
response.setRenderParameter("textBox", textBox);
} else
errorMessage = "Error, text in the text box is invalid";
response.setRenderParameter("case", Boolean.toString(isUpperCase));
if (errorMessage != null) {
response.setRenderParameter("errorMessage",errorMessage);
}
}
ActionRequest 对象包含输入到表单中的数据。为了检索表单数据,可使用 getParameter() 方法。在 processAction() 方法中,也要执行业务逻辑,确定用户是想要大写形式还是小写形式的输出。根据该逻辑,把输入的文本转换成想要的大小写形式并发送给用户。使用 setRenderParameter() 方法把数据发送给视图。
编译并打包 JSR 168 portlet
现在已经开发了 portlet,需要把它转换成已编译的形式,并为了部署到 Pluto 将它打包。首先,确保 portlet-api-1.0.jar 在 CLASSPATH 中。然后使用 javac 编译器编译 ChangeCaseConstants.java 和 ChangeCasePortlet.java:
javac ChangeCaseConstants.java
javac ChangeCasePortlet.java
接着需要为 WAR 文件创建所需要的文件夹结构,WAR 文件是归档文件,通过它把 portlet 部署到 portlet 容器。把刚才编译的两个类放在 classes\com\ibm\changecase 目录中。
为了构建 WAR 文件,需要以下的目录结构,如清单 7 所示:
清单 7. 用于部署的目录结构
changeCaseWAR\
META-INF
MANIFEST.MF
WEB-INF
classes
com
ibm
changecase
ChangeCaseConstants.class
ChangeCasePortlet.class
lib
tld
portlet.tld
portlet.xml
web.xml
index.html
view.jsp
注意,清单 7 引入了 4 个我们还没有讨论过的文件:
portlet.tld:这是 portlet 标记库。如果回想一下,您曾经用 <portlet:defineObjects /> 之类的引用在整个 JSP 中都用到过 portlet 标记库。portlet 标记库在 Apache-SVN 代码库中可以得到(参见 参考资料)。
MANIFEST.MF:因为这里不存在外部依赖,所以这个清单文件除了 Manifest-Version: 1.0 之外什么也不包含。
index.html:如果由于某些原因上下文根被直接访问,则会显示 index.html。在 index.html 中可以有任何正确格式的 HTML。
web.xml(如清单 8 所示):它定义包含单个 portlet 的 Web 应用程序。
清单 8. web.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app id="WebApp_ID">
<display-name>CasePortlet</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<taglib>
<taglib-uri>http://java.sun.com/portlet</taglib-uri>
<taglib-location>tld/portlet.tld</taglib-location>
</taglib>
<taglib id="PortletTLD">
<taglib-uri>http://java.sun.com/portlet</taglib-uri>
<taglib-location>/WEB-INF/tld/std-portlet.tld</taglib-location>
</taglib>
</web-app>
一旦生成了 MANIFEST.MF、portlet.tld、web.xml 和 index.html,就可以使用 JAR 实用工具将清单 7 所示的结构归档到一个 WAR 文件中:
C:\temp>jar -cvf changeCase.war
结果是一个叫做 changeCase.war 文件,用于部署到 JSR 168 兼容的门户。
确保 portlet 是 JSR 168 兼容的
现在使用 Apache Pluto 来查明 portlet 是否能通过 JSR168 兼容性的最终测试。
确保 Apache Pluto 启动并运行,然后导航到 Pluto 主页(http://localhost:8080/pluto/portal)。单击侧栏上的 Admin。应该看到 Deploy War portlet 显示在管理页面上,如图 4 所示。单击 Browse 并导航到在前一节中放置在一起的 changeCase.war 文件的位置,然后单击 Submit。
图 4. Pluto 的 Deploy War portlet
现在必须为 portlet 应用程序输入布局信息 —— 一个非常不重要的任务,因为在 portlet 应用程序中只有一个 portlet。正如在图 5 中可以看到的,您告知 Pluto portlet 有一行和一列,然后单击 Submit 向服务器提交此选择:
图 5.为 portlet 应用程序输入页面布局信息
接下来,必须定义 portlet 出现在 portlet 应用程序页面布局的何处。通过把 portlet 应用程序中的所有 portlet 映射到刚才定义的行和列来完成此任务。因为只有一个 portlet 需要部署并且您先前选择了一行和一列的页面布局,所以在该位置输入 ChangeCase portlet 并单击 Submit,如图 6 所示:
图 6. 映射 portlet 的位置
为了部署 portlet,您可以选择重新启动 Pluto 或者热部署 包含 portlet 的 portlet 应用程序,如图 7 所示:
图 7. 热部署 portlet
一个具有 portlet 应用程序名称(Change Case)的链接出现在侧栏。单击该超链接,现在将看到 portlet 应用程序,其中包含 portlet,如图 8 所示。这时应该与 Change Case portlet 交互并确保它的功能与预期的一样。如果与预期的一样,您就可以确定此 portlet 与 JSR 168 兼容。
图 8. 部署到 Pluto 的 Change Case portlet
Change Case Portlet 将能够运行在任何支持 JSR 168 portlet 标准的 Portlet 容器中。
参考资料
学习
您可以参阅本文在 developerWorks 全球站点上的 英文原文 。
“JSR 168 - An Introduction to the Portlet Specification”:更多地了解 JSR 168。
Apache Pluto:访问 Pluto Web 站点。
JSR 168: Portlet Specification 和 SR 286: Portlet Specification 2.0:由 Java Community Process 开发和维护的 portlet 规范。
“使用 WebSphere Portal V5.1 在 IBM Portlet 和 JSR 168 Portlet 间共享信息”(Stefan Hepper 和 Jerry Zheng,developerWorks,2006 年 2 月):编写一个自定义的 portlet 服务以允许 IBM portlet 和 JSR 168 portlet 共享作为属性的信息。
“使用 WebSphere Portal V5.1 在 JSR 168 Portlet 中缓存数据”(Stefan Hepper 和 Jerry Zheng,developerWorks,2005 年 8 月):学习如何在 JSR 168 portlet 中缓存数据以避免不必要的后端请求。
“将 WorldClock portlet 从 IBM Portlet API 转换到 JSR 168 portlet API”(Franziska Paeffgen 和 Birga Rick,developerWorks,2004 年 12 月):了解如何将最为 IBM WebSphere Portal 专有 Portlet API 开发的 portlet 转换为使用 JSR 168 标准 portlet API 的 portlet。
Verifying Apache HTTP Server Releases:有关验证来自 Apache Web 站点的下载文件的更多信息。
Java 技术专区:关于 Java 编程的各个方面的数百篇文章。
获得产品和技术
Apache Pluto:下载 Pluto。
portlet 标记库:从 Apache-SVN 代码库下载 portlet 标记。
Apache Jetspeed:一个开放源码的 portlet 容器。
Java 5.0 SDK:Pluto 需要 Java 5。
IBM 的 WebSphere Portal Server Version 5.1:支持 JSR 168 标准的商业解决方案。
GnuPG:一个免费的 PGP 工具。
分享到:
相关推荐
【在 RAD7 中开发 JSR168 Portlet】是一个关于使用IBM Rational Application Developer (RAD) 7.0.0.3版本开发遵循JSR168标准的portlet的教程。JSR168(Java Portlet API 1.0)是Java Community Process发布的一个...
开发JSR 168 portlet在WebLogic Portal 8.1上,开发人员应熟悉portlet生命周期(初始化、渲染、事件处理等)、portlet模式(如查看、编辑、帮助等)、窗口状态(如最大化、最小化、正常)以及portlet通信机制(如...
1. **jsr168plugin.jar**:这是核心插件文件,包含了实现JSR 168 Portlet Project Creator功能的类和方法。开发者可以通过安装此插件,使Eclipse具备创建JSR 168 portlet项目的功能。 2. **plugin.xml**:这是...
Struts2 JSR168 Portlet的开发是构建在Java Portlet规范(JSR168)基础上,结合流行的MVC框架Struts2来创建适用于企业级门户平台的应用组件。这种开发方式允许开发者利用Struts2的强大功能,如Action、Interceptor、...
本压缩包里含有了开发一个jsr168 portlet所需要的软件 本想包含jetspeed2.0的安装程序的,可是最多智能上传10M <br>从环境配置讲到开发步骤。 并表明了很多注意的地方 本包适合初学portlet的人使用
JSR168是portlet API的第一个版本,它为portlet开发提供了一套标准接口,使得portlet可以在不同的portlet容器中运行,比如IBM WebSphere Portal或Liferay Portal。 在JSR168中,portlet主要负责与用户交互,而...
许多大型企业的网站, 渐渐采用了 portal server 作为开发的基础. 至于什么是 portal 呢, 中文翻译为 "门户网站"。 有人可能想.. 天杀的.. 门户网站不是就像 yahoo, pchome, yam 等等。不过, 我们现在讨论的 portal ...
文章专门针对具有 JSR 168 Portlet 开发基础,并且想了解 JSR 286 Portlet 新特性和开发流程的开发人员。在学习完本系列后,您将了解相对于 JSR 168 Portlet,JSR 286 Portlet 究竟提供了哪些增强功能, 以及这些...
- **公共Portlet功能**:虽然JSR168提供了一些通用功能,但特定于某个Portlet的功能需要单独开发。 - **其他**:还有许多其他方面未在规范中提及,这些方面可能需要根据实际情况进行定制开发。 #### JSR168规范的...
文章专门针对具有 JSR 168 Portlet 开发基础,并且想了解 JSR 286 Portlet 新特性和开发流程的开发人员。在学习完本系列后,您将了解相对于 JSR 168 Portlet,JSR 286 Portlet 究竟提供了哪些增强功能, 以及这些...
标题中的"使用jsr168标准开发portlet"是指基于Java Specification Request (JSR) 168标准来创建portlet应用程序。JSR 168是Java社区进程(Java Community Process)提出的一个标准,旨在规范portlet在企业级portlet...
portlet开发样例主要涵盖两大部分:portlet的类名规范以及使用RAD7开发JSR168portlet的过程。本文将详细阐述这两个方面的内容。 首先,我们来看portlet的类名规范。类名是portlet开发中的一个重要组成部分,它需要...
JSR(Java Specification Request)168和286是定义portlet标准的两个关键版本,它们由Java Community Process(JCP)发布,旨在促进portlet在门户环境中的互操作性和可扩展性。 JSR 168是portlet规范的第一个主要...
【JSR-168 Portlet开发指南】 JSR-168,全称为Java Specification Request 168,是Java社区制定的一项标准,旨在为portlet开发者提供一套API,以实现portlet的可移植性和互操作性。Portlet是一种组件化的应用程序,...
【标题】"jsr168portlet(struts2+spring2.5+hibernate3.3)" 是一个基于Java的Web开发项目,它利用了JSR 168规范来实现portlet的功能,并结合了Struts2、Spring2.5和Hibernate3.3这三个框架的强大功能。JSR 168是Java...
总结,JSR-168为portlet开发提供了标准化的框架,使得开发者可以专注于portlet的功能实现,而不必关心如何与门户服务器协作。通过学习和掌握JSR-168,开发者可以创建出高效、灵活的portlet,提升Web门户的综合性能和...