项目类型: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} . </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} . </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} . </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} . </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} . </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}. <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}. <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}. <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}. <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}. <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>