基于Struts和Hibernate的在线考试系统
段朋鹏,郭庆平
武汉理工大学计算机学院,湖北武汉(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架构。部署描述符l用于装载和配置各种Struts组件,仅需修改它即可方便变换Controller类,从而变换程序行为,或重新指向
不同显示页面的View。
对于所有来自Web浏览器的请求,控制器部分的ActionServlet会依照配置文件l的内容正确地指派action处理,其控制置于Action类的execute()方法中。Action类可按l内的forward标记内容,将最后的运算结果交由某个JSP页面显示。在显示用户界面的View部分时,Struts提供了5种自定义的Tag Libraries供JSP使用,这些Tag Libraries能够按照收到的信息自动转为HTML,或提供条件判断等显示逻辑流程控制。Struts框架中,MVC三部分可能跨越网络位于不同硬件环境中。
为解决相互传递、交换信息的问题,采用了Data Transfer Object模式。Struts运用继承于ActionForm的JavaBean(即FormBean)来存储使用者在Web浏览器中所输入的信息,由于
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系统分层架构图
(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请求信息,根据配置文件l的配置信息,把请求转发给适当的Action对象,主要由Servlet类和Action 类构成。ActionServlet 类是 Struts 框架中的核心组件。ActionServlet 继承了Javax.servlet.http.HttpServlet 类,它在 MVC 模型中扮演中央控制器的角。ActionServlet 主要负责接受 HTTP 请求信息,根据配置文件 l 的配置信息,把请求转发给适当的 Action对象。如果该 Action对象不存在,ActionServlet 会先创建这个 Action 对象。Action 类负责调用模型的方法,更新模型的状态,并帮助控制应用程序的流程。
小型简单的应用中Action 类本身就可以完成一些实际的业务逻辑。对于大型应用,Action 充当用户请求和业务逻辑处理之间的适配器(Adaptor),其功能就是将请求与业务逻辑分开,Action 根据用户请求调用相关的业务逻辑组件。业务逻辑由 Java Bean 或 EJB 来完成,Action 类侧重于控制应用程序的流程,而不是实现应用程序的逻辑。通过将业务逻辑放在单独的 Java 包或 EJB 中,可以提高应用
程序的灵活性和可重用性。
(4) 业务逻辑层:负责业务逻辑的实现,主要包括一些JavaBean。
(5) 数据持久层:负责存储数据库的数据以及对其进行检索、更新和删除。主要由数据库中每个表对应的实体类,以及每个实体对应的Hibernate配置文件等组成。
(6) 数据库层:用于数据的存储和组织、数据库的分布式管理、数据库的备份和同步等。本系统采用的数据库是MySQL。
4.系统技术实现
4.1 表示层的实现
表示层提供用户界面,接受客户端发送来的请求,再将请求转发给业务层处理,并将处理结果发回到客户端。因此通常由JSP文件组成,且仅限于数据采集和数据显示,以及提交用户的请求,而不包括在视图上的业务流程的处理,业务流程的处理交给模型进行处理。本系统使用Struts框架来实现表示层的开发。例如用户认证模块的用户表示层部分主要包括以下一些JSP页面:主显示界面index.jsp、系统登录页面logon.jsp、管理员主页面admin.jsp、学生主页面student.jsp、教师主页面teacher.jsp等。jsp帮助文档
4.2 控制层的实现
控制层是Struts框架的核心组件,主要由Action类和ActionServlet类还有配置文件组成。配置文件l是web应用程序通用的配置文件,主要完成ActionServlet的配置,默认首页的设置等。还有个描述用户请求路径和Action映射关系的配置文件,就是l文件,在该配置文件中,每一个Action的映射信息都通过一个<action>元素来配置。这些配置信息在系统启动的时候被读入内存,供Struts在运行期间使用。该文件的作用相当于一个项目开发过程中的控制调配中心。
配置文件l除了配置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。
这里考虑到一个问题,若接口都通过其实体对象的具体子类实例化,则程序在调用时必须知道具体的子类,这样会造成修改不方便。因此这里采用工厂设计模式,根据工厂模式实现的类可以根据提供的数据生成一组类中某一个类的实例,通过这一组类有一个公共的抽象父类并且实现了相同的方法,但是这些方法针对不同的数据进行了不同的操作。工厂模式的
工作原理如图3[3]所示。
图3 工厂设计模式
然后定义DAO的工厂类,即产生DAO实例的工厂,主要依据不同的参数或配置信息得到不同类型的DAO对象的实例,增加系统的灵活性。主要实现接口与具体实现的分离,可使系统能够面向接口编程,而不是依赖于很多具体的类,系统首先实现一个公用的DAO 工厂类DAOFactory,通过调用该类的方法得到具体的DAO类的实例。
4.4.2 数据访问的实现
本系统采用Hibernate实现数据持久层,通过l文件配置Hibernate的内容包括数据库驱动程序类、登录数据库的用户名/密码、映射实体类配置文件的位置等。通过对象和关系数据库映射来为应用程序提供持久化服务。通过Hibernate管理Java类到数据库表的映射,还提供数据查询和获取数据的方法,可以大幅度减少开发时人工使用SQL和JDBC处理数据的时间。在该配置文件中主要Sessio
nFactory类建立与数据库之间的连接配置。l文件的主要配置如下,配置数据库的URL和驱动程序:
<property name="tion.driver_class"&sql.jdbc.Driver</property>
<property
name="tion.url">jdbc:mysql://localhost:3306/exam?useUnicode=true&char acterEncoding=utf8&autoReconnect=true&autoReconnectForPools=true</property>
配置数据库的用户名和密码:
<property name="tion.username">root</property>
<property name="tion.password">1234</property>
Hibernate对数据库的操作主要是对数据的增删改查,通过对数据库的这些基本操作加以封装,可以进一步简化系统与数据库的交互,使开发人员更专注于业务逻辑的开发。具体实现为:
为了方便Hibernate的初始化以及Hibernate的Session和事务的处理,在实现Hibernate 事务控制类之
前首先要建立一个Hibernate的基础工具类HibernateUtil[4]:初始化Hibernate、得到SessionFactory对象的实例、释放各种资源、重建SessionFactory。
系统通过一个Servlet过滤器来管理Hibernate的事务,通过这个过滤器来实现Hibernate 事务的自动开始和提交(或者回滚)。定义过滤器并指定一系列的配置参数,配置过滤器的拦截对象,如下:
<filter>
<filter-name>hibernateFilter</filter-name>
<filter-class>
am.filter.HibernateFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>hibernateFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
几乎所有用户的请求都要访问数据库,因此在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所使用的资源。虽

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。