1、SSH2( Struts2+Spring+Hibernate) 教 程1. 开 发环 境Unfortunately the service is unavailable at the moment.Service will be resumed as soon as possible. We apologise for the inconvenience.Thank you for your interest in Volvo Cars.本 文 开 发 环 境 为 MyEclipse7.5 和 Struts 2.2.1, Spring 和 Hibernate 使 用 MyEclipse 内 置
2、 的 版 本 。 注 意 下 载 Struts 时 , 要 下 载 完 全 版 Full Distribution, 该 版 中 包 括 样 例 “空 工 程 ”struts2-blank-2.2.1.war( 在 apps 目 录 下 ) , 这 个 文 件 中 有 我 们 快 速 开 发 可 以 套 用 的 各 种 文 件 。 附 注 : war 文 件 是 部署 Web 应 用 系 统 时 用 的 压 缩 文 件 格 式 , 但 是 也 可 以 使用 RAR 等 程 序 解压 。2. 建 立 Web 工 程 并 导入 Struts 支 持包在 “空 工 程 ”的 WEB-INFlib 目
3、 录 下 , 是 支持 Struts 所 需 要 的 最 简 化 的 jar 包 ,它 们是 :commons-fileupload-1.2.1.jar commons-io-1.3.2.jar freemarker-2.3.16.jarjavassist-3.7.ga.jar ognl-3.0.jarstruts2-core-2.2.1.jar xwork-core-2.2.1.jar将 这 些 包 解 压 到 一 个 目 录 中 ( 例 如 C:struts) , 然 后 在 MyEclipse 中 新 建 一 个 “Web Project”, 命 名 为 “WarpSpeed”并勾 选
4、Java EE 5.0( 您 需 要 在 系 统 中 已 经 安装 JDK5.0 以 上 的 版 本 ) ; 在 工 程 名 上 面 点 鼠 标 右 键 , 选 择 “Build Path - Configure Build Path”调 出 配 置 对 话 框 ( 如 图 1) , 在 该 对 话 框 中 选 择 “Libraries”选 项 卡 , 使 用 “Add External JARs”按 钮 , 将 上 面的 7 个 jar 文 件 添 加 到 工 程 目 录 中 。 这样 WarpSpeed 工 程 就 已 经 支持 Struts2 了 。图 1 工程 Build Path 配
5、置窗口3. 设 置 全 局 配 置 xml 文 件 以 支持 Struts 过 滤器在 系 统 中 加 入 Struts 支 持 , 实 际 上 就 是 要 在 系 统 中 增 加 一 个 Struts“过 滤器( filter) ”;所 有的 文件 , 在 以页 面形 式展 示 到 用 户 的 浏 览 器 之 前 , 先 要 通 过 该 过 滤 器 “过 滤 ”( 即 处 理 ) 一 遍 , 这 样 给 了 Struts 控 制 模 块 一 个 处 理 页 面 中 特 有 的 Struts 标 签 的 机 会 ; 也 就 是 说 , 后 台 程 序 可 以 将 这 些 Struts 标 签
6、“翻 译 ”成 为 相 关 的 数 据 并 处 理 后 , 才 将 生 成 的 页 面 提 交 给 终 端用 户。在 系 统 中 添 加 Struts “过 滤 器 ”的 方 法 , 是 设 置 系 统 的 全 局 配 置 文 件 web.xml ; 该 文 件 在 工 程 的 树 形 结 构 中 位 于 WebRoot/WEB-INF 目 录 下 。 我 们 暂 不 需 要 理 解 复 杂 的 配 置 语 法 , 只 需 要 在 MyEclipse 的 Package 窗 口 中 , 找 到 该 文 件 并 双击 , 即 可进 入图 形化 的 web.xml 配 置 界 面 ( 如 图 2)
7、 。 该 界面 中, 树 型结 构的 第二 项 , 即 是 “Fileters”, 选 中后 使用 窗 体 右 边 的 “Add”按 钮 , 弹 出 “Add Filters”对 话框 ;这 个框 中只 有两 项带“ *”号 的项 目是 必填 的:第 一项 是要 为我 们的 过滤 器起 一个 名字 ,你 可以 随便 起一 个好 记的 名称 ,例 如“ s2”;第 三 项 是 实 现 该 过 滤 器 的 Java 类 ; 点 击 “Browse”按 钮 , 输 入 StrutsPrepareAndExecuteFilter( 实 际 上 你 只 需 要 输 入 前几 个字 母, 例如 strut
8、sp 就 可找 到该 类) , 将该 类设 为过 滤器 类即 可。添 加 完 过 滤 器 后 , 还 需 要 指 定 哪 些 文 件 必 须 通 过 该 过 滤 器 。 在 我 们 的 例 子 中 , 我 们 简 单 地 要 求 所 有 的 文 件 都 要 通 过 Struts 过 滤 器 , 因 此 我 们 可 以 这 样 来 设 置 过 滤 器 的 “mapping”: 点击 web.xml 树 形 目 录的 Filters, 在右 边 “Filter Mappings” 列 表框 旁边 , 点 击 “Add”按 钮, 输 入我 们刚 才的 过滤 器名 “s2”, 并 在 “URL-Pat
9、tern”处 输入 “/*”, 即 要求 系统 根目 录 下 所 有 的 文 件 都 需 要 通 过 该 过 滤 器 处 理 。 保 存 web.xml 文 件 ; 这 时 我 们的 WarpSpeed 工 程 可 以 说 已 经 完 全 支持 Struts2 了 。下 面我 们验 证一 下。图 2 配置 web.xml 添加 Struts 过滤器4. 设 计 一 个 最 简 单 的 Struts2 系 统在 设 计 一 个 最 简 单的 Struts 系 统之 前, 我们 需要 理解 这样 两个 概念: “action”的 执行 和导 航。(1) 所 谓 “action”( “动 作 ”)
10、, 就 是 在 表 单 提 交 后 系 统 会 自 动 执 行 的 一 个 Java 类 , 该 类 必 须 继 承 ActionSupport(在 com.opensymphony.xwork2 中 ) 并 重 写 其 中 的 execute()方 法。 表 单提 交后 , 系 统会 将表 单里 包含 的字 段数 据传 递给 该 action 类 , 并 执 行 其 中 的 execute()方 法。(2) execute()方 法必 须返 回一 个字 符串 ,而 该字 符其 将决 定系 统要 转向 那个 页面 ;这 就是 所谓 的“ 导 航” 。 因 此, 一个 最简 单的 Struts
11、系 统, 起码 包括 这样 几个 文件 :带 有 表 单 的 页 面 文 件 ( jsp 文 件) 表 单提交后 要执 行的 action( java 类 ) Ac tion 执行 完 毕 要 转 向 的 页 面 ( jsp 文 件)因 此 , 在 构 建 系 统 前 , 我 们 首 先 要 构 思 我 们 的 系 统 到 底 需 要 怎 样 的 功 能 结 构 , 以 及 需 要 哪 些 文 件 来 实 现 这 些 功 能 这 正是 软件 工程 的“ 设 计”阶 段的 任务 。作 为最 简单 的例 子, 我们 可以 这样 设计 我们 的系 统:(1) 页 面 index.jsp, 其 中 包
12、 含 一 个 简 单 的 form, 该 form 的 action 名 为 “aCheck”, 其 中 包 含 两 个 文 本 字 段 :n ame和 password;(2) 表 单 提 交 后 要 执 行的 action 类 为 AccountCheck;(3) AccountCheck 类 执 行 时 , 打 印 出 传 递 过 来的 name 和 password 参 数的 值(4) AccountCheck 执 行 后 转 向 页面 index2.jsp。为 了 将 这 一 个 构 思 传 递 给 系 统 , 我 们 需 要 使 用 struts.xml 来 配 置 这 几 个 文
13、 件 之 间 的 逻 辑 关 系 。 在 “空 ”样 例 工 程 struts2-blank-2.2.1.war 的 WEB-INFsrcjava 目 录 下 可 以 找 到 一个 example.xml 文 件 , 该 文 件 可 以 作 为 我 们 编写 struts.xml 配 置文 件的 起点 。其 内容 为:/example/HelloWorld.jsp/example/Login.jspMenu/example/1.jsp在 上 面 的 代 码 中 , 有 四 行 代 码 我 们 做 了 下 划 线 标 记 。 我 们 采 用 第 四 行 带 下 划 线 的 代 码 的 语 法 形
14、 式 ( 即 含 有 “name”属 性 的 result 标 签 ) 来 修 改 第 三 行 带 下 划 线 的 代 码 , 并 删 除 后 面 两 个 “action”标 签 ; 修 改 后 的 这 三 行 带 下 划线 的 代 码 变 为 :/index2.jsp说 明:(1) “action”标 签 定 义 了 一 个 动 作 , 该 动 作 由 其 name 属 性 确 定 , 并 和 页 面 表 单 中 的 “action=”属 性 相 对 应 ; class 属 性 则指 定了 该动 作由 哪个 Java 类 来实 现。 例如 ,上 面的 代码 相对 应的 页面 表单 应该 有如
15、 下形 式:.则 上述 form 提 交 时 , 系 统 将 寻找 AccountCheck 类 并执 行之 。(2) “result”标 签 定 义 了 在 动 作 执 行 之 后 的 跳 转 ( 导 航 ) , 其 中 name 属 性 和 动 作 中 execute()函 数 的 返 回 值 相 应 , 也 就 是 说, 如果 动作 中 execute()返 回 值 为 字 符 串 “toIndex2”, 则 系 统 跳 转到 index2.jsp 页 面。(3) package 是 对 action 分 类 的 标 签 , 其 最 核 心 的 属 性 是 “name”, 该 name
16、是 与 其 他 package 区 分 的 依 据 ; 而 namespace( 命 名 空 间 ) 属 性 则 定 义 了 到 哪 个 地 址 寻 找 其 下 属 的 action; 例 如 , namespace=“/example“ 表 示 , 如 果 请 求 的 动 作 的URL 是/example/HelloWorld.action的 话 , 系 统 首 先 到 /example 命 名 空 间 寻 找 “HelloWorld”动 作 对 应 的 Java 类 ; 如 果 没 有 找 到 , 系 统 还 会 到 默 认 的 命 名 空 间 去 寻 找 , 以 及 到 “/”根 命 名
17、 空 间 寻 找 。 对 于 我 们 修 改 后 的 例 子 , 我 们 只 是 简 单 的 定 义 了 一 个 名 为 “default”的 package 并 指 定 根 命 名 空 间 。 需 要 注 意 的 是 , 命 名 空 间 只 有 “一 层 ”, 而 不 是 像 文 件 目 录 那 样 可 以 有 多 个 层 次 。 另 注 意 :URL 中 “xxx.action”和 简化 形式 的“ xxx”是 等同 的。5. 实 现 最 简 单 的 Struts2 系 统对 于 上 面 设 计 好 的 简 单 Struts2 系 统 , 我 们 可 以 根 据 struts.xml 的
18、要 求 按 下 面 步 骤 实 现 之 注 意 这 里 体 现 的 软 件 工 程 思 想: 先设 计, 后实 现:(1) 页 面表 单编 码: Web 工 程 默 认 的 “入 口 ”页 面是 index.jsp, 位 于 WebRoot(相 当于 网站 的根 目录 ) 下 。 最 简单 的 支持 Struts2 框 架的 JSP 文 件结 构为 :也 就 是 说 , 最 上 面 两 行 最 关 紧 要 ! 使 用 上 面 的 模 板 替 换 系 统 中 index.jsp 原 来 的 内 容 , 并 在 标 签 内 加 入 struts 表 单 :其 中“ s:”是 由上 面所 示第 二行
19、 代码规 定的 struts 标 签 的 前 缀 , 也 就 是 说 , 所 有 struts 标 签 都 要 以 “s:”打 头 。 “form”和 “submit”标 签和 HTML 表 单中 类 似 的 标 签 的 意 义 相 同 , 而 “textfield”标 签 相 当 于 HTML 表 单 的 input 标 签 。 请 注 意 下 划 线 的 部 分 : action 属 性 定 义 的 名 称 “aCheck“和 struts.xml 中 的 action name 是 一 致 的 ; 两 个 textfield 定 义 了 两 个 表 单 字 段 , 一 个 名 为 “na
20、me”, 另 一 个 名 为 “password”。 用 户 在 这 两 个 字 段 中 输 入 的 数 据 将被 Struts 传 递 到 后台 action 程 序中 。小 贴 士 : MyEclipse7.5 中 有 一 个 Web Page Editor, 用 这 个 编 辑 器 可 以 插 入 struts2 的 标 签 ! 方 法 是 在 JSP 文 件 上 点 击 鼠 标 右键 ,选 择 “Open with”, 并 从 弹 出 的 窗 口 中 找到 Web Page Editor 并 确 定 即 可 。 展 开 右 边 工 具 栏 中 “Struts Tags”即 可 使用 该
21、工 具栏 添加 Struts 标 签 了 , 可 以 节 省 不 少 键 盘 输 入 的 时 间 ( 见 图 3) 。图 3 Web Page Editor 的编辑界面(2) 动 作 编 程 : 根据 struts.xml 要 求 , 我 们 要 编 写 一 个 名 为 “AccountCheck”的 类 来 实现 action“aCheck”。 这个 类 有 4 个 要求 :a) 继 承 ActionSupport;b) 包 含表 单字 段对 应的 属性 变量 ;c) 对 上 面 的 属 性 变 量 编 写 getter 和 setter 方 法;d) 重 写 execute()方 法 ,
22、并 返 回与 struts.xml 对 应的 字符 串以 进行 导航 。AccountCheck.java 的 代码 如下 :import com.opensymphony.xwork2.ActionSupport;public class AccountCheck extends ActionSupportprivateStringname; privateStringpassword; public String getName() return name;public void setName(String name) this.name = name;public String get
23、Password() return password;public void setPassword(String password) this.password = password;public String execute() System.out.println(name+password); return“toIndex2“;上 文 中 的 核 心 代 码 只 有 4 行 ( 使 用 下 划 线 标 出 ) , 前 两 行 只 是 声 明 了 与 表 单 字 段 相 对 应 的 变 量 ( Struts 会 自动 在表 单和 action 类 之 间 进 行 数 据 传 递 ) ;
24、第 三 行 将 传 递 过 来 的 字 段 值 打 印 出 来 ( 一 个 简 单 的 数 据 处 理 ) ; 最 后 一 行 返 回 字 符 串 “toIndex2”以 指 示 系 统 导 航 到 /index2.jsp 页 面 。 注 意 其 中 的 setter 和 getter 函 数分 别用 于设 置和 获取 字段 变量 的值 ; 但 是 我们 在上 面的 代码 中并 没有 看到 对 getter 和 setter 的 引 用 , 而 其 实 这 正 是 Struts 的 奇 妙 之 处 : 当 execute()被 执行 时, 所 有的 字段 变量 已经 在 Struts 的 控制
25、 调度 下被 设置 好了 !(3) 结 果 页 面 编 程 : 根据 struts.xml 的 要 求 , 我 们 的 结 果 页 面 是 index2.jsp; 目前 我们 暂不 需要 在该 页面 中工 作 , 因 此 您可 以随 便写 个页 面并 命名 为 index2.jsp 即 可。现 在 我 们 可 以 运 行 我 们 的 系 统 了 。 由 于 我 们 的 工 程是 Web Project, 因此 只要 在工 程名 上点 鼠标 右键 ,并 选择 “Run As” “MyEclipse Server Application”MyEclipse 会 自 动 配 置 运 行 参 数 ,
26、启 动 内 置的 Tomcat 应 用 服 务 器 , 打 开 浏 览 器 并 提 供 index.jsp 页 面。 页面 地址 形如 :http:/computername:8080/WarpSpeed/index.jsp其 中 computername 是 您 的 计 算 机 的 名 称 。 我 们 可 以 输 入 一 些 内 容 , 点 击 “Submit”按 钮 , 系 统 将 自 动 转 到 index2.jsp, 并 在 控 制 台 打 印 出 来 您 输 入 的 内 容 ( 由 execute()函 数 中 的 println()实 现) 。在 这一 阶段 常见 的错 误是HTT
27、P Status 404 - There is no Action mapped for namespace / and action name xxx 该 错误 意味 着在 你指 定的 命名 空间没有 找到 名为 xxx 的 动作 (同 时在 “根 ”命 名空 间也 没有 找到) 。 你 需要 查看 并修 改 你 的 xtruts.xml 配 置文 件。6. 莫 名其 妙的 错误 ?MyEclipse 首 次 启 动 的 时 候 , 会 要 求 你 建 一个 “工 作 区 ( workspace) ”, 后 继 的 工 程 文 件 均 存 放 到 这 个 工 作 区 文 件 夹 中 。 如
28、果 在 你 的 学 习 过 程 中 , 编 写 了 多 个 工 程 , 有 时 候 会 出 现 莫 名 其 妙 的 错 误 , 那 么 除 了 认 真 阅 读 错 误 提 示 并 进 行 更 正 意 外 ,有 些错 误可 能是 你前 期的 工程 遗留 下来 的, 即 使你 早已 删除 了 那些 工程 ,其 发布 到 tomcat 中 的应 用 并 没 有 移 除干 净 !解 决的 方法 很简 单:退 出 MyEclipse, 到 workspace 目 录 , 在 .metadata.me_tcatwebapps 中 有 你 已 经 发 布 所 有 工 程 的 文 件 夹 , 找 到 原 来
29、的 工程 文 件 夹 , 删 除 那 些 有 问 题 的 工 程 ( 或 者 干 脆 全 部 删 除 , 因 为 这 并 不 影 响 你 的 源 文 件 ) , 然 后 重 新 启 动 MyEclispse 就 可 以 了。因 此, 如果 你怕 麻烦 ,最 好一 个工 程使 用一 个独 立的 工作 区。7. 结 果页 面编 程从 上 面 的 实 验 当 中 可 以 看 到 , Java 的 打 印 语 句 只 能 在 服 务 器 的 控 制 台 上 输 出 结 果 , 而 不 能 将 结 果 显 示 到 用 户 的 浏 览 器 中 。 Struts 将 action 处 理 的 数 据 ( 包
30、 括 表 单 提 交给 action 的 数据 )和 应用 ( Application) 范围 内的 数据 ,都 存储 在一 个 叫 做 “值 栈 ”( valueStack) 的 地 方 ; 有 很 多 种 方 法 可 以 从 这 里 取 出 值 来 。 现 在 我 们 重 新对 index2.jsp 编 程, 已 将这 些值 取 出到 页面 中:首 先 , 使 用 通 用 的 struts 页 面 模 板 替 换 index2.jsp 的 内容 , 并在标 签内 加上 :$password运 行 一 下 试 试 。 可 以 看 到 , 三 种 方 法 都 可 以 将 输 入的 passwo
31、rd 显 示 出 来。 其 中 前 两 种 为 Struts 标 签形 式,$ password的 写 法 是 OGNL 表 达式 语言 ,其 用法 暂略 。8. 结 果页 面导 航如 果 我 们 需 要 根 据 后 台 程 序 的 处 理 结 果 转 向 不 同 的 页 面 的 话 , 必 须 同 时 配置 struts.xml 和 action。 例如 ,如 果要 在传 递 过 来的 name 和 password 参 数 的 值 分 别 为 “wang”和 “123”时 , 系 统 导 航 转 向 index2.jsp 页 面, 否则 的话 转向 验证 失 败 页面 fail.jsp,
32、则 我 们 可 以 先 配置 struts.xml 如 下:/index2.jsp/fail.jsp根 据 这 一 配 置 , 我 们 需 要 在 action 的 execute()方 法作 相应 修改 :public String execute() if (name.equals(“wang“) elsereturn “toFail“;最 后 , 需 要 实现 fail.jsp; 由 于 这 个 页 面 比 较 简 单 , 只 需 要 将 index2.jsp 另 存为 fail.jsp, 并 将 其 页 面 内 容 修 改 为 “失 败 ” 信 息即 可( 略) 。再 次 运 行 工
33、程, 则 输 入 数 据 不 同 会 导 航 到 不 同 的 页 面。 至 此 , 我 们 已 经 完 整 的 体 验 了 Struts2 简 单而 强大 的前 后台 交互 及 表现 能力 。下 面我 们看 看如 何方 便地 与底 层数 据处 理进 行交 互。9. 为 工 程 添加 Spring 支 持 在工程 名上 点鼠 标右 键并 选择“MyEclipse” “Add Spring Capabilities”为 简 单 起 见 , 因 为 系 统 内 置的 Spring 支 持是 2.5 版 本 的 , 我 们 选 中 所 有 2.5 版 的 Spring 包 , 并 选 择 “拷 贝 支
34、 持 包 到 lib目 录” ; 另特 别注 意:( 1) 将 Spring 的 配 置 文件 applicationContext.xml 放 到 WEB-INF/目 录 下 ( 而 不 是 缺 省 的 src 目 录) ;( 2) 重要 : web.xml 中 增 加 一 个 listener:Co ntextLoaderListener; 上 述第 (2 ) 项使 得我 们可 以方 便的 获取 当前 程序 的运 行上 下文 ,从 而得 到 DAO 对 象以 操纵 数据 库。10. 添 加 Hiberbate 支 持和 上 面 的 步 骤 类 似 , 我 们 为 工 程 添加 Hibern
35、ate 支 持 。 同 样 选 择将 Hibernate 的 支 持 包 拷 贝到 lib 目 录 下 ; 在 “配 置 文 件 ” 选 项 中 , 选 择 使 用 已 有的 Spring 配 置 文 件 ( 即 上 一 步 中 的 WEB-INF/applicationContext.xml) ; 然 后, 设 定我 们要 使 用 的数 据 库 为 MyEclipse 自 带 的 小 型 数 据 库 Derby( 在 选 项 窗 口 的 “DB Driver”下 拉菜 单中 选择 ) 。 在最 后的 选项 窗口 中 , 我 们还 要为 Hibernate 创 建 一 个 专 用 的 包 :
36、点 击 “Java Package”右 边 的 “New”按 钮 , 在 src 目 录下 面输 入你 的包 名 ( 例 如 hib) 即 可 ; 这 个 包 是 你 以 后 放置 Hibernate 有 关文 件的 包。附 注: Derby 数 据 库 是 Apache 的 开 源 小 型 数 据 库 , 具 有 体 积 小 , 易 安 装 , 支 持 Java、 JDBC 和 SQL 标 准, 并 可用 于嵌 入 式环 境等 特点 ,参 见 http:/db.apache.org/derby/。11. 启 动 Derby 数 据库为 了 在 后 继 的 工 作 中 使 用 数 据 库 ,
37、我 们 需 要 先 启 动 MyEclipse 内 置的 Derby 数 据库 ,方 法是 :在 MyEclipse 的 右 上 角 , 有 一 个 带 加 号 的 窗 口 的 小 按 钮 , 名 为 “Open Perspective”(鼠 标悬 停在 该按 钮上 方的 时候 会显 示 它 的 名 称 ) ; 点 击 该 按 钮 并 选 择 “MyEclipse Database Explorer”( 或 者 使 用 “Window”菜 单 的 “Show View” “DB Browser”) 即 可 打 开 数 据 库 浏 览 窗 口 ; 双 击 其 中 的 “MyEclipse Der
38、by”即 可启 动数 据库 。Derby 启 动 以 后 , 展 开 已 经 启 动 的 数 据 库 连 接 , 可 以 看 到 有 多 个 数 据 库 , 包 括 “APP”, “CLASSICCARS”等 。 展 开 “CLASSICCARS”下 面 的 “TABLE”, 会 看 到 该 数 据 库 下 属 的 多 个 表 , 例 如 “CUSTOMER”、 “EMPLOYEE”等 ( 见 图 4) , 展 开 后 者 可 以 观 察 其 包 含 的 字 段 。 如 果 你 希 望 编 辑 该 表 中 的 数 据 , 可 以 在 表 名 上 点 击 鼠 标 右 键 并 选 择 “Edit
39、Data”。 可 以看 到,在“ EMPLOYEE”表 中,已 经有 数十 条数 据 ; 您 可以 试着 修改 一下 这些 数据 ,我 们下 面的 工作 就以 这些 数 据 为基 础。然 后 使 用 屏 幕 左 下 角 的 按 钮 回 到 “Package Explorer”视 图中 。图 4 启动内置的 Derby 数据库12. 更 为奇 怪的 错误直 到 目 前 为 止 , 我 们 还 没 有 进 行 任 何 涉 及 底 层 数 据 库 操 作 的 编 码 工 作 , 仅 仅 是 为 我 们 的 WarpSpeed 工 程 添 加 了 Spring和 Hibernate 的 支持 而已 。
40、现 在我 们看 看在 新的 支持 下, 原来 的页 面还 能正 常运 行否 : 在 工程 名上 点击 鼠标 右键 并选 择“Run As” “MyEclipse Server Application”竟 然是 “404”( 资源 无法 找到 )错 误!您 可 以 仔 细 研究 Console 控 制台 中显 示的 异常 信息 , 但 是, 我 可以 告诉 你一 个简 单得 多的 经验 : 这 个错 误本 来不 应该 发 生 !出 错的 原因 是你 添加 的各 种支 持里 面所 包含 的 JAR 包 有重 复的 ,并 且版 本不 一致 !展 开 “Package Explorer”中 的 “Re
41、ferenced Libraries”, 可 以 看 到 工 程 中 所 引 用 的 所 有 JAR 包 ;现 在知 道为 什么 在前 面的 步 骤 中 要 将 支 持的 JAR 包 拷 贝 到 同 一个 lib 目 录 下 面 了 吧 : 起 码 我 们 检 查 重复 JAR 包 的时 候方 便多 了。 仔 细检 查后可以 发现 , “asm-2.2.3.jar”和 “asm.jar”以 及 “cglib-nodep-2.1.3.jar”和 “cglib-2.1.3.jar”是 重复 的 ; 我 们要 删 除这 两对 中的 后者 ,方 法是 :在 要删 除的 包上 面点 击鼠 标右 键并 选
42、择“Build Path” “Remove From Build Path” 然 后就 可以 删除 了。 再 运行 一下 试 ,如 果还 不行 ,就 要按 照上 面第 “6”步 所说 的方 法, 彻底 地清 空一 下已 经发 布的 文件 了。13. 设 计 一 个 最 简 单 的 Table 记 录显 示系 统 目 的: 从“CLASSICCARS.EMPLOYEE”表 中读 出所 有数 据, 并显 示在 页面 中。 流 程:(1) 在 index3.jsp 中 建立 一个 表单 ,对 应的 动作 是“ eList”;(2) “eList”对 应的 Java 类 命 名 为 “Employee
43、List”, 它在 Struts 的 调控 下获 取数 据表 中的 记录 ;(3) “eList”执 行 完 毕 后 转向 elist.jsp, 在该 页面 上显 示动 作类 获取 的数 据。14. 实 现 最 简 单 的 Table 记 录显 示系 统根 据 上 述 设 计 , 首 先 修改 struts.xml 文 件, 添加 如下 的动 作配 置:/elist.jsp/fail.jsp然 后依 次编 码所 需要的各 个文 件: 首 先是 起始 页面 index3.jsp:这 里 面 实 际 上 只 有 一 个 submit 按 钮。然 后 是 动 作 类 EmployeeList.jav
44、a; 因 为该 类需 要读 取数 据 表 “CLASSICCARS.EMPLOYEE”, 因 此在 编写 该类 之前 需要 先 对所 涉及 的表 进行 所谓 “逆 向工 程 ”以 生成 相关 的实 体类 和 DAO( 数据 存取 对象 )类 。方 法是 :(1) 在 Database Explorer 中 , 找 到 数 据 表 “ CLASSICCARS.EMPLOYEE ” 并 点 击 右 键 , 选 择 “ Hibernate Reverse Engineering”, 设 定 Java src folder( 点 击 Browse 选 择 /WarpSpeed/src) 和 Java
45、Package( 还 记 得 我 们 在第 10 步 中创 建 的 hib 包 吗 ? 就 是 这 个 ) , 勾 选 下 面 的 三 个 复 选 框 ( 其 中 “Create Abstract Class”不 用选 ; 这 三个 复选 框的 含义 就是 指定 使 用 逆向 工程 生成 数据 表相 关的 实体 类或 说 POJO 类 以 及 对 应 的 DAO 类 ) 。(2) 第 二 页 中 , 比 较 重 要 的 是 确 定 Id 生 成 策 略 , 例 如 , 如 果 你 的 主 键 是 自 增 生 成 的 id, 请 使 用 identity 策 略。 我 们目 前 的 例子 暂时
46、不需 要设 置这 项, 直接 点击 “Next”到 下一 页。(3) 第 三 页 中 , 注 意 在 表 清 单 的 下 方 , 有 两 个 复 选 框 , “Include referenced tables”和 “Include referencing tables”, 意 思 是 在 逆 向 工 程 的 时 候 要 包 含 和 当 前 表 有 关 联 的 其 他 表 。 选 中 这 两 个 框 后 我 们 可 以 看 到 , 表 清 单 中 多 了 一 个 表 名 “OFFICE”, 因为 EMPLOYEE 通 过 “OFFICECODE”字 段 作 为 外 键和 OFFICE 表 关联
47、 。执 行 逆 向 工 程 后 , 在 Package Explorer 中 可 以 看 到 src/hib 包 下 面 多 了 许 多 源 文 件 , 例 如 Employee.java 是 EMPLOYEE表 对 应 的 实 体 类 ,而 EmployeeDAO.java 则 是其 DAO 类 。 说 明: DAO 类 :DAO 类 中 集 成 了 对 实 体 类 的 通 用 操 作 , 例如 findAll(), findBy(), attachDirty()等 ; 特 别 地 , DAO 类 包含 一个 静态 方法 用 于 从 应 用 上 下 文 中 获 取 该 DAO 类 的 一 个
48、 实 例 : getFromApplicationContext(ApplicationContext ctx); 这 样 只 要 我 们 获取 了 当 前 应 用 的 上 下 文 ( Context) 后 , 即 可 取得 DAO 实 例并 通过 该实 例操 作数 据对 象了 (参 见下 面的 步骤 ) 。 数 据处 理 action 的“ 三 板斧 ”为 :(1) 获 取当 前应 用上 下文 ;(2) 获 取 实 体 类 的 DAO 对 象实 例;(3) 使 用 DAO 对 象操 作数 据;特 别 提 醒 : 在 使 用 DAO 对 象 操 作 数 据 时 , 经 常 使 用 Java 的
49、 集 合 类 对 象 , 例如 List 等 。EmployeeList.java 核 心代 码为 :public class EmployeeList extends ActionSupport public String execute() ApplicationContext ct = WebApplicationContextUtils.getWebApplicationContext(ServletActionContext.getServletContext();EmployeeDAO dao = EmployeeDAO.getFromApplicationContext(ct); List list =