使用 Struts portlet 在门户应用程序中实现页面导航

类别:Java 点击:0 评论:0 推荐:

Zeynep Latif([email protected]
软件工程师,IBM
2004 年 6 月

本文描述了如何使用 Struts portlet 框架中内置的多模块支持来组织 Web 导航模式。

引言
Struts 是一个很受欢迎的开放源代码平台基础,它是为了使复杂的 Web 应用程序的创建和维护更加容易而设计的。Struts 框架支持模型-视图-控制器(Model-View-Controller,MVC)模型,并且提出了许多重要的应用程序设计和实现需要注意的事项。为了能够在门户应用程序中实现页面导航,WebSphere® Portal V5 提供了一些标记,在开发典型 portlet 和 Struts portlet 时可将这些标记用于 JavaServer Pages(JSP)。本文重点讨论 Struts 框架创建多模块的能力,并通过一个样本 Struts portlet 应用程序为您介绍如何采用 JSP 实现页面导航方法。

我们将关注以下两种互补的方法: 如何使用在 WebSphere Portal 中可用的某一 JSP 标记来从 JSP 实现页面导航
我们将会看到一个样本应用程序,包括开发环境和门户资源的屏幕快照,以及页面导航方法的代码样本。 如何使用 Struts portlet 框架中内置的多模块支持来组织 Web 导航方案
我们将会看到一些代码样本,它们阐述了如何使用页面导航特征来执行在门户环境中转换的多个 Struts 模块。

本文假定您已基本了解 Struts 应用程序,包括如何在 WebSphere Studio Application Developer 中创建 Struts 应用程序、如何将 Struts 作为 portlet 进行部署,同时也了解 WebSphere Portal 中的门户资源。(要获得这些方面的更多信息,请参见参考资料。)

在开发和部署我们的样本应用程序时用到了以下产品: WebSphere Portal V5.x WebSphere Application Server v5.x 支持 Struts Version 1.1 的 WebSphere Studio Application Developer v5.0.1 (下面称为 Application Developer)。

本文所讲解的用于实现页面导航的开发任务可同时用于标准 portlet 和 Struts portlet。

应用程序概述
在样本应用程序中,我们将会使用位于三个不同页面的三个 portlet。当用户选择其中某一 portlet 中的链接时,该用户会被定向到另一个页面,其中驻留着另一个 portlet。在整个文章中我们开发和提到的示例都会利用多 Struts 模块将 WebSphere Portal 页面导航标记并入门户环境中每个模块本身的 JSP 文件中。图 1 概括性地展示了样本应用程序将如何工作;为了把重点放在理解这些方法上,我们特意简化了样本应用程序。在本文的后面我们将会提供应用程序的细节。

图 1. 样本应用程序的高级视图

构建导航结构
WebSphere Portal 提供了自己的 JSP 标记来供 portlet JSP 使用。其中的一个标记,<wps:URLGeneration attribute="value"/>,是用于创建到门户任何地方的页面链接的。我们使用该标记中一个属性,contentNode="id|name",来创建到不同页面的 URL,以便构建导航结构。该属性利用一个惟一的标识符(内容节点的名称)来指定可以从中找到该 portlet 的页面。(关于这一标记的更多信息请参见参考资料。)

在 WebSphere Portal 中选择 Administration => Portal Settings => Custom Unique Names。我们使用 Custom Unique Names 管理 portlet 来获取为 contentNode 属性指定的门户资源的惟一标识符。管理员可以使用 Custom Unique Names portlet 来查看惟一标识符并为门户资源分配(让人易读的)自定义名称。图 2 显示了这些已配置的样本页面的惟一标识符和自定义名称: Struts_Test Struts_Receiver Struts_Receiver_2

图 2. Custom Unique Names portlet

在这个示例中,WebSphere Portal 分配给这些页面的惟一标识符分别为 6_0_LT、6_0_P1 和 6_0_IP。(您的值可能会有所不同。)在驻留 WebSphere Portal 的另一台机器上也创建了同样的门户资源 Struts_Test、Struts_Receiver 和 Struts_Receiver_2 portlet 页面。为了阅读和工作的方便,我们也为这些样本页面配置自定义名称,并在 JSP 文件中使用这些自定义名称(而不是惟一标记符)。

在 <wps:URLGeneration attribute="value"/> portlet JSP 标记主体中,可以使用 <% wpsURL %> 脚本变量将 URL 直接写入输出流。在这个示例中,我们使用以下 JSP 代码来创建从某一 JSP 页面到 Struts Receiver 页面的链接:

<wps:urlGeneration contentNode="Struts_Receiver_Page"> <A HREF="<%wpsURL.write(out);%>"style="text-decoration:none" > Any text</a> </wps:urlGeneration>

<wps:URLGeneration attribute="value"/> portlet JSP 标记属于 engine.tld 标记库,这一标记库是由门户服务器引擎使用的。为了让该门户 JSP 标记可用于我们的 JSP 中,我们在 JSP 页面的最开始位置添加标记库指示 taglib。如以下代码所示,通过前缀 wps,我们样本中所有的 engine.tld 标记现在就都可用了:

<%@ taglib uri="/WEB-INF/tld/engine.tld" prefix="wps" %>

样本页面和 portlet 配置
该样本应用程序的页面导航条包括三个 portlet(这里提供的长名称有助于强调页面导航流程): Overview Struts Portlet:
显示了两个用于将用户请示定向到包含电话号码或地址信息的页面上的链接,它位于 Struts_Test 页面(自定义名称:Struts_Test_Page),如图 3 所示:

图 3. Struts_Test 页面中的 Overview Struts Portlet

Receive Phone Numbers Request Struts Portlet:
显示用户的电话号码,位于 Struts_Receiver_2 页面(自定义名称:Struts_Receiver_2_Page),如图 4 所示:

图 4. Struts_Receiver_2 页面中的 Receive Phone Numbers Request Struts Portlet

Receive Address Request Struts Portlet:
显示用户地址信息,位于页面(自定义名称:Struts_Receiver_Page),如图 5 所示:

图 5. Struts_Receiver 页面中的 Receive Address Request Struts Portlet

请记住,到目前为止所描述的全部任务均可用于常规 portlet 或 Struts portlet 开发。接下来我们将使用多 Struts 模块中的门户 JSP 标记来实现页面导航。

在 Struts 中使用多模块支持
Struts Version 1.1 可以让我们将单个 Struts 应用程序拆分为多个模块,每个模块都有自己的操作、JSP 页面和 Struts 配置文件(图 6)。在 Struts 应用程序中实现多 Struts 模块需要以下几个步骤: 创建独立的 Struts 配置文件以及每个应用程序模块的 Struts 操作和 JSPs。 配置 Web 部署描述符(web.xml)。 从一个模块转换到另一个模块。

虽然 Struts 应用程序很容易应用,但要想在门户环境中运行 Struts 应用程序的话,您还需要执行其他的步骤。(参见参考资料)。

图 6. Struts 应用程序中的多模块支持

创建独立的 Struts 模块和文件
对于我们的样本应用程序,我们创建了四个 Struts 模块,以及它们自己的 Struts 配置文件、行为和 JSPs。这些 Struts 模块是: address phone-numbers overview default.

我们也配置了 web.xml 和 portlet.xml 文件,并使用 default 模块执行从一个模块到另一个模块的转换。

接下来,我们将会根据实现的需要讲解我们的文件需要的改动。

在 Struts 模块中开发页面导航
我们在以下三个模块中实现页面导航: overview address phone-numbers.

除了存在一些细微的差别以外,这些模块中每一个的页面导航开发任务几乎都是相同的。因此,我们将讲解实现 overview 模块的页面导航的任务,然后再描述一下其他模块的实现任务与此的差别。此外,我们还会讲解特定于 Struts 模块的开发过程,该模块是为 default 模块而转换的。在我们的实现中,default 模块用于将控制权交给下一个适当的模块;并不需要页面导航。然而,由于它启动其他模块来执行模块转换并且是导航结构的一个主要部分,所以我们这里也将它包括在内。

在 Application Developer 中,我们创建一个支持 Struts Version 1.1 的 Web 项目,然后为开发任务创建文件,如下面的表 1 所示。

表 1. 开发构件列表

以下是表 1 所示构件的简要描述: JSP 文件:
我们开发了五个 JSP 文件: 用于 default 模块的 index.jsp 和 failure.jsp 文件; 用于 address 模块的 address.jsp 文件; 用于 phone-numbers 模块的 phone-numbers.jsp 文件; 用于 overview 模块的 overview.jsp 文件。 操作:
我们在 com.test.strutstest.actions 包中创建四个 Struts 操作。它们的类为: DisplayAction DisplayAddressInfoAction DisplayPhoneInfoAction OverviewAction. 表单 bean:
我们在 com.test.strutstest.forms 包中创建两个表单 bean。它们的类为: UserFormBean OverviewFormBean. 后端 bean 和模型类:
我们在包中使用一个后端 bean 类(UserBean )和一个模型类(UserBeanHelper)。(后端 bean 包含存根数据,并不与真正后端进行通信。) Struts 配置文件:
我们开发了四个 struts-config.xml 文件,每个模块使用一个: 用于 default 模块的 WEB-INF/struts-config.xml 用于 address 模块的 WEB-INF/address/struts-config.xml 用于 phone-numbers 模块的 WEB-INF/phone-numbers/struts-config.xml 用于 overview 模块的 WEB-INF/overview/struts-config.xml。 其他配置文件:
在将 Struts 应用程序作为 portlet 进行部署时需要修改 web.xml 和 portlet.xml 文件。

以上的每一个配置文件都包含下列请求处理器(Request Processor):

<controller processorClass="com.ibm.wps.portlets.struts.WpsRequestProcessor" >

图 7 显示了在 Application Developer 开发环境中开发构件的位置:

图 7. WebSphere Studio Application Developer 中的开发构件的位置

配置 default 模块
要想启动 default 模块并查看它如何在 Struts 模块之间进行转换,需要执行以下步骤: Default 模块是在 WebSphere Portal 调用 index.jsp 文件时启动的,这是在 web.xml 文件中的 <welcome-file-list> 标记中指定的:

<welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list>

调用 index.jsp 时,在 logic Struts 标记中指定逻辑转发名 Display:

<logic:forward name="Display"/>

将 default 模块的 struts-config.xml 文件中的逻辑 forward name(在此为 Display)定义为全局转发:

<global-forwards> <forward name="Display" path="/display.do"/> </global-forwards>

在 <global-forwards> 部分中,使逻辑全局转发上下文关系路径 path="/ display.do" 与 <action-mappings> 部分中的操作元素的上下文关系路径 path="/display" 路径相匹配。这一匹配可以启动 DisplayAction 操作。操作映射部分(包括带有 path 和 type 属性的 <action> 元素)如下所示:

<action-mappings> <action path="/display" type="com.test.strutstest.actions.DisplayAction"> ................................................. </action> </action-mappings>

为了启用模块转换,请为 remaining 模块配置 default 模块的 struts-config.xml、portlet.xml 和 config.xml 文件: 配置 default 模块的 struts-config.xml 文件。我们使用 DisplayAction 作为我们的操作类和四个逻辑转发:

<action-mappings> <action path="/display" type="com.test.strutstest.actions.DisplayAction"> <forward name="failure" contextRelative="true" path="/failure.jsp"/> <forward name="address" contextRelative="true" path="/address/start.do"/> <forward name="phone-numbers" contextRelative="true" path="/phone-numbers/start.do"/> <forward name="overview" contextRelative="true" path="/overview/start.do"/> </action> </action-mappings>

配置 portlet.xml 文件,使之符合 default 模块的 struts-config.xml 文件中的配置。特别是,在 default 模块的 struts-config.xml 文件中的四个逻辑转发名称中的每一个均要与在 portlet.xml 文件中设置的 view.forward 配置参数值相匹配。表 2 显示了这一映射关系:

表 2. view.forward 配置值对转发名称配置值
表 2. view.forward 配置值对转发名称配置值" src="http://www-900.ibm.com/developerworks/cn/wsdd/techjournal/0404_latif/0404_latif_images/table_2_view_forward.gif" width=493>

配置 web.xml 文件来定义不同的模块。我们使用 config 初始化参数来将我们的 default 模块告知操作 servlet;然而,对于其他的每个模块,我们列出了一个名为 config/module 的初始化参数,其中 module 是我们的模块名称。例如: 可以这样定义 default 模块:

<init-param> <param-name>config</param-name> <param-value>WEB-INF/struts-config.xml</param-value> </init-param>

可以这样定义其他模块:

<init-param> <param-name>config/address</param-name> <param-value>WEB-INF/address/struts-config.xml </param-value> </init-param> <init-param> <param-name>config/phone-numbers</param-name> <param-value>WEB-INF/phone-numbers/struts-config.xml </param-value> </init-param> <init-param> <param-name>config/overview</param-name> <param-value>WEB-INF/overview/struts-config.xml </param-value> </init-param>

(其他模块配置和必要的 web.xml 配置设置请参见参考资料。)

对 web.xml 和 portlet.xml 文件执行标准更新来将 Struts 应用程序作为 portlet 进行部署。(要获得更多信息请参见参考资料和下载部分的样本 web.xml 和 portlet.xml 文件。)

正如 default 模块的 struts-config.xml 文件中的 <action-mapping> 部分所配置的,模块转换是在 DisplayAction 类中进行的。要想确定 WebSphere Portal 调用的是哪个模块,可以执行以下的步骤: 调用 DisplayAction 类的 execute() 方法时,访问的是在 portlet.xml 文件中设置的 view.forward 参数:

PortletSettings portletSettings = request.getPortletSettings(); String viewForward = portletSettings.getAttribute("view.forward");

对于我们的 portlet 来说,view.forward 参数会有以下的值:

表 3. 样本 portlet 的 view.forward 配置参数的值

如果 viewForward 为空,那么在 execute() 方法中会将这一变量设置为 failure。 已配置的 viewForward 值的转发映射是从 struts-config.xml 文件检索的:

ActionForward forward = new ActionForward(); try { forward = mapping.findForward(forwardName); } catch (Exception e) { ........................................... }

execute() 方法中的最后步骤返回 ActionForward(forward)的实例:

return (forward);

配置其他 struts-config.xml 文件。根据 DisplayAction 类中的模块确定结果,如果 view.forward 参数值为: address:

default 模块的 struts-config.xml 文件的 <action-mappings> 部分中匹配的 start 路径会使 DisplayAddressInfoAction 在 address 模块中调用。根据 web.xml 中的配置,这一过程需要使用到 address/struts-config.xml 文件。address/struts-config.xml 文件包含以下的设置:

<!-- ===== Global Forward Definitions ===== --> <global-forwards> <forward name="start" path="/start.do"/> </global-forwards> <!-- ===== Action Mapping Definitions ===== --> <action-mappings> <action path="/start" type="com.test.strutstest.actions.DisplayAddressInfoAction" name="userFormBean" scope="request"> <forward name="success" path="/address.jsp"/> </action </action-mappings>

phone-numbers:

default 模块的 struts-config.xml 文件的 <action-mappings> 部分中匹配的 start 路径会使 DisplayPhoneInfoAction 在 phone-numbers 模块中调用。根据 web.xml 文件中的配置,这一过程需要使用到 phone-numbers/struts-config.xml 文件。phone-numbers/struts-config.xml 文件包含以下的设置:

<!-- ===== Global Forward Definitions ===== --> <global-forwards> <forward name="start" path="/start.do"/> </global-forwards> <!-- ===== Action Mapping Definitions ===== --> <action-mappings> <action path="/start" type="com.test.strutstest.actions.DisplayPhoneInfoAction" name="userFormBean" scope="request"> <forward name="success" path="/phone-numbers.jsp"/> </action </action-mappings>

overview:

default 模块的 struts-config.xml 文件的 <action-mappings> 部分中匹配的 start 路径会使 OverviewAction 在 overview 模块中调用。根据 web.xml 文件中的配置,这一过程需要使用到 overview/struts-config.xml 文件。overview/struts-config.xml 包含以下的设置:

<!-- ===== Global Forward Definitions ===== --> <global-forwards> <forward name="start" path="/start.do"/> </global-forwards> <!-- ===== Action Mapping Definitions ===== --> <action-mappings> <action path="/start" type="com.test.strutstest.actions.OverviewAction" name="overviewFormBean" scope="request"> <forward name="success" path="/Overview.jsp"/> </action> </action-mappings>

failure:

根据 default 模块的 struts-config.xml 文件中的配置,这种参数值下会启动 failure.jsp。

到目前为止,我们已经创建了表 1 中所列出的文件,并根据我们的示例需要,对其中的大部分做了修改。现在我们就可以开始编写代码来实现使用 overview 模块的页面导航。以下部分将通过具体步骤指导您完成这一过程。

开发 overview 模块
要想生成 Overview.jsp 文件、OverviewAction 类、OverviewFormBean 类和 overview/struts-config.xml 文件来开发 Overview Struts portlet,请在操作类和 JSP 文件中遵循这些开发任务:

一旦控制权从 default 模块转移到 Overview 模块,OverviewAction 类中的 execute() 方法会执行以下这些任务: 访问 OverviewFormBean 表单 bean 并设置以下属性:

try { String forwardName = null; if (form == null) { form = (ActionForm) request.getAttribute("overviewFormBean"); } //Set-up form bean fields OverviewFormBean formBean = (OverviewFormBean) form; formBean.setPhoneNumbersLinkName("List Phone Numbers"); formBean.setAddressLinkName("Address Information"); ...................................................

在正确的作用域内存储该表单 bean:

try { //Store the bean in the correct scope if ("request".equals(mapping.getScope())) request.setAttribute(mapping.getName(), formBean); else session.setAttribute(mapping.getName(), formBean); } catch (Exception e) { .................................. }

在 overview/struts-config.xml 中查找映射并返回一个 ActionForward 类型的对象:

String forwardName = null; ActionForward forward = new ActionForward(); ....................................... //If no errors occur then look for "success" try { forward = mapping.findForward(forwardName); if (forward != null) { ..................................... } else ..................................... } catch(Exception e) { ................................... } return (forward);

如果在操作类的处理过程中没有出现错误,那么根据我们在 overview/struts-config.xml 文件中的配置,转发名称 success 会允许启动 Overview.jsp。 Overview.jsp 显示两个链接,指向已开发的其他 portlet——Receive Phone Numbers Request Struts Portlet 和 Receive Address Request Struts Portlet。我们使用页面导航方法和 Struts 标记来实现这一特征: 在 JSP 页面的最开始的地方使用 taglib 指示来使所有的 engine.tld 标记可用于剩余的带有 prefix.wps 的 JSP 页面。

<%@ taglib uri="/WEB-INF/tld/engine.tld" prefix="wps" %>

在 <wps:urlGeneration> portlet 标记中使用 contentNode 参数来指定驻留其他 portlet 的页面的惟一标识符或自定义名称。为了启动到 Receive Address Request Struts Portlet(位于 Struts_Receiver 页面)的页面导航,我们使用了自定义名称 Struts_Receiver_Page:

<wps:urlGeneration contentNode="Struts_Receiver_Page"> <A HREF="<%wpsURL.write(out);%>"style="text-decoration:none" > <bean:write name="overviewFormBean" property="addressLinkName" /></a> </wps:urlGeneration>

为了启动到 Receive Phone Numbers Request Struts Portlet(位于 Struts_Receiver_2 页面)的页面导航,我们使用自定义名称 Struts_Receiver_2_Page:

<wps:urlGeneration contentNode="Struts_Receiver_2_Page"> <A HREF="<%wpsURL.write(out);%>"style="text-decoration:none" > <bean:write name="overviewFormBean" property="phoneNumbersLinkName" /></a> </wps:urlGeneration>

这样我们就从 My Pages 和惟一名称列表获得了页面的自定义名称,如图 2 所示。 在 overview 模块中,我们使用 <bean:write>、<html:html> 和 <html:form> Struts 标记。实现这些标记需要以下的步骤: 声明 html 和 bean 前缀:

<%@ taglib uri="/WEB-INF/tld/struts-html.tld" prefix="html" %> <%@ taglib uri="/WEB-INF/tld/struts-bean.tld" prefix="bean" %>

<html:html> Struts 标记:如果在用户会话中有可用的当前地点,就会以适当的语言属性来呈现 HTML 元素。 <html:form> Struts 标记:用于在 Struts 中的所有 HTML 表单处理。form 元素必须始终包含 action 属性。action 属性必须符合 struts-config.xml 中的有效操作。在 Overview.jsp 文件中,我们使用 form 元素和它的 action 属性:

<html:form action="/start">

start 属性映射 overview/struts-config.xml 文件中的下列操作:

<action-mappings> <action path="/start" type="com.test.strutstest.actions.OverviewAction" name="overviewFormBean" scope="request"> <forward name="success" path="/Overview.jsp"/> </action> </action-mappings>

Struts 标记将表单字段和 Struts 中的表单 bean 连结在一起。根据用于相关联的 ActionMapping 的表单 bean 规范定位(或生成,如果有必要)表单 bean。我们在 overview/struts-config.xml 文件中定义的表单 bean 为 UserFormBean:

<form-beans> <form-bean name="overviewFormBean" type="com.test.strutstest.forms.OverviewFormBean"/> </form-beans>

<bean:write> Struts 标记的使用:

这一通用标记用于从 bean 输出特性值。在 Overview.jsp 文件中,它显示 <bean:write> 来显示在 UserFormBean 表单 bean 中设置的文本数据。我们使用这一标记来显示 UserFormBean 的某些特性,如下所示:

<bean:write name="overviewFormBean" property="addressLinkName" /> <bean:write name="overviewFormBean" property="phoneNumbersLinkName" />

开发其余的模块
开发 address 和 phone-numbers 模块与开发 overview 模块非常类似,不同之处在于: address 模块实现 Receive Address Request Struts Portlet 使用的是: address.jsp DisplayAddressInfoAction class UserFormBean form bean class UserBean backend bean class UserBeanHelper model class address/struts-config.xml file. phone-numbers 模块实现 Receive Phone Numbers Request Struts Portlet 使用的是: phone-numbers.jsp DisplayPhoneInfoAction class UserFormBean form bean class UserBean backend bean class UserBeanHelper model class phone-numbers/struts-config.xml.

对于 address 和 phone-numbers 模块,我们使用的都是后端 UserBean bean 类和 UserBeanHelper 模型类,这两个类都需要使用存根数据来模拟用户信息,而存根数据是使用我们的模块类在后端 bean 中设置的。这两个模块都使用同样的表单 bean。

要在 DisplayAddressInfoAction 类中开发 address 模块需要做的是:

一旦控制权从 default 模块转移到 address 模块,DisplayAddressInfoAction 类的 execute() 方法就会执行以下任务: 访问表单 bean——UserFormBean,并设置以下属性:

try { String forwardName = null; if (form == null) { form = (ActionForm) request.getAttribute("userFormBean"); } //Set-up form bean fields UserFormBean formBean = (UserFormBean) form; setFormBean(formBean); ...................................................

在正确的作用域中存储该表单 bean:

try { ........................................ //Store the bean in the correct scope if ("request".equals(mapping.getScope())) request.setAttribute(mapping.getName(), formBean); else session.setAttribute(mapping.getName(), formBean); } catch (Exception e) { .................................. }

在 address/struts-config.xml 中查找映射,并返回一个 ActionForward 类型的对象:

String forwardName = null; ActionForward forward = new ActionForward(); ....................................... //If no errors occur then look for "success" try { forward = mapping.findForward(forwardName); if (forward != null) { ..................................... } else ..................................... } catch(Exception e) { ................................... } return (forward);

调用 setFormBean(UserFormBean formBean)。这一方法获得该模型的单个实例:

UserBeanHelper userBeanHelper = UserBeanHelper.getInstance();

这一实例植入后端数据,设置 UserFormBean 的实例对象,并使用以下方法调用返回该对象:

UserFormBean userFormBean = userBeanHelper.getUserFormBean();

这一方法和适当的 getter 和 setter 方法一同设置 formBean 的属性,如下所示,其中使用从模型返回的对象实例:

public void setFormBean(UserFormBean formBean) { UserBeanHelper userBeanHelper = UserBeanHelper.getInstance(); UserFormBean userFormBean = userBeanHelper.getUserFormBean(); //These two parameters are just text values to be displayed on the browser formBean.setAddress("Address"); formBean.setUserName("UserName"); //Setting the formBean object attributes with data obtained from the backend formBean.setAddressValues(userFormBean.getAddressValues()); formBean.setUserNameValues(userFormBean.getUserNameValues()); }

如果在操作类处理过程中没有出现错误,那么转发名称 success 会根据我们在 address/struts-config.xml 文件中的配置启动待启动的 address.jsp 文件。

经过适当的修改,以上的步骤可重复用于开发 phone-number 模块。

页面导航
用于 Receive Address Request Struts Portlet 和 Receive Phone Numbers Request Struts Portlet 的 address.jsp 和 phone-numbers.jsp 文件都是使用 Overview Struts Portlet 和 Struts 标记执行页面导航的: 在 JSP 页面的最前端使用 taglib 标记库指示来使所有的 engine.tld 标记可用于剩余的带有 prefix.wps 的 JSP 页面。

<%@ taglib uri="/WEB-INF/tld/engine.tld" prefix="wps" %>

使用 <wps:urlGeneration> portlet 标记中的 contentNode 参数来调用到 Overview Struts Portlet 的页面导航。这需要指定 Overview Struts Portlet 所在的 Struts_Test 页面的自定义名称或惟一标记符。我们使用的是自定义名称 Struts_Test_Page,它是从 My Pages 和惟一名称列表中获得的,如图 2 所示。

<wps:urlGeneration contentNode="Struts_Test_Page"> <A href="<%wpsURL.write(out);%>" style="text-decoration: none"> <B>Go to Overview Struts Portlet</B></A> </wps:urlGeneration></TD>

在我们的实现中,address.jsp 和 phone-numbers.jsp 文件中均使用 <logic:iterate> Struts 标记。这一标记遍历了集合中的元素,它可以是一个属性,也可以是一个属性的特性: 声明 logic 前缀:

<%@ taglib uri="/WEB-INF/tld/struts-logic.tld" prefix="logic" %>

使用 <logic:iterate> Struts 标记;我们在 UserFormBean 操作表单中使用 userNameValues 字符串组。以下代码显示了在该操作表单中设置的用户名称:

<logic:iterate id="test" name="userFormBean" property="userNameValues" indexId="index">

建立开发环境和安装样本代码
要想在 Application Developer 中创建自己的开发环境,请使用在为 WebSphere Portal 4.2 开发 Struts 应用程序和 用 WebSphere Studio V5 编写一个简单的 Struts 应用程序 中提供的信息。您需要将下载部分的 StrutsTest.war 文件导入 Application Developer,并使用它所有的 JAR 文件。在 WebSphere Portal 中安装样本代码不需要任何特殊的安装步骤;您可以使用所包含的 WAR 文件,也可以使用一个新的 WAR 文件,愿意用哪一个都可以。

结束语
本文通过一个 portlet 标记描述由 WebSphere Portal 提供的页面导航特征,同时也描述由 Struts 门户框架所提供的多模块支持。在我们的样本实现中,我们创建了应用程序所在的门户页面,然后将 portlet JSP 标记合并在适当的 JSP 中。我们在 JSP 中使用页面的自定义名称而不是由门户服务器分配的惟一标记符,这使我们的 JSP 部署相对独立。

虽然我们的示例并不是一个很复杂的应用程序,但 Struts 所提供的框架能够很好地处理大而复杂的应用程序流。多模块支持为每个支持并行开发的模块提供单个的文件组,同时也提供更好的文件组织,多模块支持可以与 WebSphere Portal JSP 标记提供的页面导航方法一起协调工作。

致谢
作者真诚地感谢 Tim Hanis 和 Jim Bonanno 作为技术评论家对本文所做的评论和贡献。

参考资料 WebSphere Portal Information Center for V5.0:为 WebSphere Portal 提供快速而集中的信息。重要的方面包括: Developing Portlets => Struts Portlet Framework => Changes to configuration files Developing Portlets => Struts Portlet Framework => Migrating existing Struts Applications Developing Portlets => JSP tag reference
The Jakarta Apache Struts Web Application Framework's User and Developer Guides

用 WebSphere Studio V5 编写一个简单的 Struts 应用程序

开发和部署一个作为 WebSphere Portal V5 Portlet 的 Struts 应用程序

将状态模式应用于 WebSphere Portal V5 Portlet——第 1 部分:概述

将状态模式应用于 WebSphere Portal Portlet

为 WebSphere Portal 4.2 开发 Struts 应用程序

本文地址:http://com.8s8s.com/it/it13230.htm