基于 Struts 和 Hibernate 的在线考试系统
http://www.paper.edu.cn
段朋鹏,郭庆平
武汉理工大学计算机学院,湖北武汉(430063)
摘 要:在 J2EE 的 B/S 应用架构下,以 Struts 作为表示层框架,Hibernate 作为数据持久层
框架,设计一个 MVC 模式的在线考试系统。该系统运行效率高,具有良好的可扩展性、实
用性和可维护性。文中对系统的体系结构、功能和实现机制进行了详细阐述。
关键词:Struts 框架;持久化;数据访问对象;对象关系映射;过滤器;在线考试
0. 引言
计算机辅助教学作为一种现代教学技术,越来越受到人们的关注。考试作为准确了解学
生的知识掌握情况的重要手段,是教学的重要组成部分。本文结合 Struts 和 Hibernate 技术
提出了基于 J2EE 平台 B/S 结构的在线考试系统。该系统克服了传统两层架构的不足,将应
用逻辑、业务处理逻辑和显示逻辑分成不同的部分。实现层次间的松耦合,提高了代码重用
性,增强了系统的灵活性、复用性和可维护性,最终提高了软件质量。
1. MVC 模式和 Struts 框架
1.1MVC 模式
MVC(Model-View-Controller)模式[1]是当前在开发 Web 应用时使用最广泛的,第一个把表
示逻辑和业务逻辑分开的设计模式。它把程序分为三个部分,有效降低系统各个部分的耦合
程度,简化了 Web 应用的开发过程。
(1)模型(Model):模型包含了应用程序功能的核心,它封装了业务数据和对数据的操作,
用于实现特定的业务逻辑,集中体现了应用程序的状态。
(2)视图(View):视图实现模型的外观,是整个应用程序的外在表现。它可以访问模型的
数据,但不能改变这些数据。当模型发生改变时,视图会得到通知。
(3)控制器(Controller):控制器对用户的输入做出反应并将模型和视图联系在一起。作为
业务流程控制,它不对浏览器发送过来的 HTML 表单做任何逻辑处理,只是接受请求并调用
特定模型进行处理,再决定用哪个视图将模型处理后的数据显示给客户。
1.2 Struts 框架
Struts 框架实质上是在 JSP Model 2 的基础上实现的一个 MVC 架构。部署描述符
struts-config.xml 用于装载和配置各种 Struts 组件,仅需修改它即可方便变换 Controller 类,从而
变换程序行为,或重新指向不同显示页面的 View。
对 于 所 有 来 自 Web 浏 览 器 的 请 求, 控 制 器 部 分 的 ActionServlet 会 依 照 配 置 文 件
struts-config.xml 的内容正确地指派 action 处理,其控制置于 Action 类的 execute()方法中。
Action 类可按 struts-config.xml 内的 forward 标记内容,将最后的运算结果交由某个 JSP 页面
显示。在显示用户界面的 View 部分时,Struts 提供了 5 种自定义的 Tag Libraries 供 JSP 使用,
这些 Tag Libraries 能够按照收到的信息自动转为 HTML,或提供条件判断等显示逻辑流程控
制。Struts 框架中,MVC 三部分可能跨越网络位于不同硬件环境中。
为解决相互传递、交换信息的问题,采用了 Data Transfer Object 模式。Struts 运用继承于
ActionForm 的 JavaBean(即 FormBean)来存储使用者在 Web 浏览器中所输入的信息,由于
- 1 -
http://www.paper.edu.cn
JavaBean 可实现 Serialization 接口,具备跨越网络传递数据的特性,因而可以解决 MVC 间信息
传递交换问题。此外,ActionForm 也可在其内部实现信息校验。
2. Hibernate 框架
Hibernate 的精髓是持久层实现模式,是一个面向 Java 环境的对象/关系数据库映射工具。
它不仅仅管理 Java 类到数据库表的映射,还提供数据查询和获取数据的方法,可以大幅度减少
开发时人们使用 SQL 和 JDBC 处理数据的时间,而只用对对象进行操作。Hibernate 包装了
JDBC,尽可能使用最高效的 JDBC 调用。它提供开放的 API,用户可以自行扩充其功能。
Hibernate 在大多数主流 J2EE 应用服务器的受管理环境中都可以良好运作,也可以作为
独立应用程序运行。Hibernate 支持继承与多态机制,沿用了传统数据库的事务模型,提供对十
六种数据库语言的支持。图 1[2]是一个高层次的概览。
图 1 Hibernate 应用程序的结构
3. 在线考试系统的分析与设计
3.1 系统功能
在分析了当前考试系统的优缺点,结合本人的教学实践和详细了解了网上考试系统的实
际需求后,下面介绍本系统的总体功能设计。
(1)权限管理的功能是对用户的权限进行描述和声明,为安全认证系统提供必要的权限
信息。权限管理主要是建立权限模型、权限的定义方式和描述机制。
(2)用户管理的功能是教师信息的管理、学生信息管理、班级信息管理和教师任课班级
的设置。
(3) 用户认证模块主要包括:用户登录功能,重新登录功能,用户执行某个功能时的权
限校验功能和修改密码功能。
(4) 试卷发布和题库试题管理都由教师来操作的,这里试卷的题型包含四种:分别为单
项选择题、判断题、填空题和问答题。
(5) 学生考试功能包括学生在登录本系统后可以浏览到其任课教师所发布的试卷信息,
然后选择相应的试卷考试,系统自动给出学生的客观题得分情况。
3.2 系统总体架构设计
本考试系统采用基于 Struts 和 Hibernate 框架的多层架构,采用 B/S 架构,总体架构如
图 2 所示。各层的具体实现如下:
- 2 -
http://www.paper.edu.cn
图 2 系统分层架构图
(1) 客户层:用于为用户提供可视化的用户界面,进行人机交互 ,本系统就是 IE 浏览
器。
(2) 表示层:用于对客户请求作出响应,调用业务逻辑层的组件,并将结果返回给客户
层,主要由 JSP 文件和 ActionForm Bean 构成。ActionForm Bean 也是一种 JavaBean,除了
具有一些 JavaBean 的常规方法,还包含用于验证 HTML 表单数据以及将其属性重新设置
为默认值等方法。Struts 框架利用 ActionFrom Bean 来进行视图和控制器之间表单数据的传
递,Struts 框架把用户输入的表单数据保存在 ActionFrom Bean 中,把它传递给控制器,控
制器可以对 ActionFrom Bean 中的数据进行修改,JSP 文件使用 Struts 标签读取修改后的
ActionFrom Bean 的信息,重新设置 HTML 表单。
(3) 控制处理层:是 Struts 框架的核心组件,用于接收 HTTP 请求信息,根据配置文件
Struts-config.xml 的配置信息,把请求转发给适当的 Action 对象,主要由 Servlet 类和 Action
类 构 成 。 ActionServlet 类 是 Struts 框 架 中 的 核 心 组 件 。 ActionServlet 继 承 了
Javax.servlet.http.HttpServlet 类,它在 MVC 模型中扮演中央控制器的角色。ActionServlet
主要负责接受 HTTP 请求信息,根据配置文件 struts-config.xml 的配置信息,把请求转发
给适当的 Action 对象。如果该 Action 对象不存在,ActionServlet 会先创建这个 Action 对
象。Action 类负责调用模型的方法,更新模型的状态,并帮助控制应用程序的流程。
小型简单的应用中 Action 类本身就可以完成一些实际的业务逻辑。对于大型应用,
Action 充当用户请求和业务逻辑处理之间的适配器(Adaptor),其功能就是将请求与业务逻
辑分开,Action 根据用户请求调用相关的业务逻辑组件。业务逻辑由 Java Bean 或 EJB 来
完成,Action 类侧重于控制应用程序的流程,而不是实现应用程序的逻辑。通过将业务逻
辑放在单独的 Java 包或 EJB 中,可以提高应用程序的灵活性和可重用性。
(4) 业务逻辑层:负责业务逻辑的实现,主要包括一些 JavaBean。
(5) 数据持久层:负责存储数据库的数据以及对其进行检索、更新和删除。主要由数据
库中每个表对应的实体类,以及每个实体对应的 Hibernate 配置文件等组成。
(6) 数据库层:用于数据的存储和组织、数据库的分布式管理、数据库的备份和同步等。
本系统采用的数据库是 MySQL。
4. 系统技术实现
4.1 表示层的实现
- 3 -
http://www.paper.edu.cn
表示层提供用户界面,接受客户端发送来的请求,再将请求转发给业务层处理,并将处
理结果发回到客户端。因此通常由 JSP 文件组成,且仅限于数据采集和数据显示,以及提交
用户的请求,而不包括在视图上的业务流程的处理,业务流程的处理交给模型进行处理。本
系统使用 Struts 框架来实现表示层的开发。例如用户认证模块的用户表示层部分主要包括以
下一些 JSP 页面:主显示界面 index.jsp、系统登录页面 logon.jsp、管理员主页面 admin.jsp、
学生主页面 student.jsp、教师主页面 teacher.jsp 等。
4.2 控制层的实现
控制层是 Struts 框架的核心组件,主要由 Action 类和 ActionServlet 类还有配置文件组
成。配置文件 web.xml 是 web 应用程序通用的配置文件,主要完成 ActionServlet 的配置,
默认首页的设置等。还有个描述用户请求路径和 Action 映射关系的配置文件,就是
Struts-config.xml 文件,在该配置文件中,每一个 Action 的映射信息都通过一个
元素
来配置。这些配置信息在系统启动的时候被读入内存,供 Struts 在运行期间使用。该文件的
作用相当于一个项目开发过程中的控制调配中心。
配置文件 Struts-config.xml 除了配置 Action 映射关系外,还包括全局转发、配置
ActionMapping、配置 ActionForm Bean 和配置 JDBC 数据源。
4.3 业务逻辑层的实现
即 Struts 的模型部分,在这里主要是 ActionForm Bean 和 Java Bean,用于在视图组件和
控制组件之间传递 HTML 表单数据,通常每个 HTML 表单对应一个 ActionForm Bean,HTML
表单中的字段和 ActionForm Bean 中的属性一一对应,而且 ActionForm 的 validate()方法用
于对用户输入的数据进行合法性验证。
4.4 数据持久层的实现
首先设计系统的数据持久层即 DAO 层,它是 J2EE 应用的重要组件,向上提供通用的
数据库访问接口。引入 DAO 模式,实现业务逻辑和数据库访问的分离,使业务逻辑层无须
关注底层数据库访问的实现。DAO 模式也是 J2EE 设计模式中的一个核心模式。
4.4.1 DAO 层的实现
本系统中通过 DAO 层对 Hibernate 所提供的各种方法进行封装,使得在实现业务逻辑
时,可以更方便地进行对象的持久化操作。因此要为每个实体建立一个 DAO 操作类来完成
与相应实体对象相关的持久化操作。
因此系统实现的 DAO 层是先定义了一个公用的 DAO 接口并实现这个接口。针对每个
实体对象进行操作的 DAO 接口都在此 DAO 层的基础上实现。
本系统使用 Hibernate API 来实现公用的 DAO 接口,除了定义其构造方法外,还定义了
得到当前线程的 Session 对象的实例方法;得到持久化对象的方法;还有 DAO 接口的方法,
其实现类文件为 GenericHibernateDAO。
这里考虑到一个问题,若接口都通过其实体对象的具体子类实例化,则程序在调用时必
须知道具体的子类,这样会造成修改不方便。因此这里采用工厂设计模式,根据工厂模式实
现的类可以根据提供的数据生成一组类中某一个类的实例,通过这一组类有一个公共的抽象
父类并且实现了相同的方法,但是这些方法针对不同的数据进行了不同的操作。工厂模式的
- 4 -
http://www.paper.edu.cn
图 3 工厂设计模式
工作原理如图 3[3]所示。
然后定义 DAO 的工厂类,即产生 DAO 实例的工厂,主要依据不同的参数或配置信息
得到不同类型的 DAO 对象的实例,增加系统的灵活性。主要实现接口与具体实现的分离,
可使系统能够面向接口编程,而不是依赖于很多具体的类,系统首先实现一个公用的 DAO
工厂类 DAOFactory,通过调用该类的方法得到具体的 DAO 类的实例。
4.4.2 数据访问的实现
本系统采用 Hibernate 实现数据持久层,通过 Hibernate.cfg.xml 文件配置 Hibernate 的内
容包括数据库驱动程序类、登录数据库的用户名/密码、映射实体类配置文件的位置等。通
过对象和关系数据库映射来为应用程序提供持久化服务。通过 Hibernate 管理 Java 类到数据
库表的映射,还提供数据查询和获取数据的方法,可以大幅度减少开发时人工使用 SQL 和
JDBC 处理数据的时间。在该配置文件中主要 SessionFactory 类建立与数据库之间的连接配
置。Hibernate.cfg.xml 文件的主要配置如下,配置数据库的 URL 和驱动程序:
com.mysql.jdbc.Driver
jdbc:mysql://localhost:3306/exam?useUnicode=true&char
acterEncoding=utf8&autoReconnect=true&autoReconnectForPools=true
配置数据库的用户名和密码:
root
1234
Hibernate 对数据库的操作主要是对数据的增删改查,通过对数据库的这些基本操作加
以封装,可以进一步简化系统与数据库的交互,使开发人员更专注于业务逻辑的开发。具体
实现为:
为了方便 Hibernate 的初始化以及 Hibernate 的 Session 和事务的处理,在实现 Hibernate
事务控制类之前首先要建立一个 Hibernate 的基础工具类 HibernateUtil[4]:初始化 Hibernate、
得到 SessionFactory 对象的实例、释放各种资源、重建 SessionFactory。
系统通过一个 Servlet 过滤器来管理 Hibernate 的事务,通过这个过滤器来实现 Hibernate
事务的自动开始和提交(或者回滚)。定义过滤器并指定一系列的配置参数,配置过滤器的拦
截对象,如下:
hibernateFilter
cn.hxex.exam.filter.HibernateFilter
hibernateFilter
- 5 -
http://www.paper.edu.cn
/*
几乎所有用户的请求都要访问数据库,因此在 Filter 中,拦截所有的用户请求,用于在
系统开始处理用户请求之前开始一个新的事务,并在用户完成业务处理以及页面的输出显示
后关闭事务,然后建立基本操作的封装类。
这样系统中频繁的数据库操作在经过过滤器的管理和封装后变的非常简单,将开发者从
频繁的数据库访问操作中释放出来,极大提高了开发效率。
5. 系统关键技术实现
5.1 系统中集成 Hibernate
本系统中使用 Struts 作为整个系统的核心组件,所以在本应用中存在着两种方式来处理
Hibernate 事务。
一种是将 Hibernate 的事务控制在业务逻辑层之内,也即在进入业务逻辑时,开始一个
新的事务,在结束业务逻辑处理时,结束这个事务。当然在业务处理的过程中,也可能包含
数据库事务的提交、回滚和开始操作。采用 Hibernate 的事务控制在业务处理层之内的方法
就要求在返回到表示层之前必须得到所有表示层可能用到的业务数据。这可能会出现获取的
数据由于某种原因并不会被页面真正使用的情况,就造成了资源的浪费;另一处理方式是将
Hibernate 的事务扩展到处理用户请求的整个操作内。也就是当服务器开始响应用户请求时
自动开始一个事务,而在用户完成业务逻辑的处理并输出了整个响应页面后才会终止该事
务。过长的数据库事务可能会导致数据库资源被长时间占用,可能降低数据库的并发性能。
Hibernate 已很好解决了这个问题。因为 Hibernate 并非在一开始一个新的事务时,就在数据
库中开始一个事务,而是在必须要执行一个数据库操作时才开始执行一个新的数据库事务。
当 Java 程序执行到持久化操作语句时,Hibernate 并非立刻就在数据库中将该数据保存,
而是要到数据库事务结束或者必须要执行这个操作才能继续执行的时候才会进行相应的数
据库操作。采用这种方式,可以最大限度地保证只从数据库中取出需要的数据,这是因为在
显示页面的时候,Hibernate 的事务并没有结束,就不需要提前将可能用到的数据都从数据
库中取出,而是可依据实际的需要来取得相应的数据,节约数据库的资源。
本系统采用的是第二种处理方式控制 Hibernate 的事务,这样可以在很大程度上降低对
数据库资源占用的时间,减少一些不必要的数据库操作,提高数据库的并发性能。
5.2 实现 Hibernate 工具类
Hibernate 通过 getTransaction()方法可随时得到当前的事务信息并进行提交或回滚操作,
这样生成 Hibernate 工具类的方法就得以简化。
Hibernate 的工具类主要有以下功能:
1) Hibernate 的初始化操作:该功能不放在任何方法中,采用静态编码的处理方法,只
在对象初始化的时候被调用一次。
2) 得到当前的配置信息:该方法可得到当前的配置信息,以便于动态进行配置参数的
修改。
3) 得到 SessionFactory 对象的实例:用于得到当前系统运行时的 SessionFactory 对象的
实例,在整个系统中是全局唯一的。
4) 释放各种资源:用于终止 Hibernate 服务后,释放各种 Hibernate 所使用的资源。虽
- 6 -
http://www.paper.edu.cn
然这个方法几乎不会用到,但对于申请资源的及时释放是每个程序员应该掌握的基本原则。
5) 重建 SessionFactory:SessionFactory 对整个 Hibernate 应用是唯一的,并且是在
Hibernate 初始化之后就建立好的,而且对于配置文件的修改也不会影响到已经初始化的
SessionFactory 对象,重新构建 SessionFactory 对象的实例才能使修改的配置信息对 Hibernate
起作用。
6) 拦截器注册方法:用于注册拦截器并重建 SessionFactory。对于 Hibernate 的拦截器,
本系统中没使用到。
由于通过参数配置可以使用 Hibernate 所提供的内建的线程局部变量来保存当前进程的
Session 和 Transaction 对象的实例,因此就不需要进行任何处理了。
5.3 实现 Serlvet 过滤器
Servlet 的过滤器的工作原理是通过拦截所有的用户请求来实现 Hibernate 事务管理。拦
截到一个新的用户请求,则自动开启一个新的 Hibernate 事务,完成用户的请求后会自动提
交 Hibernate 的事务。
系统中实现 Servlet 事务管理的 Servlet 过滤器的文件为 HibernateFilter 类,doFilter 函数实
现 Hibernate 的事务开始和提交,关键代码如下:
……………….
public void doFilter(ServletRequest
chain)throws IOException, ServletException {
request,ServletResponse
response, FilterChain
try { …
SessionFactory sf = HibernateUtil.getSessionFactory( );
try {
log.debug("Starting a database transaction"); // 开始一个新的事务
sf.getCurrentSession( ).beginTransaction( );
log.debug( "Request Path:\t" + ((HttpServletRequest)
request).getServletPath( ) );
chain.doFilter(request, response);
sf.getCurrentSession().getTransaction().commit(); // 提交事务
}
catch (Throwable ex) { ……..
sf.getCurrentSession().getTransaction().rollback(); // 回滚事务
}
catch (Throwable rbEx) {
……… } } } // 抛出异常
public void init(FilterConfig filterConfig) throws ServletException { …}
public void destroy() {…… } //用于释放过滤器所申请的资源
}
Hibernate 的辅助工具类已实现,因此这里的拦截方法的实现流程的步骤为:
得到 SessionFactroy 对象的实例
开始一个新的事务
进行业务的处理
结束事务(提交和回滚)
实现了 Hibernate 用于事务管理的 Servlet 过滤器后,在 web.xml 文件中对这个过滤器进
- 7 -
http://www.paper.edu.cn
行上述相应的设置工作即可。
6. 结语
在线考试系统的最大特点是结合了表示层 Struts 框架和数据持久层 Hibernate 框架,采
用 B/S 多层体系结构,使应用数据的表示被限制在相应层内,降低了数据在各层之间的耦合
性,提高了整体架构的可维护性和可扩展性。
参考文献
[1] 孙卫琴. 精通 Struts:基于 MVC 的 Java Web 的设计与开发[M].北京:电子工业出 版社,2004.
[2] 陈天河. Hibernate 项目开发宝典[M].北京:电子工业出版社,2006.
[3] 阎宏. Java 与模式[M].北京:电子工业出版社,2002.
[4] Gavin King.Hibernate Reference 3[EB/OL] .http://www.hibernate. org/:2008
hib-docs/v3/reference/en/html/architecture .html# architecture-overview, 2005-01-01
Online-test system based on Struts and Hibernate
Duan Pengpeng, Guo Qingping
Computer Institute, Wuhan university of Technology, Wuhan (430063)
Abstract
Under J2EE B/S architecture,Online-test system based on MVC is designed using Struts as the
presentation layer framework and Hibernate as the data persistence layer framework.Besides good
practicability and high efficiency,the system is provided with the advantages of expansibility and
maintainability.This paper narrates the structure,function,mechanism of the system in detail.
Keywords: Struts framework, Persistence, Data Access Object,ORM, Online-test system
作者简介:
段朋鹏(1982-),女,河南洛阳人,硕士研究生,研究方向为分布式并行处理、计算机网络;
郭庆平,导师简介;教授,研究方向为分布式并行处理、网格技术和网络安全。
- 8 -