JetSpeed高级portlet技术(整理)

n        关于本教程

谁应该学习本教程?

在本教程系列的 1 部分中,您了解了如何使用 Java servlet 来开发基本 Jetspeed portlet,以及如何在注册中心中正确地注册它们。您还了解了如何检测用户正用于访问门户网站的设备,以及如何为每个用户的浏览器正确生成内容。在这篇后续教程中,您将了解如何使用象 JavaServer PagesJSP)这样的 Web 编程技术开发基于 Jetspeed 的更动态的 portlet,以及如何使内容流入 WML portlet。我们还将提到几个 Jetspeed 文档中未提及的技巧,它们可以使您工作得更轻松。本课程适合于希望大致了解使用 Jetspeed 进行门户网站和 portlet 开发并理解这一内容的开发人员和技术经理,以及完整阅读了本系列第 1 部分的读者。

关于作者

Vivek Malhotra 是无线技术行业的专家,他居住在华盛顿特区。他具有多年开发和实现无线应用程序的经验,而且是经常在专家座谈会上针对无线业界发言。如对本教程的内容有任何问题,可通过 vmalhot@yahoo.com 与他联系。

Roman Vichr DDLabs 的一名高级架构设计师,DDLabs 是一家电子商务和 EAI 咨询公司。在过去九年里,他一直致力于客户机/服务器的数据库管理和 Web 应用程序开发,他最近的兴趣包括将数据库扩展到无线技术中。他是搞光导纤维出身,在这一领域里的最高学位是 1992 年在布拉格的 Institute of Chemical Technology 获得的博士学位。可通过 rvichr@us.ddlabs.net 与他联系。

本教程系列第 2 部分简介

Jetspeed 是基于开放源码的实现,可以用来构建基于 Web 的门户网站和无线门户网站。本教程讨论了 Jetspeed 较高级的方面和 portlet 实现,包括使用 JavaServer PagesJSP)和内容联合(RSS)来构建 portlet

预备知识

在开始学习本教程之前,您应该熟悉 Java 语言、JavaServer Pages 和无线标记语言(Wireless Markup LanguageWML)的基础知识。

n        Jetspeed体系结构和概述

Jetspeed 是什么?

Jetspeed Apache 软件基金会的开放源码项目,它允许开发人员实现门户网站。Jetspeed 是用 Java 语言编写的,它为 portlet 开发提供了 Portal APIportlet 是构成门户网站构件的小型 Java 应用程序。Jetspeed 建立与外部数据和内容馈送的连接,以通过门户网站检索和显示该数据。实现门户网站的方式可以是这样的:用户可以从 Web 浏览器或无线设备(如 WAP 电话或 Palm OS 设备)访问它。Jetspeed 支持用户界面定制、高速缓存、持久性和用户认证这样的内置服务,因此门户网站开发人员不必实现这些服务。

Jetspeed 体系结构模型

本图显示了 Jetspeed 体系结构的构件。本教程将 Tomcat 3.2 用于 servlet 引擎和 HTTP 服务器,并使用 Jetspeed V 1.3a 2

在本教程的 1 部分中,我们讨论了安装和配置 Jetspeed 所需的步骤。如果您还没有在系统上启动和运行 Jetspeed,可能要先查看这份材料。

Jetspeed 所支持的 JSP portlet

Jetspeed 支持 JSP 作为 portlet 的构件。它还提供了特定于 Jetspeed 的预定义 taglib 块,这使得重复的任务更容易执行。

Jetspeed 所支持的内容格式

Jetspeed 支持 RSSRDF 站点摘要,RDF Site Summary)和 OCS(开放内容联合,Open Content Syndication)格式。RSS 是一种用于联合 Web 标题的 XML 格式。OCS 格式描述了多内容通道,包括 RSS 标题。

高级 Jetspeed 特性

Jetspeed 的一些高级特性包括:

  • 支持无线标记语言(WML
  • Web 应用程序开发基础结构
  • 跨所有支持 JDK 1.2 Servlet 2.2 的平台的可移植性
  • 可通过安全性 porlet 使用的用户、组、角色和许可权管理
  • portlet 进行基于角色的安全性访问

n        portlet 概述

portlet 是什么

可以将 portlet 看作在门户页面中显示数据的可见的活动组件。上图说明了关于门户网站的 portlet。名为 Home 的门户网站页面上显示了三个 portlet,它们名为 Reports Weather Contacts

页面布局

上图说明了包含 portlet 的页面的组织结构。在页面中,portlet 内容是由 PortletControl PortletController 渲染的。

  • portlet 页面中的 PortletControl 渲染 portlet 的标题和主体。
  • PortletController 处理多个 PortletControl(每个控制一个 portlet),以便将从所有 portlet 抽出的信息组合起来,提供完整的页面信息。

portlet 如何显示内容

portlet 使用元素构造集(Element Construction SetECSAPI 显示内容,该 API 是与 Jetspeed 捆绑在一起提供的。ECS API Java 对象生成标记元素。可以使用 JSP 技术或 servlet 模板来生成作为输出的内容,然后由 ECS 元素捕获该内容再依次显示内容。ECS 支持无线标记语言(WML)以及 HTML XML

portlet 高速缓存

Jetspeed 向开发人员提供了高级高速缓存机制。需要进行高速缓存的 portlet 连同其相关句柄信息(譬如其类名称)以及一些 portlet 配置信息(譬如其 URL)一起被放置到高速缓存中。如果必须从高速缓存中除去 portlet,那么可以通过 expire() 方法来完成该操作,该方法可以决定 portlet 何时在高速缓存中已到期。

门户网站结构标记语言(PSML

我们使用门户网站结构标记语言(Portal Structure Markup LanguagePSML)将 portlet 手工注册到 JetspeedPSML 通知 Jetspeed 哪些 portlet 可用,并将这些 portlet 注册到 Jetspeedportlet 的配置文件是 WEB-INF/conf 目录中的 jetspeed-config.jcfg。缺省配置文件名为 default.psml defaultWML.psml,它们位于 WEB-INF/psml 中。一旦创建了用户,就拥有了两个与之相关联的配置文件homeHTML.psml homeWML.psml,这两个文件存储在 WEB-INF/psml/<username> 中。

PSML 由两类标记组成:

  • 注册表标记描述了 Jetspeed 引擎可用的所有 portlet。关于每个 portlet 的所有信息都存储在 portlet 注册表中。
  • 站点标记描述了可以向特定用户显示哪些可用于 Jetspeed 引擎的 portlet。关于如何在屏幕/页面上组织 portlet 的信息,以及其表示特性的信息,是通过站点标记描述的。

n        高级JetSpeed portlet技术

用于移动设备的 JSP portlet RSS portlet

在本教程的剩余部分,我们将讨论下列特性:

  • JSP portlet
  • RSS portlet

我们还将研究未记入文档的难题,它们是在用这些类型的 portlet 在移动设备上显示数据时发生的。

可以在 Jetspeed 网站上找到关于这些 portlet 所用的常见元素的描述。

标准 Web JSP portlet

JSP portlet 显示了 JavaServer Pages 的输出。下列清单是一个示例:

<portlet-entry name="HelloWorld" hidden="false" type="ref" parent="JSP" application="false">
   
   
    <meta-info>
   
   
        <title>Hello World</title>
   
   
        <description>Example of JSP Portlet</description>
   
   
    </meta-info>
   
   
    <parameter name="template" value="hello.jsp" hidden="false"/>
   
   
    <media-type ref="html"/>
   
   
</portlet-entry>
   
   

  
  
   
    
  
  

这个 portlet 显示的内容是 hello.jsp 页面的输出。这个 JSP 文件需要定位到 <tomcat_home>/<jetspeed_directory>/WEB-INF/templates/jsp/portlets 中。该 JSP 文件本身的代码如下:


   
   
    
     
   
   
<%@ taglib uri='/WEB-INF/templates/jsp/tld/template.tld'
   
   
prefix='jetspeed' %>
   
   

   
   
    
     
   
   
<card id='_myhellotestjsp' title='HELLOWORLD'>
   
   
<p>
   
   
<b>JSP</b> Hello World<br />
   
   
<jetspeed:uriLookup type="Customize" />
   
   
Login<br/>
   
   
        <br>jetspeeed:uriLookup type="Login" />
   
   
       <br>jetspeed:contentUri
   
   
<br>apidocs/
   
   
        <br><jetspeed:contentUri href="apidocs/" />
   
   
<br>
   
   

   
   
    
     
   
   
 
 
  
  
   
   Server
  
  
  
   
    
    
     
     Port
    
    
 
 <br/>
   
   
        <%= request.getServerPort() %><br/>
   
   
</card>
   
   

标准 RSS portlet

RSS portlet 渲染 RDF 站点摘要格式馈送,并将它作为 HTML 提供给用户,如下列代码清单所示:

<portlet-entry name="Apacheweek" hidden="false" type="ref" parent="RSS" application="false">
   
   
    <meta-info>
   
   
        <title>Apacheweek</title>
   
   
    </meta-info>
   
   
    <url>http://www.apacheweek.com/issues/apacheweek-headlines.xml</url>
   
   
</portlet-entry>
   
   

  
  
   
    
  
  

url 标记提供了 RSS 馈送的位置,它必须是格式化为 RSS XML 文件。RSS portlet 支持 WML HTML 媒体类型。

 

 

n        开发用与移动设备的portlet

步骤

要使 Jetspeed 可以使用 portlet,首先必须执行这些步骤:

  1. 实现和编译 portlet
  2. 创建 portlet 注册表片段
  3. 将编译好的 portlet 放置到适当位置
  4. portlet 注册到 Jetspeed portlet 注册表
  5. 调整 portlet 代码,使之可用于移动设备

 

合并了 Jetspeed 标记库的、用于移动设备的 JSP portlet

在本章中,我们将创建一个简单的 JSP Hello World portlet。在先前所示示例中,请注意 taglib 标记,它包括 template.tld。下列清单是该 portlet 本身的代码,在这里再次列出,供您参考:


   
   
    
     
   
   
<%@ taglib uri='/WEB-INF/templates/jsp/tld/template.tld'
   
   
prefix='jetspeed' %>
   
   

   
   
    
     
   
   
<card id='_myhellotestjsp' title='HELLOWORLD'>
   
   
<p>
   
   
<b>JSP</b> Hello World<br />
   
   
<jetspeed:uriLookup type="Customize" />
   
   
Login<br/>
   
   
        <br>jetspeeed:uriLookup type="Login" />
   
   
       <br>jetspeed:contentUri
   
   
<br>apidocs/
   
   
        <br><jetspeed:contentUri href="apidocs/" />
   
   
<br>
   
   
 
 
  
  
   
   Server
  
  
  
   
    
    
     
     Port
    
    
 
 <br/>
   
   
        <%= request.getServerPort() %><br/>
   
   
</card>
  
  

每个 JSP portlet 都应该合并以下 taglib 标记:

uri='/WEB-INF/templates/jsp/tld/template.tld' prefix='jetspeed'
  
  

如果要在门户网站中包含 portlet,则它必须实现 portlet 接口 org.apache.jetspeed.portal.PortletJetspeed 提供了许多类,它们用于实现拥有最常用功能的 Portlet 接口。AbstractPortlet 类是这些预定义类中最简单的一个。RunData 对象被传递到 getContent(),因为必须将它传递给该门户框架中许多其它方法。portlet 使用元素构造集(ECSAPI 显示内容。

JSP portlet 标记函数

JSP Jetspeed 库中有几个标记可以使标准函数更简单。这些标记包括用于引用的 href 标记、用于登录的 URILookup 和用于内容的 URILookup 等。

用于移动设备的 JSP portlet 位置

portlet 文件本身的位置特别重要。在我们所使用的 Jetspeed 发行版( 1.3a 2)中,我们发现在缺省情况下应该用来放置文件的 JSP/portlets/wml/ 目录不存在,而文档本身没有指出这是为什么。您必须手工创建目录 .../jetspeed/WEB-INF/JSP/templates/JSP/portlets/wml,如下图所示。

JSP portlet 命名和卡标识名称

portlet 标识的名称很重要,因为命名错误的卡将会断开登录页面与特定 WML(移动)portlet 的链接。已注册的 JSP portlet 标题名应该与卡标识名称一致,因为来自初始页面的链接是通过 Jetspeed portlet XSL 模板生成的;这样就动态地创建了这些页面(卡)之间的超级链接,如下列代码清单所示:

  <portlet-entry name="myhellotestjsp" hidden="false" type="ref" parent="JSP"
   
   
                 application="false">
   
   
    <meta-info>
   
   
      <title>MYWMLTESTJSP</title>
   
   
      <description>Simple HELLO JSP Portlet Example</description>
   
   
    </meta-info>
   
   
  <parameter name="template" value="mywmljsp.jsp" hidden="false"/>
   
   
  <media-type ref="wml"/>
   
   
</portlet-entry>
   
   

JSP portlet 注册表片段

注册表片段包括 portlet 的定义。当您将 portlet 的媒体类型指定为 WML 时,该 portlet 的内容将被转换以用于 WML 和移动设备。下面是用于我们刚开发的 portlet 示例的注册表片段

    <portlet-entry name="myhellotestjsp" hidden="false" type="ref"
   
   
        parent="JSP" application="false">
   
   
        <meta-info>
   
   
            <title>MYWMLTESTJSP</title>
   
   
            <description>Simple HELLO JSP Portlet Example</description>
   
   
        </meta-info>
   
   
        <parameter name="template" value="mywmljsp.jsp" hidden="false"/>
   
   
        <media-type ref="wml"/>
   
   
</portlet-entry>
   
   

   
   
    
     
   
   

注册为 HTML 类型的 JSP portlet

该图显示了将媒体类型设置为 HTML,然后将输出包含到 HTML 页面时,我们 JSP portlet 的外观。

 

portlet 注册表

在创建了注册表片段文件之后,必须将它部署到 /WEB-INF/conf 下的 JetspeedJetspeed 注册表中将包含这个目录中扩展名为 .xreg 的任何文件。下列清单说明了用于我们示例的 Jetspeed 注册表页面的内容:

<portlet-entry name="myhellotestjsp" hidden="false" type="ref"
   
   
    parent="JSP" application="false">
   
   
    <meta-info>
   
   
        <title>MYWMLTESTJSP</title>
   
   
        <description>Simple HELLO JSP Portlet Example</description>
   
   
    </meta-info>
   
   
   <parameter name="template" value="mywmljsp.jsp" hidden="false"/>
   
   
    <media-type ref="wml"/>
   
   
</portlet-entry>
  
  

 

 

从门户网站查看 JSP Hello World!

在将 portlet 注册到 Jetspeed 之后,可以通过移动设备在门户网站页面上查看该 portlet 的输出。以下显示了 OpenWave 仿真器中门户网站的 Hello World portlet 的输出:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

n        用于无线的jetspeedRSS

portlet 的无线支持

正如本系列第一篇教程中所演示的,Jetspeed 支持 WAP 设备,而 WAP 浏览器渲染 WML 内容。在本章中,我们将创建两个简单的 RSS portlet 来联合内容,以便在移动设备的 WAP 浏览器上进行查看。这两者在配置和执行上有所不同,但都产生相似的结果。一个称为 LA_Times,使用 RSS 来联合 Latimes.com 网站上的内容,它使其站点上的流专用于 WML 和移动设备。另一个使用本地格式化为 RSS XML 文件。

RSS portlet

 

RSS portlet 可以注册为 WML HTML 媒体类型。注:我们的 RSS portlet 不会为移动设备修改流内容,但您可以修改流内容以使之适用于移动设备。

正如您迄今为止所了解的,每个要包含在门户网站中的 portlet 都必须实现 portlet 核心。处理 RSS portlet 的核心部分之一是名为 rss-wml.xsl XSL 文件。

RSS portlet 位置

正如所提到的,要考虑两部分 RSS portletRSS portlet 代码本身和 rss-wml.xsl,后者是专为处理 WML 的内容而编码的 RSS 处理文件。当您修改实际的 RSS portlet 代码时,就控制了联合的内容;当修改 rss-wml.xsl 时,就控制了联合内容的显示。

RSS portlet 本身位于 <tomcat_home>/<jetspeed_directory>/WEB-INF/classes/com/bluesunrise/portal/portlets/目录。

rss-wml.xsl 处理文件位置

正如您从图中看见的,RSS 处理文件 rss-wml.xsl 位于 <tomcat_home>/<jetspeed_directory>/WEB-INF/xsl/ 目录。

用于 WAP RSS portlet 注册表片段

本图显示了用于 WAP 的无线 RSS portlet 示例的注册表片段:

<media-type ref="wml"/> 标记指示 Jetspeed 解析和利用 rss-wml.xsl 来显示 WAP 内容,因为媒体类型是 WML

RSS portlet 注册表

Jetspeed Customize WML 节包含所有作为 WML 类型注册到 Jetspeed portlet。下列清单说明了用于我们两个 portlet Jetspeed 注册表页面的内容:


   
   
    
     
   
   
<portlet-entry name="wmlchannel" hidden="false" type="ref"
   
   
    parent="RSS" application="false">
   
   
    <meta-info>
   
   
        <title>testWML_RSS</title>
   
   
        <description>JETSPEED RSS Portlet Example</description>
   
   
    </meta-info>
   
   
    <media-type ref="wml"/>
   
   
    <url>/rss/Jetspeed2.rss</url>
   
   
</portlet-entry>
   
   

  
  
   
    
  
  

   
   
    
     
   
   
<portlet-entry name="LA_Times" hidden="false" type="ref"
   
   
    parent="RSS" application="false">
   
   
    <meta-info>
   
   
        <title>LA_Times</title>
   
   
        <description>Simple RSS Portlet Example</description>
   
   
    </meta-info>
   
   
    <parameter name="stylesheet.txt/vnd.wap.wml"
   
   
         value="/WEB-INF/xsl/rss-wml.xsl" hidden="false"/>
   
   
    <media-type ref="wml"/>
   
   
<url>http://www.apacheweek.com/issues/apacheweek-headlines.xml</url>
   
   
</portlet-entry>
   
   

RSS portlet 代码

Jetspeed Customize WML 部分包含所有作为 WML 类型注册到 Jetspeed portlet。下列代码清单用于联合来自本地指定的 RSS 文件中的内容。

<?xml version="1.0"?>
   
   
<rss version="0.91">
   
   
    <channel>
   
   
        <title>Apache Jetspeed</title>
   
   
        <description>
   
   
        RSS for WML.
   
   
        </description>
   
   
        <image>
   
   
            <title>Apache Jetspeed</title>
   
   
            <url>images/jetspeed-powered.gif</url>
   
   
            <link>http://jakarta.apache.org/jetspeed</link>
   
   
        </image>
   
   
        <item>
   
   
            <title>WAP-Apache Jetspeed</title>
   
   
            <link>http://jakarta.apache.org/jetspeed</link>
   
   
            <description>
   
   
            Jetspeed is an Enterprise Information Portal
   
   
            </description>
   
   
        </item>
   
   
    </channel>   
   
   
</rss>
   
   

WAP 电话查看 RSS

下面这两张图是名为 LA_Times 的已注册 RSS portlet 从无线门户内输出的内容。

第一幅图是门户网站视图,第二幅图则展示了名为 LA_Times RSS portlet 的输出。

下一幅图演示了我们第二个 portlet WAP 联合,该 portlet 有一个 Jakarta 链接:

第一幅图展示了门户网站视图,而第二幅图展示了 RSS portlet 本身的输出。

RSS portlet 技巧

Jetspeed 1.3a 2 中,我们发现了一个有趣的行为,必须手工纠正它,以便显示指定用于 WAP RSS portlet。问题在于对 portlet 本身的处理是由两个独立的 XSL 文件执行的。主 Jetspeed XSL 文件负责生成 WML 标记和从初始 WAP 屏幕到实际 RSS portlet 的超级链接,它根据注册表中 portlet 的标题解析 HREF 卡名称。另一方面,这个 Jetspeed 发行版中的 rss-wml.xsl 负责在 WAP 浏览器上显示 RSS portlet,它总是解析出任何形如 <card id="channel"> 的卡。您可以查看原始 rss-wml.xsl 文件中的错误代码:

...
   
   
...
   
   
  <xsl:template match="channel">
   
   
      <xsl:variable name="description" select="description"/>
   
   
      <card id="channel">
   
   
...
   
   
...
   
   
...
   
   
  <xsl:template match="downlevel:channel">
   
   
    <xsl:variable name="description" select="downlevel:description"/>
   
   
    <card id="channle">
   
   
    <p><xsl:apply-templates select="downlevel:title"/>
   
   
...
   
   
...
  
  

上面显示了在两个代码段中引起问题的代码。如果您不修改这个 XSL 文件,就无法将初始 WAP 屏幕与 RSS portlet 的实际详细信息链接起来。因此,我们决定修改 rss-wml.xsl 文件中的这两部分。因为我们用于 WAP RSS portlet 注册表项的名称是 wmlchannel,所以将 rss-wml.xsl 文件中的引用修改为 <card id="_wmlchannel">。有关详细信息,请参阅下列清单。

...
   
   
...
   
   
  <!--Corrected XSL-->
   
   
  <xsl:template match="downlevel:channel">
   
   
      <xsl:variable name="description" select="downlevel:description"/>
   
   
      <card id="_wmlchannel">
   
   
...
   
   
...
   
   
  <!--Corresponding registry entry-->
   
   
  <portlet-entry name="wmlchannel" hidden="false" type="ref"
   
   
       parent="RSS" application="false">
   
   
       <meta-info>
  
  

Jetspeed 所创建的作为结果的超级链接将是 #_wmlchannel,并带有 <card ID="_wmlchannel">

<img src="http://localhost:8080/jetspeed/images/wml/bullet.wbmp" alt=""><a href="#_wmlchannel">testWML_RSS</a><br/>
  
  

因此,看上去 rss_wml.xsl 中的卡标识名称应该与 portlet 注册表项中的名称匹配(除去下划线以外),至少在当前 Jetspeed 发行版中是这样。

 

 

 

n        Portlet回顾

结束语

最新的 Jetspeed 发行版在 HTML portlet 方面已经成熟了,但将它用于 WAP portlet 时,您会遇到几个问题,它们都没有被很好地记录下来。因此,我们特别推荐在此概述的技巧,以便顺利地克服这些问题。

我们确实计划在接下来的 4 6 个月中再次讨论 Jetspeed 平台,并概述可能发布的任何新特性以及改进。

n        参考资料

要获取更多信息、参考资料和工具箱,请参考下列站点:

 

 
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值