Struts 是一个很受欢迎的开放源代码平台基础,它是为了使复杂的 Web 应用程序的创建和维护更加容易而设计的。Struts 框架支持模型-视图-控制器(Model-View-Controller,MVC)模型,并且提出了许多重要的应用程序设计和实现需要注意的事项。为了能够在门户应用程序中实现页面导航,WebSphere® Portal V5 提供了一些标记,在开发典型 portlet 和 Struts portlet 时可将这些标记用于 JavaServer Pages(JSP)。本文重点讨论 Struts 框架创建多模块的能力,并通过一个样本 Struts portlet 应用程序为您介绍如何采用 JSP 实现页面导航方法。
我们将关注以下两种互补的方法:
本文假定您已基本了解 Struts 应用程序,包括如何在 WebSphere Studio Application Developer 中创建 Struts 应用程序、如何将 Struts 作为 portlet 进行部署,同时也了解 WebSphere Portal 中的门户资源。(要获得这些方面的更多信息,请参见参考资料。)
在开发和部署我们的样本应用程序时用到了以下产品:
本文所讲解的用于实现页面导航的开发任务可同时用于标准 portlet 和 Struts portlet。
应用程序概述
在样本应用程序中,我们将会使用位于三个不同页面的三个 portlet。当用户选择其中某一 portlet 中的链接时,该用户会被定向到另一个页面,其中驻留着另一个 portlet。在整个文章中我们开发和提到的示例都会利用多 Struts 模块将 WebSphere Portal 页面导航标记并入门户环境中每个模块本身的 JSP 文件中。图 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 attribute="value"/>
portlet JSP 标记属于 engine.tld
标记库,这一标记库是由门户服务器引擎使用的。为了让该门户 JSP 标记可用于我们的 JSP 中,我们在 JSP 页面的最开始位置添加标记库指示 taglib
。如以下代码所示,通过前缀 wps
,我们样本中所有的 engine.tld
标记现在就都可用了:
|
样本页面和 portlet 配置
该样本应用程序的页面导航条包括三个 portlet(这里提供的长名称有助于强调页面导航流程):
Struts_Test
页面(自定义名称:Struts_Test_Page
),如图 3 所示:
Struts_Receiver_2
页面(自定义名称:Struts_Receiver_2_Page
),如图 4 所示:
图 4. Struts_Receiver_2 页面中的 Receive Phone Numbers 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 模块需要以下几个步骤:
web.xml
)。
虽然 Struts 应用程序很容易应用,但要想在门户环境中运行 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 所示构件的简要描述:
default
模块的 index.jsp
和 failure.jsp
文件;
address
模块的 address.jsp
文件;
phone-numbers
模块的 phone-numbers.jsp
文件;
overview
模块的 overview.jsp
文件。com.test.strutstest.actions
包中创建四个 Struts 操作。它们的类为:
com.test.strutstest.forms
包中创建两个表单 bean。它们的类为:
UserFormBean
OverviewFormBean
.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
。web.xml
和 portlet.xml
文件。以上的每一个配置文件都包含下列请求处理器(Request Processor):
|
图 7 显示了在 Application Developer 开发环境中开发构件的位置:
图 7. WebSphere Studio Application Developer 中的开发构件的位置
配置 default 模块
要想启动 default
模块并查看它如何在 Struts 模块之间进行转换,需要执行以下步骤:
index.jsp
文件时启动的,这是在 web.xml
文件中的 <welcome-file-list>
标记中指定的:
|
index.jsp
时,在 logic
Struts 标记中指定逻辑转发名 Display
:
|
default
模块的 struts-config.xml
文件中的逻辑 forward name
(在此为 Display
)定义为全局转发:
|
<global-forwards>
部分中,使逻辑全局转发上下文关系路径 path
="/ display.do"
与 <action-mappings>
部分中的操作元素的上下文关系路径 path="/display"
路径相匹配。这一匹配可以启动 DisplayAction 操作。操作映射部分(包括带有 path
和 type
属性的 <action>
元素)如下所示:
|
为了启用模块转换,请为 remaining 模块配置 default
模块的 struts-config.xml
、portlet.xml
和 config.xml
文件:
default
模块的 struts-config.xml
文件。我们使用 DisplayAction 作为我们的操作类和四个逻辑转发:
|
portlet.xml
文件,使之符合 default
模块的 struts-config.xml
文件中的配置。特别是,在 default
模块的 struts-config.xml
文件中的四个逻辑转发名称中的每一个均要与在 portlet.xml
文件中设置的 view.forward
配置参数值相匹配。表 2 显示了这一映射关系:
web.xml
文件来定义不同的模块。我们使用 config
初始化参数来将我们的 default
模块告知操作 servlet;然而,对于其他的每个模块,我们列出了一个名为 config/module
的初始化参数,其中 module
是我们的模块名称。例如:
default
模块:
|
|
(其他模块配置和必要的 web.xml
配置设置请参见参考资料。)
web.xml
和 portlet.xml
文件执行标准更新来将 Struts 应用程序作为 portlet 进行部署。(要获得更多信息请参见参考资料和下载部分的样本 web.xml
和 portlet.xml
文件。)正如 default
模块的 struts-config.xml
文件中的 <action-mapping>
部分所配置的,模块转换是在 DisplayAction 类中进行的。要想确定 WebSphere Portal 调用的是哪个模块,可以执行以下的步骤:
portlet.xml
文件中设置的 view.forward
参数:
|
view.forward
参数会有以下的值:
表 3. 样本 portlet 的 view.forward 配置参数的值
viewForward
为空,那么在 execute() 方法中会将这一变量设置为 failure
。
viewForward
值的转发映射是从 struts-config.xml
文件检索的:
|
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
文件包含以下的设置:
|
phone-numbers:
default
模块的 struts-config.xml
文件的 <action-mappings>
部分中匹配的 start
路径会使 DisplayPhoneInfoAction 在 phone-numbers
模块中调用。根据 web.xml
文件中的配置,这一过程需要使用到 phone-numbers/struts-config.xml
文件。phone-numbers/struts-config.xml
文件包含以下的设置:
|
overview:
default
模块的 struts-config.xml
文件的 <action-mappings>
部分中匹配的 start
路径会使 OverviewAction 在 overview
模块中调用。根据 web.xml
文件中的配置,这一过程需要使用到 overview/struts-config.xml
文件。overview/struts-config.xml
包含以下的设置:
|
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 并设置以下属性:
|
|
overview/struts-config.xml
中查找映射并返回一个 ActionForward
类型的对象:
|
overview/struts-config.xml
文件中的配置,转发名称 success
会允许启动 Overview.jsp
。Overview.jsp
显示两个链接,指向已开发的其他 portlet——Receive Phone Numbers Request Struts Portlet 和 Receive Address Request Struts Portlet。我们使用页面导航方法和 Struts 标记来实现这一特征:
taglib
指示来使所有的 engine.tld
标记可用于剩余的带有 prefix.wps
的 JSP 页面。
|
<wps:urlGeneration>
portlet 标记中使用 contentNode
参数来指定驻留其他 portlet 的页面的惟一标识符或自定义名称。为了启动到 Receive Address Request Struts Portlet(位于 Struts_Receiver 页面)的页面导航,我们使用了自定义名称 Struts_Receiver_Page
:
|
Struts_Receiver_2
页面)的页面导航,我们使用自定义名称 Struts_Receiver_2_Page
:
|
overview
模块中,我们使用 <bean:write>
、<html:html>
和 <html:form>
Struts 标记。实现这些标记需要以下的步骤:
html
和 bean
前缀:
|
<html:html>
Struts 标记:如果在用户会话中有可用的当前地点,就会以适当的语言属性来呈现 HTML 元素。
<html:form>
Struts 标记:用于在 Struts 中的所有 HTML 表单处理。form
元素必须始终包含 action
属性。action 属性必须符合 struts-config.xml
中的有效操作。在 Overview.jsp
文件中,我们使用 form
元素和它的 action
属性:
|
start
属性映射 overview/struts-config.xml
文件中的下列操作:
|
Struts 标记将表单字段和 Struts 中的表单 bean 连结在一起。根据用于相关联的 ActionMapping 的表单 bean 规范定位(或生成,如果有必要)表单 bean。我们在 overview/struts-config.xml
文件中定义的表单 bean 为 UserFormBean
:
|
<bean:write>
Struts 标记的使用:
这一通用标记用于从 bean 输出特性值。在 Overview.jsp
文件中,它显示 <bean:write>
来显示在 UserFormBean
表单 bean 中设置的文本数据。我们使用这一标记来显示 UserFormBean
的某些特性,如下所示:
|
开发其余的模块
开发 address
和 phone-numbers
模块与开发 overview
模块非常类似,不同之处在于:
address
模块实现 Receive Address Request Struts Portlet 使用的是:
address.jsp
address/struts-config.xml
file.phone-numbers
模块实现 Receive Phone Numbers Request Struts Portlet 使用的是:
phone-numbers.jsp
phone-numbers/struts-config.xml.
对于 address
和 phone-numbers
模块,我们使用的都是后端 UserBean bean 类和 UserBeanHelper 模型类,这两个类都需要使用存根数据来模拟用户信息,而存根数据是使用我们的模块类在后端 bean 中设置的。这两个模块都使用同样的表单 bean。
要在 DisplayAddressInfoAction 类中开发 address
模块需要做的是:
一旦控制权从 default
模块转移到 address
模块,DisplayAddressInfoAction 类的 execute() 方法就会执行以下任务:
UserFormBean
,并设置以下属性:
|
|
address/struts-config.xml
中查找映射,并返回一个 ActionForward
类型的对象:
|
setFormBean(UserFormBean formBean)
。这一方法获得该模型的单个实例:
|
这一实例植入后端数据,设置 UserFormBean
的实例对象,并使用以下方法调用返回该对象:
|
这一方法和适当的 getter 和 setter 方法一同设置 formBean
的属性,如下所示,其中使用从模型返回的对象实例:
|
如果在操作类处理过程中没有出现错误,那么转发名称 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 标记执行页面导航的:
taglib
标记库指示来使所有的 engine.tld
标记可用于剩余的带有 prefix.wps
的 JSP 页面。
|
<wps:urlGeneration>
portlet 标记中的 contentNode
参数来调用到 Overview Struts Portlet 的页面导航。这需要指定 Overview Struts Portlet 所在的 Struts_Test 页面的自定义名称或惟一标记符。我们使用的是自定义名称 Struts_Test_Page,它是从 My Pages 和惟一名称列表中获得的,如图 2 所示。
|
address.jsp
和 phone-numbers.jsp
文件中均使用 <logic:iterate>
Struts 标记。这一标记遍历了集合中的元素,它可以是一个属性,也可以是一个属性的特性:
logic
前缀:
|
<logic:iterate>
Struts 标记;我们在 UserFormBean
操作表单中使用 userNameValues
字符串组。以下代码显示了在该操作表单中设置的用户名称:
|
建立开发环境和安装样本代码
要想在 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 作为技术评论家对本文所做的评论和贡献。
关于作者 Zeynep Latif 是一名软件工程师,作为一名应用程序开发人员在 IBM 的 Software Group System House(位于北卡罗来纳州的 Research Triangle Park)工作。她与同事一起负责验证所选的基于客户的业务场景,以改善客户对 Software Group 产品特别是这些产品的集成的体验。以前她是 VisualAge Generator 项目的一名开发人员。 |
到页首 | |
描述 | 文件类型 | 文件大小 | 下载方式 |
StrutsTest.zip | zip | 1.5 MB | HTTP |