几乎每个基于 Web 的商务应用程序都需要在各种数据库中存储数据。对于 Struts 2 初学者来说,开发 Web 应用程序时的最大挑战就是将数据库中存储的数据显示到浏览器页面上。
开发最佳数据处理方式需要花费很多努力。好的应用程序需要好的用户界面 (UI) 和好的后台实现。Struts 2 的强大之处在于它能提供 Model-View-Controller (MVC) 模式的整洁的实现,其具有以下几个特性:
-
Actions
- 作为框架架构的一部分,Actions 通过将业务逻辑存放在一处来提供整洁的实现。Actions 作为一个通道,将请求的数据自动转换到结果页面。 Results
- 将用户需求从应用程序展现到 Web 浏览器的 UI。 Interceptors
-
通过实现通用操作,如验证、日志报表和错误检查,来减小 Actions 的系统开销,提升性能,这在多个 Actions 中很常见。
Interceptors 在后续处理和预先处理中都会被调用。对一个 Action 请求,有一个 Interceptors 栈。
ValueStack
- 在处理请求过程中保存相关数据的对象。
图 1 显示了 Struts 2 框架的组件。
图 1. Struts 2 Action、Interceptor 和 Result
在本文中,将会学习基于 Web 的应用程序中的动态数据处理。您将会探索如何在运行时发送用户数据,还有几个用例,如用户数据值预填表单以及设置 UI 字段,显示值列表中的默认值。本文将集中探讨 Struts 2 Action 类与结果页之间的动态数据流的实现细节。
使用 Struts 2 ValueStack 进行动态数据处理
ValueStack 是 Struts 2 的强大功能之一,用于保存处理请求过程中的所有数据。Action 也会以 bean 的形式存储数据。(Struts 2 中使用 getter 和 setter 方法。一旦数据存储在 action 类对象中,Struts 2 就以 Action
对象的形式将数据放在 ValueStack 中。ValueStack 保存一个对象栈,这些数据将会公开给框架其他部分。
图 2 中,action
类使用 getter 和 setter 方法设置两个变量的值。这些数据会在处理请求过程中保存到 ValueStack 中。HelloWorld.jsp 将会从 ValueStack 中取得这些变量的值并使用 Struts 2 标记库中的 <s:property> 标记显示这些值。
图 2. ValueStack 中的数据
如果数据将在 UI 中显示的值提前知道,那么这样的数据就称为静态 数据。静态数据可以直接在 JavaServer Pages (JSP) 中编码处理。图 3 显示的是静态数据的情况。
图 3. 静态数据
如果用户想要显示从用户数据库接收的数据,那么您需要一种机制来适当处理 Action 和 JSP 中的数据,并显示在 UI 中。有了 Struts 2,这种类型的场景的构建基块就是 Action
类和 ValueStack。通过使用 getter 和 setter 方法,Action
方法将把用户值保存到 ValueStack 中。然后,JSP 将会取得匹配变量名的值并显示在 UI 中。见图 4。
图 4. 动态数据
Struts 2 还提供显示数据的标记库,以便通过丰富的可重用的 HTML 形式来帮助您创建交互性的、基于表单的应用程序。Struts 2 有通用标记(控制标记和数据标记)以及 UI 标记。UI 标记用于从 ValueStack(action 添加到 ValueStack 的数据)或数据标记获得数据。以下是 Struts 2 UI 标记 <select tag> 的例子。
- 编写
Action
类使数据在 UI 中显示,如清单 1 所示。
清单 1. 编写Action
类使数据在 UI 中显示
public class DisplayAction extends ActionSupport { private List state = new ArrayList(); private List status = new ArrayList(); public String execute() { setState(this.state); setStatus(this.status); return "success"; } //getter and setter method for state variable// public List getState() { return state; } public void setState(List state) { //implement the application specific logic to retrieve the data from the database here// //Here for displaying the data on UI, we are using few hardcoded values// state.add("Defect"); state.add("Task"); state.add("User Stories"); } public List getStatus() { return status; } public void setStatus(List status) { //implement the application specific logic to retrieve the data from the database here// //Here for displaying the data on UI, we are using few hardcoded values// status.add("New"); status.add("Fixed") status.add("Resolved"); status.add("Closed"); } }
本例中,
DisplayAction
类用几个值来设置ArrayList
对象的 state 和 status。Action
类将数据保存到 ValueStack 中,然后,JSP 将其显示到 UI 中。 - 要在 JSP 中处理数据,需要编写 <select> 标记来获取
state
和status
,如清单 2 所示:
清单 2. 编写 <select> 标记,它将获取state
和status
的值
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <%@ taglib prefix="s" uri="/struts-tags" %> <html> <title>Sample Display Page</title> <body> <s:select list="%{status}" name="Status"></s:select> <s:select list="%{state}" name="State"></s:select> </body> </html>
- 用 struts.xml 配置
Action
和 JSP,如清单 3 所示。
清单 3. 用 struts.xml 映射配置Action
和 JSP
<!DOCTYPE struts PUBLIC"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <package name="sample.exmaple" extends="struts-default"> <action name=”DisplayAction” class=”com.sample.example.DisplayAction”> <result name=”success”>/DisplayPage.jsp </result> </action> </package> </struts>
以上代码示例中:
-
Action
类具有列表变量,名为state
和status
。 - 通过将
state
和status
设置为arraylist
类型将数据添加到Action
类。 -
<s:select>
具有列表参数(必要),它与Action
类中定义的同名。 - 使用
%{<list-variable>}
设置这些列表变量。 - JSP 中的列表变量必须匹配
Action
类中的名称。
图 5 显示的是输出的例子。
图 5. 输出 1:显示 Status 列表
图 6 中,<select> 标记 Status
用 Action
类中的值初始化。
图 6. 输出 2:显示 State 列表
<select> 标记 State
也用 Action
类中的值初始化。
假设用户有个值列表。用户想要在 UI 加载时从列表元素中选取一个作为默认值。
以下例子中,用户有个组合框,想要在 UI 加载后显示最后一个值。
- 修改
Action
类,并添加默认值的代码,如清单 4 所示。public class DisplayAction extends ActionSupport { private List state = new ArrayList(); private List status = new ArrayList(); private String defaultState = ""; private String defaultStatus = ""; public String execute() { //set status and state list values// setState(this.state); setStatus(this.status); //set default values for state and status which //a user wants to display on the User Interface setDefaultState("Task"); setDefaultStatus("Closed"); return "success"; } //getter and setter method// public List getState() { return state; } public void setState(List state) { //implement the application specific logic to retrieve //the data from the database here// //Here for displaying the data, we are using few //hardcoded values state.add("Defect"); state.add("Task"); state.add("User Stories"); } public List getStatus() { return status; } public void setStatus(List status) { //implement the application specific logic to retrieve //the data from the database here// //Here for displaying the data, we are using few //hardcoded values// status.add("New"); status.add("Fixed"); status.add("Resolved"); status.add("Closed"); } public String getDefaultState() { return defaultState; } public void setDefaultState(String defaultState) { this.defaultState = defaultState; } public String getDefaultStatus() { return defaultStatus; } public void setDefaultStatus(String defaultStatus) { this.defaultStatus = defaultStatus; } }
上面的
Action
类中,又添加了两个 getter/setter 方法来设置<select>
标记默认值的变量。 - 已修改的 JSP 代码如以下清单 5 所示。
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <%@ taglib prefix="s" uri="/struts-tags" %> <html> <title>Sample Display Page</title> <body> <s:select list="%{status}" name="Status" value="%{defaultStatus}"></s:select> <s:select list="%{state}" name="State" value="%{defaultState}"></s:select> </body> </html>
本例中的 struts.xml 映射还是一样。
在以上的示例代码中:
- 在
Action
代码中,要显示的两个默认值保存在两个字符串变量中。 - 在 JSP 中,用
<select>
标记的value
参数处理这些值。 -
Action
类中的默认值变量名必须匹配结果 JSP 中的名称。
图 7 显示了输出的例子。
图 7. 输出 1:显示 Status 默认值
图 8 中,当 UI 加载时,Status 列表的默认值设置为 Closed。
图 8. 输出 2:显示 State 默认值
图 8 中,当 UI 加载时,State列表的默认值设置为 Task。
Struts 2 是第二代 Web 应用程序框架,在 Java Servlets 中运用广泛。它采用了通用的 MVC 设计模式。Struts 2 将常见任务自动化,让您可以轻松地通过使用基于 SML 的配置利用 Action 到结果页面的映射。该框架包含基于 Web 应用程序实现的底层细节,并提供一部分结构化软件。
本文中,您了解了 Struts 2 作为一个完整框架的功能。您已经探索了一些最常见的用例,以及由 Struts 2 的强大功能提供的解决方案。
http://www.ibm.com/developerworks/cn/web/wa-dynamicstruts/index.html?ca=drs-