基于Jsp+Servlet的在线考试系统

项目类型:JAVA WEB项目
项目名称:在线考试系统
用户类型:双角色(老师+学生)
难度:3
系统类型:后台系统
设计模式:Jsp+Servlet
开发工具:Eclipse 
数据库:Mysql+Navicat
数据库表:5张
jsp页面:18个页面
适用:软件工程、计算机科学与技术等JAVA课程的学习和实验,可以参考文中的部分代码,实现自己所需要的功能。

功能特点
1.学生和老师登录,无注册(只能老师录入)
2.学生管理:添加、修改、删除、查询考生
3.题目管理:添加、修改、删除、查询题目,设置题目的分值,答案
4.考试设置:单选题、多选题、判断题、填空题、简答题
5.试卷设置:设置试卷的题型
6.学生考试:学生考试功能,和显示里的一样
7.学生信息管理:学生自己登录后可以修改密码

项目截图

1.学生在线考试

2.学生个人信息 

3.教师登录

4.后台管理 

5.录入考试学生

 6.生成试卷

7.项目结构

 

 8.对于考题数量和考试时间的处理,Servlet类。获取前端Jsp页面输入的数据信息,并执行update语句,执行后将数据信息存储。

/**
 * @author 
 *	该类负责修改考题数量和考试时间
 */
@WebServlet("/PaperQuantity")
public class PaperQuantityServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doPost(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8"); // 编码处理
		response.setCharacterEncoding("UTF-8");
		response.setContentType("text/html;charset=UTF-8");
		int id=Integer.valueOf(request.getParameter("id"));
		int time=Integer.valueOf(request.getParameter("time"));
		int qty_sing=Integer.valueOf(request.getParameter("qty_sing"));
		int qty_muti=Integer.valueOf(request.getParameter("qty_muti"));
		int qty_jud=Integer.valueOf(request.getParameter("qty_jud"));
		int qty_fill=Integer.valueOf(request.getParameter("qty_fill"));
		int qty_ess=Integer.valueOf(request.getParameter("qty_ess"));
		
		int quantity=qty_sing+qty_muti+qty_jud+qty_fill+qty_ess;

		try {

			DatabassAccessObject db = new DatabassAccessObject();

			db.modify("UPDATE paper SET time=?,  qty_sing = ? , qty_muti = ? , qty_jud = ? , qty_fill=?, qty_ess=? , quantity = ? WHERE id = ? ;", time,
				qty_sing, qty_muti, qty_jud,qty_fill,qty_ess,quantity,id);
			PrintWriter out = response.getWriter();
			out.println("<script language=javascript>alert('已成功修改');window.location='" + request.getContextPath()
					+ "/teacher/teacher_paper_manage.jsp '</script>");

		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

}

 9.通过外部EXCEL表格,将考题导入。

 * 该类是自动抽提组卷类,实现功能:
 * 1.每种题型随机抽取指定条数,例:选择题抽5条;
 * 2.被抽中的题目信息传入QuestionBean储存;
 * 3.把Bean存入动态数组ArrayList组成试卷数组;
 * 4.把试卷数组存入Session对象,供考生作答。
 */

/**
 * @author 
 * 该类是自动抽提组卷类,实现功能:
 * 1.每种题型随机抽取指定条数,例:选择题抽5条;
 * 2.被抽中的题目信息传入QuestionBean储存;
 * 3.把Bean存入动态数组ArrayList组成试卷数组;
 * 4.把试卷数组存入Session对象,供考生作答。
 */
@WebServlet("/HandlePaper")
public class QuestionExtractServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	int tihao = 0;
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doPost(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		ArrayList<QuestionBean> listALL = new ArrayList<QuestionBean>();
		
		//抽题数量
		//单选题抽5道,多选题抽4道,判断题抽5道,填空题抽5道,简答题抽3道
		int num1=5,num2=4,num3=5,num4=5,num5=3;
		int examTime=30;
		try {
			DatabassAccessObject db = new DatabassAccessObject();
			ResultSet rs=db.query("select * from paper");
			num1=Integer.valueOf(rs.getString("qty_sing"));
			num2=Integer.valueOf(rs.getString("qty_muti"));
			num3=Integer.valueOf(rs.getString("qty_jud"));
			num4=Integer.valueOf(rs.getString("qty_fill"));
			num5=Integer.valueOf(rs.getString("qty_ess"));
			examTime=Integer.valueOf(rs.getString("time"));
		} catch (Exception e) {
			
		}
		
		try {
			DatabassAccessObject db = new DatabassAccessObject();
			ResultSet rs = db.query("SELECT * FROM question");
			//区分每种题型,将所有相同题型的行号存入双向循环链表,用于随机取题目
			LinkedList<Integer> list1 = new LinkedList<Integer>();
			LinkedList<Integer> list2 = new LinkedList<Integer>();
			LinkedList<Integer> list3 = new LinkedList<Integer>();
			LinkedList<Integer> list4 = new LinkedList<Integer>();
			LinkedList<Integer> list5 = new LinkedList<Integer>();
			while (rs.next()) {	//遍历整个题库表
				switch (rs.getString(2)) {	//多分支语句区分题型
				case "单选题":
					list1.add(rs.getRow());//获取所有选择题的行号
					break;
				case "多选题":
					list2.add(rs.getRow());
					break;
				case "判断题":
					list3.add(rs.getRow());
					break;
				case "填空题":
					list4.add(rs.getRow());
					break;
				case "简答题":
					list5.add(rs.getRow());
					break;
				default:
					break;
				}
			}

					
			listALL.addAll(randomQue(list1, rs,num1));	
			listALL.addAll(randomQue(list2, rs,num2));	
			listALL.addAll(randomQue(list3, rs,num3));	
			listALL.addAll(randomQue(list4, rs,num4));	
			listALL.addAll(randomQue(list5, rs,num5));	

			tihao=0;	//题号从0开始
			HttpSession session = request.getSession();
			session.setAttribute("examTime", examTime);
			session.setAttribute("ques", listALL);	//把试卷数组保存到Session对象
			//重定向到试卷页面,供考生作答
			response.sendRedirect(request.getContextPath()+"/student/student_exam_paper.jsp");

		} catch (Exception e) {
			e.printStackTrace();
		}

	}
	

 * 负责每种题型、指定数量的随机抽题
     * @param list    题目链表(存储了一类题型的行号)
     * @param rs    数据表结果集
     * @param count 抽取指定的题目数量
     * @return    返回一个(存储了count条指定类型的题目)数组

/**
	 * 负责每种题型、指定数量的随机抽题
	 * @param list	题目链表(存储了一类题型的行号)
	 * @param rs	数据表结果集
	 * @param count 抽取指定的题目数量
	 * @return		返回一个(存储了count条指定类型的题目)数组
	 */
	public ArrayList<QuestionBean> randomQue(LinkedList<Integer> list,ResultSet rs,int count) {
		int m = -1;
		int index = -1;
		ArrayList<QuestionBean> listA = new ArrayList<QuestionBean>();
		while (list.size() > 0&&count>0) {
			count--;
			m = (int) (Math.random() * list.size());
			index = list.get(m);
			System.out.println(index);
			list.remove(m);
			tihao++;
			try {
				rs.absolute(index);
				QuestionBean queBean = new QuestionBean();
				queBean.setQ_id(String.valueOf(tihao));
				queBean.setQ_type(rs.getString(2));
				queBean.setQ_title(rs.getString(3));
				String selectString = rs.getString(4);
				System.out.println(rs.getString(2));
				queBean.setQ_score(rs.getString(5));
				queBean.setQ_key(rs.getString(6));
				queBean.setQ_img(rs.getString(7));
				if (selectString != null) {
					queBean.setQ_select(selectString);
					String[] temp = selectString.split("\\@");
					queBean.setOptions(temp);
				}
				listA.add(queBean);
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return listA;
	}
}

 10.对已有题目进行增删改查

/**
 * @author 
 * 负责处理题库表中题目的增删改查
 */
@WebServlet("/HandleQue")
@MultipartConfig //支持文件上传
public class QuestionModifyServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doPost(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8"); // 编码处理
		response.setCharacterEncoding("UTF-8");
		response.setContentType("text/html;charset=UTF-8");
		
		String executeMode = request.getParameter("executeMode");
		int mode = Integer.parseInt(executeMode); // 转化整形
		System.out.println(mode);
		
		String number=request.getParameter("number");
		String type="";
		String title="";
		String score="";
		String key="";
		String select = "";
		String fileName ="";
		if (mode!=2) {	//如果不用执行删除,就执行
			type=request.getParameter("type");
			title=request.getParameter("title");
			score=request.getParameter("score");
			key=request.getParameter("key");
			if (type.equals("单选题")||type.equals("多选题")) {
				String[] temp=request.getParameterValues("select");
				for (int i = 0; i < temp.length; i++) {
					select+=temp[i];
					if (i!=temp.length-1) {
						select+="@";
					}
				}
			}else {
				select=request.getParameter("select");
			}
			System.out.print(select);
			Part part = request.getPart("img"); //题目配图
			fileName = part.getSubmittedFileName(); // 获取part对象所携带的文件名称
			if (fileName.length() > 0) { //如果用户上传了题目配图
				String savePath = getServletContext().getRealPath("/images");
				part.write(savePath + "/" + fileName);//上传图片到发布目录下

				try {//try能保证文件流被正确关闭
					//图片的原始路径(tomcat的发布目录下)
					Path sorcePath = Paths.get(savePath + "/" + fileName); 
					//图片的目标路径(当前项目目录)
					Path targetPath = Paths.get("E:\\WorkSpace_All\\cli_workspace\\"+
							request.getContextPath()+"/WebRoot/images/" + fileName);
					//复制文件并替换已存在的文件
					Files.copy(sorcePath, targetPath, StandardCopyOption.REPLACE_EXISTING);
				} catch (Exception e) {}
				
			}
		}

		try {
			DatabassAccessObject db = new DatabassAccessObject();
			switch (mode) {
			case 0://增
				db.insert("insert into question values (?,?,?,?,?,?,?) ; ",number,type,title,select,score,key,fileName);
				break;
			case 1://改
				if (fileName!="") {
				db.modify("update question set type = ? , title  = ? , `select` = ? , score = ? , `key` = ? , img = ? where number = ? ;",type,title,select,score,key,fileName,number);
				}else {
					db.modify("update question set type = ? , title  = ? , `select` = ? , score = ? , `key` = ?  where number = ? ;",type,title,select,score,key,number);
				}
				break;
			case 2://删
				db.modify("delete from question where number = ? ; ", number);
				break;
			default:
				break;
			}		
		} catch (Exception e) {
		}
		
		if (mode==0) {
			PrintWriter out = response.getWriter();
			out.println ("<script language=javascript>window.location='"+request.getContextPath()+"/teacher/teacher_que_add.jsp';alert('已成功添加题目');</script>");
		}else
		response.sendRedirect("ShowQuePage");

	}

}

 11.对题目信息通过列表来分页查询

/**
 * @author  * 分页显示题库表的题目信息
 * 默认每页10条
 */
@WebServlet("/ShowQuePage")
public class QuestionShowByPageServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void service(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// 如果没有参数传递过来,初定每页显示10条记录,显示第一页。
		// 然后把这两个参数压到request容器传到前台页面。request容器是前台页面收到即销毁的容器。
		int cpage = 0;
		int per = 10;
		if (request.getParameter("cpage") != null) {
			cpage = Integer.parseInt(request.getParameter("cpage"));
		}
		request.setAttribute("cpage", cpage);
		if (request.getParameter("per") != null) {
			per = Integer.parseInt(request.getParameter("per"));
		}
		request.setAttribute("per", per);
		// 之后进行数据库的查询
		try {
			// 先数据库的查询结果有多少条记录
			DatabassAccessObject db = new DatabassAccessObject();
			ResultSet rsTotal = db.query("select count(*) as total from question");
			if (rsTotal.next()) {
				// 求出总页数压到request容器传递给前台页面。
				request.setAttribute("totalPage", 1 + (rsTotal.getInt("total") - 1) / per);
			}
			// 新建一个动态数组用来存放查询结果
			ArrayList<QuestionBean> queBeanAllList = new ArrayList<QuestionBean>();
			
			ResultSet rs=null;
			String q_title=request.getParameter("q_title");
			String q_type="";
			q_type=request.getParameter("q_type");
			if (q_title!=null) {
				rs=db.query("select * from question where title LIKE '%"+q_title+"%' ;");
			}else if(q_type!=null&&q_type.length()>0){
				
				rs=db.query("select * from question where type='"+q_type+"' ;");
			}
			else {
				rs = db.query("select\r\n" + 
						"    *\r\n" + 
						"from\r\n" + 
						"    question\r\n" + 
						"order by\r\n" + 
						"    case \r\n" + 
						"      when type='单选题' then 1\r\n" + 
						"      when type='多选题' then 2\r\n" + 
						"			when type='判断题' then 3\r\n" + 
						"			when type='填空题' then 4\r\n" + 
						"			when type='简答题' then 5\r\n" + 
						"    end");
			}
			// 所有查询结果存入数组
			int total = 0;
			while (rs.next()) {
				QuestionBean queBean = new QuestionBean();
				queBean.setQ_id(rs.getString("number"));
				queBean.setQ_type(rs.getString("type"));
				queBean.setQ_title(rs.getString("title"));
				String selectString = rs.getString("select");
				if (selectString != null) {
					queBean.setQ_select(selectString);
					String[] temp = selectString.split("\\@");
					queBean.setOptions(temp);
				}
				queBean.setQ_score(rs.getString("score"));
				queBean.setQ_key(rs.getString("key"));
				queBean.setQ_img(rs.getString("img"));
				queBeanAllList.add(queBean);
				total++;
			}
			ArrayList<QuestionBean> queTableList = new ArrayList<QuestionBean>();
			for (int i = cpage * per; i < cpage * per + per && i < total; i++) {
				queTableList.add(queBeanAllList.get(i));
			}
			String temp=request.getParameter("modify_id");
			request.setAttribute("modify_id", temp);
			request.setAttribute("total", total);
			request.setAttribute("queTableList", queTableList);
			request.getRequestDispatcher("/teacher/teacher_que_manage.jsp").forward(request, response);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

 12.考试情况的处理
/**
 * @author 
 * 该类负责统计考生作答的分数;
 * 每种题型分别记分,成绩存入数据库。
 */

/**
 * @author 
 * 该类负责统计考生作答的分数;
 * 每种题型分别记分,成绩存入数据库。
 */
@WebServlet("/CalScoreServlet")
public class ScoreCalServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doPost(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setCharacterEncoding("UTF-8");
		request.setCharacterEncoding("UTF-8");

		HttpSession session = request.getSession(true);

		if (session == null) {
			response.sendRedirect("login.jsp");
		}
		//获取先前存储到Session对象中的试卷题目
		@SuppressWarnings("unchecked")
		ArrayList<QuestionBean> ques = (ArrayList<QuestionBean>) session.getAttribute("ques");
		String stuAnsArr[] = null;
		//每种题型分值,初值均为0
		float score = 0;
		float score_muti = 0;
		float score_sing = 0;
		float score_jud = 0;
		float score_fill = 0;
		float score_ess = 0;
		for (int i = 0; i < ques.size(); ++i) {
			QuestionBean que = ques.get(i);
			stuAnsArr = request.getParameterValues(que.getQ_id());//获取每道题的答案
			//如果是多选题,存在多个选项值,因此需要getParameterValues方法获取多个值

			if (!que.getQ_type().equals("简答题")) {//非简答题的记分方式相同,简答题独立计算
				if (stuAnsArr != null) {
					String stuAns = ""; //每道题的答案
					for (int j = 0; j < stuAnsArr.length; j++) {//多选题拥有多个答案
						stuAns += stuAnsArr[j];//组装学生答案
					}
					System.out.println(stuAns);
					if (stuAns.equalsIgnoreCase(que.getQ_key())) {	//匹配学生答案和正确答案
						switch (que.getQ_type()) { //每道题分别记分
						case "单选题":
							score_sing += Float.parseFloat(que.getQ_score());
							break;
						case "多选题":
							score_muti += Float.parseFloat(que.getQ_score());
							break;
						case "判断题":
							score_jud += Float.parseFloat(que.getQ_score());
							break;
						case "填空题":
							score_fill += Float.parseFloat(que.getQ_score());
							break;
						default:
							break;
						}
					}
				}
			} else { //简答题的判断方法
				String[] KEY_WORD = que.getQ_key().split("\\@");	//拆分正确答案中的关键词
				Float totalScore = Float.parseFloat(que.getQ_score());	//获取简答题分值
				Float singleScore = 0.0f;	//每个的分点的细分
				String stuAns = "";
				if (stuAnsArr != null) {
					for (int j = 0; j < stuAnsArr.length; j++) {
						stuAns += stuAnsArr[j];	//组装学生答案
					}
				}
				// 使用contains方法
				if (KEY_WORD != null) {	//如果关键词存在
					singleScore = totalScore / KEY_WORD.length; //按照关键词数量细分分值
					for (int j = 0; j < KEY_WORD.length; j++) {
						if (stuAns.contains(KEY_WORD[j])) { //判断考生答案中是否出现关键词
							System.out.println(stuAns + "包含关键词:" + KEY_WORD[j]);
							score_ess += singleScore;
						} else {
							System.out.println("不包含关键词:" + KEY_WORD[j]);
						}
					}
				}

			}
		}
		
		score = score_sing + score_muti + score_jud + score_fill + score_ess;
		String grade = "";
		int f = Math.round(score);
		int g = ((f < 0) == true ? 1 : 0) + ((f < 60) == true ? 1 : 0) + ((f < 75) == true ? 1 : 0)
				+ ((f < 85) == true ? 1 : 0) + ((f < 95) == true ? 1 : 0);
		switch (g) {
		case 0:
			grade = "优秀";
			break;
		case 1:
			grade = "良好";
			break;
		case 2:
			grade = "中等";
			break;
		case 3:
			grade = "及格";
			break;
		case 4:
			grade = "不及格";
			break;
		case 5:
			grade = "缺考";
			break;
		default:
			break;
		}
		
		try {
			//实例化数据库连接对象,把上面计算到的分值分别存入数据库中
			DatabassAccessObject db = new DatabassAccessObject();
			LoginBean loginBean = (LoginBean) session.getAttribute("loginBean");
			String ID = loginBean.getID();
			db.insert("update student set score = ? where ID = ? ", score, ID);
			
			ResultSet rs = db.query("select * from score where id = ?", ID);
			if (!rs.next()) {
				db.insert("insert into score values(?,?,?,?,?,?,?,?)", ID, score, score_sing, score_muti, score_jud,
						score_fill, score_ess,grade);
			} else {
				db.modify(
						"update score set score = ? , score_sing = ? , score_muti= ? , score_jud = ? , score_fill = ? , score_ess = ?,grade = ? where ID = ?  ;",
						score, score_sing, score_muti, score_jud, score_fill, score_ess,grade, ID);
			}
			rs = db.query("select * from student where id = ?", ID);
			rs.first();
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println(score);
		response.setContentType("text/html;charset=utf-8");
		
		//如果考生交了白卷,且作答时间有剩余5分钟以上,则建议考生继续作答,重定向回试卷页面;
		//否则,视为交卷成功,重定向回学生信息页。
		PrintWriter out = response.getWriter();
		long curTime = System.currentTimeMillis() / 1000;
		long endTime = (long) session.getAttribute("endTime");
		if (score == 0 && endTime - curTime >= 300) {
			out.println("<script language=javascript>if(confirm('时间尚有剩余,请认真作答')){window.location='" + request.getContextPath()
					+ "/student/student_exam_paper.jsp';}</script>");
			out.println("<script language=javascript>window.location='" + request.getContextPath()
					+ "/student/student.jsp';alert('试卷已经提交,可以查阅成绩单');</script>");
			LoginBean loginBean = (LoginBean) session.getAttribute("loginBean");
			loginBean.setScore(score);

		} else {
			LoginBean loginBean = (LoginBean) session.getAttribute("loginBean");
			loginBean.setScore(score);
			session.removeAttribute("examTime");
			session.removeAttribute("endTime");
			out.println("<script language=javascript>window.location='" + request.getContextPath()
					+ "/student/student.jsp';alert('试卷已经提交,可以查阅成绩单');</script>");
		}
	}
}

 13.分页查询考生的成绩

@WebServlet("/ShowScorePage")
public class ScoreShowByPage extends HttpServlet {
	private static final long serialVersionUID = 1L;
	
	protected void service(HttpServletRequest request,
			HttpServletResponse response) throws ServletException {
		// 如果没有参数传递过来,初定每页显示10条记录,显示第一页。
		// 然后把这两个参数压到request容器传到前台页面。request容器是前台页面收到即销毁的容器。
		int cpage = 0;
		int per = 10;
		if (request.getParameter("cpage") != null) {
			cpage = Integer.parseInt(request.getParameter("cpage"));
		}
		request.setAttribute("cpage", cpage);
		if (request.getParameter("per") != null) {
			per = Integer.parseInt(request.getParameter("per"));
		}
		request.setAttribute("per", per);
		
		try {
			// 数据库的查询结果有多少条记录
			DatabassAccessObject db=new DatabassAccessObject();
			ResultSet rsTotal = db
					.query("select count(*) as total from student");
			if (rsTotal.next()) {
				// 求出总页数压到request容器传递给前台页面。
				request.setAttribute("totalPage", 1
						+ (rsTotal.getInt("total") - 1) / per);
			}
			// 新建一个动态数组用来存放查询结果
			ArrayList<StudentInfoBean> stuBeanAllList = new ArrayList<StudentInfoBean>();
			ResultSet rs=null;
			String s_ID=request.getParameter("s_ID");
			if (s_ID!=null) {
				rs=db.query("select score.ID,class,name,score_sing,score_muti,score_jud,score_fill,score_ess,score.score,grade from student join score on student.id=score.id where score.id LIKE '%"+s_ID+"%' ;");
			}else {
				rs = db.query("select score.ID,class,name,score_sing,score_muti,score_jud,score_fill,score_ess,score.score,grade from student join score on student.id=score.id order by ID ;");
			}
			

			int total = 0;
			while (rs.next()) {
				String ID=rs.getString(1);
				String CLASS=rs.getString(2);
				String name=rs.getString(3);
				Float score_sing=Float.valueOf(rs.getString(4));
				Float score_muti=Float.valueOf(rs.getString(5));
				Float score_jud=Float.valueOf(rs.getString(6));
				Float score_fill=Float.valueOf(rs.getString(7));
				Float score_ess=Float.valueOf(rs.getString(8));
				Float score=Float.valueOf(rs.getString(9));
				String grade=rs.getString(10);
				stuBeanAllList.add(new StudentInfoBean(ID, CLASS, name, score_sing, score_muti, score_jud, score_fill, score_ess, score,grade));
				total++;
			}
			// 再通过根据cpage与per求出要推回给前台显示的数组
			ArrayList<StudentInfoBean> stuTableList = new ArrayList<StudentInfoBean>();
			for (int i = cpage * per; i < cpage * per + per && i < total; i++) {
				stuTableList.add(stuBeanAllList.get(i));
			}
			String temp=request.getParameter("modify_id");
			System.out.println(temp);
			request.setAttribute("modify_id", temp);
			request.setAttribute("total", total);
			request.setAttribute("stuTableList", stuTableList);
			request.getRequestDispatcher("/teacher/teacher_score_manage.jsp").forward(request,
					response);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

 14.数据库连接配置

 *该类是数据库连接对象,实现功能:
 *连接数据库,增加、删除、修改、查询数据。

/**
 * 
 *该类是数据库连接对象,实现功能:
 *连接数据库,增加、删除、修改、查询数据。
 */
public class DatabassAccessObject {
	private Connection con;
 
	/**
	 * 构造函数,连接数据库
	 * @throws Exception
	 */
	public DatabassAccessObject() throws Exception {
		String dburl = "jdbc:mysql://localhost:3306/jsp_examonline?serverTimezone=UTC&characterEncoding=utf8&useSSL=false";
		String dbusername = "root";
		String dbpassword = "123456";
		Class.forName("com.mysql.jdbc.Driver");
		this.con = DriverManager.getConnection(dburl, dbusername, dbpassword);
	}
 
	/**
	 * 数据库查询
	 * @param sql  任意的SQL查询语句
	 * @param args 任意个用于替换占位符的形参
	 * @return		返回RestultSet类型的结果集
	 * @throws Exception
	 */
	public ResultSet query(String sql, Object... args) throws Exception {
		PreparedStatement ps = con.prepareStatement(sql);
		for (int i = 0; i < args.length; i++) {
			ps.setObject(i + 1, args[i]);
		}
		return ps.executeQuery();
	}
 
	/**
	 * 向数据库插入一条数据
	 * @param sql	任意的SQL插入语句
	 * @param args	任意个用于替换占位符的形参
	 * @return		返回值是布尔类型
	 * @throws Exception
	 */
	public boolean insert(String sql, Object... args) throws Exception {
		PreparedStatement ps = con.prepareStatement(sql);
		for (int i = 0; i < args.length; i++) {
			ps.setObject(i + 1, args[i]);
		}
		if (ps.executeUpdate() != 1) {
			return false;
		}
		return true;
	}
 
	/**
	 * 修改数据库中的数据
	 * @param sql	任意的SQL更新语句
	 * @param args	任意个用于替换占位符的形参
	 * @return		返回值是布尔类型
	 * @throws Exception
	 */
	public boolean modify(String sql, Object... args) throws Exception {
		PreparedStatement ps = con.prepareStatement(sql);
		for (int i = 0; i < args.length; i++) {
			ps.setObject(i + 1, args[i]);
		}
		if (ps.executeUpdate() != 1) {
			return false;
		}
		return true;
	}
 
	// 析构函数,中断数据库的连接
	protected void finalize() throws Exception {
		if (!con.isClosed() || con != null) {
			con.close();
		}
	}
}

15.student_exam.jsp页面

在线考试的jsp页面详情。

<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<c:set var="basepath" value="${pageContext.request.contextPath}" />
<html>
<head>
<link href="${basepath}/css/student_exam_paper_style.css"
	rel="stylesheet">
<link href="${basepath}/square/square.css" rel="stylesheet">
<script src="${basepath}/js/jquery.js"></script>
<script src="${basepath}/js/icheck.js"></script>
<%
	long curTime = System.currentTimeMillis() / 1000;
	request.setAttribute("curTime", curTime);
%>
<c:if test="${empty endTime}">
	<c:set var="endTime" scope="session" value="${curTime+sessionScope.examTime*60}" />
</c:if>
<script>
	var second =(${sessionScope.endTime-curTime});
	var timer=null;
	var showTime = function(){
		var s = second % 60; // 秒
		var mi = (second - s) / 60 % 60; // 分钟
		var h = ((second - s) / 60 - mi ) / 60 % 24; // 小时
		return h + "时" + mi + "分" + s + "秒";
	}

	timer=setInterval(function(){
		second --;
		document.getElementById("times").innerHTML = showTime ();
		if(second<=0){
			second=0;
			clearInterval(timer);
			alert("作答时间结束!");
			document.getElementById("paperForm").submit();
		}
	}, 1000); 
	
	$(document).ready(function() {
		$('input').iCheck({
			checkboxClass : 'icheckbox_square',
			radioClass : 'iradio_square',
			increaseArea : '20%' // optional
		});
		$("input:radio").on('ifClicked',function(){
			var opt=$(this).val();$('.ans'+this.name).html(opt);
        });
		$("input:checkbox").on('ifChecked',function(){
			var opt=$(this).val();$("#s"+this.name+opt).append(opt);
        });
        $("input:checkbox").on('ifUnchecked',function(){
			var opt=$(this).val();$("#s"+this.name+opt).empty(opt);
        });
        $("input:text").on('change',function(){
			var opt=$(this).val();$('.ans'+this.name).html(opt);
        });
	});


        
</script>
</head>
<body>


	<c:set var="count" scope="request" value="0"></c:set>
	<div id="content">
		<div id="top">
			<h1>欢迎使用在线考卷</h1>
			<p>
				准考证号:
				<c:out value="${loginBean.ID}" />
			</p>
			<p>
				考生姓名:
				<c:out value="${loginBean.name}" />
			</p>
			<p>
				所在班级:
				<c:out value="${loginBean.CLASS}" />
			</p>
		</div>
		<br>
		<hr>
		<br>
		<div id="paper">
			<form action="${basepath}/CalScoreServlet" method="post" name="paper"
				id="paperForm">

				<c:forEach var="que" items="${sessionScope.ques}" varStatus="status">
					<c:choose>
						<c:when test="${que.q_type eq '单选题'}">
							<c:if test="${count==0}">
								<h3>一、单选题(每道3分,共15分)</h3>
								<c:set value="${count+1}" var="count"></c:set>
							</c:if>

							<div class="que">
								<span id="${que.q_id}">${que.q_id}&nbsp;.&nbsp; </span><span>${que.q_title}</span>
								<c:if test="${not empty  que.q_img }">
									<div class="img">
										<img alt="配图" src="${basepath}/images/${que.q_img}">
									</div>
								</c:if>
								<br> <br>
								<div class="option">
									<label><input type="radio" name="${que.q_id}" value="A" />A.${que.options[0]}</label><br />
									<label><input type="radio" name="${que.q_id}" value="B" />B.${que.options[1]}</label><br />
									<label><input type="radio" name="${que.q_id}" value="C" />C.${que.options[2]}</label><br />
									<label><input type="radio" name="${que.q_id}" value="D" />D.${que.options[3]}</label><br />
								</div>
							</div>
							<hr>
						</c:when>

						<c:when test="${que.q_type eq '多选题'}">
							<c:if test="${count==1}">
								<h3>二、多选题 (每道5分,共20分)</h3>
								<c:set value="${count+1}" var="count"></c:set>
							</c:if>
							<div class="que">
								<span id="${que.q_id}">${que.q_id}&nbsp;.&nbsp;</span> <span>${que.q_title}</span>
								<c:if test="${not empty  que.q_img }">
									<div class="img">
										<img alt="配图" src="${basepath}/images/${que.q_img}">
									</div>
								</c:if>
								<br> <br>
								<div class="option">
									<label><input type="checkbox" name="${que.q_id}"
										value="A" />A.${que.options[0]}</label><br /> <label><input
										type="checkbox" name="${que.q_id}" value="B" />B.${que.options[1]}</label><br />
									<label><input type="checkbox" name="${que.q_id}"
										value="C" />C.${que.options[2]}</label><br /> <label><input
										type="checkbox" name="${que.q_id}" value="D" />D.${que.options[3]}</label><br />
								</div>
							</div>
							<hr>
						</c:when>


						<c:when test="${que.q_type eq '判断题'}">
							<c:if test="${count==2}">
								<h3>三、判断题(每道4分,共20分)</h3>
								<c:set value="${count+1}" var="count"></c:set>
							</c:if>
							<div>
								<span id="${que.q_id}">${que.q_id}&nbsp;.&nbsp; </span><span>${que.q_title}</span>
								<c:if test="${not empty  que.q_img }">
									<div class="img">
										<img alt="配图" src="${basepath}/images/${que.q_img}">
									</div>
								</c:if>
								<br> <br>
								<div class="option">
									<label><input type="radio" name="${que.q_id}" value="对" />对</label>
									<label><input type="radio" name="${que.q_id}" value="错" />错</label>
								</div>
								<br />
							</div>
							<hr>
						</c:when>


						<c:when test="${que.q_type eq '填空题'}">
							<c:if test="${count==3}">
								<h3>四、填空题(每道3分,共15分)</h3>
								<c:set value="${count+1}" var="count"></c:set>
							</c:if>
							<div class="que">
								<span id="${que.q_id}">${que.q_id}&nbsp;.&nbsp;</span><span>${que.q_title}</span>
								<c:if test="${not empty  que.q_img }">
									<div class="img">
										<img alt="配图" src="${basepath}/images/${que.q_img}">
									</div>
								</c:if>
								<br> <br> <input type="text" name="${que.q_id}"
									placeholder="请在此处作答" />
							</div>
							<br>
							<hr>
						</c:when>


						<c:when test="${que.q_type eq '简答题'}">
							<c:if test="${count==4}">
								<h3>五、简答题(每道10分,共30分)</h3>
								<c:set value="${count+1}" var="count"></c:set>
							</c:if>
							<div class="que">
								<span id="${que.q_id}">${que.q_id}&nbsp;.&nbsp; </span><span>${que.q_title}</span>
								<c:if test="${not empty  que.q_img }">
									<div class="img">
										<img alt="配图" src="${basepath}/images/${que.q_img}">
									</div>
								</c:if>

								<br> <br>
								<div class="option">
									<textarea rows="6" cols="50" name="${que.q_id}"></textarea>
								</div>
							</div>
							<hr>
						</c:when>
					</c:choose>
				</c:forEach>
			</form>
			<div id="submit">
				<input type="button" value="提交答卷" id="examEnd"
					onclick="javascript:if(confirm('考试时间尚未结束,确认交卷吗?')){paper.submit()}" />
			</div>
		</div>
	</div>

	<div id="showTime">
		<div class="navs">
			时间剩余:
			<hr>
			<div id="times"></div>
		</div>
	</div>
	<c:set value="0" var="count"></c:set>
	<div id="queNav">
		<div class="navs">题目导航</div>
		<c:forEach var="que" items="${sessionScope.ques}" varStatus="status">

			<c:choose>
				<c:when test="${que.q_type eq '单选题'}">
					<a href="#${que.q_id}"> <c:if test="${count==0}">
							—${que.q_type}—<br>
							<c:set value="${count+1}" var="count"></c:set>
						</c:if>>${que.q_id}. &nbsp;<span class="ans${que.q_id}"></span></a>
				</c:when>
				<c:when test="${que.q_type eq '多选题'}">
					<a href="#${que.q_id}"> <c:if test="${count==1}">
							—${que.q_type}—<br>
							<c:set value="${count+1}" var="count"></c:set>
						</c:if>>${que.q_id}.&nbsp; <span class="ans${que.q_id}"> <span
							id="s${que.q_id}A"></span> <span id="s${que.q_id}B"></span> <span
							id="s${que.q_id}C"></span> <span id="s${que.q_id}D"></span>
					</span></a>
				</c:when>
				<c:when test="${que.q_type eq '判断题'}">
					<a href="#${que.q_id}"><c:if test="${count==2}">
							—${que.q_type}—<br>
							<c:set value="${count+1}" var="count"></c:set>
						</c:if> >${que.q_id}.&nbsp;<span class="ans${que.q_id}"></span></a>
				</c:when>
				<c:when test="${que.q_type eq '填空题'}">
					<a href="#${que.q_id}"> <c:if test="${count==3}">
							—${que.q_type}—<br>
							<c:set value="${count+1}" var="count"></c:set>
						</c:if> >${que.q_id}.&nbsp;<span class="ans${que.q_id}"></span></a>
				</c:when>
				<c:when test="${que.q_type eq '简答题'}">
					<a href="#${que.q_id}"><c:if test="${count==4}">
							—${que.q_type}—<br>
							<c:set value="${count+1}" var="count"></c:set>
						</c:if>>${que.q_id}.&nbsp; <span class="ans${que.q_id}"></span></a>
				</c:when>
			</c:choose>
		</c:forEach>
		<c:set value="0" var="count"></c:set>
	</div>
</body>
</html>

猜你喜欢

转载自blog.csdn.net/qq_59059632/article/details/117856150#comments_30188867