扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
利用 Struts 的灵活性
BEA引入了 Webflow/Pipeline 框架来开发 Web 应用程序,将其作为Struts的替代品。Webflow 框架与 Struts 同样基于 Model-View-Controller 模式,并且能够带来与其他任何基于 MVC 的框架类似的收益。然而 Webflow 使用了 BEA 和 WebLogic 的专有库,这使得使用 Webflow 编写的应用程序只能运行在 WebLogic 应用服务器之上,而且整合新功能的灵活性非常有限。许多 IT 组织都意识到了这些缺点,他们迫切希望迁移到像Struts这样的开源框架,以便利用其提供的灵活性和可维护性。
本文为计划迁移或正在迁移 Web 应用程序的开发人员和架构师撰写,解释了如何使用Rational Application Developer(以下称为 RAD)将用Webflow开发的Web应用程序迁移到Struts。读者应对熟练掌握 Java 编程,并且基本了解 Struts 框架和 RAD 测试环境。
在本文中,您将查看对一个使用 WebLogic 框架编写的简单 Web 应用程序所做的分析,还会逐步见证如何有效地向 Struts 迁移各种组件。
Webflow 应用程序分析
正如 Brian Pontarelli 和 Grant Zemont撰写的 “Go with the Flow”(JavaWorld,2003年2月)中所描述的那样,Webflow 完全是由表示 Web 应用程序中一个对象的节点和抽象组件构成。节点由转换或事件连接在一起: 初始 JSP(JavaServer Pages) >输入处理器> 目标 JSP。其中的每个> 符号都是 Webflow 系统所处理的一个事件。因此,Webflow 就是一系列彼此连接的节点,用来勾勒Web 应用程序一部分的逻辑流。
使用 BEA Webflow/Pipeline 架构编写的典型 Web 应用程序包含以下组件:
BEA提供的用于视图的标签库
Pipeline 组件和 Pipeline 会话
输入处理器
Webflow API 和属性文件
Webflow 应用程序的核心是一个名为 webflow.properties 的属性文件,它控制着 Web 页面的显示,并负责启动与这些页面相关的业务逻辑的执行。Webflow 属性文件中包含针对各JSP页面的部分,每部分对应于一个JSP页面。
一般来说,webflow.properties 文件中的每个转换都可编写为:
下表描述了不同 webflow.properties 元素的有效值。
元素 有效值
例如,webflow.properties 文件中的一个典型条目可能类似于login.jsp.button(createUser)=mypage.jsp。此处,当前状态为 login.jsp。事件是一个名为 createUser 的按钮,而结果状态是 nextpage.jsp。值得注意的是,这里并不包含输入处理器或者 Pipeline 组件。在登录 JSP 页面中,表单标签会使用 WebFlowJSPHelper API 来为下一个页面创建 URL。具体来说, webflow.properties 文件中的 URL 包含了页面名称以及与当前状态相符的事件:
FORM method="post" action="<%=WebflowJSPHelper.createWebflowURL(pageContext,
"login.jsp", button(createUser)", false)%>">
您可以在 JSP 页面的开头包含WebFlowJSPHelper 类,具体如下:<%@ page import="com.beasys.commerce.webflow.WebflowJSPHelper" %>
本例说明了一个简单的情景,即通过点击(createUser)按钮就可以实现一个 JSP页面与另一个 JSP 页面之间的导航。然而,webflow.properties 文件中的状态并不受限于其他的 Web 页面。通常,您可以整合输入处理器(Webflow 操作类)将流导向一些业务逻辑类或验证类。
将一个简单的 Webflow应用程序迁移到Struts
在本文中,我使用了一个称为 ComputeDay 的简单应用程序来解释如何将一个 Webflow 应用程序迁移到Struts(代码片断可以从 资源下载)。ComputeDay 应用程序包括一个简单的 Web 页面,可以接受年、月和日期等输入值及代码,从而操作数据并计算出今天是星期几。如果输入值是有效的,那么所计算出的值将显示在输出 Web 页面上;如果输入值无效,将在输入页面显示一条错误消息。
用于这种简单应用程序的webflow.properties 文件可能如下所示:
# Invoke the input processor
index.jsp.button(submit)= ComputeDay.inputprocessor
# Specify the fully qualified class name for the input processor
ComputeDay.inputprocessor=com.beasys.commerce.ebusiness.
customer.webflow.ComputeDay
# Specify the result state for successful execution
ComputeDay.inputprocessor.success = Output.jsp
# Specify the result state for unsuccessful execution
ComputeDay.inputprocessor.exception(ProcessingException)=
index.jsp
需注意从索引 JSP 页面到操作处理程序以及从操作处理程序到输出 JSP 或返回至索引 JSP 的事件链,具体取决于操作处理程序是否成功执行。
将 Webflow 组件迁移到 Struts
这一节逐步描述了如何运用 RAD 将简单 Webflow 应用程序(ComputeDay)的单个组件迁移至其对应的 Struts 组件。为了简化迁移,我依照一个应用程序的视图、模型和控制器提供了具体的迁移步骤。
第一步: 创建一个空的 Struts 项目
使用 Rational Application Developer 来创建一个空的Struts 项目:
在菜单栏中单击 File,然后再单击New 和 Dynamic Web Project
在 Dynamic Web Project 页面中,输入项目名称:ComputeDay
单击 Next
在 Features 页面中,确保 Struts 复选框被选中
单击 Finish
RAD中最终的 Struts 项目应类似于图1
图1. 项目结构
第二步:识别应用程序组件
识别应用程序组件是一个简单而重要的迁移步骤。您必须识别特定的 Webflow 应用程序包。典型的 Webflow 应用程序包中包含以下内容:
Java代码: 包含模型和控制器组件
Web 内容: 包含 JSP 页面、HTML、Cascading Style Sheets、标签库、WebLogic/Web XML 文件和图像等。
属性: 包含 webflow.properties 和特定于应用程序的属性文件
JAR: Java 归档文件;这些归档文件可以是特定于 WebLogic的,也可以是应用程序的相关库文件
需要注意的是,以上的程序包结构只能作为指导原则。一般来说,不同组织使用的程序包会略有不同。您应该对迁移应用程序进行适当的分析以识别上述组件。
第三步: 导入应用程序组件
下面我们把第二个步骤中所识别的 Webflow 工件导入到第一个步骤所创建的项目结构中。RAD 提供了拖放功能,因此您可以轻松地拖动合适的组件——例如,Java 代码包、JSP 页面、HTML 和图像等等,并将其放到第一个步骤所创建的对应项目结构中。
默认情况下,RAD 的自动编译选项是启用的,因此将尝试编译并列举任何与资源缺失或者未知库相关的错误。根据我的经验,最好从缺失的资源入手,并确保所有需要的应用程序工件都已成功地导入到 RAD 中。
需要注意您无需导入任何特定于 WebLogic 的库或者 XML 文件。
第四步: 创建 Web 图表
创建 Web 图表是整个迁移过程中最为重要的一部分。在创建了一个支持Struts 的动态 Web 项目的同时,一个 Web 图表就会被自动创建出来,但不会自动打开。该图表构成了 Struts 项目的基础;第一步是分析 webflow.properties 文件并且了解由一个节点向另一节点的转换。需要注意,在此处的上下文中,“节点”可以是一个 JSP 页面也可以是一个 InputProcessor 类。
对 webflow.properties 文件的分析揭示了第一个节点是 index.jsp 页面,下一个节点可以是 computeDay 操作也可以是 index.jsp,这主要取决于验证是否成功。从 computeDay 节点开始,下一个节点是 output.jsp。图2中的 Web 图表捕获了这一简单流程:
图2. webflow.properties 文件的序列: computeDay 捕获 computeDayIP,dateData 对 PipelineSession做出响应。点击缩略图查看完整图像。
我在此不对如何绘制 Web 图表做任何讨论,这样的讨论超出了本文的范围。请阅读 资源中指定的教程
使用 Web 图表的优点主要在于两方面。首先,它为您提供了通过图形化的方式捕获Webflow 操作序列的功能。其次,它可以生成您在项目的 Web 图表中指定的所有工件,包括 JSP 页面和 Java 代码文件。在迁移的过程中,您可以将这些生成的文件用作模板。例如,您可以将来自 Webflow 应用程序的 index.jsp 内容复制到 Web 图表生成的内容中。
基本项目结构完成后,下面我们就要讨论如何按照下列步骤迁移项目的模型、视图和控制器。
第五步:迁移视图
迁移一个 Webflow 应用程序的视图非常简单。首先,迁移特定于 BEA 的标签并且把这些标签替换为标准的 Struts 库标签。
清单1. 迁移 JSP 标签
Webflow:
<%@ taglib uri = "WebFlow.tld" prefix="wf" %>
Struts:
<%@ taglib uri="/WEB-INF/struts.tld" prefix="struts" %>
其次,在 JSP 页面的开始处替换(如果对应的 Struts 类可用)或者删除任何特定于 BEA 的导入语句。
清单2. 迁移 JSP 包含语句
Webflow:
<%@ page import="com.beasys.commerce.webflow.WebflowJSPHelper" %>.
使用Struts时,不需要导入语句。Struts 表单标签及操作类将取代上面的导入语句。
第三,使用 Struts 标准格式标签来替换 Webflow JSP 文件格式的标签。在索引 JSP 页面中,表单标签使用 WebFlowJSPHelper API 来为下一个页面创建 URL。具体来说,URL 包含了页面名称以及与 webflow.properties 文件中的现状相符的事件。它可以迁移至 Struts,具体如下:
清单3. 迁移 JSP 表单标签
Webflow:
FORM method="post" action="<%=WebflowJSPHelper.createWebflowURL
(pageContext, "index.jsp", button(submit)", false)%>">
Struts:
Struts-config.xml 中的
< name="dateData" scope="request" input="/index.jsp" < name="dateData" scope="request" input="/index.jsp" 下一步就是将 JSP 页面和对应的 Java 类中的输入验证转换为标准的 Struts 输入验证和错误处理。Webflow 框架同时使用了 ValidatedForm API 和 Webflow 标签库来验证用户输入。通过使用表单bean中的 ActionErrors 和validate() 方法,Struts 可以提供标准的输入验证和错误处理机制。举例如下: 清单4. 迁移 JSP 验证 WebFlow JSP 代码: <%@ taglib uri = "WebFlow.tld" prefix="wf" %> JSP 中的验证表单如下: Year Month Day 对应的 Java 代码: ComputeRequest compRequest = new ComputeRequest(); Request.setAttribute("computeRequest", compRequest); ValidatedForm vFrom = ValidatedFormFActory.getValidatedForm(); ValidatedValues vValus = ValidatedValuesFactory.getValidatedValues(request); vForm.validate(vValues, compRequest); vForm.validate(vValues, STRING_VALIDATOR, "year", newMaxExpression(4), "The Year must be four digit" if(vValues.getInvalidFieldCount() >0) { throw new InvalidFormDataException("Please correct the invalid fields"); } Struts: public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) { ActionErrors errors = new ActionErrors(); If (!year.length() = 3) { errors.add ("year", new ActionError("year-format"); } } Struts在 JavaSource 文件夹中提供了 ApplicationResources.properties 文件。该文件经过编辑可提供以下错误消息: 清单5. Struts ApplicationResources.properties year-length=
2006. Please enter it correctly 需要注意的是,相对于 Webflow 通过与应用程序代码密切相关的应用程序错误处理方式,Struts 是如何使用表单bean和外部属性文件来进行输入验证和错误处理的。 第六步:迁移控制器 像上文介绍简单 Webflow 应用程序一节所描述的那样,输入处理器或者 IP 可以构成 Webflow 应用程序的控制器。Struts 以操作的形式提供了与输入处理器相同的功能。 下面演示了一个简单的迁移: 清单6. 迁移 InputProcessor Webflow: public class ComputeDayIP extends InPutProcessorSupport Struts: public class ComputeDay extends org.apache.strtus.action.Action 看看使用 Struts的Action 类来替换输入处理器有多么简单。 第七步:迁移模型 Webflow 应用程序的模型主要由包含了名称/值对的 PipelineSession 对象组成。一旦您了解了如何在特定文件中使用 PipelineSession,迁移模型就会变得相当容易。 值得注意的是,先前的 Webflow 实现是在 HTTPSession 中存储 PipelineSession 对象的,而不是在 HTTPRequest 中。在 Struts 中,表单 bean 提供了与 Webflow PipelineSession 功能等同的模型。 清单7. 迁移 PipelineSession 对象 Webflow: PipelineSession pSession = null; String namespace = null; pSession = getPipelineSession(req); String year = pSession.getYear(); Struts: DateData dateData = (DateData) form; year = dateData.getYear(); 编译和测试应用程序 使用 RAD,您可以立即编译应用程序、创建 WAR (Web 归档文件),并且将其部署到工具所提供的测试环境中。通常在一个迁移项目中,需要进行多次源代码变更和编译的迭代循环过程。 RAD v6为 WebSphere Application Server 6 提供了一个内置的测试环境。在一个真正的迁移项目中,一旦您在RAD 中对应用程序进行了单元测试,就可以将其部署到系统集成测试环境中,并且可以通过将应用程序与外部系统组件进行集成来完成端对端的测试。 结束语 本文循序渐进地介绍了一种方法,帮助您使用 RAD 将 BEA Webflow 应用程序迁移至开源Struts。通过本文,您了解了 Webflow 应用程序是由哪些不同的组件构成的,以及它们是如何映射到对应的 Struts 组件中的。您还学会了如何创建一个简单的 Web 图表(使用 RAD),这有助于将 Webflow 应用程序中的应用程序导航映射到 Struts 中。
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者