README.md

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

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

    博客原文:https://blog.csdn.net/qq_59059632/article/details/117856150

    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 randomQue(LinkedList list,ResultSet rs,int count) { int m = -1; int index = -1; ArrayList listA = new ArrayList(); 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 queBeanAllList = new ArrayList();

       	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}" />

    <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>
    ———————————————— 版权声明:本文为CSDN博主「那条学长V」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/qq_59059632/article/details/117856150

    项目简介

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

    功能特点: 1.学生和老师登录,无注册(只能老师录入) 2.学生管理:添加、修改、删除、查询考生 3.题目管理:添加、修改、删除、查询

    发行版本

    当前项目没有发行版本

    贡献者 1

    那条学长V @qq_59059632

    开发语言