1. 简介
该文档的PDF版本可在此处获取 |HERE|。
文档中的示例可在此处查看 |此处|。
本文旨在通过实例介绍 Struts 2 的核心概念。Struts 2 是一个 Web 框架,它提供:
- 以 JAR 文件形式提供的多个库
- 一个开发框架:Struts 2 影响 Web 应用程序的开发方式。
理解这些示例的先决条件如下:
- Java 语言的基础知识
- 具备 Web 开发的基础知识,特别是 HTML。
满足这些先决条件所需的所有资源均可在网站 [https://developpez.com] 上找到。其中部分资源由我编写,可在网站 [https://stahe.github.io] 上查阅。
本文档中的示例可通过网址 [https://stahe.github.io/zh-struts2-janv-2012/] 获取。
若需进一步了解 Struts 2,可参考以下资料:
- [ref1]:Struts 2 文档,可在 Struts 网站上获取
- [ref2]:Donald Brown、Chad Michael Davis 和 Scott Stanlick 合著、Manning 出版社出版的《Struts 2 in Action》一书。这本书特别具有指导意义。
我们将不时引用[ref2],以便读者知晓可通过该书对相关主题进行更深入的探索。
本文件在编写时已考虑到读者可能无法随时使用计算机阅读的情况,因此我们加入了大量屏幕截图。
1.1. Struts 2 在 Web 应用程序中的作用
首先,让我们明确 Struts 2 在 Web 应用程序开发中的定位。通常情况下,Web 应用程序会基于如下所示的多层架构构建:
![]() |
- [Web] 层是与 Web 应用程序用户直接交互的层。用户通过浏览器显示的网页与 Web 应用程序进行交互。Struts 2 仅位于这一层,且仅限于这一层。
- [业务]层实现应用程序的业务逻辑,例如计算工资或发票。该层通过[Web]层获取用户数据,并通过[DAO]层获取DBMS数据。
- [DAO](数据访问对象)层、[JPA](Java持久化API)层以及JDBC驱动程序共同管理对DBMS数据的访问。[JPA]层充当ORM(对象关系映射器),在[DAO]层处理的对象与关系型数据库中的数据行和列之间起到桥梁作用。
- 这些层的集成可通过 Spring 容器或 EJB3(企业级 JavaBeans)实现。
下面提供的示例大多仅使用单一层,即 [Web] 层:
![]() |
不过,本文最后将介绍如何构建一个多层Web应用程序:
![]() |
[业务]、[DAO] 和 [JPA/Hibernate] 层将以 JAR 归档的形式提供给我们,因此,我们只需构建 [Web] 层即可。
1.2. Struts 2 MVC 开发模型
Struts 2 通过以下方式实现了 MVC(模型–视图–控制器)架构模式:
![]() |
客户端请求的处理流程如下:
请求的 URL 采用 http://machine:port/contexte/rep1/rep2/.../Action 的形式。路径 [/rep1/rep2/.../Action] 必须与 Struts 2 配置文件中定义的操作相对应;否则,该请求将被拒绝。操作在 XML 文件中按以下格式定义:
在前面的示例中,假设请求了 URL [http://machine:port/contexte/actions/Action1]。随后将执行以下步骤:
- 请求 - 浏览器客户端向控制器 [FilterDispatcher] 发起请求。控制器负责处理所有客户端请求,它是应用程序的入口点,即 MVC 架构中的 C。
- 处理
- C 控制器查询其配置文件,发现 actions/Action1 操作存在。命名空间(第 1 行)与操作名称(第 2 行的 name 属性)拼接后,定义了 actions/Action1 操作。
- C控制器实例化[2a]一个类型为[actions.Action1]的类(第2行的class属性)。该类的名称和包名可以是任意值。
- 如果请求的 URL 包含 [param1=val1¶m2=val2&...] 形式的参数,则控制器 C 会按以下方式将这些参数赋值给 [actions.Action1] 类:
因此,[actions.Action1] 类必须为每个预期的 parami 参数都提供相应的 setParami 方法。
- 控制器 C 调用 [actions.Action1] 类中签名 [String execute()] 的方法来执行操作。该方法随后可以利用类已获取的 parami 参数。在处理用户请求时,它可能需要 [business] 层 [2b]。一旦处理了客户端的请求,它就可以生成各种响应。一个经典的例子是:
- 若请求无法正确处理,则返回错误页面
- 否则返回确认页面
execute 方法会向 C 控制器返回一个字符串类型的结果,称为导航键。在上例中,[*actions.Action1*].*execute 可以生成两个导航键:“page1”(第 3 行)和“page2”(第 4 行)。 [actions.Action1].execute 方法还会更新 M* 模型 [2c],该模型将被用于响应用户请求时发送的 JSP 页面。该模型可能包含以下元素:
- 已实例化的 [actions.Action1] 类
- 用户的会话
- 应用程序作用域数据
- ...
- 响应 - C 控制器会指示与导航键对应的 JSP 页面进行显示 [3]。这就是视图,即 MVC 中的 V。JSP 页面使用 M 模型来初始化其必须发送给客户端的响应中的动态部分。
现在,让我们澄清 MVC Web 架构与分层架构之间的关系。实际上,这是两个不同的概念,有时会被混淆。让我们以一个单层的 Struts 2 Web 应用程序为例:
![]() |
如果我们使用 Struts 2 实现 [Web] 层,确实会形成 MVC Web 架构,但并非多层架构。在此情况下,[Web] 层将处理所有内容:呈现、业务逻辑和数据访问。在 Struts 2 中,执行这些工作的正是 [Action] 类。
现在,让我们考虑一种多层Web架构:
![]() |
Web 层可以在不使用框架且不遵循 MVC 模型的情况下实现。这样我们就得到了一个多层架构,但 Web 层并未实现 MVC 模型。
在MVC中,我们曾提到M模型即V视图所呈现的数据集。有时(通常),MVC中对M模型还有另一种定义:
![]() |
许多作者认为,位于[Web]层右侧的部分构成了MVC中的M模型。为避免歧义,我们可以将:
- 当指代[呈现]层右侧的所有内容时,称之为领域模型
- 当指代视图 V 所显示的数据时,称之为视图模型
下文中,“M模型”一词将专指视图V的模型。
1.3. 所使用的工具
接下来,我们将使用(2011年12月)
- NetBeans 7.01 集成开发环境(IDE),可从 [http://www.netbeans.org] 获取
- 适用于 NetBeans 7.01 的 Struts 2 插件,可从 [http://plugins.netbeans.org/plugin/39218] 获取
- Struts 2 2.2.3 版本,可从 [http://struts.apache.org/] 获取
请注意,仅需 [http://struts.apache.org/] 提供的 Struts 2 库即可开发后续示例。NetBeans 可以替换为其他 IDE(如 Eclipse、JDeveloper、IntelliJ 等),而 Struts 2 插件仅是为了方便开发者,并非必需。
1.3.1. NetBeans IDE
在 NetBeans 下载页面,我们选择 Java EE 版本:

1.3.2. Struts 2 插件
根据 NetBeans 的不同版本,该插件并非一直可用。截至 2011 年 12 月,可通过 URL [http://plugins.netbeans.org] 获取。该 URL 列出了适用于 NetBeans 的各种插件。您可以筛选搜索结果。在 [1] 中,我们搜索名称中包含“struts”一词的插件。
![]() |
- 请点击链接 [2]
![]() |
下载插件并解压 [2]。要将其集成到 NetBeans 中,请按以下步骤操作:
- 启动 NetBeans
![]() |
- 在 [1] 中,选择“工具/插件”菜单
- 在 [2] 选项卡中,点击 [3] 按钮
- 在 [4] 中,选择已下载插件的 .nbm 文件。此处,我们选择 Struts 2.2.3 库,而非 Struts 2.0.14 的库
- 返回 [2] 选项卡,点击 [5] 按钮安装所选插件。
安装插件通常需要重启 NetBeans。
1.3.3. Struts 2 库
如果您已下载了适用于 NetBeans 的 Struts 2 插件,则已拥有 Struts 的主要库,但并非全部。后续操作中,我们将需要 Struts 2 网站 [http://struts.apache.org/] 上提供的某些库。
![]() |
请依次点击链接 [1] 和 [2],下载 2.2.3.1 版本的 zip 文件。解压包后,Struts 所需的库文件位于该包的 [lib] 文件夹 [3] 中。由于文件数量众多,自然会产生疑问:哪些才是必不可少的?此时,Struts 插件将派上用场。










