基于JSP的网上购书系统
点击以下链接获取源码:
https://download.csdn.net/download/qq_64505944/88825694?spm=1001.2014.3001.5503
Java项目-15
源码+论文+数据库+配置文件
基于JSP的网上购书系统
摘要
在当今的社会中, 随着社会经济的快速发展以及计算机网络技术和通讯技术的快速成长,网络应用领域也一天天扩大,网络中的新鲜事物层出不穷。电子商务的发展增加了许多商业交易的平台,借助于这种互联网平台,人们进行商品宣传、业务交易等多种行为,进而使得电子商务快速发展,成为当今社会迅速成长的主流之一,电子商务在我们日常生活中扮演着越来越重要的角色。
在网络如此发达的潮流中,顺应趋势,设计了基于JSP的网上购书系统这个销售平台,让用户可以更直观、便捷,足不出户即可在虚拟书店里购书。本网站页面主要用JSP实现,业务逻辑层用SSH框架(Hibernate+Struts+Spring)及Java代码实现,数据管理用MySQL数据库,开发工具使用Eclipse,服务器用Tomcat8最新版本。本系统针对管理员和普通两类用户设置了不同的功能。管理员功能包括:图书信息管理、图书类别管理、订单管理、用户信息管理;普通用户功能包括:注册信息、浏览书店信息、浏览图书信息、搜索图书、在线生成订单等功能。该系统用户界面友好,模块划分清晰,具有使用方便,安全稳定,维护简单等特点。
关键词:网上购书;Java;JSP;MySQL
The Online Bookstores System Based On JSP
Abstract
In today’s society, the fast development of computer network technology and the communication technology, the increasing scale of the network, the new things in the network also increased a lot, in the Internet platform for publicity, trading and other acts, which makes the network more and more become the mainstream of today’s social development, the site is composed of a very large network elements.
Online book system This sales platform, allowing users to more intuitive and moreconvenient, do not have to go home to see a lot of books. The software system for ordinaryusers of the web page is mainly used to achieve JSP, the business logic layer with SSHframework (Hibernate+Struts+Spring) and Java code, data management with MySQL database, development tools using Eclipse, the latest version of the server with Tomcat 8.The system sets differentfunctions for administrators and ordinary users. Administrator functions include: book information management, book category management, order management, user information management; Common user functions include: regist information browsing bookstore information, browsing book information, searching book,generating orders online, etc.The system has the advantages of friendly user interface, clear module division, convenient operation, safety and stability, simple maintenance and so on.
Key words:Online Bookstores;Java;JSP;MySQL
目 录
摘要 i
Abstract ii
1 前言 1
1.1 概述 1
1.2 整体叙述 1
2 系统开发背景 3
2.1 课题的背景 3
2.2 课题的研究现状 3
2.3 课题的研究意义 3
3 系统分析 5
3.1 系统开发目的与意义 5
3.2 可行性分析 5
3.2.1 技术可行性 5
3.2.2 经济可行性 5
3.2.3 操作可行性 6
3.2.4 法律可行性 6
3.2.5 管理可行性 6
3.3 需求分析 6
3.3.1 功能需求分析 6
3.3.2 数据逻辑分析 6
3.3.3 性能需求分析 7
3.4 数据库分析 7
3.5 开发环境 7
3.6 开发工具及技术 8
3.6.1 开发工具 8
3.6.2 开发技术 8
4 系统总体设计 10
4.1 设计思想 10
4.2 功能模块设计 10
4.3 界面设计 12
4.4 系统用户用例图 13
4.4.1 普通用户用例图 13
4.4.2 管理员用例图 13
4.5 数据库的设计 14
4.5.1 数据库概念结构设计 14
4.5.2 数据库逻辑结构设计 16
5 系统详细设计与实现 20
5.1 管理员登录页面 20
5.2 管理员模块 21
5.2.1 图书类目管理 21
5.2.2 图书信息管理 23
5.2.3 用户信息管理 27
5.2.4 订单信息管理 28
5.2.5 退出系统 28
5.3 普通用户模块 28
5.3.1 系统主页面实现 28
5.3.2 图书查询 29
5.3.3 用户登录注册 30
5.3.4 图书分类查询 30
5.3.5 在线下单 31
5.3.6 管理订单功能 32
6 系统测试 33
6.1 系统测试目的与意义 33
6.2 测试过程 33
6.2.1 网站首页用户登录测试 33
6.2.2 管理员删除图书信息测试 34
6.2.3 生成订单测试 34
6.2.4 其他错误测试 35
7 系统的运行和维护 36
结论 37
参考文献 38
致谢 39
附录:外文原文 40
中文翻译 49
1 前言
1.1 概述
当今人类社会的生活方式因为互联网的蓬勃发展而发生了质的变化,网络给人们带来了足不出户即可了解新鲜事物和获得自己想要的东西的便利,所以正是需求推动社会发展,在虚拟网络中买卖交易商品,人们越来越来喜欢这种网上购物方式。
互联网行业刚兴起才露出其新面容是上世纪90年代,国内也发展起来了几大互联网企业,一些商业人士也就泛起了通过网络进行交易买卖图书的别人没想过的主意。但是在互联网初期还存在一些问题,比如企业的信誉不是一时半会能建立起来的、不完善的国家对于的网络的政策、当时不发达的物流等一连串的原因致使网上交易生意发展的步伐有所迟缓。新世纪以来,整个社会成长进步了不少,影响网上业务买卖的各大问题被消灭,越来越多的企业看出互联网势不可挡,互联网的队伍日益壮大[6]。
小时候购买图书都是现场商家与消费者面对面销售,卖书的地点对于大部分商家来说都是固定的,客流量也是固定的,并且图书种类偏向固定,这样导致利润上涨缓慢,甚至不盈利。
从商家角度来看,当打点店铺的职工想查找哪一类图书销量大需要进货时,要根据每一天的销量情况来决定。当然用数据说话更准确,例如用库房的电脑查看销售图书数量以及类别,这样就很繁琐。从买家为出发点的话,想要购买书籍还要先去图书馆查看是否有心中所想的那本书及价钱,要想比较不同书店同一本书的价格还要跑到另一家去让工作人员手工查找,很费时间及人力。随着社会发展,网店的出现,机械以精准、快速而远超过手工运转的大优势替代手工,工作职员再也不用手工查书了,更方便的是其可在电脑上输入书名就能快速出现结果;消费者也可以通过在同一个平台的不同页面查询自己需要的书籍及单价,还能同时登陆不同的平台来进行比较不同商家的同一件商品,很大水平上节省了人们的时间,因此网上购书既节约时间又不耗费人力、不必要的费用,让卖家和买家间的沟通矛盾有效减少了。
1.2 整体叙述
本论文所包括的主要内容章节整体信息如下:
1、可行性分析
本系统的分析主要从技术方面着手,判断可完成的功能,再从经济角度出发,得出系统开发的成本和硬件条件以及最后系统的部署环境、运行成本等,以上都可行后说明该系统的是有必要开发的[6]。
2、系统分析
当今社会互联网的飞快发展,社会主流网络购物已经深入众多消费者人心,因此,
为了让消费者的买书需求得到满足让人们的生活水平提高,也是为更好的社会发展,让消费者买书更方便快捷,就此,尝试开发一个小型网上购书系统来满足众多消费者。目前,也有很好的购书网站,比如淘宝网、亚马逊、当当网等平台被人们所熟知,本小型平台在借鉴他人劳动成果的基础上锻炼自己的技术水平。每个软件项目在正式开发前都要研究分析其是否可行,意义在于预防开发中未预料到的问题的出现。
3、系统总体设计
(1)浏览器/服务端模式是本系统总体开发的模式,该模式有以下好处:
(a)层次清晰分明的前台、后台逻辑处理关系,符合很多已经对于网络搜索熟悉习惯的消费者;
(b)使用面向对象理念设计和开发概念、使用模块化方式设计。模块化设计就是将所有功能都分解开来,分成若干个子功能模块,这样简化系统设计实现,让重复的代码能将其单独作为一个类或方法,实现代码重载,不仅让开发更简单,而且提高了代码维护性。系统开发不仅要实现功能,而且要考虑系统可靠性,既满足设计要求又可以在此基础上进行改进扩展,更能适应社会发展满足人们需求。
(2)数据库设计:使用MySQL,本系统后台程序使用Struts+Spring+hibernate即SSH框架,在Spring的配置文件中配置数据库相关信息。
4、系统详细设计与实现
系统详细设计要完成的是各模块代码的编写(包括前端网站各页面和后台管理系统),用户交互界面的设计等内容。
系统前台模块包括用户进入网站首页、查看图书和网站虚拟书店的信息,注册信息、登录网站、加入购物车和下订单等内容;系统后台管理模块分为管理层用户登录后台、添加图书类别、更新图书信息等内容;用户交互界面的设计包括一般用户登录模块界面的设计和后台管理界面的设计。
该网上购书系统的界面简单大方,方便各年龄阶段的消费者使用,有着友好和错误的提示操作。系统管理者功能有:更新书籍信息、对书籍分类、对订单标记已处理、添加用户、管理系统等。普通用户可以查看图书信息,图书分类查询,生成购买书籍订单,修改个人的基本信息等功能。保障性大,避免了人为的破坏性行为。
5、系统测试
每个系统开发中都会有或多或少的bug,系统检测的目的是极大多数的检查出软件中出现的问题,增强程序的可靠性。这个过程又分为3个步骤:模块、接口、验收测试。
在系统初步形成时,为了看到自己开发的成果,一开始用于检测的信息都是随意输入,单纯地为了测试,用户信息也不是真的。但是到后来,要检验系统的可靠性使用了较真实的测试信息,并清除了假数据。
在通过不断的测试消灭各种bug,才能让系统放心运作起来。
6、系统运行和维护
系统开发测试完毕后就要投入使用了,确保系统能正常运行非常重要,社会不断发展人们的需求也在不断变化,这就要求系统维护人员能及时发现系统问题并向上级反映对系统改进。
2 系统开发背景
2.1 课题的背景
自从进入互联网时代以来,网络以其前所未有的速度改变着人们的生活方式,改变着人们的价值观念。如果说这是一次经济革命,它比工业革命所带来的影响价值更深入彻底得多,它将传统经济推向了无形的虚拟空间。地球村即真是地体现了经济全球化的趋势。网络经济模式以迅猛势头席卷我们生活的各个领域:随着电子商务的日益成熟,网上购书应运而生,并以其方便、快捷等一系列优点冲击着我们传统的图书发行产业,这既是机遇又是挑战。网络时代的今天,谁能更好的利用好这柄双刃剑必将成为威力啊图书出版发行业新的主宰者。我过由于网络技术起步较晚,电子商务体系还不很完善,与欧美等国有一定的差距。[3]
网上购书是电子商务网站的一种类型。网上购书是近年来随着网络技术的发展而产生的一种新型的书店形式。随着网络的发展,电子商务的不断完善,卖书商家越来越强烈地意识到网络带来的巨大商机,几乎都进行图书的线上销售经营活动,不管对于商家网上销售还是对于消费者网上购书都是种新型的销售和购书模式,并很受欢迎。
2.2 课题的研究现状
随着我国经济的发展,电子商务在企业的日常生活中将会发挥越来越多的作用,尤其在金融、政府、事业单位方面电子商务更是可以发挥其竞争优势。网上购书系统的研究主要是从信息流、资金流等角度进行研究。
李大星认为,最具代表性的网上购书系统首推亚马逊网站。用户访问该网站首页,利用电脑检索图书,物色到自己喜欢的书。通过键盘向该网站订购,美国本土的购书人大概两三天内便可收到。其主页推荐的书目每日更换,提供最新书目和相关信息。客户如向网站提供自己的个人信息,网上购书系统会定期向你传递有关的书目信息及相关著作,形成个性化服务。
张志强根据中国互联网络发展状况统计报告对国内网上图书销售的优势、存在问题等进行了分析。它认为长远角度看,国内网上图书销售具有消费主体、消费习惯、需求等优势,但也存在着交易安全性、图书质量、支付手段等问题。他建议网上销售图书要重视信誉,树立品牌;增加技术含量,提高服务质量;恰当运用网上广告等扩大影响。由于我国电子商务的概念并未深入人心、信息服务不完善、安全保障等问题令人担忧。这些问题既严重阻碍了我国网上图书购买的发展,也妨碍了我国的信息化进程。网上购书面临的这些问题有待解决。[3]
2.3 课题的研究意义
近年来,随着计算机的普遍推广,电子商务得以快速发展,网上购书不仅成为一种时尚,也成为人们学习必做的功课。网上购书系统运用计算机技术将卖家、买家、厂商等紧密地结合在一起,大大弥补了过去时间和空间带来的障碍,从而帮助人们节约了成本,扩大了营销市场,同时通过此次项目的开展,我可以更进一步了解项目开发的一般流程,深化对基于B/S模式下开发项目的了解,进一步了解和掌握Web开发技术。
基于JSP的网上购书系统是在当今网上购物风靡一时的情况下根据老师的指导和建议得出的课题,重点在于检验学生知识的运用能力和实际操作能力。随着时间的推移,电子商务得到快速发展同时人们的生活节奏也越来越快,更多的人追求速度和效率,实物店购买图书难以满足人们的要求,因此网上购物成为人们必要的选择。网上购书系统包括:查看图书信息、增加图书信息、删除图书信息、用户注册、订单处理、后台管理等工作。
3 系统分析
3.1 系统开发目的与意义
该系统作为基于网络平台的书籍交易系统,跟以前旧销售方式比较,主要优点有:
1、检索便捷
网上购书提供了比较多的检索途径,比如可以根据分类查找、根据价格查找、根据是否是特价商品或根据图书的作者等多种途径进行检索,方便、快速、准确。
2、信息量大
与以前在某个地点卖书的旧形式不同,老形式销售老板带的书数量有限,种类不会那么齐全,而该系统基于网络不受时间、地点的限制,遍及世界各地,这也就极大限度地扩大了出版物的发行范围。
3、成本低,无区域限定
网上购书最大的优势是消费者可于任何时间、地点购买心仪的书籍,增多了消费者群体,提高了商家竞争力,更节约了开实体店所需投入的资本(人力、生产力以及物力)和租赁钱财。
基于以上网上购书的优点,网上购书才能得以在短时间内迅速发展起来。其目的与意义就是为了让人们更方便购书,更快乐地享受生活。
3.2 可行性分析
任何一个系统的开发,都有时间和资源上一定的限制。所以每一个项目在开发之前,对其进行可行性分析是必不可少的,这样才能降低项目开发过程中的风险,较少及避免财力、物力、人力的浪费。以下在技术、操作、经济还有法律4个方面进行可行性分析的阐述。
3.2.1 技术可行性
该软件系统使用我们学过的开发工具Eclipse开发,用具有性能高、跨平台、代码可重载的Java编程语言编码,数据库使用开源软件MySQL。而且对于ssh框架这些都有所学习, ssh框架有良好的可扩展性和可维护性,提高了对象管理方法,因此对我而言,在技术上实现该系统是行得通的。
本软件体系的协议传输和请求返回原理工作图如下图1:
图3.1 系统工作原理图
3.2.2 经济可行性
由于本系统是毕业设计课题这一特殊性,通过使用含有标准配置的电脑,下载JDK以及开发所需要的jar包即可进行开发,由于该系统中使用的软件是开源的,这就节省了开发系统节所需的大部分的资金和时间,实现了更低的开发成本,提高了系统开发的效率。
3.2.3 操作可行性
本系统操作简单,页面框架基本上使用统一风格,且页面简单,可根据需要和文字提示即可完成图书的搜索和购买,很容易上手操作,学起来是比较简单的,对操作人员的要求条件不高,只需要熟练操作Windows操作系统,另外再对系统运行的操作稍加训练即可,而系统的可视性很好,所以不会很难使用。
3.2.4 法律可行性
本网上购书系统是一个自主开发的购书系统,是一个对大部分消费者来说很实用的系统,开发环境工具和数据库的操作都有开源的代码,该系统的开发与普通软件系统的开发有不同的地方,在法律上没有任何侵犯,是可行的。
3.2.5 管理可行性
系统设计目标应该放长远,让此系统的开发具有良好的扩展性,不会因企业的变动而随之淘汰。
具体实施体现为以下几点:
(1)标准性:一保证系统运行质量,二在此标准技术上有所进步。
(2)可靠性:系统的软硬件质量必须保证。
(3)安全性:控制用户接触数据的权限。确保用户只可操作对应的数据。
(4)高效性:数据库的大小影响浏览器的响应。
(5)可维护性:系统设计分成几个模块来设计,这样既能减少工作人员工作量,又能便于开发及维护。
3.3 需求分析
3.3.1 功能需求分析
1、该系统所具有的功能需求有:
1)前台网站:
a、一般游客:浏览书店简介、浏览图书信息、搜索图书、根据分类 查寻图书、注册信息等功能;
b、在线用户:包含上边普通游客所有功能,登陆网站、添加书籍到购物车、管理已购买书籍订单等功能。
2)后台管理:管理员可管理图书、设置是否是促销或最新图书;工作人员可以查看、增添用户;管理图书种类,包含查看所有分类、增添书籍类型;管理订单包括查看所有用户订单、标记订单是否已处理、查看详情、删除等功能。
3.3.2 数据逻辑分析
在网站系统页面,若注册信息,用户填写的信息会提交到UserAction类,判断用户名和密码是否正确从而调用service层,service层调用dao层添加用户信息,以此类推,各种数据只要和数据库打交道那就需要经过action类,在对应action类中进行逻辑处理,跳转到相应页面,需要操作数据库时action类调用service层类,再调用dao层类来实现数据的保存或更新及删除。
3.3.3 性能需求分析
1、系统的安全性
在管理限定上严格管制,本软件体系要求如下:
1)对于后台管理系统,首先必须是系统的管理员才能对系统各方面进行更新,其次须凭借无误的昵称和密码口令登陆到系统,没有权限包含不是管理工作人员或者是工作人员时输入不正确的昵称或密码口令登陆系统的人员都不能登陆进后台,对系统中任何信息都不能查看或更新,这样来保证系统的安全性和可靠性。
2)对于前台网站首页,对于拥有不同权限的用户来说,有两种权限分别是一般游客和在线用户,这两种消费者不能跨越本级别操作。具体:一般游客只能在网站首页浏览虚拟书店的介绍信息、书籍的基本信息以及分类查询书籍和搜索书籍,这类用户通过在网站注册信息登录即可变成在线用户;在线用户不但具备一般游客全部能力,而且可以生成订单、管理订单、更改个人基本信息。
2、数据的完整性
- 系统用到的全部信息的完整性,包含保存用户个人信息和书籍的信息。
2) 信息和信息保持一定的互动。 - 同一种信息在不同表中保存的数据应保持相同。
3.4 数据库分析
数据库是计算机系统的核心,其在数据库系统的管理下,对信息进行收集、整理、储存、检索、数据更新、数据加工以及数据统计和有用消息的传达等操纵。现在,信息系统等计算机系统的根基和核心部分已经成为了数据库,因此数据库的品质好坏直接关系到整个体系的质量和效率。[4]
MySQL是一种关系型数据库,其所使用的SQL语言是常用的访问数据库的标准化语言,MySQL具有体积小、速度快的优点,更因其是开源软件,这个大特点就很大程度降低了开发成本,纵使MySQL也有不足之处,但它提供的功能已绰绰有余,因此本系统使用MySQL数据库。
3.5 开发环境
1、硬件环境:
CPU:Intel(R)Core(TM)i5
内存:4GB
磁盘:400G以上
2、软件环境:
系统类型:Win7 64位操作系统
开发工具:Eclipse j2EE
后台服务器:Tomcat 8.0
主要开发语言:JSP、Java
浏览器:Firefox/IE8.0/Google Chrome
3.6 开发工具及技术
3.6.1 开发工具
1、Eclipse
Eclipse是基于Java的完全开源的一个可扩展的开发平台,Eclipse Enterprise Workbench是针对Eclipse IDE的扩展,是Eclipse针对企业开发的平台(简称Eclipse),使得我们在企业级开发应用、部署、封装,数据库管理方面方面提升了较高的效率。简单来说,Eclipse是一个JavaEE开发平台,它有编写代码、Debug模式下用断点来排错即调试、测试功能、发布应用功能,并且它完全支持一些流行框架如Hibernate、Struts等,前端编码语言如HTML、JSP、CSS、JavaScript,还有数据库SQL语句。
2、Tomcat
Tomcat是web应用开发以及调试JSP代码的首选。Tomcat 是属于轻量级免费的、开源的应用服务器。[5]选择tomcat作为服务器,一般是中小型企业还有一些对于同一项目同一时间访问的人数不是特别高的公司使用的,在开发和调试JSP 程序中,Tomcat占有绝对的优势,运行时占用的系统资源小。[10]这些暂且不说,而且它的扩展性非常好,因为以上原因Tomcat已经备受关注,但是Tomcat并没有说因为当前成就而停止前进的步伐。
3、MySql
MySQL是一种关系型数据库,最主要的功能就是将来前台和后台对数据进行查询、保存等操作,其所使用的SQL语言是常用的访问数据库的标准化语言。Hibernate它对JDBC做了简单的封装,使用Hibernate对数据进行增删改查的功能,这次用Hibernate是因为他可实现实体类反向生成数据库,操作简单。
MySql支持多种操作系统如常见的Windows、Linux等; 提供了TCP / IP、ODBC和JDBC等数据库的连接路径; 作为开源软件,MySQL是小中型系统开发的不二之选。[4]
3.6.2 开发技术
1、JSP
JSP在服务端器实现给客户端浏览器响应的是html页面,因此客户端只要有浏览器方可看到响应内容,JSP页面包括两部分一个是Java语言写的脚本代码,另一个是html代码。客户端发出请求之后,页面上的Java脚本代码在客户端请求web页面之后被解析处理,然后返回给浏览器响应的html页面。[2]
JSP技术的优势:
(1)一次编码,各个系统平台都能运转。
(2)JSP组件跨平台。在不同的平台上都能运行。
(3)拥护多种网页格式。JSP支持html、wml等浏览器样式。
(4)JSP标签可扩充性。JSP技术准许开发人员扩展JSP标签,还能自定义标签,降低了制作网页的复杂度。
(5)健壮性与安全性。JSP页面包含Java代码,而Java有健壮的存储管理机制和高安全性,因此JSP也有健壮性和安全性。[8]
2、JavaScript
JavaScript脚本语言是动态弱类型的语言,它的解释器是浏览器所包含的,运行在客户端,通常应用在网页端的脚本语言中。它一开始用于HTML(超文本标记语言)页面,以向HTML网页增添动态功能。
JavaScript的特点是:
(1)js是一种执行时再翻译的动态语言(代码未预先编译);
(2)提高用户界面交互体验,为页面添加动态验证
(3)脚本部分的代码要放在特定的标记中间,或者单独写成js文件,并引用进来;(4)js是基于浏览器,是运行在浏览器中的,就算在不同的平台上也可运作。[3]
3、Struts2
Struts2优势:
(1)Struts2Action对象为每一个请求产生一个实例,因此没有线程安全问题。
(2)Struts2强大的标签库提高开发效率。
(3)页面脉络清晰,通过查看配置文件把握整个系统的关系,方便开发人员岗位流动时的维护。
4、Spring
Spring是一个轻量级的控制反转(IOC)和面向切面(AOP)的容器框架。
Spring优势:
(1)Spring提供了一种管理对象的方法,可以把中间层对象有效地组织起来。一个完美的框架“黏合剂”。
(2)有利于面向接口编程习惯的养成,使代码结构清晰。
(3)采用了分层结构,可以增量引入到项目中。
(4)目的之一是为了写出易于测试的代码。
(5)非侵入性,应用程序对SpringAPI的依赖可以减至最小限度。
(6)一致的数据访问介面。
(7)一个轻量级的架构解决方案。
5、Hibernate
Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。
Hibernate优势:
(1)Hibernate是JDBC轻量级的封装,占用内存较少,性能比较高。与JDBC相比,如果开发JDBC的人员技术能力非常强,hibernate执行效率会比JDBC弱一些,但是大部分情况是程序员在使用JDBC时是不可能做到最高效率,hibernate可以帮大部分开发人员提高运行效率。
(2)可以引入第三方二级缓存,提高系统查询效率,减少系统里存在大量单例类(singleton),大量的单例类,会降低系统的可测试性和面向对象程度。
(3)优秀的ORM框架,理论上节省开发人员95%的开发工作量。
(4)Hibernate兼容JDBC。
4 系统总体设计
4.1 设计思想
设计思想遵循以下几点:
1、本系统使用浏览器 / 服务器模式开发,因为考虑到许多用户已经习惯于在页面上搜索。
2、Java面向对象的思想应融合在整个系统的开发中,每个模块都是独立的,各模块组成一个整体,零散而聚集;
3、系统应具有安全性以及可靠性,分配角色权限是解决他们的最好途径;
4、操作方便,界面从优;
5、设计不仅要重点突出,而且要细致周到。为满足设计要求,在可能的基础上改进系统的扩展,以适应用户的需求。
4.2 功能模块设计
该系统使用起来容易,操作简单,有清晰明了的提示文字,让用户的整个购书过程很轻松享受。本体系实现的基本功能如下:
1、一般游客:浏览书店简介、浏览图书信息、搜索图书、根据分类查寻图书、注册信息等功能;
2、在线用户:包括一般游客全部功能,除此之外,还有登录网站首页、管理购物车、生成订单、查看订单等功能;
3、管理员具有图书类型管理、图书信息管理、订单查看删除管理、用户添加删除管理、后台管理功能;
4、除了以上,该系统的用户交互界面简易明了,易于使用,还有友善的不正确的提示信息,有比较好的安全性。
系统整体的功能模块图如图4.1所示:
图4.1 系统总体功能模块图
软件体系的总体功能模块图,分普通用户模块,管理员模块。
普通用户的模块图说明:普通用户在网店首页可以进行了解书店简介,浏览图书信息;如果要在线操作首先需要备案一个个人账号,再登录上网站,可进行在线下订单,书籍查询操作,如图4.2所示:
图4.2 普通用户模块
管理员功能结构模块图说明:作为一种用户角色,管理员的权限能力最高。管理员功能结构模块图,如图4.3所示:
图4.3 管理者模块
(1)用户管理模块:该模块可观察浏览用户信息、更正、消除用户信息功能。
(2)订单管理模块:该模块主要处理买家完成的订单,查察、删除等功能。
(3)图书管理模块:该模块主要管理书籍,包括增添图书、更新图书信息、设置最新图书、推荐图书、促销图书等。
(4)书籍分类管理模块:该模块对图书类型信息进行打理,包含添加新类型、查询类别意思、改动、和消除等功能操作。其中图书类别信息主要是类别称号、类别含义。
(5)系统管理模块:书店简介信息的更新,系统维护。
(6)修改密码模块:修改管理员密码功能。
4.3 界面设计
目前,软件质量评估的重要指标就是界面设计,良好的用户界面可以加强用户对整个软件体系使用的信念和感觉。用户界面可以说是用于在系统和顾客之间交互和交换信息的媒介,用户界面实现了数据的内部形式和人本身可接受的形式之间的更调。
1、输出设计
使得网上购书系统的成果能满足用户需求的一些数据和效果即输出。输出设计的目标是实时反映和构成各部门无误管理需求所需的信息,信息是否满足人们的需求,直接关系到软件体系的投入使用和该体系是否是告成的。
设计系统的过程刚好与实施过程相反,并不是从输入设计到输出设计,而与其正好是相反的,输出设计的准则是不但要周全的反映不同工作人员的要求,并且要简洁,而不是把用户需求和不必要的全供应给用户。[10]
2、输入设计
提高效率、减小误差是输入设计的最终目的。输入接口把信息系统与用户链接起来,根据用户的需求来设计准确的输入格式,使得输出更准确即让管理员及消费者能得到正确信息。
通过以下几点可以实现其目的:克制输入量;尽可能快的输入;降低输入误差;减少不必要的步骤。[10]
4.4 系统用户用例图
用例图的主要作用有:
(1)获取需求;
(2)指导测试;
(3)对整个系统开发过程中其它工作流起到指导作用。
4.4.1 普通用户用例图
从安全方面的角度思量,为了对买家信息和订单保密,普通用户即没有登录系统的游客不能生成订单、更新自己基本信息,只有在网站首页浏览图书基本信息和对图书查询、浏览书店简介等功能,其它功能须登录实现,普通用户用例图如图4.4所示:
图4.4 用例图-普通用户
4.4.2 管理员用例图
管理工作人员是该系统的焦点角色,共包含六大功能模块,管理人员的权利最大,该软件的全部功能管理人员都能操作,其能够实时更新系统所包含的书籍、订单信息,而且是动态的。管理员用户用例图如下图4.5所示:
图4.5 用例图-管理员
4.5 数据库的设计
数据库是一种对信息的保存的过程,它建立在选定好数据库的基础之上。进行数据库的设计除了分析用户需求之外,还需要进行概念结构的设计、逻辑结构设计以及物理结构的设计,做到与系统分析与设计的阶段相对应。根据系统需要在数据库中创建订单、用户、书籍类别、图书等表。
4.5.1 数据库概念结构设计
概念结构设计的任务是将它们笼统为不依靠任何必定机械的数据模型,即概念模型,其是建立在需求分析阶段生成的需求规范的基础上。概念模型让设计者能集中注意力于最重要的新闻的组织结构和处理模式上。
概念结构设计最直观的表达方式是E-R图即是实体-联系图,它更加清晰的、方便的、直观的去看实体属性之间的联系,将现实社会物体非常好的展现出来,其能直观的看出实体具有的属性,对数据库设计起到辅助作用。
综上,使用E-R图的设计方法对数据库设计,以下对数据表进行E-R图设计,可以直观地观察到表中各属性的结构。
系统主要的实体及其属性如下:
1、普通用户实体
主要说明普通用户个体的基本信息,如图4.6所示:
图4.6 普通用户实体图
2、管理员登录信息实体
主要说明了管理员要登录后台管理系统需要的用户名和密码有效信息,如图4.7所示:
图4.7 管理员登录信息实体图
3、书籍信息实体
主要说明了每本书的基本信息,如图4.8所示:
图4.8 书籍信息实体图
4、图书类别实体
主要说明了书籍的分类的类目,包括类目名称和介绍,其实体结构如图4.9所示:
图4.9 图书类别实体图
5、订单信息实体
主要说明用户在线生成的订单的各种信息,如下图4.10所示:
图4.10 订单信息实体图
4.5.2 数据库逻辑结构设计
上边的数据库概念设计是在系统需求分析结果中总结实体信息,这个过程很重要,在这个基础上再对各实体及属性进行详细设计在,因此根据在数据库概念结构设计中的E-R图来设计出本系统中,涉及到的数据项和表结构,逻辑结构设计首先要把E-R图转换为关系模型,转换时要留意:一是E-R图中每个实体和关系模型一一对应;二是表中主键不能为空;三是实体之间的联系其中多对多这种情况应该将这种关系独立为一个关系模型。
下图为各实体转换后的关系模型,如图4.11所示:
图4.11 关系模型图
由上边关系模型图可知有6个表,以下是详细的表结构:
1、普通用户表
描述登录该系统网站用户的登录信息,具体字段类型如表4.1所示:
表4.1 普通用户表
2、图书类别信息表
描述了书籍分类的类目信息,具体字段类型如表4.2所示:
表4.2 图书类目信息表
3、图书信息表
描述每本图书的基本介绍,具体字段类型如下表4.3所示:
表4.3 图书信息表
4、管理员信息表
描述管理工作人员的基本信息,具体字段类型如表4.4所示:
表4.4 管理员信息表
5、订单项表
该表主要描述了买家全部订单的明细信息,具体字段类型如表4.5所示:
表4.5 订单项表
6、订单表
描述了用户购买图书产生的订单条目,包括订单id、书籍总价、订单是否被处理、用户昵称、订单产生时间等,具体字段类型如下表4.6所示:
表4.6 订单信息表
5 系统详细设计与实现
在经过上边对这个系统的一连串必要步骤进行完之后,现在正式开始系统的详细设计阶段,也就是程序编码过程。需求分析确定了系统的所有功能,系统设计阶段确定了所用到的技术以及结合自己我会不会该技术,然后数据库设计阶段确定了在该阶段我要把数据以怎样的形式存起来,详细设计是系统从分析到实现、从逻辑到物理实现的过程,该阶段是系统分析系统设计之后一重要环节。
5.1 管理员登录页面
1、描述:从确保本系统的安全性方面思量,作为管理工作者要想操作该系统后台管理系统必需先登录进系统的后台管理中。下图是后台登陆界面,界面简洁大方。
2、运行效果如图5.1所示:
图5.1 管理员登录界面
3、功能实现:
管理员在后台系统登录界面输入用户名和密码,点登录请求跳转到后台的action类中,在该类中进行逻辑判断,用户名和密码都对的情况下跳转到管理主界面,其中一项信息错误就出现“用户名或密码错误”提示信息,没有任何页面跳转。
登录界面判断输入信息准不准确,不准确提示错误信息的部分代码:
if (adminService.checkUser(admin.getUsername(), admin.getPassword())) {
getSession().put(“admin”, admin.getUsername());
return “main”;
}
addActionError(“用户名或密码不正确!”);
return “login”;
5.2 管理员模块
1、描述:管理员对系统管理的主界面:左侧页面显示管理员可进行操作的四大功能,而且各个模块都有对应的二级子菜单来选择具体操作。
2、运行效果如图5.2所示:
图5.2 管理员主页面
5.2.1 图书类目管理
5.2.1.1 添加类目
1、描述:工作人员输入类目名称,不用输入类别id,存入类别后id会自增。
2、运行效果如图5.3所示:
图5.3 添加图书类目
3、功能实现:
添加类别关键代码:
Action层:
categoryService.add(category);
return “recategory”;
Service层:
public Integer add(Category category) {
return categoryDao.save(category);
}
Dao层:
getSession().save(object);
5.2.1.2 图书类目列表
1、描述:管理员点左边的“类目管理”菜单,下边出现子菜单,点击“类目列表”,调用后台的逻辑处理类从数据库中查找所有的图书分类信息,右侧出来所有图书类别名称和对应操作。该页面左下角点击增添类目即可跳到增添类目页面。每个类目右边有对应修改和删除操作。
2、运行效果如图5.4所示:
图5.4 图书类目列表
3:实现代码:
categoryService.update(category);
return “recategory”;
5.2.1.3 类目信息删除
1、描述:点左侧“类目管理”菜单,点击“类目列表”,在类目列表页面,点击修改或者删除来实现对应操作。
2、运行效果如图5.5所示:
图5.5 类别删除功能
3、实现代码:
categoryService.delete(category);
public boolean delete(Category category) {
return categoryDao.delete(category);
}
try {
getSession().delete(object);
} catch (HibernateException e)
5.2.2 图书信息管理
5.2.2.1 添加图书
1、描述:点左边“图书管理”、“添加图书”,在右侧添加图书信息,填写下图中包含的图书信息,在此也可将图书直接划分到所属的类别中,使用下拉框实现。
2、运行效果如图5.6所示:
图5.6 图书信息录入
3、代码实现:
在该页面出版日期组件使用datepicker组件完成,初始日期是本天,对应设置语句为$( “#datepicker” ).datepicker(‘setDate’, new Date());
5.2.2.2 图书信息列表
1、描述:在管理主页面上点击左边“图书管理”菜单,在二级子目录中点击“图书列表”,调用后台的逻辑处理类查找出全部的书籍信息,将封装这些信息的collection放入请求对象中,然后带着这些数据转跳到响应的jsp页面,从而书籍信息展现在右侧页面中。
2、运行效果如图5.7所示:
图5.7 图书信息列表页面
3、代码实现:
图书管理关键代码:
Action层:
bookList = bookService.getList(status, page, rows);
return “book”;
Service层:
return bookDao.getList(status, page, rows);
Dao层:
public List getList(int status, int page, int rows){
return getSession().createQuery(“from Book “+packSql(status)+” order by id desc”);
}
5.2.2.3 图书信息管理
1、描述:点击“图书管理”,出现推荐列表、最新列表、促销列表,在图书列表中,每个书后边的操作一栏中,可将该书设置成为推荐图书或最新图书或促销图书,然后可在左边栏中点击推荐列表、最新列表、促销列表来查看该书。
2、运行效果如图5.8所示:
图5.8 图书管理图
3、代码实现:
<s:if test=“!special”>[<a href=“admin!bookSet.action?id=<s:propertyvalue=“id”/>&flag=11&status=KaTeX parse error: Expected 'EOF', got '&' at position 9: {status}&̲page={page}”>设为推荐]
其他功能“设为最新”、“设为促销”类似代码。
修改和删除类似。
5.2.2.4 图书推荐列表
1、描述:点击“图书管理”,点击“推荐列表”,右侧出现的图书均为商家对买家推荐的书籍,用户可根据爱好需求下订单。
2、运行效果如图5.9所示:
图5.9 推荐图书列表图
3、代码实现:
public String bookSet(){
book = bookService.get(id);
switch (flag) {
case 10:
book.setSpecial(false);
break;
case 11:
book.setSpecial(true);
break;
case 20:
book.setNews(false);
break;
case 21:
book.setNews(true);
break;
case 30:
book.setSale(false);
break;
case 31:
book.setSale(true);
break;
}
bookService.update(book);
return “rebook”;
}
5.2.2.5 图书最新列表
1、描述:点击“图书管理”,点击“最新列表”,右侧出现的图书均为商家对买家推荐的最新书籍,用户可根据爱好需求进行浏览下订单。
2、运行效果如图5.10所示:
图5.10 最新图书列表图
3、代码实现:同上边的推荐列表部分的代码。
5.2.2.6 图书促销列表
1、描述:点击“图书管理”,点击“促销列表”,右侧出现的图书均为商家对买家推荐的最新书籍,用户可根据爱好需求进行浏览下订单。
2、运行效果如图5.11所示:
图5.11 促销图书列表图
3、代码实现:同上边的推荐列表部分的代码。
5.2.3 用户信息管理
5.2.3.1 用户信息列表
1、描述:消费者进入该网站首页就成为了该系统的一位用户,管理员登录后台系统后能对注册后的用户信息进行管理,点击左边栏目“用户管理“,页面链接到后台的逻辑处理类(userAction),在这个类里边,和数据库打交道取出信息,把用户信息查寻出来,进一步输出到响应的jsp显示页面。
2、运行效果如图5.12所示:
图5.12 用户信息列表
3、关键代码实现:
userList = userService.getList(page, rows);
5.2.3.2 管理员用户添加
1、描述:管理员在后台能增添管理员用户,这些用户都是系统保护用户,不会被删除。
2、运行效果如图5.13所示:
图5.13 添加管理用户图
3、代码实现:
if (adminService.isExist(admin.getUsername())) {
addActionError(“用户名已存在!”);
return “adminadd”;
}
adminService.add(admin);
return “readmin”;
5.2.4 订单信息管理
5.2.4.1 订单信息管理
1、描述:管理人员在后台管理页面能看到所有用户完成的订单,进而对订单进行管理。
2、运行效果如图5.14所示:
图5.14 订单信息管理
5.2.5 退出系统
1、描述:点击这四个字,回到网站首页。 点此“注销”退出后台系统,返回到后台系统登陆界面。
2、关键代码:
网站首页
注销
5.3 普通用户模块
5.3.1 系统主页面实现
1、描述:网站首页界面由四部分组成:上面是关于主题书的照片以及导航条、搜索栏,左边是各页面展示的区域,右边的上方是固定的对于网站书店(该书店是虚拟的)的简介,右边的下方是图书的分类信息以及促销书籍的展示,下方是固定区域显示其他信息。
2、运行效果如图5.15所示:
图5.15 网站主页面设计
3、功能实现:页面由JSP完成,具体代码不做展示。
5.3.2 图书查询
1、描述:用户在搜索框中输入图书名称查寻。调用后台的java类search.Action查询图书,在显示层jsp展示出来。
2、运行效果如图5.16所示:
图5.16 类别查询界面设计
3、功能实现:
搜索功能关键代码:
图5.17 用户登录界面设计
3、功能实现:
普通用户登录关键代码:
public boolean checkUser(String username, String password){
return userDao.getByUsernameAndPassword(username, password);
}
5.3.4 图书分类查询
1、描述:用户可根据不同类别的名称点进去查找心仪图书,这样可减小查寻范围。
2、运行效果如图5.18所示:
图5.18 图书分类查询
3、功能实现:
图5.19 未登录下订单失败
用户登录后下订单成功如图5.20所示:
图5.20 登录后下订单成功
3、功能实现:
判断用户是否在线下订单关键代码:
if (getSession().get(“username”)==null || getSession().get(“username”).toString().isEmpty()) {
addActionMessage(“请登录后提交订单!”);
return “login”;
}
要想提交订单只有登录的用户才能成功提交。以此来升高系统的安全性,防止用户没通过登录页面直接进入子菜单页面。
5.3.6 管理订单功能
1、描述:用户在成功登陆网站并完成订单后,点击可查察所有订单,但不能删除已下订单,删除可与管理员取得联系,因为若用户可随意删除已下订单的话,对管理员很不好处理用户的订单,所以设计成只能管理员单向删除订单。
2、运行效果如图5.21所示:
图5.21 用户查看所有订单图
3、功能实现:
用户查看所有订单关键代码:
我的订单(<s:property value=“#session.username”/>)
6 系统测试
6.1 系统测试目的与意义
一个完整的系统的实现所经历的周期中非常重要和历时最长完成的阶段就是系统测试,本网上购书系统也不例外,确保该系统的方方面面的质量和实用性是系统测试过程中非常重要的,是最终的系统实现,包含系统平台的分析、系统模块的设计以及系统平台完成的最后的一道程序。[9]
尽可能多的检验出代码中的错误是系统测试环节的目的,从而增强系统的实用和可靠性,系统检测的目的是测试系统“用户体验怎么样”。系统测试过程又分三阶段从不同的角度测试:分别是单元测试、组装测试、确认测试;第一步测试每个单元模块代码的准确性,第二步测试模块间衔接的准确性,第三步对整个软件体系经过调试后看是否满足用户功能要求和性能要求进行测试,找出不准确地方的原因和位置,然后纠正。测试的目的是想给用户更好的体验,让工作人员根据不用的测试用例,不同的思路去发现系统中可能出现的错误或者说是安全隐患,为企业的利益做到最大化。
6.2 测试过程
6.2.1 网站首页用户登录测试
测试步骤:
1、进入系统主页面,输入多次不同类型错误的信息
2、尝试登录查看效果
3、最后输入对的用户名和密码
4、点击登录查看效果
设计该模块的测试用例如表6.1所示:
表6.1 主界面的登录功能测试表
6.2.2 管理员删除图书信息测试
测试步骤:
1、管理员登录后台管理,在图书管理中先删除一本书籍
2、在前台搜索栏中用关键字搜索图书,看能否找到该图书
3、查看测试结果
结论:图书删除的功能正常。
删除前如图6.1所示:
图6.1 删除图书前效果图
删除后再搜索如图6.2所示:
图6.2 删除图书后效果图
6.2.3 生成订单测试
测试步骤:
1、打开系统网站首页,不登录时往购物车添加一本图书,看能不能成功
2、登录后再添加,看能不能添加成功
3、查看测试结果
结论:未登录时用户只能将商品添加到购物车,不能生成订单,登录后才能提交订单,所以生成订单功能正常。
效果图如图6.3所示:
图6.3 未登录提交订单效果图
6.2.4 其他错误测试
在执行程序的过程中肯定会产生种种不可预知的错误,好比说写入错误,值类型不匹配,参数的传递等问题。这些不仅需要仔细的测试,而且需要连续调试去解决掉。例如,当由于粗心错误导致的action路径配置错误引起的操作时,如图6.4所示:
图 6.4 action路径配置错误,运行出现的提示
7 系统的运行和维护
作为现代化的软件,它首先应该有良好的界面,使用方便的特点;在性能方面,要求他速度快、存储数据容量大、方便操作等特点且CPU处理数据的速率要快。由于以上出发点,本次系统开发的工具,使用了Java语言,MySQL 数据库,Tomcat服务器。软件开发行业,只有系统具有稳定性操作以及系统的吞吐量足够好,才是一款优秀的软件应用。在此基础上,还应该做好用户的维护。在整个软件体系使用期间,一直都进行的一件工作就是系统维护,确保系统能正常运行和管理是系统维护的主要目的。[5]
系统运行正常可靠,可以使系统持续改善,从而使它充分展现其作用,以下两类是系统维护的主要分类:对数据库的维护和代码维护。前者主要对数据库安全方面和数据完整性还有事务的并发进行负责和控制,当需要往数据库中增加信息时,管理员对相关数据进行更改,最重要的是当有某些不可抗因素导致数据会丢失时,要及时对数据进行备份和恢复;后者的维护,社会在进步,人们的思想在更新,还有业务需求的变动使软件体系都会做出相应变动,系统代码会相应增长、删除还有增加新的模块。
结论
现在网上销售书籍平台的优势有很多,所以更多的人在网上购买或者在网络上开自己的店销售物品,该系统是自己练习锻炼的一个项目,在老师、实习同事们和同学们的帮助下让我能完成现在的系统,让我充分了解了专业知识,虽然基本功能已有,但是系统还有很多不足的地方,比如网上支付和书籍发货以及物流跟踪功能,这些功能还需要我继续学习。
本系统主要模块是前台针对用户的购书平台和后台针对管理员管理系统的平台。前台主要实现了图书信息浏览、虚拟书店介绍展示,用户注册登录、增添图书到购物车、生成订单等功能;后台模块主要实现了管理员管理用户、管理图书信息、管理订单信息、图书类别管理功能。层次分明、操作简单,用户和管理员能方便舒适的使用该系统。
参考文献
[1]郑阿奇.JSP实用教程.电子工业出版社,2008
[2] 飞思科技产品研发中心. JSP应用开发详解(第二版) [M]. 北京:电子工业出版社,2004
[3] 吴以欣,陈小宁.JavaScript脚本程序设计[M]. 北京:人民邮电出版社,2005
[4] 萨师煊,王珊.数据库系统概论(第五版)[M]. 北京:高等教育出版社,2014
[5]孙卫琴,李洪成.Tomcat与Java Web开发技术详解[M]. 北京:电子工业出版社,2004
[6] 刘中兵,李伯华,邹晨.JSP数据库项目案例导航.清华大学出版社,2006.
[7] 刘长生,谢强,丁秋林.Java应用中的汉字乱码问题分析[J]. 计算机技术与发展,2006,16(1):158-161
[8] Tsui,Frank F. JSP EM DASH A RESEARCH SIGNAL PROCESSOR IN JOSEPHSON TECHNOLOGY[C]. IBM Journal of Research and Development,Vol24, No2,1980:243-252
[9] Sanden, Bo. SYSTEMS PROGRAMMING WITH JSP:EXAMPLE - A VDU
[10] Mark Wutka,Alan Moffet,Kunal Mittal.Sams Teach Yourself JAVAServer Pages 2.0 with Apache Tomcat in 24 Hours[M].Sams Publishing,2003 [14]James Turner,Kevin Bedell. Struts Kick Start[M]. SAMS,2004 [15] Kong Michael. An environment for secure SQL/Server computing [M].Oxford University Press Inc., 1993: 149
致谢
我的毕业设计和论文是在老师的指导下完成进行的,老师将其学生拉入一个QQ群,会集中处理我们的问题,认真负责有耐心,非常感谢老师对我的指导。
感谢上海杰普老师在毕业设计期间给我的帮助,王老师有事情会给我打电话及时解决问题,感谢老师。
感谢我的同事和同学对我的关心和帮助。
附录:外文原文
Hibernate In Action
Retrieving objects
Retrieving persistent objects from the database is one of the most interesting (andcomplex) parts of working with Hibernate. Hibernate provides the following waysto get objects out of the database:
●Navigating the object graph, starting from an already loaded object,byaccessingtheassociatedobjectsthrough property accessor methods such as a User.getAddress().getCity().Hibernate will automatically load (or preload)nodes of the graph while you navigate the graph if the Session is open.
●Retrieving by identifier, which is the most convenient and performant method when the uniqueidentifier value of an object is known.
●Using the Hibernate Query Language (HQL), which is a full object-orientedquerylanguage.
●Using the, Hibernate Criteria API, which provides a type-safe and objectoriented way to perform queries without the need for string manipulation.This facility includes queries based on an example object.
●Using native SQL queries, where Hibernate takes care of mapping the JDBC result sets to graphs of persistent objects.In your Hibernateapplications, you’ll use a combination of these techniques.Each retrieval method may use a different fetching strategy—that is, a strategy that defines what part of the persistent object graph should be retrieved. The goal is to find the best retrieval method and fetching strategy for every use case in your application while at the same time minimizing the number of SQL queries for best performance. We won’t discuss each retrieval method in much detail in this section; instead we’ll focus on the basic fetching strategies and how to tune Hibernate mapping files for best default fetching for all methods. Before we look at the fetchingstrategies,we’ll give an overview of the retrieval methods. (We mention the Hibernate caching system but fully explore it in the next chapter.)Let’s start with the simplest case, retrieval of an object by giving its identifier value (navigating the object graph should self-explanatory). You saw a simple retrieval by identifier earlier in this chapter, but there is more to know about it.
Retrieving objects by identifier
The following Hibernate code snippet retrieves a User object from the database:
User user = (User) session.get(User.class, userID);The get() method is special because the identifier uniquely identifies a single;instance of a class. Hence it’s common for applications to use the identifier as aconvenient handle to a persistent object. Retrieval by identifier can use the cachewhen retrieving an object, avoiding a database hit if the object is already cached. Hibernate also provides a load() method:User user = (User) session.load(User.class, userID); The load() method is older; get() was added to Hibernate’s API due to userrequest. The difference is trivial:
●If load() can’t find the object in the cache or database, an exception isthrown. The load() method never returns null. The get() method returnsnull if the object can’t be found.
●The load() method may return a proxy instead of a real persistent instance.A proxy is a placeholder that triggers the loading of the real object when it’s accessed for the first time; we discuss proxies later in this section. On the other hand, get() never returns a proxy.Choosing between get() and load() is easy: If you’re certain the persistentobject exists, and nonexistence would be considered exceptional, load() is a good option. If you aren’t certain there is a persistent instance with the given identifier, use get() and test the return value to see if it’s null. Using load() has a further implication: The application may retrieve a valid reference (a proxy) to a persistent instance without hitting the database to retrieve its persistent state. So load() might not throw an exception when it doesn’t find the persistent object in the cache or database; the exception would be thrown later, when the proxy is accessed. Of course, retrieving an object by identifier isn’t as flexible as using arbitrary queries
Introducing HQL
The Hibernate Query Language is an object-oriented dialect of the familiar relational query language SQL. HQL bears close resemblances to ODMG OQL andEJB-QL; but unlike OQL, it’s adapted for use with SQL databases, and it’s much more powerful and elegant than EJB-QL (However, EJB-QL 3.0 will be very similar to HQL.) HQL is easy to learn with basic knowledge of SQL. HQL isn’t a data-manipulation language like SQL. It’s used only for object retrieval, not for updating, inserting, or deleting data. Object state synchronization is the job of the persistence manager, not the developer.
Most of the time, you’ll only need to retrieve objects of a particular class and restrict by the properties of that class. For example, the following query retrieves a user by first name:
Query q = session.createQuery(“from User u where u.firstname = :fname”); q.setString(“fname”, “Max”); List result = q.list(); After preparing query q, we bind the identifier value to a named parameter, fname.The result is returned as a List of User objects.
HQL is powerful, and even though you may not use the advanced features all the time, you’ll need them for some difficult problems. For example, HQL supports the following:
●The ability to apply restrictions to properties of associated objects related by reference or held in collections (to navigate the object graph using query language).
●The ability to retrieve only properties of an entity or entities, without the overhead of loading the entity itself in a transactional scope. This is sometimes called a report query; it’s more correctly called projection.
●The ability to order the results of the query.
●The ability to paginate the results.
●Aggregation with group by, having, and aggregate functions like sum, min, and max.
●Outer joins when retrieving multiple objects per row.
●The ability to call user-defined SQL functions.
●Subqueries (nested queries).
Query by criteria
The Hibernate query by criteria (QBC) API lets you build a query by manipulating criteria objects at runtime. This approach lets you specify constraints dynamically without direct string manipulations, but it doesn’t lose much of the flexibility or power of HQL. On the other hand, queries expressed as criteria are often less readable than queries expressed in HQL.
Retrieving a user by first name is easy using a Criteria object: Criteria criteria = session.createCriteria(User.class); criteria.add( Expression.like(“firstname”, “Max”) ); List result = criteria.list(); A Criteria is a tree of Criterion instances. The Expression class provides static factory methods that return Criterion instances. Once the desired criteria tree is built, it’s executed against the database.
Many developers prefer QBC, considering it a more object-oriented approach. They also like the fact that the query syntax may be parsed and validated at compile time, whereas HQL expressions aren’t parsed until runtime.
The nice thing about the Hibernate Criteria API is the Criterion framework. This framework allows extension by the user, which is difficult in the case of a query language like HQL
Query by example
As part of the QBC facility, Hibernate supports query by example (QBE). The idea behind QBE is that the application supplies an instance of the queried class with certain property values set (to nondefault values). The query returns all persistent instances with matching property values. QBE isn’t a particularly powerful approach, but it can be convenient for some applications. The following code snippet demonstrates a Hibernate QBE:
User exampleUser = new User(); exampleUser.setFirstname(“Max”); Criteria criteria = session.createCriteria(User.class); criteria.add( Example.create(exampleUser) ); List result = criteria.list(); A typical use case for QBE is a search screen that allows users to specify a range of property values to be matched by the returned result set. This kind of functionality can be difficult to express cleanly in a query language; string manipulations would be required to specify a dynamic set of constraints.
Both the QBC API and the example query mechanism are discussed in more detail in chapter 7. You now know the basic retrieval options in Hibernate. We focus on the strategies for fetching object graphs in the rest of this section. A fetching strategy defines what part of the object graph (or, what subgraph) is retrieved with a query or load operation.
Fetching strategies
In traditional relational data access, you’d fetch all the data required for a particular with a single SQL query, taking advantage of inner and outer joins to retrieve related entities. Some primitive ORM implementations fetch data piecemeal, with many requests for small chunks of data in response to the application’s navigating a graph of persistent objects. This approach doesn’t make efficient use of the relational database’s join capabilities. In fact, this data access strategy scales poorly by nature. One of the most difficult problems in ORM—probably the most difficultis providing for efficient access to relational data, given an applicationthat prefers to treat the data as a graph of objects.
For the kinds of applications we’ve often worked with (multi-user, distributed, web, and enterprise applications), object retrieval using many round trips to/from the database is unacceptable. Hence we argue that tools should emphasize the R in ORM to a much greater extent than has been traditional.
The problem of fetching object graphs efficiently (with minimal access to the database) has often been addressed by providing association-level fetching strategies specified in metadata of the association mapping. The trouble with this approach is that each piece of code that uses an entity requires a different set of associated objects. Butthis isn’t enough. We argue that what is needed is support forfine-grained runtime association fetching strategies. Hibernate supports both, it lets you specify a default fetching strategy in the mappingfile and then override it at runtime in code.
Hibernate allows you to choose among four fetching strategies forany association, in association metadata and at runtime:
●Immediate fetching—The associated object is fetched immediately, using a sequential database read (or cache lookup).
●Lazy fetching—The associated object or collection is fetched “lazily,” when it’s first accessed. This results in a new request to the database (unless the associated object is cached).
●Eager fetching—The associated object or collection is fetched together with the owning object, using an SQL outer join, and no further database requestis required.
●Batch fetching—This approach may be used to improve the performance of lazy fetching by retrieving a batch of objects or collections when a lazy association is accessed. (Batch fetching may also be used to improve the performance of immediate fetching.)
Let’s look more closely at each fetching strategy.
Immediate fetching
Immediate association fetching occurs when you retrieve an entity from the database and then retrieve another associated entity or entities in a further request to the database or cache. Immediate fetching isn’t usually an efficient fetching strategy unless you expect the associated entities to almost always be cached already.
Lazy fetching
When a client requests an entity and its associated graph of objects from the database, it isn’t usually necessary to retrieve the whole graph of every (indirectly) associated object. You wouldn’t wantto load the whole database into memory at once; for example, loading a single Category shouldn’t trigger the loading of all Items inthat category.
Lazy fetching lets you decide how much of the object graph is loaded in the first database hit and which associations should be loaded only when they’re first accessed. Lazy fetching is a foundational concept in object persistence and the first step to attaining acceptable performance.
We recommend that, to start with, all associations be configured for lazy (or perhaps batched lazy) fetching in the mapping file. Thisstrategy may then be overridden at runtime by queries that force eager fetching to occur.
Eager (outer join) fetching
Lazy association fetching can help reduce database load and is often a good default strategy. However, it’s a bit like a blind guessas far as performance optimization goes.
Eager fetching lets you explicitly specify which associated objects should be loaded together with the referencing object.Hibernatecan then return the associated objects in a single database request,utilizing an SQL OUTER JOIN. Performance optimization in Hibernate often involves judicious use of eager fetching for particular transactions.Hence, even though default eager fetching may be declared in the mapping file, it’s more common to specify the use of this strategyat runtime for a particular HQL or criteria query.
Batch fetching
Batch fetching isn’t strictly an association fetching strategy; it’s a technique that mayhelp improve the performance of lazy (or immediate) fetching. Usually,when you load an object or collection, your SQL WHERE clause specifies the identifier of the object or object that owns the collection.If batch fetching is enabled, Hibernate looks to see what other proxied instances or uninitialized collections are referenced in the current session and tries to load them at the same time by specifying multiple identifier values in the WHERE clause.
We aren’t great fans of this approach; eager fetching is almostalways faster. Batch fetching is useful for inexperienced users who wish to achieve acceptable performance in Hibernate without having to think too hard about the SQL that will be executed. (Note that batch fetching may be familiar to you, since it’s used by many EJB2engines.)
We’ll now declare the fetching strategy for some associations inour mapping metadata.
Struts——An Open-source MVC Implementation
This article introduces Struts, a Model-View-Controller implementation that uses servlets and JavaServer Pages (JSP) technology. Struts can help you control change in your Web project and promote specialization. Even if you never implement a system with Struts, you may get some ideas for your future servlets and JSP page implementation
Introduction
Kids in grade school put HTML pages on the Internet. However, there is a monumental difference between a grade school page and a professionally developed Web site. The page designer (or HTML developer) must understand colors, the customer, product flow, page layout, browser compatibility, image creation, JavaScript, and more. Putting a great looking site together takes a lot of work, and most Java developers are more interested in creating a great looking object interface than a user interface. JavaServer Pages (JSP) technology provides the glue between the page designer and the Java developer.
If you have worked on a large-scale Web application, you understand the term change. Model-View-Controller (MVC) is a design pattern put together to help control change. MVC decouples interface from business logic and data. Struts is an MVC implementation that uses Servlets 2.2 and JSP 1.1 tags, from the J2EE specifications, as part of the implementation. You may never implement a system with Struts, but looking at Struts may give you some ideas on your future Servlets and JSP implementations.
Model-View-Controller (MVC)
JSP tags solved only part of our problem. We still have issues with validation, flow control, and updating the state of the application. This is where MVC comes to the rescue. MVC helps resolve some of the issues with the single module approach by dividing the problem into three categories:
Model
The model contains the core of the application’s functionality. The model encapsulates the state of the application. Sometimes the only functionality it contains is state. It knows nothing about the view or controller.
View
The view provides the presentation of the model. It is the look of the
application. The view can access the model getters, but it has no knowledge of the setters. In addition, it knows nothing about the controller. The view should be notified when changes to the model occur.
Controller
The controller reacts to the user input. It creates and sets the model.
Struts details
Displayed in Figure 6 is a stripped-down UML diagram of the
org.apache.struts.action package. Figure 6 shows the minimal relationships among ActionServlet (Controller), ActionForm (Form State), and Action
(Model Wrapper).
The ActionServlet class
Do you remember the days of function mappings? You would map some input event to a pointer to a function. If you where slick, you would place the configurationinformation into a file and load the file at run time. Function pointer arrays were the good old days of structured programming in C.
Life is better now that we have Java technology, XML, J2EE, and all that. The Struts Controller is a servlet that maps events (an event generally being an HTTP post) to classes. And guess what – the Controller uses a configuration file so you don_t have to hard-code the values. Life changes, but stays the same.
ActionServlet is the Command part of the MVC implementation and is the
core of the Framework. ActionServlet (Command) creates and uses Action, an ActionForm, and ActionForward. As mentioned earlier, the struts-config.xml file configures the Command. During the creation of the Web project, Action and ActionForm are extended to solve the specific problem space. The file struts-config.xml instructs ActionServlet on how to use the extended classes. There are several advantages to this approach:
The entire logical flow of the application is in a hierarchical text file. This makes it easier to view and understand, especially with large applications. The page designer does not have to wade through Java code to understand the flow of the application.
The Java developer does not need to recompile code when making flow changes.
Command functionality can be added by extending ActionServlet.
中文翻译
Hibernate的实践与应用
检索对象
从数据库中检索对象是使用Hibernate最有趣(也是最复杂)的部分。Hibernate 提供下列方式 从数据库中提取对象:
●导航对象图,从一个已经装载的对象开始,通过像aUser.getAddress().getCity()的属性访问器方法访问相关的对象。如果Session是打开的,当你导航图时,Hibernate会自动装载图的节点。
●当对象的唯一标识符值是已知的时候,通过标识符检索是最方便最有性能的方法。使用Hibernate查询语言(HQL),它是完全面向对象的查询语言。
●使用Hibernate 条件API,它提供了类型安全的面向对象的方式执行查询而不需要操纵字符串。这种便利性包括基于例子对象的查询。
●使用本地SQL查询,这种查询Hibernate只关心把JDBC 结果集映射到持久对象图。在Hibernate 应用程序中,将结合使用这几种技术。每一种检索方法可能使用不同的抓取策略—那就是定义持久对象图的哪个部分应该检索的策略。目标是在你的应用程序中为每个使用场合发现最好的检索方法和抓取策略,同时最小化查询语句的数量以获得最好的性能。在这一节我们不仔细讨论每个检索方法,相反,我们将集中于基本的抓取策略和怎样调整Hibernate 映射文件以便对所有的方法达到最好的默认抓取性能。在看抓取策略之前,我们将给出检索方法的概述。(我们提到Hibernate缓存系统但是将在下一章完全研究它。)让我们开始最简单的例子,通过给定的标识符值检索对象(导航对象图不加以说明了)。
在这一章的前半部分你已经看过一个简单的通过标识符检索的例子,但是还有许多需要知道。
根据标识符检索对象
下面的Hibernate 代码片断从数据库中检索User对象: User user =(User)session.get(User.class, userID); get()方法很特别,因为标识符唯一地标识类的单个实例。因此,应用程序通常使用标识符方便地处理持久对象。当用标识符检索对象时可以使用缓存,如果对象已经缓存了可以避免数据库碰撞(hit)。
Hibernate也提供了load()方法:
User user = (User) session.load(User.class, userID); load()方法是旧的,因为用户的请求已经把get()方法加入到Hibernate API。
不同之处微不足道:
●如果load()方法不能在缓存或数据库中找到对象会抛出异常。load()方法从不返回null。如果对象没找到get()方法返回null。
●load()方法返回代理而不是真正的持久实例。代理是一个占位符,当第一次调用它时才装载真正的对象。我们将在本节的后半部分讨论代理。另一方面,get()方法从不返回代理。在get()和load()之间选择很简单:如果你能确定持久实例存在,不存在将会认为是异常,那么load()是很好的选择。如果你不能确定给定的标识符是否有一个实例,使用get()测试返回值,看它是否为null。使用load()有更深的含义:应用程序可能检索一个对持久实例的引用(代理)而不会强制数据库检索它的持久状态。因此,在缓存或数据库中不能找到持久对象时load()不能抛出异常。异常会在以后抛出,当代理被访问的时候。
当然,使用标识符检索对象没有使用任意的查询复杂。
介绍HQL
Hibernate 查询语言是与其相似的关系型查询语言SQL 的面向对象方言。HQL与ODMGOQL和EJB-QL很相像,但是不像OQL,它是用于SQL数据库的,并且比EJB-QL更强大更优秀(然而,EJB-QL3.0 将会与HQL非常相似。)只要有SQL基础HQL非常容易学。HQL不是像SQL这样的数据操纵语言。它只能用来检索对象,不能更新、插入或删除数据。对象状态同步是持久管理器的工作,而不是开发者的工作。
大部分时间你仅仅需要检索特定类的对象,并且受那个类的属性的约束。例如,下面的查询根据姓来检索用户:
Query q = session.createQuery(“from User u where u.firstname = :fname”); q.setString(“fname”, “Max”); List result = q.list();准备查询q 之后,我们把标识符值绑定到命名参数fname 上。User 对象的List 作为结果返回。HQL功能非常强大,虽然你不会一直使用其高级特征,但是你将会需要它们来解决一些复杂问题。例如,HQL支持下面这些功能:
●通过引用或持有集合(使用查询语言导航对象图)把限制条件应用到相关的关联对象的属性上的能力。
●在事务范围仅仅检索一个或多个实体的属性而不是装载整个实体的能力。有时把它称为report query,更正确的说法是projection。
●排列查询结果的能力。
●分页查询的能力。
●使用group、having及统计函数(如sum、min和max)进行统计。
●当在一行中检索多个对象时使用外联接。
●调用用户自定义的SQL函数的能力。
●子查询(嵌套查询)。
通过条件查询
Hibernate的通过条件查询(query by criteria(QBC))API允许你在运行时通过操纵查询对象来建立查询。这种方法允许动态的指定约束而不是直接操纵字符串,但是,它也丢掉了许多HQL的复杂性或强大功能。另一方面,以条件表示的查询比以HQL表示的查询可读性差。
通过名字检索用户使用查询对象更简单:
Criteria criteria = session.createCriteria(User.class); criteria.add( Expression.like(“firstname”, “Max”)); List result = criteria.list();
Criteria 是一个Criterion 实例树。Expression 类提供返回Criterion 实例的静态工厂方法。 一旦建立了想要的查询树,就会对数据库执行。许多开发者喜欢QBC,把它认为是更复杂的面向对象方法。他们也喜欢查询语法在编译时解释和验证的事实,而HQL只有在运行时才解释。
关于Hibernate Criteria API最好的方面是Criterion框架。这个框架允许用户对其进行扩展,像HQL这样的查询语言却很困难。
通过例子查询
作为QBC便利性的一部分,Hibernate支持通过例子查询(QBE)。使用QBE的前提条件是应用程序支持具有某种属性值集合(非默认值)的查询类实例。查询返回所有的匹配属性值的持久实例。QBE 不是特别强大的方法,但是对一些应用程序却很方便。下面的代码片断演示Hibernate的QBE:
User exampleUser = new User(); exampleUser.setFirstname(“Max”);
QBE 的典型用例是允许用户指定属性值范围的查找屏幕,指定属性值范围用来匹配返回的结果集。这种功能在查询语言中很难清晰地表达,操纵字符串需要指定动态的约束集。QBC API和这种查询机制的例子将在第七章详细讨论。现在你知道Hibernate中基本的检索选项。我们在本节的剩余部分关注对象图的抓取策略。抓取策略定义了用查询或装载操作检索对象图(或子图)的哪一部分。
抓取策略
传统的关系数据访问利用内连接和外连接检索相关的实体,用单个SQL查询抓取对某个计算所需要的所有数据。一些原始的ORM实现分开抓取数据,多次请求小块的数据,应用程序作为响应也会多次导航持久对象图。这种方法不能有效利用关系数据库的连接能力。实际上,这种数据访问策略将来很难扩展。ORM中的一个最困难的问题—可能是最困难的—是提供对关系数据库的有效访问,鉴于应用程序喜欢把数据当成对象图看待。
对于我们经常开发的多种应用程序(多用户,分布式,web 和企业应用),检索对象时多次往返于数据库是不可取的。因此,我们讨论的工具比传统的工具更强调ORM中的R(关系)。有效地抓取对象图的问题已经通过在关联映射的元数据中指定关联级抓取策略解决了。
这种方法存在的问题是每段代码使用一个需要不同集合的相关对象的实体。但是这是不够的我们需要的是支持细粒度的运行时关联抓取策略。Hibernate 两者都支持,允许在映射文件中指定默认的抓取策略,然后在代码运行时重载。
Hibernate对于任何关联允许在四种抓取策略中选择,在关联元数据和运行时:
●立即抓取—立即抓取关联的对象,使用连续的数据库读(或缓存查找)。
●延迟抓取—当第一次访问时,“延迟”抓取相关的对象或集合。这个结果在对数据库的新请求中(除非缓存了相关的对象)。
●提前抓取—相关的对象或集合同拥有它们的对象一起抓取,使用SQL外连接,不需要额外的数据库请求。
●批量抓取—在访问延迟关联时,这种方法通过检索一批对象或集合来提高延迟抓取的性能(批量抓取也用来提高立即抓取的性能。)让我们仔细看看每种抓取策略。
立即抓取
立即的关联抓取发生在从数据库中检索实体然后立即在下一个对数据库或缓存的请求中检索另一个(或一些)相关的实体的时候。立即抓取通常不是有效的抓取策略除非希望关联的实体一直被缓存。
延迟抓取
当客户请求数据库中的实体及其相关的对象图时,通常不必检索每个(非直接的)关联对象的整个对象图。你不希望立即把整个数据库装载到内存中,例如,装载单个Category 不应该触发装载这个目录的所有Item。延迟抓取能够让你决定第一次访问数据库时装载多少对象图,并且与其关联的对象只有在第一次访问时才装载。延迟抓取是对象持久化中的基本内容,而且是取得可接受性能的第一步。
我们推荐在开始的时候把映射文档中所有的关联映射为延迟(或可能是批量延迟)抓取。
这种策略然后被强制提前抓取发生的查询重载。
提前(外连接)抓取
延迟关联抓取能够帮助减少数据库装载,而且通常是一种好的默认策略。然而,这在性能优化发生前有点盲目猜测。
提前抓取让你显式地指定哪些关联的对象应该同引用它们的对象一起装载。Hibernate 然后在单个数据库请求中使用SQL的OUTER JOIN 返回关联的对象。Hibernate的性能优化通常包括针对某些事务明智地使用提前抓取。因此,即使在映射文件中声明了默认的抓取策略,在运行时对于某个HQL或条件查询指定使用这种策略更普遍。
批量抓取
批量抓取不是严格的关联抓取策略,它是帮助提高延迟(或立即)抓取性能的一种技术。通常,当装载对象或集合的时候,SQL的WHERE 子句指定对象的标识符或拥有集合的对象。
如果开启了批量抓取,Hibernate看起来知道什么会在当前session 中引用其它代理实例或未初 始化的集合,尽量通过在WHERE 子句中指定多个标识符值来同时装载这些对象。我们不是这种方法的热心者,提前抓取几乎一直是更快的。批量抓取对那些希望用Hibernate 达到可接受的性能而不用想太多关于要执行的SQL 的经验不足的用户很有用。(注意,你可能很熟悉批量抓取,因为它已经被许多EJB2 引擎使用)。
现在我们在映射元数据中对一些关联声明抓取策略。
Struts——一种开源MVC的实现
这篇文章介绍 Struts,一个使用 servlet 和 JavaServer Pages 技术的一种 Model-View-Controller 的实现。Struts 可以帮助你控制 Web 项目中的变化并提高专业化。即使你可能永远不会用 Struts实现一个系统,你可以获得一些想法用于你未来的 servlet 和 JSP 网页的实现中。
1、简介
在小学校园里的小孩子们都可以在因特网上发布 HTML 网页。然而,有一个重大的不同在一个小学生和一个专业人士开发的网站之间。网页设计师(或者 HTML开发人员)必须理解颜色、用户、生产流程、网页布局、浏览器兼容性、图像创建、JavaScript 等等。设计漂亮的网站需要做大量的工作,大多数 Java 开发人员更注重创建优美的对象接口,而不是用户界面。JavaServer Pages (JSP) 技术为网页设计人员和 Java 开发人员提供了一种联系钮带。
如果你开发过大型 Web 应用程序,你就理解“变化”这个词语。“模型-视图-控制器”(MVC) 就是用来帮助你控制变化的一种设计模式。MVC 减弱了业务逻辑接口和数据接口之间的耦合。Struts 是一种 MVC 实现,它将 Servlet 2.2 和 JSP 1.1 标记(属于 J2EE 规范)用作实现的一部分。你可能永远不会用 Struts 实现一个系统,但了解一下 Struts 或许使你能将其中的一些思想用于你以后的 Servlet和 JSP 实现中。
2、模型-视图-控制器 (MVC)
JSP标签只解决了我们问题中的一部分。我们依然有验证、流控制、以及更新应用程序结构的问题。这就是MVC从哪儿来以及来干嘛的。MVC通过把问题分成三类来帮助解决一些与单模块相关的问题:
Model(模型)
模块包括应用程序功能的核心。模型封装着应用程序的各个结构。有时它所包含的唯一功能就是结构。它对于视图或者控制器一无所知。
View(视图)
视图提供了模型的演示。它是应用程序的外表。视图可以进入模型获得者,第 1 页共 8 页
中北大学2014届毕业设计英文文献译文
但是它对于设置者一无所知。除此之外,它对于控制器也是一无所知。视图仅仅当模型发生改变的时候才被通知。
Controller(控制器)
控制器对于用户的输入做出反应。它创造和设置模型。
Struts 详细资料
ActionServlet 类
你还记得使用函数映射的日子吗?你会映射一些输入时间到一个函数的一个指针。如果你很老练,你可以把这些配置信息放进一个文件里并且在运行时加载该文件。函数指针装扮了在C语言结构化程序设计中的旧时光。
现在日子好过多了,自从我们有了Java技术、XML、J2EE等等之后。Struts控制器是一个映射事件(事件通常是一个HTTP post)到类的一个 servlet。猜猜怎么着-- 控制器用一个配置文件以致于你不必非硬编码这些值。生活变了,但方法依然如此。
ActionServlet 是 MVC 实现的命令部分并且它是框架的核心。
ActionServlet (Command) 创建并使用 Action 、 ActionForm 和
ActionForward 。正如前面所提及的, struts-config.xml 文件配置Command。在Web 工程创建期间, Action 和 ActionForm被扩展用来解决特殊的问题空间。文件 struts-config.xml 指导 ActionServlet 如何扩展这些类。这种方法有几个优点:
应用程序的整个逻辑流程处于分层文本文件中。这使得更容易查看和理解,特别是在大型应用程序中。页面设计人员不必通过Java代码来了解应用程序的流程。
Java开发人员在进行流程更改时不需要重新编译代码。
可以通过扩展ActionServlet来添加命令功能。