首页 [IT/计算机]软件工程实验修改版

[IT/计算机]软件工程实验修改版

举报
开通vip

[IT/计算机]软件工程实验修改版[IT/计算机]软件工程实验修改版 软件工程实验指导书 陈小辉、张峰、李红卫编 榆林学院信息工程学院 二0一一年九月 前 言 软件工程实验是为计算机相关专业本科《软件工程》课程配套设置的,是《软件工程》课程讲授中一个重要的、不可或缺的实践环节。其目的是使学生能够针对具体软件工程项目,全面掌握软件工程管理、软件需求分析、软件初步设计、软件详细设计、软件测试等阶段的方法和技术,通过该课程设计使学生进一步理解和掌握软件开发模型、软件生命周期、软件过程等理论在软件项目开发过程中的意义和作用,培养学生按照软件工程...

[IT/计算机]软件工程实验修改版
[IT/计算机]软件工程实验修改版 软件工程实验指导书 陈小辉、张峰、李红卫编 榆林学院信息工程学院 二0一一年九月 前 言 软件工程实验是为计算机相关专业本科《软件工程》课程配套设置的,是《软件工程》课程讲授中一个重要的、不可或缺的实践环节。其目的是使学生能够针对具体软件工程项目,全面掌握软件工程管理、软件需求分析、软件初步 设计 领导形象设计圆作业设计ao工艺污水处理厂设计附属工程施工组织设计清扫机器人结构设计 、软件详细设计、软件测试等阶段的方法和技术,通过该课程设计使学生进一步理解和掌握软件开发模型、软件生命周期、软件过程等理论在软件项目开发过程中的意义和作用,培养学生按照软件工程的原理、方法、技术、标准和 规范 编程规范下载gsp规范下载钢格栅规范下载警徽规范下载建设厅规范下载 ,进行软件开发的能力,培养学生的合作意识和团队精神,培养学生对技术文档的编写能力,从而使学生提高软件工程的综合能力,提高软件项目的管理能力。 按该课程的特点,实验内容包括软件开发的两大方法学的专 快递公司问题件快递公司问题件货款处理关于圆的周长面积重点题型关于解方程组的题及答案关于南海问题 训练,即结构化(生命周期学)的方法学和面向对象的方法学,通过对一个简单项目,要求学生利用结构化软件开发技术或面向对象的软件开发技术完成对该项目的开发。因此设置五个实验项目,从项目发的准备工作,系统分析过程,系统设计过程,软件测试到系统实施,覆盖软件开发的整个过程,此外又引入我国国家《计算机开发规范》,以规范技术文档的书写标准,提高实验教学质量。 通过实验训练,达到如下目的: 使学生进一步了解和掌握软件工程原理,提高对实际项目的分析和设计能力,通过实验课程,熟悉和基本掌握软件工程方法学、软件开发的过程,文档资料的编写格式及规范,全面领会和贯通所学习的理论知识,从而培养学生综合运用所学课程知识,分析解决问题的能力,培养学生理论联系实际作风,实事求是,严肃认真的科学态度和良好的工作作风,为今后从事科学研究工作打下基础。 榆林学院软件工程实验手册 目录 实验项目一:超市进销存管理信息系统 ....................................................................................... 4 1、需求说明............................................................................................................................. 4 1.1系统开发目的 ..................................................................................................................... 4 1.2系统需求分析 ............................................................................................................. 4 1.3项目确立 ..................................................................................................................... 4 1.4(应用范围 .................................................................................................................. 4 1.5(定义 .......................................................................................................................... 4 2.系统分析过程 ....................................................................................................................... 7 2.1系统功能分析 ............................................................................................................. 7 3.系统设计过程 ...................................................................................................................... 10 3.1 系统模型: .............................................................................................................. 10 3.2(模块子系统结构: ................................................................................................ 12 4.系统实施.............................................................................................................................. 15 4.1.系统介绍 ................................................................................................................... 15 实验项目二:基于JSF+EJB3+A4J框架的网上定餐系统 ......................................................... 16 1 系统需求说明 ................................................................................................................... 16 1.1 项目背景 ................................................................................................................ 16 .1.2 需求分析 ............................................................................................................... 16 1.3 主要用例说明 ........................................................................................................ 16 2 系统架构设计 ................................................................................................................... 17 3 网上定餐系架构说明 ....................................................................................................... 17 3.1 客户层 .................................................................................................................... 17 3.2 Web层 ................................................................................................................... 18 3.3 Service层 ............................................................................................................... 18 3.4 DAO 层 ................................................................................................................. 18 3.5 数据持久层PO ...................................................................................................... 18 3.6 值对象层VO ......................................................................................................... 18 4 业务实体层设计 ............................................................................................................... 19 4.1 设计域模型 ............................................................................................................ 20 4.2 设计数据模型 ........................................................................................................ 21 5 网上定餐系开发环境的搭建 ........................................................................................... 21 5.1 创建Web及JSF应用........................................................................................... 21 5.2 A4J的配置 ............................................................................................................ 23 6 创建实体Bean ................................................................................................................. 24 6.1 创建实体表 ............................................................................................................ 24 .6.2 编写Entity ............................................................................................................ 25 .7 创建DAO ........................................................................................................................ 29 .8 创建Web业务逻辑组件 ................................................................................................ 29 .9 创建Action组件 ............................................................................................................. 29 .10 JSF的配置 ..................................................................................................................... 30 .11 应用A4J和JSF设计Web页面 .................................................................................. 30 实验项目三:飞机零部件电子商务交易平台(BSP) .............................................................. 31 1 系统需求说明 ................................................................................................................... 31 1 榆林学院软件工程实验手册 1.1 项目背景 ................................................................................................................ 31 1.2 需求分析 ................................................................................................................ 31 1.3 主要用例说明 ................................................................................................................ 32 2 系统架构设计 ................................................................................................................... 32 2.1 BSP系统架构说明 ................................................................................................ 33 .2 系统软硬件环境 .............................................................................................................. 35 3 业务实体层设计 ............................................................................................................... 35 3.1 设计域模型 ............................................................................................................ 35 3.2 设计数据模型 ........................................................................................................ 36 3.3 创建数据库 ............................................................................................................ 40 4 BSP开发环境的搭建 ..................................................................................................... 40 4.1 应用MyEclipse创建BSP项目 ........................................................................... 40 4.2 Hibernate Annonations设置 .................................................................................. 41 4.3 应用Hibernate 3注解设计数据持久层 ............................................................... 42 4.4 Struts 2.1应用设置................................................................................................ 49 4.5 Spring 2.5应用设置 .............................................................................................. 50 4.6 Dojo应用设置 ....................................................................................................... 51 4.7 DWR应用设置 ..................................................................................................... 51 5 DAO层设计 ..................................................................................................................... 52 6 业务逻辑层设计 ............................................................................................................... 54 7 Web层设计 ...................................................................................................................... 56 7.1 表现层UI设计...................................................................................................... 57 7.2 访问控制层公用类设计 ........................................................................................ 61 8 BSP系统目录及模块列表设计 ....................................................................................... 62 9 BSP主页面设计............................................................................................................... 62 9.1 利用Dojo和Struts 2设计登录表现层界面 ........................................................ 63 9.2 应用Struts 2注解设计登录控制层Action .......................................................... 63 9.3 设计模型驱动层VO ............................................................................................. 63 9.4 登录DAO层实现设计 ......................................................................................... 63 9.5 登录业务逻辑层实现设计 .................................................................................... 63 9.6 登录验证码的应用 ................................................................................................ 63 9.7 利用Strtus2和Ajax实现验证码 ......................................................................... 64 10 BSP用户注册实现设计 ................................................................................................. 64 10.1 利用Dojo、DWR和Struts 2设计用户注册首页 ............................................ 64 10.2 利用Dojo、DWR和Struts 2设计公司注册页面 ............................................ 64 10.3 利用Dojo、DWR和Struts 2设计管理员注册页面 ........................................ 64 10.4 利用Dojo、DWR和Struts 2设计普通用户注册页面..................................... 64 10.5 用户注册控制层流程分析 .................................................................................. 64 10.6 应用Struts 2注解设计用户注册首页控制层Action ........................................ 65 10.7 应用Struts 2注解和DWR设计公司注册控制层Action ................................. 65 10.8 公司注册模型驱动层VO ................................................................................... 65 10.9 应用DWR、Dojo、Spring、Struts 2实现Ajax调用 ...................................... 65 10.10 应用Struts 2注解设计普通用户注册控制层Action ...................................... 66 10.11 用户注册模型驱动层VO ................................................................................. 66 2 榆林学院软件工程实验手册 10.12 应用DWR、Spring判断公司是否已注册的 Ajax调用 ............................... 66 10.13 注册DAO层实现设计 ..................................................................................... 66 10.14 注册业务逻辑层实现设计 ................................................................................ 66 10.15 部署层发送邮件系统的设计 ............................................................................ 67 11 用户找回密码实现设计 ................................................................................................. 67 11.1 利用Dojo、Struts 2设计找回密码表现层界面 ................................................ 67 11.2 找回密码控制层动作类的设计 .......................................................................... 67 11.3 找回密码模型驱动层VO ................................................................................... 67 11.4 找回密码DAO层实现设计 ............................................................................... 67 11.5 找回密码业务逻辑层实现设计 .......................................................................... 68 12 公告信息发布实现设计 ................................................................................................. 68 12.1 公告信息浏览表现层界面设计 .......................................................................... 68 12.2 利用Ajax、Struts 2和Hibernate进行显示分页 .............................................. 68 12.3 分页器的设计 ...................................................................................................... 68 12.4 在Struts 2的Action中分页控制 ....................................................................... 68 12.5 公告信息发布模型驱动层VO ........................................................................... 68 12.6 在DAO中实现分页 ........................................................................................... 69 12.7 利用Dojo的Dialog组件设计发布公告页面 ................................................... 69 12.8 发布公告信息控制层动作类的设计 .................................................................. 69 12.9 公告信息DAO层实现设计 ............................................................................... 69 12.10 公告信息发布逻辑控制层实现设计 ................................................................ 69 13 联系人通讯录的设计 ..................................................................................................... 69 13.1 利用Dojo、Struts 2设计联系人通讯录表现层界面 ........................................ 69 13.2 利用Dojo的Dialog组件设计增加通讯录表现层界面 ................................... 70 13.3 增加联系人信息控制层动作类的设计 .............................................................. 70 13.4 增加联系人DAO层实现设计 ........................................................................... 70 13.5 增加联系人逻辑控制层实现设计 ...................................................................... 70 14 公司认证管理的设计 ..................................................................................................... 70 14.1 显示公司认证信息表现层界面设计 .................................................................. 70 14.2 利用Dojo的Dialog组件设计增加公司认证信息表现层界面 ....................... 70 14.3 公司认证信息控制层动作类的设计 .................................................................. 71 14.4 公司认证模型驱动层VO ................................................................................... 71 14.5 增加公司认证DAO层实现设计 ....................................................................... 71 14.6 增加公司认证逻辑控制层实现设计 .................................................................. 71 15 询价单管理 ..................................................................................................................... 71 16 利用Quartz定时邮件发送实现设计 ............................................................................ 73 16.1 Quartz的应用 ...................................................................................................... 73 16.2 Quartz 包含的触发器 ......................................................................................... 73 16.3 作业任务的的调度实现 ...................................................................................... 73 17 BSP实时消息系统的设计 ............................................................................................. 73 17.1 利用DWR的反向Ajax技术实现消息系统 ..................................................... 73 17.2 反向Ajax的配置与实现 .................................................................................... 74 17.3 反向Ajax调用的服务器端的发布者实现 ........................................................ 74 3 榆林学院软件工程实验手册 实验项目一:超市进销存管理信息系统 1、需求说明 1.1系统开发目的 1(大大提高超市的运作效率; 2(通过全面的信息采集和处理,辅助提高超市的决策水平; 3(使用本系统,可以迅速提升超市的管理水平,为降低经营成本, 提高效益,增强超市扩张力, 提供有效的技术保障。 1.2系统需求分析 超市的进销存管理信息系统,首先必须具备的功能是记录仓库存货、销售以及进货情况,通过该系统了解超市进货渠道、商品单价、数量,库存商品的种类、数量,销售商品种类、价格、数量,以便管理员根据以上信息作出经营管理决策。 在性能方面要求系统核算准确,使实存商品、销售商品与所记帐目一致,能够被超市长期有效使用。 数据主要来自于入库单、发票,超市销售在营业期间内一直发生,数据也就一直变化。销售商品后开出发票,并且要显示商品价格数额。 在当天汇总时修改相应文件,注重的是总额、总数量。为减少月末工作量,日常中要对报表数据逐步统计核算。 超市数据资料有些属内部资料,不能为外人所知,系统须有保密措施,设置密码。 查看资料需输入正确密码,销售人员销售货物需输入代号才能打开收银柜。万一泄露密码,应设修改密码的程序,同时密码不能过于简单 1.3项目确立 针对超市的特点,为了帮助超市解决现在面临的问题,提高小型超市的竞争力,我们将开发以下系统:前台POS销售系统、后台管理系统,其中这两个子系统又包含其它一些子功能。 1.4(应用范围 本系统适应于各种超市。 1.5(定义 1 商品条形码:每种商品具有唯一的条形码,对于某些价格一样的商品,可以使用自定义条形码。 4 榆林学院软件工程实验手册 2 交易清单:包括交易的流水账号、每类商品的商品名、数量、该类商品的总金额、交易的时间、负责本次收银的员工号。 3 商品积压:在一定时期内,远无法完成销售计划的商品会造成积压。 4 促销:在一定时期内,某些商品会按低于原价的促销价格销售。 库存告警提示:当商品的库存数量低于库存报警数量时发出提示。 5 盘点:计算出库存、销售额、盈利等经营指标。 1.6(可行性研究 1(管理可行性分析 超市的经营者大多具备电脑基本操作知识,对于必要的专业操作经短期培训即可;管理基础工作和各项 管理制度 档案管理制度下载食品安全管理制度下载三类维修管理制度下载财务管理制度免费下载安全设施管理制度下载 比较健全,执行严格,原始数据采集完整,保存良好。 2(经济可行性分析 超市管理系统的投入,能够提高工作效率,减少工作人员,从而减少人力资本的投入,根据核算,系统投入三个月后,就能够基本收回开发系统的投资,从经济角度来说,本系统开发完全必要。 3(技术可行性分析 (1)(硬件:电脑一台 (2)(软件:操作系统:中文Windows 2000 开发系统:Microsoft Visual Foxpro 6.0 安装SQL Server 2000的服务器版本 系统本身对硬件和软件的要求都不高且系统兼容性很强,平台的移植性也很好,因此无论在系统的硬件及软件上都满足开发的要求。 (3)(本系统涉及到的技术因素: ? 管理系统的开发方法。使用面向对象开发方法开发软件系统 ? 网络和通信技术。开发小组有基于C/S开发的经验 ? C/S机构规划和技术设计。开发小组有应用数据库开发经验 ? 数据库技术。开发小组能使用Visual Foxpro编程 (4)(运行上的可行性: ? 操作简单:简单的操作规则使操作人员能轻松掌握。 ? 查询方便:用户可设定任意条件和任意的查询项目进行检索。 ? 统计灵活:任意条件下任意项目的产品入库时间、数量等的统计及查询项目均可进行交叉统计。 5 榆林学院软件工程实验手册 灵活,便于学习,因此,该系统具有可行性。通过经济、技术、和社会等方 面的可行性研究,可以确定本系统的开发完全必要,而且是可行的,可以立项开 发。 6 榆林学院软件工程实验手册 2.系统分析过程 2.1系统功能分析 1. 零售前台(POS)管理系统,本系统必须具有以下功能: 商品录入:根据超巿业务特点制定相关功能,可以通过输入唯一编号、扫描条形码、商品名称等来实现精确或模糊的商品扫描录入。该扫描录入方法可以充分保证各种电脑操作水平层次的人员均能准确快速地进行商品扫描录入。 收银业务:通过扫描条形码或者直接输入商品名称(对于同类多件商品采用一次录入加数量的方式)自动计算本次交易的总金额。在顾客付款后,自动计算找零,同时打印交易清单(包括交易的流水账号、每类商品的商品名、数量、该类商品的总金额、交易的时间、负责本次收银的员工号)。如果顾客是本店会员并持有本人会员卡,则在交易前先扫描会员卡,并对所购物品全部实行95折优惠,并将所购物品的总金额累计到该会员的总消费金额中。 会员卡的有效期限为一年,满一年未续卡者,该会员卡将被注销。 安全性:OS登陆、退出、换班与操作锁定等权限验证保护;断电自动保护最大限度防止意外及恶意非法操作。 独立作业:有的断网收银即在网络服务器断开或网络不通的情况下,收银机仍能正常作业 2. 后台管理系统,本系统必须具备以下功能 进货管理: 根据销售情况及库存情况,自动制定进货计划(亦可手工制定修改),可以避免盲目进货造成商品积压。 按计划单有选择性地进行自动入库登记。 综合查询打印计划进货与入库记录及金额。 销售管理: 商品正常销售、促销与限量、限期及禁止销售控制。 综合查询各种销售明细记录、各地收银员收银记录以及交结账情况等。 按多种方式统计生成销售排行榜,灵活察看和打印商品销售日、月、年报表。 库存管理: 综合查询库存明细记录。 库存状态自动告警提示。如库存过剩、少货、缺货等。软件为您预警,避免库存商品积压损失和缺货。 库存自动盘点计算。 人员管理: 员工、会员、供货商、厂商等基本信息登记管理。 员工操作权限管理。 客户销售权限管理。 2.2.系统结构 系统总体结构 7 榆林学院软件工程实验手册 小型超市零售管理系统 前台POS销售系统 后台管理系统 商收进销库人品银货售存员录业管管管管入 务 理 理 理 理 2.3.流程图 前台管理系统 1.1快速商品录 入商品录入信息 商品信息 商品信息销售人员 商品信息表 2.1支持会员卡打 折条形码信息商品信息 商品信息 1.2条形码扫描业务信息 2.3打印交易清单 业务清单会员信息2.2交易总额 业务清单 业务信息 会员信息表文档交易信息表 2.4.系统ER图 8 榆林学院软件工程实验手册 用户姓名 用户类型 用户号 用户ID 用户密码 用户 m 销售 销售ID 销售日期 供货商ID 商品ID n 供货商名称 n m 商品 供货 供货商地址 商品名供货商 称 供货商电话 价格 供货金额 供货日期 允许打折 厂商ID m 厂商名称 促销价格 1 生产 厂商 允许销售 厂商地址 n 消费 购买日期 厂商电话 消费金额 m 会员 会员卡号 会员ID 累计金额 注册时间 1.商店中的所有用户(员工)可以销售多种商品,每种商品可由不同用户(工)销售; 2.每个顾客可以购买多种商品,不同商品可由不同顾客购买; 每个供货商可以供应多种不同商品,每种商品可由多个供应商供应。 9 榆林学院软件工程实验手册 3.系统设计过程 3.1 系统模型: 商品录入 营业员 收银业务 员工基本信息管理 商品销售控制员工操作权限管理总经理 进货管理客户销售权限管理超市经理 库存管理 1.户类型与职能 (1) 员工(营业员): 通过商品条形码扫描输入商品到购买清单 操作软件计算交易总金额 操作软件输出交易清单 对会员进行会员卡扫描以便打折 (2) 超市经理 操作软件录入商品,供货商,厂商 操作软件制定进货计划 查询打印计划进货与入库记录 操作软件控制商品销售与否 查询打印销售情况 操作软件生成销售排行榜 查询库存明细记录 根据软件发出的库存告警进行入货 操作软件进行盘点计算 (3) 总经理: 基本信息登记管理 员工操作权限管理 客户销售权限管理 10 榆林学院软件工程实验手册 2.零售前台(POS)管理系统用例视图 商品录入 条形码扫描 销售管理顾客 营业员 结帐 添加VIP 会员业务 删除VIP打折 3.后台管理系统用例视图 11 榆林学院软件工程实验手册 自动制定进货计划 销售管理 自动入库登记 生成销售排行榜 超市经理查询库存明细记录仓管员 库存管理 库存状态自动告警 自动盘点计算 自动制定进货计划 进货管理 自动入库登记 查询打印计划 员工基本信息登记管理 人员管理 员工操作权限管理客户销售权限管理提示 3.2(模块子系统结构: 商品录入 1. 商品录入 快条 速形 录码 入扫 商描 品 支 持 功能描述:商品录入子系统要求能快速录入商品,因此必须支持条形码扫描。 12 榆林学院软件工程实验手册 2. 收银业务 收银业务 交打会 易印员 总交卡 额易打 折 计清 算 单 功能描述:收银业务子系统能计算交易总额,打印交易清单,并根据会员卡打折。 3. 进货管理 进货管理 指入查询打 定库印进货 进登与入库 记 记录 货 计 划 功能描述:进货管理子系统可以根据库存自动指定进货计划,进货时自动等级以 及提供查询和打印计划进货与入库记录的功能。 4. 销售管理 销售管理 商查 销 产询售 品打排 销印行 售销榜 控售 制 情 况 13 榆林学院软件工程实验手册 功能描述:销售管理子系统可以控制某商品是否允许销售,查询每种商品的销售情况并产生年、月、日报表,同时可以生成销售排行榜。 5. 库存管理 库存管理 查库自 库存动 存状盘 明态点 细报计 录 警 算 功能描述:库存管理子系统提供查询库存明细记录的基本功能,并根据库存的状 态报警,以及自动盘点计算。 6.人员管理 人员管理 信员客 息工户 登操权 记作限 管管管 理 理 理 功能描述:人员管理子系统提供基本信息登记管理,员工操作权限管理,客户权 限管理 14 榆林学院软件工程实验手册 4.系统实施 4.1.系统介绍 21世纪,超市的竞争也进入到了一个全新的领域,竞争已不再是规模的竞争,而是技术的竞争、管理的竞争、人才的竞争。技术的提升和管理的升级是超市业的竞争核心。零售领域目前呈多元发展趋势,多种业态:超市、仓储店、便利店、特许加盟店、专卖店、货仓等相互并存。如何在激烈的竞争中扩大销售额、降低经营成本、扩大经营规模,成为超市营业者努力追求的目标。 工作流程 小型超市零售管理系统 前台POS销售系统 后台管理系统 商收进销库人 品银货售存员 录业管管管管 入 务 理 理 理 理 , 服务器 服务器可根据应用的规模选定,即可采用各种专用的服务器系统(如;SUN服务器), 也可使用操作系统为Win NT服务器的小型服务器。 , 数据库软件 数据库软件采用Oracle (7.3.3以上版本),可根据服务器操作系统平台选择相应的 Oracle数据库。 , Web应用服务器 Oracle Application Server(3.0以上版本) IE浏览器(4.0以上版本) , 客户机 客户机分为两类,采用C/S结构的子系统运行在Win9X操作系统上,硬件要求为 Pentium166/32M以上配置;采用B/S结构的子系统运行在Win9X的浏览器之上,硬件 要求为Pentium133/32M以上配置。 15 榆林学院软件工程实验手册 16 实验项目二:基于JSF+EJB3+A4J框架的网上定餐系统 1 系统需求说明 1.1 项目背景 随着我国餐饮行业的发展,因餐饮业门坎较低,中国的大多数餐饮企业的老板是从小店发展起来的,家族式管理的居多,还没有发展到聘请职业经理人,许多还是"人治",并没有一套现代企业制度和监督管理体制,所以从观念意识、经营思想和管理水平还有待专业化。在管理模式方面,我国企事业的管理,已由传统的管理逐步转数字、知识、信息的管理,信息管理就是对业务流程中无序的信息进行系统化管理,实现信息收集、处理、共享和再利用,以提高业务水平和效率。通过对某公司定餐流程的考察,对业务细节进行了全面的分析,结合目前最先进的软件开发技术,实现了某公司订餐的数字化、网络化管理。 .1.2 需求分析 如今基于互联网的电子商务系统越来越流行。网上定餐系统是一个在互联网上进行菜单信息发布和网上定餐以及建立客户关系的电子商务系统。餐饮企业可以通过这个电子商务系统发布自己的工菜单信息以供客户在线定餐。客户可以通过查看菜单信息在线定餐。 餐饮企业通过定餐系统的用户界面,可以查看客户注册信息、管理用户信息、添加菜单信息、查看客户定单信息。客户可以注册个人的信息,选择菜品添加到购物车中,最后生成定单发送给餐饮企业,以便餐饮企业上餐上门。 根据以上分析,得出程序的主要用例图,如图1所示。主要的角色(Actor)包括企业管理员(Administrator)、客户(Customer)和数据库(Database)。 图1 网上定餐系统用例图 下面介绍应用程序中的主要用例(user case)。 1.3 主要用例说明 1(用户登录和注册 用户登录是电子商务应用必需的功能之一。当用打开系统时,首先需要登录系统,如果 16 榆林学院软件工程实验手册 17 用户没有注册,则需要注册。注册的用户分为普通用户和管理员用户,管理员用户可以维护已注册的用户信息。当用户登录系统后,可以查看当前系统中的菜单信息以及定餐等操作。 2(管理员发布菜单信息 管理员可以通过在线定餐系统动态发布菜单信息,发送菜单信息后,登录的客户要以查看到菜单信息并选择某些菜品进行定餐。 3(购物车管理 客户可选中某些菜品添加到购物车中,也可以删除购物车中的某一菜品或全部清空购物车。 4(定单管理 客户把所需要的菜品添加到购物车后,就可以根据购物车中的菜品下定单,客户填写好定单后,发送给餐饮企业,餐饮企业根据用户定单信息进行送餐。 2 系统架构设计 用例图分析了该应用系统的主要功能需求,这些需求是设计开发的依据。下面开始讲解网上定餐系统的架构设计。整个系统架构基于Java EE技术体系设计。 Java EE体系包括JSP、Servlet、EJB3、Web Service等多项技术。这些技术的出现给电子商务时代的Web应用开发提供了一个非常有竞争力的选择。怎样把这些技术组合起来,形成一个适应项目需要的稳定架构是项目开发过程中一个非常重要的步骤。 此步骤一般主要由架构设计师完成,设计师将根据项目需求,对Java EE体系中的各处技术进行筛选取舍,并考虑到开发过程中的角色分工、后期的运行维护,以及系统扩展性等诸多因素,建立系统的架构。 一个成功的软件需要有一个成功的架构,但软件架构的建立是一个复杂而又持续改进的过程,软件开发者们不可能对每个不同的项目做不同的架构,而总是尽量重用以前的架构,或开发出尽量通用的架构 方案 气瓶 现场处置方案 .pdf气瓶 现场处置方案 .doc见习基地管理方案.doc关于群访事件的化解方案建筑工地扬尘治理专项方案下载 。 网上定餐系统严格按MVC 模式设计,按Java EE分层设计的理念,将中间层严格分成业务逻辑层、DAO 层和数据持久层等。MVC 层的控制器绝对禁止持久层访问,甚至不参与业务逻辑的实现。表现层采用JSP 、A4J和JSF技术。JSP 技术结合JSF的标签库,让应用的表现层层次清晰,可读性比较好。 3 网上定餐系架构说明 本系统采用的是典型的Java EE三层结构,分为表现层、中间层(业务逻辑层)和数据服务层。三层体系将业务规则、数据访问及合法性校验等工作放在中间层处理。客户端不直接与数据库交互,而是通过组件与中间层建立连接,再由中间层与数据库交互。该系统的表现层是JSF和A4J技术, 使其用户界面操作更方便和简洁。中间层采用的是流行的EJB3技术 ,为了将控制层与业务逻辑层分离,又细分为以下几种。 3.1 客户层 Java EE应用可以是基于Web 的,也可以是不基于Web 的。在基于Web 的Java EE 应用 17 榆林学院软件工程实验手册 18 中,用户的浏览器在客户层中运行,并从一个Web服务器上下载Web 层中的静态HTML 页面或由JSP 或Servlets 生成的动态HTML 页面 。 3.2 Web层 Java EE Web组件可以由JSP 页面、基于Web 的Applets 以及显示HTML页面的Servlets 组成。调用Servlets 或者JSP 页面的HTML页面在应用程序组装时与Web 组件打包在一起。就像客户层一样,Web层可能包括一个Java Bean类来管理用户输入,并将输入发送到在业务层中运行的Enterprise Beans 类来处理 。运行在客户层的Web 组件依赖容器来支持诸如客户请求和响应及Enterprise Bean 查询等。一般来讲,一个典型的Web应用的的末端应该是表示层。 3.3 Service层 Service层(业务逻辑层)负责实现业务逻辑。业务逻辑层以DAO 层为基础,通过对DAO组件的模式包装,完成系统所要求的业务逻辑。业务逻辑层包含布署层,可发送电子邮件、调用远程服务等。 3.4 DAO 层 数据访问DAO 层负责与持久化对象交互。该层封装了数据的增、删、查、改的操作。 3.5 数据持久层PO 数据持久层PO ,持久化对象。通过实体关系映射工具将关系型数据库的数据映射成对象,很方便地实现以面向对象方式操作数据库,该系统采用EJB3的实体Bean作为ORM 框架。EJB3容器的作用贯穿了整个中间层,将Web 层、Service 层、DAO 层及PO 无缝整合。 3.6 值对象层VO 值对象层VO主要对应界面显示的数据对象。对于一个WEB页面,或者SWT、SWING的一个界面,用一个VO对象对应整个界面的值。通常用于业务层之间的数据传递,和PO一样也是仅仅包含数据而已。但应是抽象出的业务对象,可以和表对应,也可以不,这根据业务的需要。 网上定餐系统层次架构如图2所示,架构模型如图3所示。 18 榆林学院软件工程实验手册 19 2 网上定餐系层次架构模型 图3 网上定餐系架构模型图 4 业务实体层设计 业务实体在内存中表现为实体域对象,在数据库中表现为关系数据。实现业务实体包括以下内容: (1) 设计域模型,创建域模型实体对象。 19 榆林学院软件工程实验手册 20 (2) 设计关系数据模型。 (3) 创建对象,关系映射文件。 其中,前两项适用于大多数由持久化数据驱动的应用程序,最后一项目是特定于EJB应用的。不同的实现方式可能需要不同的步骤。 4.1 设计域模型 网上定餐系应用中的业务实体包用户(Employees),菜单信息(Foodinfo),定单信息(Foodorderinfo),定单项目(OrderItem),购物车(Shopcart)。下面将详细介绍这些实体模型含义。 Employees:代表一个用户实体,主要属性包括用户ID(id)、用户名(name)、年龄(age)、地址(address)、注册日期(registerTime)、口令(password)等。 Foodinfo:代表一个菜单信息实体,主要包括菜品标识(id)、菜品名(foodname)、 菜品图片(foodImg)、价格(foodprice)、菜品描述(description)、菜品数量(count)、备注等。 Foodorderinfo:代表了一个定单实体,主要属性包括定单编号(orderid)、联系电话(telPhone)、送餐地址(address)、客户名(customerName)、送餐方式(notice)、邮编(zipCode)、下定单用户Id(uid)、下定单日期(orderdate)、总金额(sumprice)、等。 OrderItem:代表一个定单所涉及的菜单项实体,主要属性包括定单编号(orderid)、菜品名(foodname)、数量(count)等。 Shopcart:代表购物车实体,主要属性包括菜品名(foodname)、用户名(userid)、数量(count)、价格(foodprice)等。 网上定餐系应用域模型的业务实体关系图如图 -4所示。接下来将介绍各实体之间的对应关系。 Foodorderinfo与OrderItem之间是一对多的关系,一个定单可以有多个定单项,Shopcart和Foodorderinfo之间是一对多的关系,一个购物车中可以有多个菜品。 图4 BSP应用的业务实体关系图 20 榆林学院软件工程实验手册 21 4.2 设计数据模型 在图4 中的Employees, Foodinfo,Foodorderinfo, OrderItem, Shopcart对象都需要持久化,它们在数据库中有对应的表。如图5所示为网上定餐系的关系数据模型。 图5 BSP的关系数据模型 5 网上定餐系开发环境的搭建 在前面章节己经创建了JavaEEAPP企业应用模块及JavaEEAPPEJB模块,本例的测试代码都是基于JavaEEAPPEJB编写。 5.1 创建Web及JSF应用 下面应用MyEclipse开发向导在JavaEEAPP应用项目中添加一个名为jsfejb3的Web模块。创建完jsfejb3 Web应用模块后,接着在新建的jsfejb3项目上,单击右键,在弹出的菜单中选择MyEclipse项,如图6所示。在弹出的子菜单中,选择Add JSF Capabilities项,弹出如图7所示对话框。根据弹出的对话框向导选择JSF版本及其产生的类所要存放的包。 21 榆林学院软件工程实验手册 22 图6 添加JSF应用能力 图7 产生JSF配置文件 JSF作为构建在Servlet技术之上的Java EE Web应用程序框架,与其他Java EE Web应用程序一样也都是通过一个名为web.xml的文件来进行配置的,该文件也叫Web应用的部署描述符。在该文件中要指定FacesServlet,并将请求映射到该Servlet上。另外,还要在该文件中配置JSF的配置文件的位置。在应用MyEclipse开发向导添加JSF应用能力后,系统会配置web.xml文件内容并生成JSF的配置文件faces-config.xml。本示例应用的web.xml文件的代码如清单1所示。 清单-1 22 榆林学院软件工程实验手册 23 javax.faces.STATE_SAVING_METHOD client javax.faces.CONFIG_FILES /WEB-INF/faces-config.xml,/WEB-INF/pagesnavigation.xml Faces Servlet javax.faces.webapp.FacesServlet 0 Faces Servlet *.faces index.html 在上面的定义中,将所有.faces的请求交由FaceServlet来处理,FaceServlet会调用相应的JSP网页,例如请求是 /main.faces,而实际上会调用/main.jsp网页,完成以上的配置就可以开始使用JSF了。 5.2 A4J的配置 最新的A4J可以从 下载,当前最新版本为3.3, 解压下载的richfaces-ui-3.3.0.GA-bin.zip 文件包, 然后复制lib目录下的 richfaces-api-3.3.0.GA.jar 、richfaces-impl-3.3.0.GA.jar、richfaces-ui-3.3.0.GA.jar三个文件添加到项目的WEB-INF/lib 文件夹下,要运行A4J还需要把commons-beanutils.jar、commons-collections.jar、commons-digester.jar和commons-logging.jar包添加到项目的WEB-INF/lib 文件夹下,然后把下面的内容添加到Web的程序的 WEB-INF/web.xml 文件中: Ajax4jsf Filter ajax4jsf org.ajax4jsf.Filter ajax4jsf Faces Servlet REQUEST FORWARD INCLUDE 接着在每个使用Ajax功能的JSP页面中添加下面的内容; <%@ taglib uri="; prefix="a4j"%> 23 榆林学院软件工程实验手册 24 6 创建实体Bean 6.1 创建实体表 在本例中首先创建一个员工信息记录表employees,该表所包含的字段有员工ID、员工姓名、 年龄、住址、信息录入日期。在前面的章节中己经介绍了数据库的创建和配置。本节利用前 面创建的MySQL数据库javaeedb来创建表,创建employees表的SQL清单如清单-2所示。 清单-2 USE javaeedb; CREATE TABLE employees ( id int(11) NOT NULL auto_increment, name varchar(56) NOT NULL default '', age int(11) default NULL, address varchar(128) default NULL, registerTime timestamp NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 创建foodinfo表的SQL清单如清单-3所示。 清单-3 create table `javaeedb`.`foodinfo`( `id` INT UNSIGNED not null auto_increment, `foodname` VARCHAR(45) default '' not null, `foodImg` VARCHAR(45), `foodprice` INT UNSIGNED default '' not null, `description` VARCHAR(145), `remark` VARCHAR(245), `count` INT UNSIGNED default '' not null, primary key (`id`) ); create unique index `PRIMARY` on `javaeedb`.`foodinfo`(`id`); 创建foodorderinfo表的SQL清单如清单-4所示。 清单-4 create table `javaeedb`.`foodorderinfo`( `telPhone` VARCHAR(15) default '' not null, `address` VARCHAR(45) default '' not null, `customerName` VARCHAR(25), `notice` VARCHAR(45), `send` VARCHAR(45), `zipCode` VARCHAR(6), `uid` VARCHAR(45) default '' not null, `orderdate` DATETIME default '' not null, `sumprice` INT UNSIGNED, `orderid` VARCHAR(20) default '' not null, primary key (`orderid`) ); create unique index `PRIMARY` on `javaeedb`.`foodorderinfo`(`orderid`); 创建shopcart表的SQL清单如清单-5所示。 清单-5 create table `javaeedb`.`shopcart`( `foodname` VARCHAR(45) default '' not null, `count` INT UNSIGNED default '' not null, `foodprice` INT UNSIGNED default '' not null, 24 榆林学院软件工程实验手册 25 `userid` VARCHAR(45) default '' not null, primary key (`foodname`,`userid`) ); create unique index `PRIMARY` on `javaeedb`.`shopcart`(`foodname`,`userid`); 创建orderitem表的SQL清单如清单-6所示。 清单-6 create table `javaeedb`.`orderitem`( `foodname` VARCHAR(45) default '' not null, `count` VARCHAR(45) default '' not null, `orderid` VARCHAR(20) default '' not null, primary key (`foodname`,`orderid`) ); alter table `javaeedb`.`orderitem` add index `FK_OrderItem_1`(`orderid`), add constraint `FK_OrderItem_1` foreign key (`orderid`) references `javaeedb`.`foodorderinfo`(`orderid`); create unique index `PRIMARY` on `javaeedb`.`orderitem`(`orderid`,`foodname`); .6.2 编写Entity 下面编写employees表对应的实体Bean,在前面章节己经创建了JavaEEAPPEJB应用模块, -7所示。 本例的测试代码都是基于JavaEEAPPEJB编写。Employees的部分源代码如清单 清单 -7 package com.javaee.jsfejb3demo.entity; .... @Entity//标注为实体Bean @Table(name = "employees", catalog = "javaeedb")//对应数据库中的表 public class Employees implements java.io.Serializable { // 实体的属性 private Integer id; private String name; private Integer age; private String address; private Date registerTime; @Id//定义实体ID @GeneratedValue(strategy = GenerationType.AUTO)//ID的产生方式为自动产生 @Column(name = "id", unique = true, nullable = false) public Integer getId() { return this.id; } //省略getter和setter方法 .... } 在上面代码中,用@GeneratedValue(strategy = GenerationType.AUTO)注解来设置id属性的值为自动增加,这样就需要在创建数据表时设置id字段的值为自动增加,例如在上面的employees表中,用auto_increment来表示id值为自动增加。 Foodinfo的部分源代码如清单-8所示。 清单 8 package com.javaee.jsfejb3demo.entity; .... @Entity//标注为实体Bean @Table(name = "foodinfo", catalog = "javaeedb") 25 榆林学院软件工程实验手册 26 public class Foodinfo implements java.io.Serializable { //实体的属性 private Integer id; private String foodname; private String foodImg; private Integer foodprice; private String description; private String remark; private Integer count; // 标注实体的ID @Id @GeneratedValue(strategy = GenerationType.AUTO) //ID的产生方式为自动产生 @Column(name = "id", unique = true, nullable = false) public Integer getId() { return this.id; } //省略getter和setter方法 .... } 在上面代码中,用@GeneratedValue(strategy = GenerationType.AUTO)注解来设置id属性的值 为自动增加,这样就需要在创建数据表时设置id字段的值为自动增加,例如在上面的 Foodorderinfo表中,用auto_increment来表示id值为自动增加。 清单 9 package com.javaee.jsfejb3demo.entity; .... @Entity//标注为实体Bean @Table(name = "foodorderinfo", catalog = "javaeedb") public class Foodorderinfo implements java.io.Serializable { // 实体的属性 private String orderid; private String telPhone; private String address; private String customerName; private String notice; private String send; private String zipCode; private String uid; private Date orderdate; private Integer sumprice; private Set orderItems = new HashSet(0); // 定义实体的ID @Id @Column(name = "orderid", unique = true, nullable = false, length = 20) public String getOrderid() { return this.orderid; } //省略getter和setter方法 .... //用@OneToMany注解为一个合同对应多个合同项目 @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "foodorderinfo") public Set getOrderItems() { return this.orderItems; } .... } 正如前面所介绍的内容,在EJB3规范中多对一这端几乎总是双向关联中的主体端,而一对 26 榆林学院软件工程实验手册 27 多这端的关联注解为@OneToMany( mappedBy= foodorderinfo),在上面程序中,Foodorderinfo 通过foodorderinfo属性和OrderItem建立了一对多的双向关联。 在mappedBy端不必也不能再定义任何物理映射。 清单 -10 package com.javaee.jsfejb3demo.entity; .... @Entity//标注为实体Bean @Table(name = "shopcart", catalog = "javaeedb") public class Shopcart implements java.io.Serializable { // 实体的属性 private ShopcartId id; private Integer count; private Integer foodprice; // 定义实体的复合主键 @EmbeddedId @AttributeOverrides( { @AttributeOverride(name = "foodname", column = @Column(name = "foodname", nullable = false, length = 45)), @AttributeOverride(name = "userid", column = @Column(name = "userid", nullable = false, length = 45)) }) public ShopcartId getId() { return this.id; } .... } 在Shopcart程序中,应用一个可嵌入的ShopcartId类作为主键表示,并使用@EmbeddedId 注解来表示Shopcart的复合主键,用@AttributeOverrides注释指明主键要中的字段属性覆盖对应Entity类中所关联表中的对应列。ShopcartId的部分源代码如清单11所示。 清单11 package com.javaee.jsfejb3demo.entity; .... @Embeddable//标注为是一个可嵌入式的实体 public class ShopcartId implements java.io.Serializable { // 实体字段 private String foodname; private String userid; //省略getter和setter方法 .... public boolean equals(Object other) { if ((this == other)) return true; if ((other == null)) return false; if (!(other instanceof ShopcartId)) return false; ShopcartId castOther = (ShopcartId) other; return ((this.getFoodname() == castOther.getFoodname()) || (this .getFoodname() != null && castOther.getFoodname() != null && this.getFoodname() .equals(castOther.getFoodname()))) && ((this.getUserid() == castOther.getUserid()) || (this .getUserid() != null && castOther.getUserid() != null && this.getUserid() .equals(castOther.getUserid()))); } public int hashCode() { int result = 17; 27 榆林学院软件工程实验手册 28 result = 37 * result + (getFoodname() == null ? 0 : this.getFoodname().hashCode()); result = 37 * result + (getUserid() == null ? 0 : this.getUserid().hashCode()); return result; } } OrderItem的部分源代码如清单 -12所示。 清单 12 package com.javaee.jsfejb3demo.entity; .... @Entity//标注为实体 @Table(name = "OrderItem", catalog = "javaeedb") public class OrderItem implements java.io.Serializable { // 实体属性 private OrderItemId id; private Foodorderinfo foodorderinfo; private String count; // 定义复合主键 @EmbeddedId @AttributeOverrides( { @AttributeOverride(name = "orderid", column = @Column(name = "orderid", nullable = false, length = 20)), @AttributeOverride(name = "foodname", column = @Column(name = "foodname", nullable = false, length = 45)) }) public OrderItemId getId() { return this.id; } .... //用@ManyToOne注解来表示一个定单可以有多个定单项 @ManyToOne(fetch = FetchType.LAZY) //@JoinColumn注解来指定OrderItem通过orderid与Foodorderinfo关联 @JoinColumn(name = "orderid", nullable = false, insertable = false, updatable = false) public Foodorderinfo getFoodorderinfo() { return this.foodorderinfo; } //省略getter和setter方法 .... } 在OrderItem程序中,用@ManyToOne注解来表示一个定单可以有多个定单项,并用@JoinColumn注解来指定OrderItem通过orderid与Foodorderinfo关联。 应用一个可嵌入的OrderItemId类作为主键表示,并使用@EmbeddedId注解来表示OrderItem的复合主键,用@AttributeOverrides注释指明主键要中的字段属性覆盖对应Entity类中所关联表中的对应列。OrderItemId的部分源代码如清单 -13所示,代码所在包javawebProject\JavaEEAPPEJB\src\com\javaee\jsfejb3demo\entity\ OrderItemId.java文件内容。 清单 -13 package com.javaee.jsfejb3demo.entity; .... @Embeddable//标注为可嵌入式组件 public class OrderItemId implements java.io.Serializable { // 组件的属性 private String orderid; private String foodname; // Property accessors @Column(name = "orderid", nullable = false, length = 20) 28 榆林学院软件工程实验手册 29 public String getOrderid() { return this.orderid; } public void setOrderid(String orderid) { this.orderid = orderid; } @Column(name = "foodname", nullable = false, length = 45) public String getFoodname() { return this.foodname; } public void setFoodname(String foodname) { this.foodname = foodname; } public boolean equals(Object other) { ... } public int hashCode() { ... } } .7 创建DAO 前面己创建了实体Bean,接下来需要创建访问各个实体Bean的DAO类。 , 用户管理 DAO接口 , 菜单管理 DAO接口 , 购物车管理DAO接口 , 定单管理DAO接口 , 用户管理接口的实现会话Bean , 创建菜单管理接口的实现 , 创建购物车接口的实现会话Bean , 创建定单管理接口的实现会话Bean .8 创建Web业务逻辑组件 , 用户管理服务组件 , .菜单管理服务组件 , . 购物车服务组件 , . 定单服务组件 , . 创建VO组件 .9 创建Action组件 , 创建JSF调用的用户管理Action组件 , 创建JSF调用的菜单管理Action组件 29 榆林学院软件工程实验手册 30 , 创建JSF调用的购物车管理Action组件 , 创建JSF调用的定单管理Action组件 .10 JSF的配置 与其他框架一样,JSF也有自己的配置文件,默认的JSF配置文件名为faces-config.xml。为了让JSF知道我们所设计的Bean以及页面流程,在配置文件中一般要配置JavaBean,在这个配置文件中管理的Bean叫做托管Bean(managed bean)、导航规则、注册自定义的转换器和验证器等。 .11 应用A4J和JSF设计Web页面 , 设计引导文件 , 设计登录页面 , 设计用户管理页面 , 设计主页面 , 设计菜单显示页面 , 设计购物车页面 , .设计定单页面 , 设计CSS文件 , 部署并运行程序 30 榆林学院软件工程实验手册 31 实验项目三:飞机零部件电子商务交易平台(BSP) 该系统是个简单的航材部件询价系统,简称BSP,通过该系统,可以实现航空部件维修公司与飞机部件供应商之间建立业务关系。维修商通过询价单向航材供应商询问航材价。 系统采用最流行的基于J2EE的SSH架构。该系统结构成熟、性能良好、运行稳定。系统中应用Spring的IoC容器负责管理业务逻辑组件、持久层组件及控制层组件,充分利用依赖注入的优势,进一步增强系统的解耦,提高应用的可扩展性,降低了系统统重构的成本, 后台定时计算的作业调度使用Quartz 框架完成。 其用户访问流量和 1 系统需求说明 1.1 项目背景 随着我国电子业发展,电子维修业也快速发展起来,部件维修商需要查询电子部件的的供应商和价格。通过价格对比,从而确定所要购买的航材,部件供应商能过该平台发布自己所要卖的航材。所以开发一套基于电子部件及价格查询系统以满足维修商和供应商之间的需求。 1.2 需求分析 如今基于互联网的电子商务系统越来越流行。BSP是一个在互联网上进行航材部件需求信息发布和部件询价以及建立客户关系的电子商务系统。电子部件维修商可以通过这个电子商务系统发布自己的需求信息。部件供应商可以发布自己的出售信息。 维修商通过BSP系统的用户界面,可以查看其他用户发布的求购信息,也可以查找部件供应商,加入到自己的联系人通讯录中。维修商可以注册公司的信息。给自己的客户发布部件询价单,以查询所需求的部件价格。部件供应商收到询价格单后,进行报价处理。 根据以上分析,得出程序的主要用例图,如图1所示。主要的角色(Actor)包括企业管理员(Administrator)、企业用户(Customer)、程序系统(System)和数据库(Database)。 31 榆林学院软件工程实验手册 32 图1 BSP用例图 下面介绍应用程序中的主要用例(user case)。 1.3 主要用例说明 1(用户登录和注册 用户登录是电子商务应用必需的功能之一。当用打开系统时,用户可以查看公共需求信息以用发布公共信息。但需要发布询价单时,BSP的登录页面要求用户输入用户名和口令及验证码。在输入用户名和口令及验证码后,系统将验证用户名和口令及验证码是否正确,如果验证成功,就使用户处于登录状态。否则,系统显示用户名或密码等错误信息。用户在登录页面中能查看己注册的公司信息而能够注册新用户。在注册用户前,需要先注册公司信息及公司管理员信息,如果公司信息己注册,则可以公司管理员ID登录系统,进行公司用户信息注册。 2(发布需求信息 用户可以公告板中发布求购航材或出售航材等信息。并且可以查看其他用户发布的信息。用户通过搜索查找自己感兴趣的信息。 3(增加联系人 用户可以添加系统中己注册的用户到自己的通讯录中,以便给联系人发送询价单。用户还可以认证己注册的公司。通过认证的公司,在发送询价单时,可以发给认证过的公司。 4(发布询价单 用户可以发送询价信息给自己的联系人或己认证的公司及所有公司。并可以查看己发送的询价单,用户也可以保存询价单为草稿,暂不发给用户。等编辑好询价后在发给用户。用户也可以删除草稿和取消询价。 2 系统架构设计 用例图分析了该应用系统的主要功能需求,这些需求是设计开发的依据。下面开始讲解BSP应用系统的架构设计。整个系统架构基于J2EE技术体系设计。 32 榆林学院软件工程实验手册 33 J2EE体系包括JSP、Servlet、EJB、Web Service等多项技术。这些技术的出现给电子商务时代的Web应用开发提供了一个非常有竞争力的选择。怎样把这些技术组合起来,形成一个适应项目需要的稳定架构是项目开发过程中一个非常重要的步骤。 此步骤一般主要由架构设计师完成,设计师将根据项目需求,对J2EE体系中的各处技术进行筛选取舍,并考虑到开发过程中的角色分工、后期的运行维护,以及系统扩展性等诸多因素,建立系统的架构。 一个成功的软件需要有一个成功的架构,但软件架构的建立是一个复杂而又持续改进的过程,软件开发者们不可能对每个不同的项目做不同的架构,而总是尽量重用以前的架构,或开发出尽量通用的架构方案,Struts就是其中之一,Struts是流行的基于J2EE的架构方案,其他常用的基于J2EE的架构方案还有Hibernate、Spring等。 BSP系统严格按MVC 模式设计,按J2EE 分层设计的理念,将中间层严格分成业务逻辑层、DAO 层和数据持久层等。MVC 层的控制器绝对禁止持久层访问,甚至不参与业务逻辑的实现。表现层采用传统JSP 技术。JSP 技术结合Struts 的标签库,让应用的表现层层次清晰,可读性比较好。 2.1 BSP系统架构说明 本系统采用的是典型的J2EE三层结构,分为表现层、中间层(业务逻辑层)和数据服务层。三层体系将业务规则、数据访问及合法性校验等工作放在中间层处理。客户端不直接与数据库交互,而是通过组件与中间层建立连接,再由中间层与数据库交互。该系统的表现层是传统的JSP 技术, JSP 技术自1999 年问世以来,经过多年的发展,其广泛的应用和稳定的表现,为其作为表现层技术打下了坚实的基础。中间层采用的是流行的Spring+Hibernate ,为了将控制层与业务逻辑层分离,又细分为以下几种。 1(客户层(Client Tier) J2EE应用可以是基于Web 的,也可以是不基于Web 的。在基于Web 的J2EE 应用中,用户的浏览器在客户层中运行,并从一个Web服务器上下载Web 层中的静态HTML 页面或由JSP 或Servlets 生成的动态HTML 页面 。 2(Web 层 J2EE Web组件可以由JSP 页面、基于Web 的Applets 以及显示HTML页面的Servlets 组成。调用Servlets 或者JSP 页面的HTML页面在应用程序组装时与Web 组件打包在一起。就像客户层一样,Web层可能包括一个Java Bean类来管理用户输入,并将输入发送到在业务层中运行的Enterprise Beans 类来处理 。运行在客户层的Web 组件依赖容器来支持诸如客户请求和响应及Enterprise Bean 查询等。一般来讲,一个典型的Web应用的的末端应该是表示层。 3(Service 层 Service层(业务逻辑层)负责实现业务逻辑。业务逻辑层以DAO 层为基础,通过对DAO组件的模式包装,完成系统所要求的业务逻辑。业务逻辑层包含布署层,可发送电子邮件、调用远程服务等。 4(DAO 层 数据访问DAO 层负责与持久化对象交互。该层封装了数据的增、删、查、改的操作。 5(数据持久层PO 数据持久层PO ,持久化对象。通过实体关系映射工具将关系型数据库的数据映射成对象, 33 榆林学院软件工程实验手册 34 很方便地实现以面向对象方式操作数据库,该系统采用Hibernate 作为ORM 框架。Spring 的作用贯穿了整个中间层,将Web 层、Service 层、DAO 层及PO 无缝整合。 BSP层次架构如图2所示,架构模型如图3所示。 图2 BSP层次架构模型 图3 BSP架构模型图 34 榆林学院软件工程实验手册 35 .2 系统软硬件环境 1(服务器端 , 操作系统:Windows 2003 Server 或者 2000 Server。 , 应用服务器:Tomcat 6。 , Java虚拟机:JDK 1. 6。 , 数据库系统:Java DB或MySql。 2(客户端 Linux。 , 操作系统:Windows 2000 或XP、 , IE 浏览器。 3(开发环境 , Java:Java SE6。 , 应用服务器:Tomcat 6。 , 开发工具:Eclipse3.3,MyEclipse6.5。 3 业务实体层设计 业务实体在内存中表现为实体域对象,在数据库中表现为关系数据。实现业务实体包括以下内容: , 设计域模型,创建域模型实体对象。 , 设计关系数据模型。 , 创建对象,关系映射文件。 其中,前两项适用于大多数由持久化数据驱动的应用程序,最后一项目是特定于Hibernate应用的。不同的实现方式可能需要不同的步骤。 3.1 设计域模型 BSP应用中的业务实体包括企业(BspCorp),用户(BspUser),通讯录(BspMySplContact),公司认证(BspCorpSpl),询价单(BspInq),询价单涉及航材(BspInqParts),公告信息(BspMessage)。下面将详细介绍这些实体模型含义。 (1)BspCorp:代表一个公司实体,主要属性包括企业代码(corpid)、中文企业(corpname)、英文企业名称(corpnameEn)、国家(nation)、企业地址(mad_cn)、电话号码(telnum)、联系人(contact)等。 (2)BspUser:代表一个用户实体,主要包括用户标识(usernbr)、用户名(fname)、 用户密码(password)、电子邮件、用户状态、联系地址、联系电话等。 (3)BspMySplContact:代表了一个联系人通讯录实体,主要属性包括我的代码(myid)、 我的联系人的代码(contid)、联系人姓名、联系人企业代码、联系人传真、联系人电话等。 (4)BspCorpSpl:代表一个己认证公司实体,主要属性包括企业代码(corpid)、供应商代码(spl)、有效日期(LDATE)、备注等。 (5)BspInq:代表一个询价单,主要属性包括询价记录代码(iid)、用户代码(buyerid)、询价日期(cdate)、 报价单状态(status)、备注等。 35 榆林学院软件工程实验手册 36 (6)BspInqParts:代表一个询价单涉及航材实体,主要属性包括询价记录代码(iid)、件号(pnr)、制造商代码(mfr)、关键字(keyw)、采购数量(qut)、计量单位代码、状态等。 (7)BspMessage:代表一个公告信息实体,主要属性包括标识(id)、主题(sbj)、信息类型(mty)、内容(cont)、发布日期(cdate)、有效期(exday)、截止日期(exdate)、联系人(contact)、联系方式等。 BSP应用域模型的业务实体关系图如图7所示,其中*代表0或多个。接下来将介绍各实体之间的对应关系。 BspCorp与BspUser之间是一对多的关系,一个企业可以注册多个员工账号,BspUser和BspMySplContact之间是一对多的关系,一个用户可以有多个联系人。BspUser与BspCorpSpl之间是一对多的关系,一个用户可以认证多个公司。BspInq与BspInqParts之间是一对多的关系,一个询价单中可以包括多个航材。BspInq与BspUser之间是多对一的关系,多个询价单可对应一个用户。 图7 BSP应用的业务实体关系图 3.2 设计数据模型 在图7中的BspCorp、BspUser、BspMySplContact、BspInq、BspInqParts、BspCorpSpl和BspMessage对象都需要持久化,它们在数据库中有对应的表。如图8所示为BSP的关系数据模型。在图8中,BspInqParts表是连接表,是BspInq的关联,下面介绍数据模型的数据字典。 企业实体注册BSP_CORP数据字典如表2所示。 表2企业实体注册数据字典 项次 字段名 必输 数据类型/长度 中文名/说明 1 CORP_ID Y(PK) VARCH/5 企业代码 2 CORPNAME_CN Y VARCH/50 企业名称(中文) 3 CORPNAME_EN Y VARCH/50 企业名称(英文) 4 NATION Y VARCH/15 国家 5 MAD_CN Y VARCH/100 企业地址(中文) 36 榆林学院软件工程实验手册 37 项次 字段名 必输 数据类型/长度 中文名/说明 6 MAD_EN Y VARCH/100 企业地址(英文) 7 TELNUM Y VARCH/15 电话号码 8 FAXNUM Y VARCH/15 传真号码 9 CONTACT Y VARCH/20 联系人 10 POSTCODE Y NUMBER/10 邮政编码 11 EMAIL Y VARCH/30 邮箱地址 12 CORPTYPE Y VARCH/3 企业类型:代码表(CORPTYPE):MFR:制造商; SPL:供应商 ALC:航空公司 REP:维修商 图8 BSP的关系数据模型 用户代码注册BSP_USER数据字典如表3所示。 表3 用户代码注册BSP_USER数据字典 项次 字段名 必输 数据类型/长度 中文名/说明 1 USERNBR Y(PK) VARCH/20 用户代码 2 FNAME Y VARCH/20 姓名 4 CORP_ID Y(FK) VARCH/5 企业代码 5 TELNUM NUMBER/15 办公室电话号码 37 榆林学院软件工程实验手册 38 项次 字段名 必输 数据类型/长度 中文名/说明 6 MPHONE NUMBER/12 个人移动电话号码 7 FAXNUM NUMBER/15 传真号码 8 UADD VARCH/100 地址 9 POSTCODE NUMBER/10 邮政编码 10 EMAIL Y VARCH/30 Email 邮箱地址 11 PASSWORD Y VARCH/10 口令 12 AST Y VARCH/1 用户账户状态;该字段允许BSP管理员进行更改。 "N"表示新用户 "A"表示活动用户 "C"表示取消或者禁止 14 ROLE VARCHAR(20) 角色: MFR:制造商; SPL:供应商 ALC:航空公司 REP:维修商 SYS:系统 + USER:注册用户 ADMIN:管理员 GUEST:未注册来客 企业实体认证的供应商BSP_CORP_SPL数据字典如表4所示。 表4 企业实体认证的供应商BSP_CORP_SPL数据字典 项次 字段名 必输 数据类型/长度 中文名/说明 1 CORP_ID Y VARCH/5 企业代码 2 SPL Y VARCH/5 供应商代码 3 LDATE Y DATE 有效日期 4 NOTES VARCH/3000 备注 我的供应商联系人BSP_MY_SPL_CONTACT数据字典如表5所示。 表5 我的供应商联系人BSP_MY_SPL_CONTACT数据字典 项次 字段名 必输 数据类型/长度 中文名/说明 1 MY_ID Y (PK) VARCH/20 我的代码 2 CONT_ID Y (PK) VARCH/20 我的联系人的代码 2 FNAME Y VARCH/20 姓名 3 LNAME VARCH/20 姓 4 CORP_ID Y(FK) VARCH/5 企业代码 5 TELNUM NUMBER/15 办公室电话号码 6 FAXNUM NUMBER/15 传真号码 7 MPHONE NUMBER/12 个人移动电话号码 8 UADD VARCH/100 地址 9 POSTCODE NUMBER/10 邮政编码 10 EMAIL Y VARCH/30 Email 邮箱地址 公告板BSP_MESSAGE数据字典如表6所示。 表6 公告板BSP_MESSAGE数据字典 项字段名 必数据类型/长度 中文名/说明 次 输 1 SID Y NUMBER(6) 惟一ID 2 SBJ Y VARCH/100 主题 3 MTY Y VARCH/2 信息类型 38 榆林学院软件工程实验手册 39 项字段名 必数据类型/长度 中文名/说明 次 输 "BU"表示"求购航材";"HI"表示"求租航材";"SE"表示"出售航 材"; "LE"表示"出租航材"; "AD"表示"管理信息" 4 CONT VARCH/256 内容 6 CDATE Y DATE TIME 发布日期 7 EXDAY Y INTEGER 有效期(Days) 8 EXDATE DATE TIME 截止日期 9 CONTACT Y VARCH/30 联系人 代码/姓名 10 CON_INF VARCH/100 联系人联系方式 询价记录表BSP_INQ数据字典如表7所示。 表7 询价记录表BSP_INQ数据字典 项次 字段名 必输 数据类型/长度 中文名/说明 1 IID Y (PK) VARCH/20 询价记录代码 询价单号:[企业代码][年月日/8][序列/7] 2 OIC VARCH/20 询价者内部询价单编号 3 BUYER_ID Y VARCH(20) 用户代码 4 CDATE Y DATE 询价日期 5 STATUS Y VARCHAR(2) 报价单状态: 0=草稿 ; 1=已发送 6 REM N VARCH/5000 备注 询价记录航材项次表BSP_INQ_PARTS数据字典如表8所示。 表8 询价记录航材项次表BSP_INQ_PARTS数据字典 项次 字段名 必输 数据类型/长度 中文名/说明 1 IID Y VARCH(20) 询价单号:[企业代码][年月日/8][序列/7] 2 IIN Y INT(3) 询价单项次编号 3 PNR Y VARCH(32) 件号 4 MFR Y VARCH(8) 制造商代码 5 KWD Y VARCH/30 关键字 (英文) 6 KWD_CN VARCH/30 关键字 (中文) 7 BQU Y NUMBER[2] 采购数量 8 UNT Y VARCH/2 计量单位代码 9 CND VARCH/2 状态代码 "NU":表示新件 "US":表示可用件 "OH":表示翻新件 10 LTM Y VARCH/3 订货至交货时间 11 PRI NUMBER/1 优先级 12 REM VARCH/500 备注 13 CERT VARCH/45 证书 供应商收到询价记录表BSP_INQ_SPL数据字典如表9所示。 表9 供应商收到询价记录表BSP_INQ_SPL数据字典 39 榆林学院软件工程实验手册 40 项次 字段名 必输 数据类型/长度 中文名/说明 1 IID Y VARCH/20 询价单号:[企业代码][年月日/8][序列/7] 2 SELLER_ID Y VARCH(20) 供应商操作员代码 3 SDATE DATETIME 发送时间 4 RESP_STATUS VARCHAR(2) 对询价单的应答状态: 0=没有应答(未读) 1=正在作报价 2=报价已发出 3=不报价 5 RDATE DATETIME 接收时间 6 QID VARCHAR(20) 报价单代码 BUYER_ID VARCHAR(20) 询价人代码 由于篇幅所限,上述数据字典对应用的创建数据模型的SQL不在列出,对应的创建实体数据模型的SQL请参考光盘中的javawebProject\bspdemo\src\com\bsp\dbsql目录下的SQL文件内容,其中公司实体BSP_CORP数据模型对应的文件为bsp_corp.sql,用户实体BSP_USER数据模型对应的文件为bsp_user.sql,公司认证数据模型对应的文件为bsp_corp_spl.sql,联系人数据模型对应的文件为bsp_my_spl_contact.sql,询价单数据模型对应的文件为bsp_inq.sql,询价单涉及航材数据模型对应的文件为bsp_inq_parts.sql,公告信息数据模型对应的文件为bsp_message.sql,供应商收到的询价单实体对应的文件为bsp_inq_spl.sql。 3.3 创建数据库 BSP系统采用MySql作为数据库,应用MySql管理员图形工具创建一个名为bspdb的数据库,然后在MySql Query Browser执行光盘中的javawebProject\bspdemo\src\com\bsp\dbsql目录下的SQL建表语句。 4 BSP开发环境的搭建 4.1 应用MyEclipse创建BSP项目 首先应用MyEclipse建立一个J2EE Web项,选择MyEclipse主菜单中的File?New Project命令,建立一个Web项目,取名为bspdemo。如图9所示。同时需要运行的JDK必须为JDK1.5以上版本。Struts 2的Web应用默认需要Java 5运行环境,需要Web容器支持Servlet API 2.4和JSP API 2.0。J2EE 版本不要选择为Java EE 5.0,否则Struts 2应用无法启动。 40 榆林学院软件工程实验手册 41 选择J2EE1.4 图9 创建BSP项目 4.2 Hibernate Annonations设置 在上面新建的bspdemo项目上,单击右键,弹出的菜单中选择MyEclipse项,如图10所示,在弹出的子菜单中,选择Add Hibernate Capabilitiesa项,弹出如图10所示对话框,在弹出的设置向导中,可以产生Hibernate配置文件,并自动加载Hibernate所需的类库。在Hibernate 3.2以前,Hibernate依靠外部的XML文件来配置持久化对象,数据库映射文件定义在一组XML映射文件里并且在程序开始的时候被装载,从Hibernate 3.2版本开始,利用新的Hibernate Annonations 库,可以发布一次如你以前的映射文件所定义的信息,就是把注解直接嵌入Java类文件中,注解带来了一种强大灵活地声明持久化映射的办法。所以在图11所示的页面中选择Enable Hbernate Annonations Souport项,以便加入Hibernate Annonations 库。 图10 选择Add Hibernate Capabilitiesa项 41 榆林学院软件工程实验手册 42 选择Hibernate Annotations 项目 AnaAaAAA 图11 设计Hibernate向导 Hibernate annotations 也支持最新的EJB 3持久化规范,这些规范目的是提供一个标准的Java持久化机制。当然Hibernate 3也提供了更多的解决方案,能够非常容易的靠近标准并且利用EJB 3编程模型编写Hibernate持久化层。在BSP系统中,采用最新的Hibernate annotations 作为类与实体之间的映射, Hibernate annotations支持最新的EJB 3持久化规范,这些规范目的是提供一个标准的Java持久化机制。当然Hibernate 3也提供了更多的解决方案,能够非常容易的靠近标准并且利用EJB 3编程模型编写Hibernate持久化层。 4.3 应用Hibernate 3注解设计数据持久层 设置完Hibernate配置后,在bspdemo项目的src目录建立一个com.bsp.entity多级类包,在如图12所示的MyEclipse数据库导航器中,选中所要创建表,单击右键,在弹出的菜单中,选择Hibernate Reverses Enginnering项,弹出如图13所示对话框。 图12 MyEclipse数据库导航器 42 榆林学院软件工程实验手册 43 选择Hibernate Annotations 项目AnaAaAAA 图13 生成POJO向导 根据向导提示,生成相对应的Hibernate annotations POJO文件。这里列出生成的经修改后的Hibernate annotations POJO映射文件。要使用二级缓存,还需要在Hibernate配置文件中设置,设置内容如下: org.hibernate.cache.EhCacheProvider true 然后在实体Bean中增加@Cache注解即可。 BspCorp类的映射文件BspCorp.java部分内容如清单1所示,代码所在包javawebProject\bspdemo\src\com\bsp\entity\BspCorp.java文件内容。 清单1 package com.bsp.entity; ...... import org.hibernate.validator.Length; import org.hibernate.validator.NotNull; import org.hibernate.annotations.CacheConcurrencyStrategy; @Entity//标记为实体 //添加二级缓存,指定缓存的策略为非严格读/写缓存策略 @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) @Table(name="bsp_corp" ,catalog="bspdb" ) public class BspCorp implements java.io.Serializable { // 字段属性 ...... private Set bspMySplContacts = new HashSet(0); private Set bspUsers = new HashSet(0); private Set bspCorpSpls = new HashSet(0); @Id //标注为实体的ID @NotNull(message = "编号不能为空") @Length(min = 1, max = 5, message = "编号长度应在1至5之间") @Column(name="CORP_ID", unique=true, nullable=false, length=5) // 省略getter和setter方法 ...... //标记为一对多的映射关系 43 榆林学院软件工程实验手册 44 @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="bspCorp") public Set getBspMySplContacts() { return this.bspMySplContacts; } @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="bspCorp") public Set getBspUsers() { return this.bspUsers; } @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="bspCorp") public Set getBspCorpSpls() { return this.bspCorpSpls; } ........ } 正如前面所介绍的内容,在EJB3规范中多对一这端几乎总是双向关联中的主体端,而一对多这端的关联注解为@OneToMany( mappedBy= bspCorp),在上面程序中,BspCorp通过bspCorp属性和BspCorpSpl、BspUser、BspMySplContact建立了一对多的双向关联。 在mappedBy端不必也不能再定义任何物理映射。 BspUser类的映射文件BspUser.java部分内容如清单2所示,代码所在包javawebProject\bspdemo\src\com\bsp\entity\BspUser.java文件内容。 清单2 package com.bsp.entity; .... @Entity //添加二级缓存,指定缓存的策略为非严格读/写缓存策略 @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) @Table(name = "bsp_user", catalog = "bspdb") public class BspUser implements java.io.Serializable { // 字段属性 ... @Id @NotNull(message = "用户编号不能为空") @Length(min = 1, max = 20, message = "用户编号长度应在1至20之间") @Column(name = "USERNBR", unique = true, nullable = false, length = 20) // 省略getter和setter方法 //@ManyToOne表示一个公司可以有多个职员 @ManyToOne(fetch = FetchType.LAZY) //@JoinColumn注解来指定BspUser通过CORP_ID与BspCorp关联 @JoinColumn(name = "CORP_ID", nullable = false) public BspCorp getBspCorp() { return this.bspCorp; } ... } 在BspUser文件中,用@ManyToOne注解来表示一个公司可以有多个职员,并用@JoinColumn注解来指定BspUser通过CORP_ID与BspCorp关联。 BspCorpSpl类的映射文件BspCorpSpl.java部分内容如清单3,代码所在包javawebProject\bspdemo\src\com\bsp\entity\BspCorpSpl.java文件内容。 清单3 package com.bsp.entity; ... @Entity @Table(name = "bsp_corp_spl", catalog = "bspdb") public class BspCorpSpl implements java.io.Serializable { // 字段属性 .... 44 榆林学院软件工程实验手册 45 @EmbeddedId//定义BspCorpSpl的复合主键 @AttributeOverrides( {@AttributeOverride(name = "corpId", column = @Column(name = "CORP_ID", nullable = false, length = 5)), @AttributeOverride(name = "spl", column = @Column(name = "SPL", nullable = false, length = 5)) }) public BspCorpSplId getId() { return this.id; } //@ManyToOne注解来表示一个公司可以有多个认证联系人 @ManyToOne(fetch = FetchType.LAZY) //@JoinColumn注解来指定BspCorpSpl通过CORP_ID与BspCorp关联 @JoinColumn(name = "CORP_ID", nullable = false, insertable = false, updatable = false) public BspCorp getBspCorp() { return this.bspCorp; } ... } 在BspCorpSpl文件中,用@ManyToOne注解来表示一个公司可以有多个认证联系人,并用@JoinColumn注解来指定BspCorpSpl通过CORP_ID与BspCorp关联。同时应用一个可嵌入的BspCorpSplId类作为主键表示,并使用@EmbeddedId注解来表示BspCorpSpl的复合主键,用@AttributeOverrides注释指明主键要中的字段属性覆盖对应Entity类中所关联表中的对应列。BspCorpSplId主键类的部分实现代码如清单4所示,代码所在包javawebProject\bspdemo\src\com\bsp\entity\BspCorpSplId.java文件内容。 清单4 package com.bsp.entity; .... @Embeddable public class BspCorpSplId implements java.io.Serializable { // 字段属性 private String corpId; private String spl; @NotNull(message = "编号不能为空") @Length(min = 1, max = 5, message = "编号长度应在1至5之间") @Column(name = "CORP_ID", nullable = false, length = 5) public String getCorpId() { return this.corpId; } .... public boolean equals(Object other) { if ((this == other)) return true; if ((other == null)) return false; if (!(other instanceof BspCorpSplId)) return false; BspCorpSplId castOther = (BspCorpSplId) other; return ((this.getCorpId() == castOther.getCorpId()) || (this .getCorpId() != null && castOther.getCorpId() != null && this.getCorpId().equals( castOther.getCorpId()))) && ((this.getSpl() == castOther.getSpl()) || (this.getSpl() != null && castOther.getSpl() != null && this.getSpl().equals( castOther.getSpl()))); } public int hashCode() { int result = 17; 45 榆林学院软件工程实验手册 46 result = 37 * result + (getCorpId() == null ? 0 : this.getCorpId().hashCode()); result = 37 * result + (getSpl() == null ? 0 : this.getSpl().hashCode()); return result; } } 在上面程序中,复合主键类实现java.io.serializable并具必须实现equals()和hashcode()方法。 BspMySplContact类的映射文件BspMySplContact.java部分内容如清单5所示,代码所在包javawebProject\bspdemo\src\com\bsp\entity\BspMySplContact.java文件内容。 清单5 package com.bsp.entity; ... @Entity @Table(name = "bsp_my_spl_contact", catalog = "bspdb") public class BspMySplContact implements java.io.Serializable { // 字段属性 ... @EmbeddedId//用@EmbeddedId注解来表示BspMySplContact的复合主键 @AttributeOverrides( { @AttributeOverride(name = "myId", column = @Column(name = "MY_ID", nullable = false, length = 20)), @AttributeOverride(name = "contId", column = @Column(name = "CONT_ID", nullable = false, length = 20)) }) public BspMySplContactId getId() { return this.id; } //用@ManyToOne注解来表示一个公司可以有多个联系人 @ManyToOne(fetch = FetchType.LAZY) //用@JoinColumn注解来指定BspMySplContact通过CORP_ID与BspCorp关联 @JoinColumn(name = "CORP_ID", nullable = false) public BspCorp getBspCorp() { return this.bspCorp; } .... } 在BspMySplContact文件中,用@ManyToOne注解来表示一个公司可以有多个联系人,并用@JoinColumn注解来指定BspMySplContact通过CORP_ID与BspCorp关联。同时应用一个可嵌入的BspMySplContactId类作为主键表示,并使用@EmbeddedId注解来表示BspMySplContact的复合主键,用@AttributeOverrides注释指明主键要中的字段属性覆盖对应Entity类中所关联表中的对应列。BspMySplContactId主键类的部分实现代码如清单6所示,代码所在包 javawebProject\bspdemo\src\com\bsp\entity\BspMySplContactId.java文件内容。 清单6 package com.bsp.entity; ... @Embeddable public class BspMySplContactId implements java.io.Serializable { // 字段属性 ... @NotNull(message = "编号不能为空") @Length(min = 1, max = 20, message = "编号长度应在1至20之间") @Column(name = "MY_ID", nullable = false, length = 20) public String getMyId() { return this.myId; } 46 榆林学院软件工程实验手册 47 .... } BspInq类的映射文件BspInq.java部分内容如清单7所示,代码所在包javawebProject\bspdemo\src\com\bsp\entity\BspInq.java文件内容。 清单7 package com.bsp.entity; ... @Entity @Table(name = "bsp_inq", catalog = "bspdb") public class BspInq implements java.io.Serializable { // 字段属性 private Set bspInqSpls = new HashSet(0); private Set bspInqPartses = new HashSet(0); ... @Id @Column(name = "IID", unique = true, nullable = false, length = 20) public String getIid() { return this.iid; } // BspInq通过bspInq属性和BspInqParts建立了一对多的双向关联 @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "bspInq") public Set getBspInqSpls() { return this.bspInqSpls; } //用@OneToMany元素来表示一个BspInq询价单应用多个BspInqParts部件项 @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "bspInq") public Set getBspInqPartses() { return this.bspInqPartses; } ... } 在BspInq文件中,用@OneToMany元素来表示一个BspInq询价单应用多个BspInqParts部件项,在上面程序中,BspInq通过bspInq属性和BspInqParts建立了一对多的双向关联。 在mappedBy端不必也不能再定义任何物理映射。 BspInqParts类的映射文件BspInqParts.java部分内容如清单8所示,代码所在包javawebProject\bspdemo\src\com\bsp\entity\BspInqParts.java文件内容。 清单8 package com.bsp.entity; ... @Entity @Table(name = "bsp_inq_parts", catalog = "bspdb") public class BspInqParts implements java.io.Serializable { // 字段属性 ... @EmbeddedId//用@EmbeddedId元素来表示BspInqParts的组合主键 @AttributeOverrides( { @AttributeOverride(name = "iin", column = @Column(name = "IIN", nullable = false)), @AttributeOverride(name = "iid", column = @Column(name = "IID", nullable = false, length = 20)) }) public BspInqPartsId getId() { return this.id; } //用@ManyToOne元素来表示多个询价部件BspInqParts对应一个询价单BspInq @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "IID", nullable = false, insertable = false, updatable = false) public BspInq getBspInq() { 47 榆林学院软件工程实验手册 48 return this.bspInq; } ... } 在BspInqParts文件中,用@EmbeddedId元素来表示BspInqParts的组合主键,组合主键由 BspInqPartsId类表示。同时用@ManyToOne元素来表示多个询价部件BspInqParts对应一个 询价单BspInq。BspInqPartsId主键类的部分实现代码如清单9所示,代码所在包 javawebProject\bspdemo\src\com\bsp\entity\BspInqPartsId.java文件内容。 清单9 package com.bsp.entity; ... @Embeddable public class BspInqPartsId implements java.io.Serializable { // 字段属性 private Integer iin; private String iid; ... @NotNull(message = "编号不能为空") @Length(min = 1, max = 20, message = "编号长度应在1至20之间") @Column(name = "IID", nullable = false, length = 20) public String getIid() { return this.iid; } ... } BspMessage类的映射文件BspMessage.java部分内容如清单10所示,代码所在包 javawebProject\bspdemo\src\com\bsp\entity\BspMessage.java文件内容。 清单10 package com.bsp.entity; ... @Entity @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) @Table(name = "bsp_message", catalog = "bspdb") public class BspMessage implements java.io.Serializable { // 字段属性 @Id @NotNull(message = "编号不能为空") @Length(min = 1, max = 5, message = "编号长度应在1至5之间") @Column(name = "SID", unique = true, nullable = false) public Integer getSid() { return this.sid; } ... } BspInqSpl类的映射文件BspInqSpl.java部分内容如清单11所示,代码所在包 javawebProject\bspdemo\src\com\bsp\entity\BspInqSpl.java文件内容。 清单11 package com.bsp.entity; ... @Entity @Table(name = "bsp_inq_spl", catalog = "bspdb") public class BspInqSpl implements java.io.Serializable { // 字段属性 ... @EmbeddedId @AttributeOverrides( { 48 榆林学院软件工程实验手册 49 @AttributeOverride(name = "iid", column = @Column(name = "IID", nullable = false, length = 20)), @AttributeOverride(name = "sellerId", column = @Column(name = "SELLER_ID", nullable = false, length = 20)) }) public BspInqSplId getId() { return this.id; } //用@ManyToOne元素来表示一个询价单BspInq发送个多个接收人 @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "IID", nullable = false, insertable = false, updatable = false) public BspInq getBspInq() { return this.bspInq; } ... } 在BspInqSpl文件中,用@EmbeddedId元素来表示BspInqSpl的组合主键,组合主键由BspInqSplId类表示。BspInqSplId主键类的部分实现代码如清单12所示,代码所在包javawebProject\bspdemo\src\com\bsp\entity\BspInqSplId.java文件内容。 package com.bsp.entity; ... @Embeddable public class BspInqSplId implements java.io.Serializable { // 字段属性 private String iid; private String sellerId; ... @NotNull(message = "编号不能为空") @Length(min = 1, max = 20, message = "编号长度应在1至20之间") @Column(name = "IID", nullable = false, length = 20) public String getIid() { return this.iid; } ... } 通过使用Hibernate 持久层,可以避免使用传统的JDBC 操作数据库,从而能够更好地使用面向对象的方式来操作数据库。保证了整个软件开发过程以面向对象的方式进行,即面向对象分析、设计及编程。 4.4 Struts 2.1应用设置 在BSP系统,应用Struts 2.1作为控制层中间件,首先需要把前面下载的struts-2.1.6-all.zip freemarker.jar、解压包中lib目录中的struts2-spring-plugin-2.1.6.jar、commons-logging.jar、ognl.jar、struts2-core.jar、xwork.jar、 commons-io-1.3.2.jar、commons-fileupload-1.2.1.jar、struts2-dojo-plugin-2.1.6.jar、struts2-dwr-plugin-2.1.6.jar、spring-web-2.5.3.jar (lib目录中Struts 2框架的类库有版本后缀。例如commons-logging.jar,可能是commons-logging-1.0.4.jar;struts2-core.jar可能是struts2-core-2.1.6.jar),加入到项目的WEB-INF\lib目录中,这里需要确保这些包的版本一致。然后打开WebRoot\WEB-INF目录中的web.xml文件,在其内容中添加Struts 2配置内容,配置后的内容如下: 最后在bspdemo项目的src目录下创建一个Struts.properties配置文件,内容如下: #指定Struts 2处于开发状态 struts.devMode = true #指定当Struts 2配置文件改变后,Web框架是否重新加载Struts 2配置文件 struts.configuration.xml.reload=true #设置字符集 struts.i18n.encoding=UTF-8 #该属性指定Http的请求后缀 struts.action.extension=do,action #指定当前应用默认的国际化地区信息 #struts.locale=zh_cn struts.custom.i18n.resources=globalMessages struts.objectFactory =spring 4.5 Spring 2.5应用设置 在创建Hibernate 3.2+Spring2.5+Struts 2.1应用程序时,需要相应的类库,应用MyEclipse开发时,可通过开发向导导入所需要的包,具体方法在新建的项目上,单击右键,在弹出的菜单中选择Properties项,弹出如图14所示对话框。在对话框中选择Java Build Path项。在右边选择第三个Tab项Libraries,列出了当前项目己添加的类库,要添加MyEclipse中的类库,单击Add Library按钮,弹出如图15 所示对话框。在弹出的对话框中选择MyEclipse Libraties 项,单击Next按钮,进入MyEclipse Libratis库的选择界面,如图16所示。本例选择的类库有Spring 2.5 AOP Libraties、Spring 2.5 Core Libraties、Spring 2.5 Misc Libraties和Spring2.0 Persistence Core Libraties。 50 榆林学院软件工程实验手册 51 图14 类库配置页面 4.6 Dojo应用设置 Dojo的下载地址为:, 当前最新版本是1.2.3。笔者下载的开发为dojo-release-1.2.3.tar.gz。解压后需要将 Dojo放在对应Tomcat服务器的 Web 目录下。在BSP系统中,已经创建了一个名为bspdemo的项目。首先需要在Tomcat服务器webapps\bspdemo目录下创建一个dojoapp子目录,然后把dojo-release-1.2.3.tar.gz包中的内容解压到该目录中。 4.7 DWR应用设置 在Struts 2中使用DWR实现AJAX表单校验,为了让DWR的核心Servlet起作用,必须在web.xml文件中配置核心Servlet,配置代码如下: dwr org.directwebremoting.servlet.DwrServlet debug true dwr /dwr/* 此外还需要配置一个dwr.xml文件,将此文件放在WEB-INF\目录下,它的内容可以是固定的,代码如下: 51 榆林学院软件工程实验手册 52 ); ]]> DWR的下载地址为,最新测试版本为3.0。这里下载的应用包为dwr.war,解压后将WEB-INF\lib中的所有jar包放在Web工程的WEB-INF\lib\目录中。这里还需要Struts 2解压包中lib目录中struts2-dwr-plugin-2.1.6.jar包。 至此,BSP项目的开发环境已搭建完毕,接下来进一步设计BSP其他现层的代码。 5 DAO层设计 在持久层的基础上,可以使用DAO 组件再次封装数据库操作。通过DAO 层,可以让业务逻辑层与具体持久层技术分离,一旦需要更换持久层技术时,业务逻辑层组件不需要任何改变。因此,使用DAO 组件,即意味着引入DAO 模式,使每个DAO 组件包含了数据库的访问逻辑,每个DAO 组件可对一个数据库表完成基本的CRUD等操作。 DAO 模式的实现至少需要如下三个部分: (1)DAO工厂类。 (2)DAO接口。 (3)DAO接口的实现类。 DAO模式抽象出数据访问方式,业务逻辑组件无须理会底层的数据库访问,而只专注于业务逻辑的实现。DAO将数据访问集中在独立的一层,所有的数据访问都由DAO对象完成,这层独立的DAO分离了数据访问的实现与其他业务逻辑,使得系统更具可维护性。DAO还有助于提升系统的可移植性。独立的DAO层使得系统能在不同的数据库之间轻易切换,底层的数据库实现对于业务逻辑组件是透明的。数据库移植时仅仅影响DAO层,不同数据库的切换不会影响业务逻辑组件,因此提高了系统的可复用性。对于不同的持久层技术, Spring的DAO提供一个DAO模板,将通用的操作放在模板里完成,而对于特定的操作,则通过回调接口完成。Spring为Hibernate提供的DAO支持类是HibernateDaoSupport 。 由于DAO组件中的方法会随着业务逻辑的需求而增加,但以下几个方法是通用的。 , save:保存持久化实例。 , update: 更新持久化实例。 , delete: 删除持久化实例。 , get: 根据主键加载持久化实例。 使用DAO接口的原因是避免业务逻辑组件与特定的DAO组件耦合。DAO接口没有任何实现方法,仅仅是对DAO组件包含的CRUD方法的定义,这些方法定义的实现取决于具体的实现类, DAO组件的实现既可以使用传统JDBC ,也可以采用Hibernate持久化技术,以及iBATIS 等技术。BSP应用中部分持久化类、DAO层及上层业务逻辑的关系图如图17 52 榆林学院软件工程实验手册 53 所示。 图17 持久化类、DAO层及上层业务逻辑的关系图 下面介绍DAO接口的代码定义。 BspCorpDAO接口程序代码如清单13所示。 清单13 package com.bsp.dao; import java.util.List; import com.bsp.entity.BspCorp; public interface BspCorpDAO { //根据属性和对应的值查找公司信息 public List findByProperty(String propertyName, Object value); public void save(BspCorp transientInstance);// 保存公司信息 public void update(BspCorp transientInstance);// 更新公司信息 public BspCorp findById(java.lang.String id);// 根据公司ID查找 public void delete(String id);//删除公司信息 } BspUserDAO接口代码如清单14所示。 清单14 package com.bsp.dao; import java.util.List; import com.bsp.entity.BspUser; public interface BspUserDAO { public int valid(String id, String pass);// 验证用户登录信息 //根据属性和对应的值查找用户信息 public List findByProperty(String propertyName, Object value); public void save(BspUser transientInstance);//保存员工信息 public void update(BspUser transientInstance);//更新用户信息 public BspUser findById(java.lang.String id);//根据用户ID查找用户信息 public void delete(String id); } BspCorpSplDAO接口代码如清单15所示。 清单15 package com.bsp.dao; import java.util.List; import com.bsp.entity.BspCorpSpl; public interface BspCorpSplDAO { public java.util.List getCerCorp(String uid) ;//根据公司ID查找认证的公司信息 public java.util.List geCorp() ;//查找系统中所有公司信息 public void save(BspCorpSpl transientInstance);//保存认证公司信息 public void update(BspCorpSpl transientInstance);//更新公司认证信息 53 榆林学院软件工程实验手册 54 public List getAllCorp(String uid);//查找除用户ID外的所有公司信息 } BspMySplContactDAO接口代码如清单16所示。 清单16 package com.bsp.dao; import java.util.List; import com.bsp.entity.BspMySplContact; public interface BspMySplContactDAO { public java.util.List getMyContact(String uid) ;//根据用户ID查找联系人信息 public void save(BspMySplContact transientInstance);//保存联系人信息 public List getUser(String cid,String unbr);//根据用户ID查找用户信息 public void update(BspMySplContact transientInstance); public List getInqContact(String uid) ;//根据我的ID查找我的联系人 } BspMessageDAO接口代码如清单17所示。 清单17 package com.bsp.dao; import com.bsp.entity.BspMessage; import com.bsp.util.PageBean; public interface BspMessageDAO { public java.util.List getBspMessage(String context,String type,PageBean pagebean) ;//分页根据公告标题或内容和公告类型查找公告信息 public java.util.List getBspMessage(String context,String type );//根据公告标题或内容和公告类型查找公告信息 public void save(BspMessage transientInstance);//保存公告信息 public Integer findNewId();//// 生成公告信息ID } BspInqDAO接口代码如清单18所示。 清单18 package com.bsp.dao; import java.util.List; import com.bsp.entity.BspInq; public interface BspInqDAO { public int getInqRow();//获得询价单表中的记录数 public BspInq findById(java.lang.String id);//根据询价单号查找询价单信息 public void save(BspInq transientInstance);//保存询价单信息 public List findByProperty(String propertyName, Object value);//根据属性和对应的值查找发出去的询价单信息 } BspInqPartsDAO接口代码如清单19所示。 清单19 package com.bsp.dao; import com.bsp.entity.BspInqParts; public interface BspInqPartsDAO { public void save(BspInqParts transientInstance);//保存部件列表 } 6 业务逻辑层设计 业务逻辑组件同样分为接口和实现类两个部分,接口用于定义业务逻辑组件,定义 业务逻辑组件必须实现的方法是整个系统运行的核心。BSP核心的业务逻辑主要分为3类,分别为用户账户相关操作的逻辑、询价单操作相关逻辑和公告信息发布操作相关的逻辑。因此在服务逻辑层设计了3个服务类,分别为AccountManager、InqManager和MessageManager。 54 榆林学院软件工程实验手册 55 每个服务都有对应的接口和实现。增加业务逻辑组件的接口,也是为了提供更好的解耦。通过面向接口编程,控制器无须与具体的业务逻辑组件耦合,而是面向接口编程。假如需要改变业务逻辑的实现时,可以只提供新的实现类,而不需要改变其控制器代码。上层调用者通过Manager的工厂方法获取所需要的Manager实例。Manager工厂的实现是由Spring容器来管理,工厂所需的DAO组件由Spring 的反向控制(Inverse of Control, IoC)或者称为依赖注入(Dependency Injection , DI)机制完成的。这样,业务逻辑和DAO都在Spring的统一控制下进行操作。 ManagerFactory工厂类的代码如清单20所示。 清单20 package com.bsp.service; public class ManagerFactory { //定义Manager工厂方法,该工厂的实现组件由Spring注入和管理 protected AccountManager accountmanager; protected InqManager inqmanager; protected MessageManager messagemanager; //依赖注入业务逻辑组件必需的setter和getter方法 public void setAccountmanager(AccountManager mag) { this.accountmanager = mag; } public AccountManager getAccountmanager() { return this.accountmanager; } public void setInqmanager(InqManager mag) { this.inqmanager = mag; } public InqManager getInqmanager() { return this.inqmanager; } public void setMessagemanager(MessageManager mag) { this.messagemanager = mag; } public MessageManager getMessagemanager() { return this.messagemanager; } } AccountManager接口代码如清单21所示。 清单21 package com.bsp.service; import java.util.List; import com.bsp.entity.*; public interface AccountManager { public void saveBspCorp(BspCorp transientInstance);// 保存公司信息 public void saveBspUser(BspUser transientInstance);//保存员工信息 public void saveBspSpl(BspCorpSpl transientInstance);//保存认证公司信息 public void updateBspCorp(BspCorp transientInstance);// 更新公司信息 public void updateBspUser(BspUser transientInstance);//更新用户信息 public void updateBspSpl(BspCorpSpl transientInstance);//更新公司认证信息 public BspCorp findByCorpId(String id);// 根据公司ID查找 public java.util.List getMyContact(String uid) ;//根据用户ID查找联系人信息 public void save(BspMySplContact transientInstance);//保存联系人信息 public List getUser(String cid,String unbr);//根据公司ID和用户ID查找用户信息 public BspUser findByUserId(String id);//根据用户ID查找用户信息 public List getCerCorp(String uid) ; public List getAllCorp(String uid);//查找除用户ID外的所有公司信息 public List findBspUserByProperty(String propertyName, Object value);//根据属性和对应的值查找用户信息 55 榆林学院软件工程实验手册 56 public List getInqContact(String uid) ;//根据我的ID查找我的联系人 public List findBspCorpByProperty(String propertyName, Object value);//根据属性和对应的值查找公司信息 public List findSplByProperty(String corpid);//根据公司ID查找己认证公司信息 public List findCorp();//查找系统中所有公司信息 // 验证用户登录信息 public int validateUser(String username, String pass, String vcode, String vcode1); } InqManager接口代码如程序清单22所示。 清单22 package com.bsp.service; import java.util.List; import com.bsp.entity.*; public interface InqManager { public List findInqByProperty(String propertyName, Object value) ;//根据属性和对应的值查找发出去的询价单信息 public List findInqsplByProperty(String propertyName, Object value) ;//根据属性和对应的值查找供应商收到询价记录表信息 public void saveInq(BspInq transientInstance);//保存询价单信息 public void saveParts(BspInqParts transientInstance);//保存部件列表 public void saveInqSpl(BspInqSpl transientInstance);//保存供应商收到询价记录表 public BspInq findById( java.lang.String id);//根据询价单号查找询价单信息 public int getInqRow();//获得询价单表中的记录数 } MessageManager接口代码如程序清单23所示。 清单23 package com.bsp.service; import com.bsp.entity.*; import com.bsp.util.PageBean; public interface MessageManager { public java.util.List getBspMessage(String context,String type,PageBean pagebean) ;//分页根据公告标题或内容和公告类型查找公告信息 public java.util.List getBspMessage(String context,String type) ;//根据公告标题或内容和公告类型查找公告信息 public void save(BspMessage transientInstance);//保存公告信息 public Integer findNewId();//// 生成公告信息ID } 7 Web层设计 系统的Web 层采用的是经典的J2EE Web MVC 框架Struts ,其表现层也大量使用Struts的标签库及JSP技术。同时也应用Web 2.0及Ajax技术。 一个良好的用户界面(UI)设计对一个系统的成功是至关重要的。一个使用起来困难的界面,会造成用户直接拒绝使用该系统,而不管系统的功能如何。因此,用户界面的设计是系统成功完成的重要组成部分。探索性的开发是用户界面设计的最有效方式,如图18所示,为用户界面设计的迭代过程。 56 榆林学院软件工程实验手册 57 图18 用户界面设计的迭代过程 7.1 表现层UI设计 表现层主要体现用户界面的设计,BSP采用了软件设计中常用的界面开发方法。这里只设计各功能模块的表示界面,方便开发人员设计界面。为统一界面样式风格,采用style.css样式定义的方式约定系统的界面风格。 1(BSP主页面UI BSP主页面由操作导航栏、标题栏、内容显示组成。导航栏主要显示功能模块及用户登录等相关操作。标题栏显示系统的LOG、登录人员信息、常用功能导航等功能。内容显示栏为工作区内容,用户的所有操作都在本区域内进行。BSP主页面如图18所示。 图18 BSP主页面 2(用户注册 使用该系统的每个用户都有一个在系统中注册的公司实体。在注册公司实体时,必须同时为公司实体注册一名管理员账户。管理员能够管理其公司实体下的用户,用户注册主页面显示当前己以注册的公司信息,如果用户所在的公司己注册,用户可选择注册个人用户信息,如果用户所在的公司还没有注册,则需要选注册公司信息,用户注册主页面如图19所示。 57 榆林学院软件工程实验手册 58 图19 注册页面 3(公司注册UI 公司注册页面提供公司信息录入功能,用户输入公司信息后,进入注册公司管员界面。公司注册页面如图20所示。 图20 公司注册页面 在公司管理员注册界面中,涉及到公司相关信息,系统应自动继承公司相信并显示到管理员注册界面中,公司管理员信息注册如图21所示。 图21 管理员注册页面 4(普通用户注册UI 普通用户注册主要是对己注册公司的工作人员进行注册,在用户注册时,首先要提供管理员登录ID和登录口令,经系统验证后,才能进行用户注册。管理员登录验证界面如图17-20所示。用户注册界面如图22所示。 图22 管理员登录验证界面 58 榆林学院软件工程实验手册 59 图23 普通用户注册页面 5(公告信息发布UI 公告信息发布页面主要为访问BSP的用户提供一个发布求购/出售等信息的平台。用户可以按照标题等查找相关信息。公告信息浏览页面如图24所示,发布公司信息界面如图24所示。 图24 浏览公告信息页面 图25 发布公告信息页面 6(公司认证管理UI 公司认证管理页面主要为使用系统的用户建立一个公司认证信息库,方便用户在发询价单时能够直接发送给己认证的公司。公司认证界面如图26所示。 59 榆林学院软件工程实验手册 60 图26 公司认证信息页面 7(联系人管理UI 用户可以通过联系人管理页面建立自己的通讯录,用户可以查看己存在联系人信息,也可以查找系统中己注册的用户信息添加到自己的联系人库中。查看通讯录界面如图27所示,查找添加联系人界面如图27所示。 图27查看通讯录页面 图28 查找添加联系人页面 8(询价单管理UI 询价单管理模块分为新建询价单界面,如图29所示,编辑部件界面,如图30所示,查看己发送的询价单界面,如图31所示。 60 榆林学院软件工程实验手册 61 图29 新建询价单页面 图30 编辑部件页面 图31 查看询价单页面 7.2 访问控制层公用类设计 BSP访问控制层采用Struts 2的Action作为用户访问控制器,Struts 2的Action实现非常简单,通过继承Struts 2的Action基类重载execute方法,并在该方法里调用业务逻辑组件的业务方法。在Spring与Struts 2的整合策略里介绍过,业务逻辑组件的实现也不是由Action 自己控制的,而是接受Spring容器的依赖注入。 1(自定义Action基类 通过上述分析,在BSP中可以发现所有的Action 有个共同之处是都需要调用业务逻辑组件。 61 榆林学院软件工程实验手册 62 而在分析服务层时,业务逻辑组件统一封装成了工厂类ManagerFactory,所以定义一个基类BaseAction。 8 BSP系统目录及模块列表设计 为了更好组织各功能模块,在系统模块功能实现设计前要进行系统的目录结构设计,一个好的目录结构有利于系统功能层次的化分和维护。BSP系统文件目录主要由源码文件、JSP文件、资源文件、库文件组成。每类文可化分为一大类,然后在细分,BSP系统的文件目录结构如图32所示。Java类文件按架构的层次进行化分,如dao目录存放DAO层相关类文件,dbsql目录存放创建数据库表所需要的SQL文件,entity目录存放PO及ORM文件,Service存放业务逻辑层类文件,action目录存放Struts 2的动作类。WebRoot下存放Web相关文件,如JSP文件、Web配置文件、Struts配置文件、图标文件、样式表文件、编译后的类文件、帮助文件等。BSP系统中所用到的Struts配置文件为struts.xml和struts.properties,Spring的配置文件为applicationContext.xml,Hibernate的配置文件为hibernate.cfg.xml。读者可以在光盘中对应的工程目录下找到相应的文件,由于篇幅所限,本章不在列出上述三个配置文件的所有内容。而是分节介绍对应的配置信息。有关Struts 2、Hibernate 3、Spring2应用整合方法请参考第13章相关内容,本章不在重述。 图32 BSP系统的文件目录结构 9 BSP主页面设计 BSP主页是整个系统的操作和导航中心,涉及到的所有操作都是基于主页面进行的。BSP主页面由操作导航栏、标题栏、内容显示组成。导航栏主要显示功能模块及用户登录等相关操作。系统的主文件为index.jsp,该文件是个框架结构,导航栏文件为Admin_Left.jsp,标题栏显示系统的LOG、登录人员信息、常用功能导航等功能。标题栏文件为top.jsp。内容显示栏为工作区内容,用户的所有操作都在本区域内进行。 62 榆林学院软件工程实验手册 63 9.1 利用Dojo和Struts 2设计登录表现层界面 系统登录及功能列表文件为Admin_Left.jsp,这个文件由两部分组成,一部分为登录部分;另一部 分为登录后显示系统功能列表部分。 9.2 应用Struts 2注解设计登录控制层Action 用户提交表单后,系统需要处理登录的表单请求的Action,从上面的登录页面文件中得到登录的Action为/logonAction.do,处理登录请求的Action为LogonAction。 9.3 设计模型驱动层VO 在Struts 2框架中,无论是属性驱动还是模型驱动,都是通过拦截器负责提取请求参数,并将请求数据封装到相应的Action对象中定义的属性或模型的属性中。属性驱动就是属性(property)作为贯穿MVC流程的信息载体。也就是使用Action实例来封装请求参数和处理结果信息。前面的例子都属于属性驱动模式。在BSP系统中,采用模型驱动的方式,模型驱动就是使用单独的JavaBean作为贯穿整个MVC流程的信息 载体。也就是使用单独的VO(值对象)来封装请求参数和处理结果信息。 9.4 登录DAO层实现设计 登录DAO是通过组件BspUserDAOImpl实现的,该组件应用了Spring对Hibernate的DAO支持。 9.5 登录业务逻辑层实现设计 登录业务组件AccountManager的validateUse方法进行判断用户登录信息,AccountManager的实现类为AccountManagerImpl,该类所需的DAO是通过Spring注入的。 9.6 登录验证码的应用 , 验证码的生成 , 验证码的显示 , 验证码验证 63 榆林学院软件工程实验手册 64 9.7 利用Strtus2和Ajax实现验证码 用户在输入验证码时,有时可能会看不清验证码,这就需要提供一个“看不清,换一张”的刷新功能,但不需要刷新整个登录页面,为了实现这一个功能,在BSP应用中,利用Ajax技术来实现这一功能。 10 BSP用户注册实现设计 在主页导航栏中单击“注册”按钮后就可以进入注册页面,如果用户公司己经在系统中注册登记,需要与公司管理员联系才能注册个人用户,如果公司没有在系统中登记注册,需要先注册公司用户和管理员。 在公司注册页面中,需要填写相关信息,如果用户没有填写必输项时,会显示错误提示信息。 10.1 利用Dojo、DWR和Struts 2设计用户注册首页 用户注册首页文件主要显示己注册的公司信息及提供注册公司和注册个人按钮。 10.2 利用Dojo、DWR和Struts 2设计公司注册页面 公司注册的表单文件提供公司信息注册。 10.3 利用Dojo、DWR和Struts 2设计管理员注册页面 管理员注册的表单文件提供管理员信息注册。 10.4 利用Dojo、DWR和Struts 2设计普通用户注册页面 普通用户注册主要是对己注册公司的工作人员进行注册,在用户注册时,首先要提供管理员登录ID和登录口令,经系统验证后,才能进行用户注册。 10.5 用户注册控制层流程分析 在注册公司实体时,必须同时为公司实体注册一名管理员账户。管理员能够管理其公司实体下的用户,用户注册主页面显示当前己以注册的公司信息,如用户所在的公司己注册,用户可选择注册个人用户信息,如果用户所在的公司还没有注册,则需要选注册公司信息,用户注册流程如图39所示。 64 榆林学院软件工程实验手册 65 图39 注册公司、用户注册流程 10.6 应用Struts 2注解设计用户注册首页控制层Action 用户进入注册页面后,首先显示当前己注册的公司,处理登录请求的Action为USERREGAction。 10.7 应用Struts 2注解和DWR设计公司注册控制层Action 公司注册的Action控制主要功能是保存公司表单信息。 管理员注册Action先从公司注册会话中取出公司注册表单并复制部分公共信息到管理员注册表单,用户在次提交时,需要进行表单提交验证,表单验证后,进行保存公司和管理员注册信息,把注册信息发送到用户邮箱中。 10.8 公司注册模型驱动层VO 公司注册表单的模型模型驱动VO为REG_CORP_ADMINVO,该类实现代码与实体类BspCorp有相同的getter和setter方法。 10.9 应用DWR、Dojo、Spring、Struts 2实现Ajax调用 在前面的REG_CORP_ADMIN.jsp和 REG_CORP_ADMIN1.jsp注册页面,用DWR、Dojo、Spring、Struts 2实现判断公司是否已注册的Ajax功能,要应用DWR框架,首先需要在web.xml文件中设置DWR,以下配置内容必须被添加到WEN-INF/web.xml文件中。然后在web.xml的同一目录下,创建一个DWR的配置文件dwr.xml,并且将要被调用的java类写 65 榆林学院软件工程实验手册 66 入其中。 DWR与Spring整合需要用Spring Creator,这个创造器会在applicationContext.xml中查询beans,并且会使用Spring去创建它们。 接下来是在jsp文件中使用DWR, 首先要引用dwr的js文件,其中engine.js是必须要引用的文件,如果需要用到dwr提供的一些工具,还需要引用util.js。然后还要引用dwr自动生成的js文件,如上例子的文件为dwr/interface/service.js,注意js文件名字要与dwr.xml中配置的javascript名称一样。 10.10 应用Struts 2注解设计普通用户注册控制层Action 普通用户注册首先需要输入公司管员ID和口令进行验证,验过通过后,才能进入用户注册页面。 用户输入的信息通过系统验证后,根据管理员ID获取公司信息,保存到会话中,以便在注册用户时调用公司信息。注册动作是通过调用业务组件ManagerFactory中AccountManager的saveBspUser方法进行保存用户注册信息。ManagerFactory是通过Spring注入的。 10.11 用户注册模型驱动层VO 用户注册表单的模型模型驱动VO为User_RegVO和REG_CORP_USERVO,其中User_RegVO用于提供输入管理员ID和口令数据, REG_CORP_USERVO实现代码与实体类BspUser有相同的getter和setter方法。 10.12 应用DWR、Spring判断公司是否已注册的 Ajax调用 在前面的BSP_User_Reg.jsp注册页面,用DWR、Dojo、Spring、Struts 2实现判断用户是否已注册的Ajax功能,在dwr.xml文件中加入将要被调用的java类。DWR与Spring整合需要用Spring Creator,这个创造器会在applicationContext.xml中查询beans,并且会使用Spring去创建它们。 10.13 注册DAO层实现设计 用户注册DAO通过BspCorpDAOImpl和BspUserDAOImpl组件实现。这两个组件应用了Spring对Hibernate的DAO支持。 10.14 注册业务逻辑层实现设计 注册业务组件AccountManager为各种数据保存方法进行注册信息保存,AccountManager的实现类为AccountManagerImpl,该类所需的DAO是通过Spring注入的。 66 榆林学院软件工程实验手册 67 10.15 部署层发送邮件系统的设计 用户注册成功后,系统自动发送注册信息到用户注册时所提供的邮箱中。 登录邮件服务器后,就可以请求邮件服务器的服务,包括查看收件箱里的新邮件或通过邮件服务器发送邮件。现在,在Internet上存在着很多免费的邮件服务提供商,很多用户都在这些邮件服务中拥有一个账户,可以通过这些邮件服务器发送和接收邮件。登录邮件服务器有几个必要的条件,首先要提供POP3邮件服务器和SMTP发信服务器的地址,还要提供登录服务器的用户名和密码。先通过指定POP3服务器和SMTP服务器的网址属性创建一个 Store)对象,再利用用户名和密码通过Session对象,然后在Session对象中取得邮件存储( Store对象的connect方法进行连接,就可以对服务器上的邮件进行操作了。 在SendMail中调用了一个实现是否需要验证的安全类MailAuthenticator,该类实现代码如下: 11 用户找回密码实现设计 当用户忘记登录密码时,可通过找回密码功能来查询密码,用户在找回密码页面中输入登录账号或注册时提供的邮件地址,系统根据登录账号或邮件地址查找登录密码,如要系统中存在用户输入的账号信息,则以邮件的方式发送到用户注册时提供的邮箱中。 11.1 利用Dojo、Struts 2设计找回密码表现层界面 找回密码页面文件提供两个输入框,以供用户输入用户ID和邮件。并显示系统返回的验证和查找信息。 11.2 找回密码控制层动作类的设计 找回密码的Action很简单,其主要功能是读取用户输入到信息,通过调用业务逻辑组件验证后,发送查找到的密码到用户邮箱中。 11.3 找回密码模型驱动层VO 找回密码表单的模型模型驱动VO为BSP_USER_GetPassVO,该类代码实现了用户ID和用户邮件的getter和setter方法。 11.4 找回密码DAO层实现设计 找回密码DAO是通过组件BspUserDAOImpl实现的,其实现方法与用户登录和用户注册所用到的方法相同,首先根据用户ID或邮件地址在数据库中查找,如是在系统中找不到用户注册信息,提示用户无法找到注册信息,否则发送用户密码到用户邮箱中。 67 榆林学院软件工程实验手册 68 11.5 找回密码业务逻辑层实现设计 找回密码的业务逻辑与用户注册的业务逻辑共用其中一些方法,如根据用户ID查找信息的findByUserId方法等,具体实现请参考用户注册业务组件实现类。 12 公告信息发布实现设计 公告信息发布页面主要为访问BSP的用户提供一个发布求购/出售等信息的平台。用户可以按照标题查找相关信息。 12.1 公告信息浏览表现层界面设计 公告信息首页文件为BC_LISTAjax.jsp,该文件主要显示己发布的公告信息,提供按主题、内容和信息类型进行搜索的功能,还有新增公告信息功能。并提供分页显示功能,在JSP页面中,实现显示分页信息,以供用户选择页码,并根据Action中保存的数据记录和分页器进行发页显示数据。 12.2 利用Ajax、Struts 2和Hibernate进行显示分页 Ajax的分页解决方法主要就是通过编写一个分页器(一个Bean)用来记录当前的页面、记录数、和页面的大小等属性,JSP页面传给Action 查询条件,主要包在QueryFormBean中。由于以前普通的分页翻页时都会刷新整个页面,使用起来很不方便。 12.3 分页器的设计 为了实现对分页信息进行封装,需要定义一个分页器。 12.4 在Struts 2的Action中分页控制 通过Action,获取表单中传入的分页信息,例如当前显示的页码数,Action根据查询条件获取总记录数,把值赋给分页器Bean,分页器根据总记录数、每页显示记录数自动计算总页数等信息。如果调用的是Ajax技术分页,则生成XML文档,返回给所调用的Ajax请求。 12.5 公告信息发布模型驱动层VO 公告信息发布表单的模型模型驱动VO为BspMessageVO,该类代码实现了BspMessage实体各属性的getter和setter方法。 68 榆林学院软件工程实验手册 69 12.6 在DAO中实现分页 在Hibernate查询接口Query中,根据传入的分页器,设置存取数据的位置和记录数。 12.7 利用Dojo的Dialog组件设计发布公告页面 发布公告信息的页面文件为BC_EDIT.jsp,该文件主要提供信息录入功能,用户录入想发布的信息,保存后,其他用户即可看到公告信息。 12.8 发布公告信息控制层动作类的设计 用户进入公告信息页面后,先显示当前己发布的公告信息,显示公告信息的Action是BspMessageAction,发布公告信息的Action也是BspMessageAction,在程序中通过在页面中传入的标记来判断用户的操作。 12.9 公告信息DAO层实现设计 公告信息发布DAO通过BspMessageDAOImpl组件实现。这个组件应用了Spring对Hibernate的DAO支持。 12.10 公告信息发布逻辑控制层实现设计 发布公告业务组件MessageManager的实现类为MessageManagerImpl,该类所需的DAO是通过Spring注入的。 13 联系人通讯录的设计 用户可以通过联系人管理页面建立自己的通讯录,用户可以查看己存在联系人信息,也可以查找系统中己注册的用户信息并添加到自己的联系人库中。 13.1 利用Dojo、Struts 2设计联系人通讯录表现层界面 联系人通讯录显示文件为BUY_SPL_LIST.jsp,该文件主要显示己添加的联系人信息,按公司进行分组显示联系人信息,利用Struts 2逻辑标签库中的嵌套iterator实现分组。 69 榆林学院软件工程实验手册 70 13.2 利用Dojo的Dialog组件设计增加通讯录表现层界面 增加联系人文件为BUY_SPL_EDIT.jsp,其主要功能是从系统中查找己注册的联系人信息,按公司进行分组显示,用户可选择想要添加的联系人添加到自己的通讯录中。 13.3 增加联系人信息控制层动作类的设计 用户进入联系人信息页面后,先显示当前己存在的联系人信息,显示联系人信息的Action是BUY_SPL_LISTAction。这个动作主要功能是按公司进行分组显示联系人信息,查找到的信息保存在一个哈稀表中,以公司名称为关键字,个人信息对象为值进行保存。 13.4 增加联系人DAO层实现设计 增加联系人DAO通过BspMySplContactDAOImpl组件实现。这个组件应用了Spring对Hibernate的DAO支持。 13.5 增加联系人逻辑控制层实现设计 增加联系人业务组件AccountManager提供各种数据保存方法,AccountManager的实现类为AccountManagerImpl,该类所需的DAO是通过Spring注入的。 其实现代码如清单79所示。 14 公司认证管理的设计 公司认证管理页面主要为使用系统的用户建立一个公司认证信息库,方便用户在发询价单时能够直接发送给己认证的公司。 14.1 显示公司认证信息表现层界面设计 公司认证信息显示文件主要显示己添加的公司认证信息。 14.2 利用Dojo的Dialog组件设计增加公司认证信息表现层界面 增加公司认证信息文件为BUY_CEREDIT_SPL.jsp,该文件主要功能是从己注册的公司中选择公司并添加到公司认证信息表中. 70 榆林学院软件工程实验手册 71 14.3 公司认证信息控制层动作类的设计 用户进入公司认证信息页面后,先显示当前己认证的公司信息,显示和保存认证公司信息的Action是BUY_CER_SPLAction。 14.4 公司认证模型驱动层VO 公司认证表单的模型模型驱动VO为BUY_CER_SPLVO,该类代码实现了BspCorpSpl实体各属性的getter和setter方法。 14.5 增加公司认证DAO层实现设计 增加公司认证DAO通过BspCorpSplDAOImpl组件实现。这个组件应用了Spring对Hibernate的DAO支持。 14.6 增加公司认证逻辑控制层实现设计 增加公司业务组件AccountManager提供进行数据保存和查找公司信息方法,AccountManager的实现类为AccountManagerImpl,该类所需的DAO是通过Spring注入的。 15 询价单管理 用户可以发送询价信息给自己的联系人、己认证的公司及所有公司。并可以查看己发送的询价单,用户也可以保存询价单为草稿,暂不发给用户,等编辑好询价后在发给用户。用户也可以删除草稿和取消询价。 1 新建询价单表现层界面设计 新建询价单文件主要新建询价单信息并发送给联系人,用户可以选择发给我的联系人、认证的供应商、指定联系人和所有公司。 2 利用Dojo的Dialog等组件设计增加询价的部件表现层界面 一个询价单可以对应多个部件信息,部件信息通过弹出窗口进行增加 3 利用DWR、Dojo组件设计指定联系人表现层界面 用户可以指定联系人并给其发送询价单。 4 询价单模型驱动层VO 询价单表单的模型模型驱动VO为BUY_INQ_EDITVO, BUY_INQ_EDITVO实现代码与实体类BspInq有相同的getter和setter方法。 5 配置DWR DWR、Dojo、Spring、Struts 2实现保存用户选择的联系人的Ajax调用功能。 6 DWR与Spring整合配置 DWR与Spring整合需要用Spring Creator,这个创造器会在applicationContext.xml中查询 71 榆林学院软件工程实验手册 72 beans,并且会使用Spring去创建它们。 7 调用远程对象 供DWR远程调用实现保存用户所选择的联系人信息。 8 显示己发送的询价单表现层界面设计 显示己发送的询价单信息文件的主要功能是显示己发送的询价单信息。 9 询价单信息控制层动作类的设计 询价单信息页面的Action是BUY_INQ_EDITAction。这个动作主要功能是从表单中读取询价单信息进行保存,根据操作标记进行功能导航,操作标记主要包括新增、查找、保存询价单。当为保存询单时,需要先根据发送给的联系人方式查找相应的信息,用户可以选择发给我的联系人、认证的供应商、指定联系人和所有公司,其次是保存询价记录,询价单编号的生成采用自定义编码的方式,这种编码的方式主要是不断探测当前系统的记录总数,生成编码,然后判断此码是否存在,如果不存在则保存数据,否则继续探测。然后是保存询价单涉及到的部件。最后需要按联系人类型发送给供应商询价信息,以便供应商在收到询价单后进行报价。 10 询价单DAO层实现设计 询价单DAO通过BspInqDAOImpl和BspInqPartsDAOImpl组件实现。这两个组件应用了Spring对Hibernate的DAO支持。 BspInqDAOImpl代码如清单95所示。 BspInqPartsDAOImpl代码如清单96所示。 11 询价单管理逻辑控制层实现设计 询价单业务组件InqManager提供各种数的据保存方法,InqManager的实现类为InqManagerImpl,该类所需的DAO是通过Spring注入的。 在BSP系统中,供应商根据收到的询价信息进行报价格给询价的询价人,询价人在收到报价单后,把所需的部件加入到自己的采购清单中,形成定单,发给供应商。供应商在收到定单后,双方进行确认,最后形成采购合同。 图51 询价流程图 72 榆林学院软件工程实验手册 73 16 利用Quartz定时邮件发送实现设计 16.1 Quartz的应用 系统中常常有些需要自动执行的任务,这些任务可能每隔一段时间就要执行一次,也可能需要在固定的时间自动执行,这些任务的自动执行必须使用任务的自动调度。Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的日程序表。 16.2 Quartz 包含的触发器 Quartz 调度包的两个基本单元是作业和触发器。作业是能够调度的可执行任务,触发器提供了对作业的调度。虽然这两个实体很容易合在一起,但在 Quartz 中将它们分离开来是有原因的,而且也很有益处。通过把要执行的工作与它的调度分开,Quartz 允许在不丢失作业本身或作业的上下文的情况下,修改调度触发器。而且,任何单个的作业都可以有多个触发器与其关联。 16.3 作业任务的的调度实现 , 定义Job调度类 , 在Spring中集成Quartz , 利用JobDetailBean 包装QuartzJobBean 的子类。 , 利用MethodInvokingJobDetailFactoryBean 工厂bean 包装普通Java Bean 。, 使用triggers和SchedulerFactoryBean来包装任务 17 BSP实时消息系统的设计 17.1 利用DWR的反向Ajax技术实现消息系统 BSP消息系统主要实现的功能有管理员可以向所有在线用户发送实时公告消息,在线用户向所有其他在线用户发送消息,在本例中,利用返向DWR的反向Ajax技术来实现这一功能。反向Ajax的基本概念是客户端不必从服务器获取信息,服务器会把相关信息直接推送到客户端。这样做的目的是解决Ajax传统Web模型所带来的一个限制:实时信息很难从技术上解决。原因是,客户端必须联系服务器,主动询问是否存在变更,如果有变更就会更新页面(或者页面的一部分)。虽然可以非常快速完成这个操作,让人感觉好像是实时的,但是实际上不是实时的。我们需要的是,服务器联系查看其页面的所有浏览器,并通告所发生的变更。 反向Ajax是克服这个限制的一种方式。像Ajax本身一样,这不是一门专门的技术,而是按照不寻常方式组合使用已有的技术达到不寻常的效果。 73 榆林学院软件工程实验手册 74 17.2 反向Ajax的配置与实现 要让DWR程序支持反向AJAX,首先需要在web.xml中DWRServlet里添加一个初始化参数。 除了上述配置,为了启用反向Ajax技术,在页面中还需要一些JavaScript代码,即: 17.3 反向Ajax调用的服务器端的发布者实现 处理轮询请求的过程通常是在服务器端编写一些代码,以更新附加到服务器端的每个客户端的会话。DWR会记录与之联系的每个客户端,分别存储每个客户端的会话。这一点与通常的HTTP会话不同。借助于此,可以调用JavaScript代码,下一个轮询请求会通知这些调用。 15 总结 本章以BSP软件系统为例,全面介绍了开发一个应用软件的分析、设计、实现的全过程,通过本章的学习能够进一步提高读者的综合设计水平。BSP系统涉及了目前应用软件所需的大部分功能,如邮件、ICQ、任务调度Quartz、Spring2、Hibernate 3、Struts 2、DWR、Dojo的整合应用。读者在本章的例子上稍作修改就可应用到自己的项目中。首先介绍了BSP的项目背景及需求分析,并对BSP系统进行架构分析和设计和BSP系统的主要功能进行了用例图说明;然后定义BSP系统实现层次,并对各层进行了详细的设计。按分层的设计理念,对BSP系统功能模块进行设计与实现。在本章最后,介绍了利用Quartz定时发送邮件,并就利用DWR的反向Ajax技术实现消息系统的应用作了简单的介绍。 74
本文档为【[IT&#47;计算机]软件工程实验修改版】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_597436
暂无简介~
格式:doc
大小:780KB
软件:Word
页数:0
分类:
上传时间:2018-12-29
浏览量:4