前言
Hi,同学们好呀,学长今天带大家复盘一个学长帮往届同学做的一个毕业作品
基于java web的网络考试系统的设计与实现
1 课题描述
科技在进步,人们生活和工作的方式正发生着改变,不仅体现在人们的衣食住行,也体现在与时俱进的考试形式上。以前的考试需要组织者投入大量的时间和精力,需要对考试的试题进行筛选,对后期的考卷进行批阅,这么多的步骤影响了整个考试执行的效率。因此,本文提出了一种网络考试系统,用于解决上述的一些问题。
学长设计的网络考试系统主要是利用浏览器作为界面,利用B/S模式,即用户可利用浏览器直接访问本站点。主要用到的技术是采用JavaWeb技术和MySql数据库等设计出了各种功能。该系统主要有用户管理、功能管理、角色权限管理、学生网络考试、试题管理、错题管理、自动组卷等功能。
本篇博客提供了一些该系统的部分代码跟截图帮助介绍该系统,对系统的总体设计、详细设计以及测试都给出了一些介绍,还对运行截图以及代码作出了相应的解释。该网络考试系统基本上可以满足一些简单的考试,运行良好,基本可以满足设计要求。
2 相关技术
- JAVA
- J2EE
- MySQL
- MyEclipse
- JavaScript
- JQuery
- CSS3
- JSP
- Tomcat服务器
3 系统需求分析
3.1 功能需求分析
网络考试系统主要用于实现高校在线考试,基本功能包括:自动组卷、试卷发布、试卷批阅、试卷成绩统计等。
学长设计的系统结构如下:
3.1.1 学生端:
- 登录模块:登录功能;
- 网络考试模块:可参加考试,并查看考试结果,提交试卷后老师允许的情况下查看错题;
3.1.2 超级管理员端:
- 登录模块:实现管理员登录功能;
- 用户管理模块:实现用户信息的增加、修改、查看功能;
- 角色权限管理模块:实现角色的增加、修改、查看功能;
- 试卷管理模块:实现试卷信息的增加、修改、查看功能;
- 试题管理模块:实现试题信息的增加、修改、查看功能;
3.1.3 试题管理员端(老师):
- 试卷管理模块:实现试卷信息的增加、修改、查看功能;
- 试题管理模块:实现试题信息的增加、修改、查看功能;
4 系统设计框架
这个系统所开发的网络考试系统主要分成了三个模块的主要功能,系统功能、考试功能和学生功能,每个功能都包含了几个子功能,子功能主要包括:对于系统功能方面的管理、角色的管理、用户方面的管理、对于试题管理、对于的试卷管理、学生答题、总结出错题库与得分。
系统的概要功能图如下图所示:
4.1 系统基本功能
系统功能的划分方式可以分成很多种类,前面是按照功能模块进行划分,将系统分成三个模块,本章节依据网络考试系统的系统角色不同,可以分成用户端和管理员端。用户端包括:登录功能、学生答题、答题得分以及考完试之后的错题解析。管理员端包括:登录功能、系统功能管理、用户管理、角色管理、题目管理、试卷管理。下面本节主要对各个基本的功能进行一个简介。(此处没有对试题管理员进行详细介绍,因为管理员的题目管理跟试卷管理的功能就是他的功能)
4.2 登录功能
登录功能是一个系统的重要组成部分,也是一个系统重要的门户功能,登录功能主要实现了使用者对系统的登录,在本文所设计的体系中,登录主要分成了两种身份:学生用户和管理员。两种身份登陆,能细分系统的功能模块,实现更加方便的操作和管理。
4.3 系统答题
系统答题模块是本系统的一个重要功能,可以实现让用户的答题操作。系统答题功能主要是学生用户登录以后操作的,学生用户在输入正确的用户名和密码以后能开始系统答题,系统答题的题目均来自数据库。
4.4 答题得分
答题得分功能实现了学生用户在答题结束以后对自己得分情况的查看,该功能就实现了登录系统的学生用户在完成自己的试卷以后,点击体提交就能看到自己的得分,因此该功能是一个展示性质的功辅助能。
4.5 错题解析
错题解析功能是系统答题功能的一个辅助或者说优化的功能,只有学生用户在登录系统完成答题以后在老师允许的情况下才能进行该功能的操作,学生答题可能存在一定的错误,对错误题目的查看成为考试系统的子功能。因此本文所设计的错题解析功能,能让学生迅速发现正确或者错误题目,以及解析过程。这样方便自学和改进。学生功能结构图,如下图所示:
4.6 系统功能管理
系统功能管理主要实现了对系统的其他功能进行管理,主要包括对新功能的添加和编辑,对现有功能的添加和修改,同时能对现有的功能进行子功能的编辑和修改,修改后的功能可以在系统中被查看。
4.7 用户管理
用户管理是一个系统的重要功能之一,对用户的管理可以实现对系统使用者的了解和查看,能让使用者更加方便的使用本系统,用户的种类分为多种,本文主要体现在学生用户和管理者两种用户上面,可以对用户的信息进行添加修改等。
4.8 角色管理
角色管理主要是针对用户来设计的,不同的用户拥有不同的权力。换句话说就是操作的权限是不同的。学生账号只能进行答题等行为,而不能进行后台的管理员操作。管理员账号也拥有不一样的权利。这些权力体现在对账号的操作,试卷和题目的管理上,因此对权限的管理能很好的控制系统用户的行为,有利于系统更加稳定的运行。
4.9 题目管理
题目管理主要是针对管理员的功能,该功能面向系统中试卷所使用的题目库,在本系统中,管理员能通过对题目的添加和修改对题目进行管理,可以查看现有的题目,同时也能对新的题目进行添加,为试卷的生成提供更多题目的选择。
4.10 试卷管理
试卷管理是本系统的核心功能,主要实现的是对学生用户考试答题的试卷进行管理,通过系统随机抽取的题目自动生成试卷并且能将试卷存入数据库,供学生考试时进行选择。管理员功能结构图,如下图所示:
5 系统代码设计
5.1 学生端
在这个系统中使用者主要是分为管理员和学生,我在这里先介绍学生用户系统的运行情况。以下是学生用户从登陆到错题解析的整个运行流程情况将在下面文进行展示。
5.1.1 学生用户登录
学生用户登陆,先到这个界面。 如下图所示:
在进入登录界面以后选择学生登录,再输入正确的用户名和正确的密码,就可以登录。如下图所示:
用户正确完成登录输入以后,系统会根据用户所输入的信息,通过功能代码实现与数据库中存储数据的对比,从而判别该登录用户是否合法,如果不合法将提示输入正确的登录信息,输入正确则登录系统,进入系统的主界面。
5.1.2 主界面
学生用户正确登录系统之后会跳转到学生用户端的界面,主界面如图所示:
学生用户的主界面主要包含了试卷列表和查看错题两个功能,试卷列表中罗列了所有考试的试卷,学生可以根据老师的要求选择对应的的试卷进行考试,考试结束以后还可以进行错题查看功能。
5.1.3 系统答题
学生用户登录系统以后选择试卷列表中的试卷进行考试答题,答题界面如图所示:
学生要在一定的时间内,完成试卷上的所有题目,然后进行提交,答题的进度和时间的限制可以系统会给出提示,运行界面如图所示:
5.1.4 答题得分
学生在规定的时间内完成答题,完成以后提交系统,提交系统,系统会根据题库对比得到考试成绩,成绩界面如图所示:
计时器(到时自动交卷)功能,交卷时判断试卷是否有未答题、计算得分等功能都在paper.jsp中用javascript来实现
// 交卷功能
判断是否有未答题目
function unAnswer(){
if(unanswer != 0){
layer.open({
title:'警告',
content: "还有"+unanswer+"道题目未做!",
icon:2,
end:function(){
postAnswer();
}
});
}else{
postAnswer();
}
}
计算得分
function getScore(){
//var spid = n
$.post({
url: basePath + 'user/studentPaper?cmd=score&userid='+'${userid}'+'&spid='+ now.getTime(),
contentType: false,
processData: false,
success: function(res) {
console.log(res)
layer.open({
title:'得分',
content: res,
icon:1,
end:function(){
location.href = basePath+'user/studentPaper?cmd=stupaper';
}
})
},
error: function(res) {
console.log('error');
}
})
}
倒计时功能
//小于10的数字前面补0
function p(n){
return n<10?'0'+n:n;
}
//获取当前时间
var now=new Date();
//获取结束时间
var endDate=new Date();
//设置考试时间(单位分钟)
endDate.setMinutes(now.getMinutes()+20)
function getTime(){
var startDate=new Date();
var countDown=(endDate.getTime()-startDate.getTime())/1000;
var h=parseInt(countDown/(60*60)%24);
var m=parseInt(countDown/60%60);
var s=parseInt(countDown%60);
$('.time').html(p(h)+'时'+p(m)+'分'+p(s)+'秒');
if(countDown<=0){
document.getElementById('time').innerHTML='考试结束';
layer.open({
title:'警告',
content: '考试时间到,试卷已经提交!',
icon:5,
end:function(){
unAnswer();
}
})
}else{
setTimeout('getTime()',500);
}
}
getTime()
学生得到成绩以后可以对自己的本次成绩进行查看,也能对自己的其他考试试卷的成绩进行查看,查看界面如图所示:
5.1.5 错题解析
学生用户能对自己的答题试卷中错误的题进行查看,并且能看到错题的解析,但是此功能只是一个辅助优化功能,必须是在交卷之后老师同意的情况下,才能查看。错题的解析界面如图所示
学生能根据数据库中给出的正常答案,对比自己的错误选项进行研究和学习,达到考试提升能力的效果。
5.2 管理员端
管理员端的功能主要为了更好的管理系统,让学生用户能顺利考试,因此管理员功能在实现的时候需要考虑的因素和功能会比较多,下面对管理员如何在这个系统中操作进行演示。试卷管理员(老师)的功能包括在其中。
5.2.1 管理员登录
管理员登录和学生用户登录使用的是同一个登录界面,区别在于登录时选取的身份是管理员身份,登录界面如图所示:
5.2.2 管理员主界面
管理员正确输入信息后会跳转到管理员的主界面,主界面如图所示
在管理员主界面上,我们可以看到管理员端主要分成了两个部分的功能,第一个是系统功能,第二个是试卷管理功能,下面将对这两个功能下的子功能进行逐一介绍。
5.2.3 系统功能管理
系统功能管理实现了所有的父功能和子功能之间的联系,能让管理员更方便得查看各个功能的实现情况。系统功能管理的界面如图所示:
功能之间存在着主次关系,可以通过新建实现新的功能,也可以通过编辑来实现功能间的联系,新建功能如图所示:
5.2.4 用户管理
实现用户的管理解决的是学生的使用系统有关的问题,用户管理界面如图所示:
用户管理可以对用户进行新增、修改和查询,用户新增界面如图所示:
5.2.5 角色管理
角色管理主要把各个角色之间的权限管理实现了,方便最高权限的人对其他管理员的管理。角色管理界面如图所示:
5.2.6 试卷管理
试卷的管理是学生考试的关键功能,试卷管理界面如图所示:
试卷的种类分为很多种,要想从试卷中找到相关的试卷可以启动搜索功能,搜索界面如图所示:
在DAO层,利用随机函数,(设置试卷题目和插入题目数量)实现自动组卷
public Integer addpaper(Paper paper) {
// TODO Auto-generated method stub
String sql = "INSERT INTO paper(pname,sid) SELECT ?,sid FROM " +
"subject where sstate = 1 ORDER BY rand() LIMIT ?";
Integer rtn =DBUnitHelper.executeUpdate(sql,paper.getPname(),paper.getScount());
5.3 数据库管理
数据管理对代码与数据库之间的连接和交互起作用,数据库交互实现的代码为
Connection conn = null;
try {
DbUtils.loadDriver("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/exam", "root", "zhs2668281");
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
完成数据库的连接,进行一些简单的数据库操作,包括增删改查等,主要代码为:
public static Integer executeUpdate(String sql,Object ...objects){
Connection conn = getConn();
QueryRunner qr = new QueryRunner();
Integer rtn = 0;
try {
if(objects == null){
rtn = qr.update(conn, sql);
}else{
rtn = qr.update(conn, sql, objects);
}
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
DbUtils.close(conn);
} catch (Exception e) {
e.printStackTrace();
}
}
return rtn;
}
public static Integer executeUpdate(String sql){
return executeUpdate(sql, null);
}
public static <T> List<T> executeQuery(String sql,Class<T> cls,Object ...objects){
Connection conn = getConn();
List<T> list = null;
try{
QueryRunner rq = new QueryRunner();
if(objects == null){
list = rq.query(conn, sql,new BeanListHandler<T>(cls));
}else{
list = rq.query(conn, sql,new BeanListHandler<T>(cls),objects);
}
}catch(Exception e){
e.printStackTrace();
}finally{
try {
DbUtils.close(conn);
} catch (SQLException e) {
e.printStackTrace();
}
}
return list;
}
其中分页查找的代码为:
/**
* 带分页的查询
* @param sql SQL语句
* @param map SQL参数
* @param pc 分页控制对象,需要传递参数:当前第几页(currentindex),每页显示多少行:(pagesize)
* 分页控件显示多少也:showpcount
* @return
*/
public static <T> Pager<T> execlist(String sql,PageControl pc,Class cls,String pk,Object...object){
//获取总记录数sql
String sqlcount = "select count(*) as count from ("+sql+") a";
//获取具体数据的SQL语句
Integer min = (pc.getCurrentindex()-1)*pc.getPagesize();
Integer max = pc.getPagesize();
String sqllist = "select * from ("+sql+") a where a."+pk+" limit "+min+","+max;
Connection conn = getConn();
Pager<T> pager = new Pager<T>();
try {
QueryRunner rq = new QueryRunner();
Object count = rq.query(conn, sqlcount, new ScalarHandler<Object>("count"), object);
List<T> list = executeQuery(sqllist,cls,object);
//设置总记录数
Integer c = 0;
if(count!=null){
c=Integer.parseInt(count.toString());
}
pc.setRscount(c);
pager.setList(list);
pc = dealpage(pc);
pager.setPagectrl(pc);
DbUtils.close(conn);
} catch (Exception e) {
e.printStackTrace();
}
return pager;
}