一、系统介绍
1.开发环境
开发工具:IDEA2018.2
JDK版本:jdk1.8
Mysql版本:8.0.13
2.技术选型
1.后端:使用Java+SSH进行开发,使用过滤器来验证用户是否登录,使用MVC进行分层。
2.数据库:使用Hibernate作为数据持久化框架。
3.前端:使用Bootstrap作为前端框架来开发,使用到jstl来遍历数据。jsp来展示页面。
3.系统功能
1.学生
1.在线开始
2.成绩查询
3.修改密码
2.管理员
1.学生信息管理
考生信息的增删改查
2.考试成绩查询
3.试卷信息管理
试卷的增删改查
4.试题信息管理
试题信息的增删改查
4.数据库
/* Navicat Premium Data Transfer Source Server : Mysql Source Server Type : MySQL Source Server Version : 80013 Source Host : localhost:3306 Source Schema : ssh_online_exam Target Server Type : MySQL Target Server Version : 80013 File Encoding : 65001 Date: 11/07/2021 02:00:10 */ SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for t_exam -- ---------------------------- DROP TABLE IF EXISTS `t_exam`; CREATE TABLE `t_exam` ( `id` int(11) NOT NULL AUTO_INCREMENT, `examDate` datetime(0) NULL DEFAULT NULL, `moreScore` int(11) NOT NULL, `score` int(11) NOT NULL, `singleScore` int(11) NOT NULL, `paperId` int(11) NULL DEFAULT NULL, `studentId` varchar(40) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE, INDEX `FK_l14kkd2w86mpy8v2snw37hskx`(`paperId`) USING BTREE, INDEX `FK_sl2v4qucyp0qe9yvnk6icka10`(`studentId`) USING BTREE, CONSTRAINT `FK_l14kkd2w86mpy8v2snw37hskx` FOREIGN KEY (`paperId`) REFERENCES `t_paper` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `FK_sl2v4qucyp0qe9yvnk6icka10` FOREIGN KEY (`studentId`) REFERENCES `t_student` (`id`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE = InnoDB AUTO_INCREMENT = 25 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of t_exam -- ---------------------------- INSERT INTO `t_exam` VALUES (25, '2021-06-30 15:42:37', 0, 40, 40, 1, 'JS1001'); -- ---------------------------- -- Table structure for t_manager -- ---------------------------- DROP TABLE IF EXISTS `t_manager`; CREATE TABLE `t_manager` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `userName` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of t_manager -- ---------------------------- INSERT INTO `t_manager` VALUES (1, '管理员', 'admin', 'admin'); -- ---------------------------- -- Table structure for t_paper -- ---------------------------- DROP TABLE IF EXISTS `t_paper`; CREATE TABLE `t_paper` ( `id` int(11) NOT NULL AUTO_INCREMENT, `joinDate` datetime(0) NULL DEFAULT NULL, `paperName` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of t_paper -- ---------------------------- INSERT INTO `t_paper` VALUES (1, '2014-01-01 00:00:00', 'Java试卷一'); INSERT INTO `t_paper` VALUES (2, '2014-02-01 00:00:00', '语文试卷二'); INSERT INTO `t_paper` VALUES (3, '2014-01-01 00:00:00', '数学试卷一'); -- ---------------------------- -- Table structure for t_question -- ---------------------------- DROP TABLE IF EXISTS `t_question`; CREATE TABLE `t_question` ( `id` int(11) NOT NULL AUTO_INCREMENT, `answer` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `joinTime` datetime(0) NULL DEFAULT NULL, `optionA` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `optionB` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `optionC` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `optionD` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `subject` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `type` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `paperId` int(11) NULL DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE, INDEX `FK_ebouwob97chiilpjmc6gtgwkw`(`paperId`) USING BTREE, CONSTRAINT `FK_ebouwob97chiilpjmc6gtgwkw` FOREIGN KEY (`paperId`) REFERENCES `t_paper` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT ) ENGINE = InnoDB AUTO_INCREMENT = 21 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of t_question -- ---------------------------- INSERT INTO `t_question` VALUES (1, 'D', '2014-01-01 00:00:00', 'A. a1', 'B. $1', 'C. _1', 'D .11', '下列不可作为java语言修饰符的是?', '1', 1); INSERT INTO `t_question` VALUES (2, 'A', '2014-01-01 00:00:00', 'A. a1.java', 'B. a.class', 'C. a1', 'D. 都可以', '有一段java应用程序,它的主类名是a1,那么保存 它的源文件名可以是?', '1', 1); INSERT INTO `t_question` VALUES (3, 'A,B', '2014-01-01 00:00:00', 'A. String []a', 'B. String a[]', 'C. char a[][]', 'D. String a[10]', '下面正确声明一个一维数组的是?', '2', 1); INSERT INTO `t_question` VALUES (4, 'A,D', '2014-01-01 00:00:00', 'A. 在java中只允许单继承。', 'B. 在java中一个类只能实现一个接口。', 'C. 在java中一个类不能同时继承一个类和实现一个接口。', 'D. java的单一继承使代码更可靠。', '下面关于继承的叙述哪些是正确的?', '2', 1); INSERT INTO `t_question` VALUES (5, 'C', '2014-01-01 00:00:00', 'A. 一个子类可以有多个父类,一个父类也可以有多个子类', 'B. 一个子类可以有多个父类,但一个父类只可以有一个子类', 'C. 一个子类可以有一个父类,但一个父类可以有多个子类', 'D. 上述说法都不对', '在Java中?', '1', 1); INSERT INTO `t_question` VALUES (6, 'A,D', '2014-01-01 00:00:00', 'A. 包的声明必须是源文件的第一句代码。', 'B. 包的声明必须紧跟在import语句的后面。', 'C. 只有公共类才能放在包中。', 'D. 可以将多个源文件中的类放在同一个包中。', '可以将多个源文件中的类放在同一个包中?', '2', 1); INSERT INTO `t_question` VALUES (7, 'C', '2014-01-01 00:00:00', 'A. Java是跨平台的编程语言', 'B. Java支持分布式计算', 'C. Java是面向过程的编程语言', 'D. Java是面向对象的编程语言', '下列关于Java语言的特点,描述错误的是?', '1', 1); INSERT INTO `t_question` VALUES (21, 'D', '2021-06-29 16:00:00', '1', '2', '3', '4', 'Java基础类有几个?', '1', 1); -- ---------------------------- -- Table structure for t_student -- ---------------------------- DROP TABLE IF EXISTS `t_student`; CREATE TABLE `t_student` ( `id` varchar(40) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, `cardNo` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `name` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `password` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `prefession` varchar(40) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `sex` varchar(5) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of t_student -- ---------------------------- INSERT INTO `t_student` VALUES ('JS1001', '1001', '张三', '123456', '计算机科学', '男'); INSERT INTO `t_student` VALUES ('JS1002', '1002', '李四', '123456', '软件工程', '男'); INSERT INTO `t_student` VALUES ('JS1003', '1003', '王五', '123456', '网络攻防', '女'); SET FOREIGN_KEY_CHECKS = 1;
5.工程截图
二、系统展示
1.学生-登录页面
2.学生-主页面
3.学生-在线考试
4.学生-成绩查询
5.学生-修改密码
6.管理员-登录页面
7.管理员-主页面
8.管理员-考生信息管理
9.管理员-考生成绩查询
10.管理员-试卷管理
11.管理员-题目管理
三、部分代码
ExamAction
package com.java.yzl.action; //考试Action类 import com.java.yzl.actionInter.ExamActionInter; import com.java.yzl.bean.Exam; import com.java.yzl.bean.PageBean; import com.java.yzl.bean.Question; import com.java.yzl.dao.ExamDao; import com.java.yzl.dao.QuestionDao; import com.java.yzl.util.PageUtil; import com.java.yzl.util.PropertiesUtil; import com.java.yzl.util.StringUtil; import com.opensymphony.xwork2.ActionSupport; import org.apache.struts2.interceptor.ServletRequestAware; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import java.util.*; import java.util.Map.Entry; public class ExamAction extends ActionSupport implements ServletRequestAware, ExamActionInter { private static final long serialVersionUID = 1L; private ExamDao examDao = new ExamDao(); private QuestionDao questionDao = new QuestionDao(); private HttpServletRequest request; private String mainPage; private Exam exam; private Exam s_exam; private List<Exam> examList; private String page; private int total; private String pageCode; public String getMainPage() { return mainPage; } public void setMainPage(String mainPage) { this.mainPage = mainPage; } public Exam getExam() { return exam; } public void setExam(Exam exam) { this.exam = exam; } public List<Exam> getExamList() { return examList; } public void setExamList(List<Exam> examList) { this.examList = examList; } public Exam getS_exam() { return s_exam; } public void setS_exam(Exam s_exam) { this.s_exam = s_exam; } public String getPage() { return page; } public void setPage(String page) { this.page = page; } public int getTotal() { return total; } public void setTotal(int total) { this.total = total; } public String getPageCode() { return pageCode; } public void setPageCode(String pageCode) { this.pageCode = pageCode; } /** * 计算/添加考试成绩 * * @return * @throws Exception */ public String add() throws Exception { Map<String, String[]> keyMap = new HashMap<String, String[]>(); keyMap = request.getParameterMap(); Iterator<Entry<String, String[]>> it2 = keyMap.entrySet().iterator(); int totalScore = 0; int singleScore = 0; int moreScore = 0; while (it2.hasNext()) { Entry<String, String[]> entry = it2.next(); String keyStr = entry.getKey(); String values[] = entry.getValue(); String key; String value = ""; if (keyStr.equals("exam.student.id") || keyStr.equals("exam.paper.id")) { continue; } if (keyStr.split("-")[1].equals("r")) { // 单选 key = keyStr.split("-")[2]; value = values[0]; singleScore += this.calScore(key, value, "1"); } else { // 多选 key = keyStr.split("-")[2]; for (String s : values) { value += s + ","; } value = value.substring(0, value.length() - 1); moreScore += this.calScore(key, value, "2"); } } totalScore = singleScore + moreScore; exam.setSingleScore(singleScore); exam.setMoreScore(moreScore); exam.setScore(totalScore); exam.setExamDate(new Date()); examDao.saveExam(exam); mainPage = "exam/examResult.jsp"; return SUCCESS; } /** * 计算每道题目的得分 * * @param questionId * @param userAnswer * @return */ private int calScore(String questionId, String userAnswer, String type) throws Exception { Question question = questionDao.getQuestion(questionId); if (userAnswer.equals(question.getAnswer())) { if ("1".equals(type)) { return 20; } else { return 30; } } else { return 0; } } /** * 获取考试成绩 * * @return * @throws Exception */ public String getExams() throws Exception { examList = examDao.getExams(s_exam, null); mainPage = "exam/myExam.jsp"; return SUCCESS; } /** * 获取所有考试成绩 * * @return * @throws Exception */ public String examList() throws Exception { HttpSession session = request.getSession(); if (StringUtil.isEmpty(page)) { page = "1"; } if (s_exam != null) { session.setAttribute("s_exam", s_exam); } else { Object o = session.getAttribute("s_exam"); if (o != null) { s_exam = (Exam) o; } else { s_exam = new Exam(); } } PageBean pageBean = new PageBean(Integer.parseInt(page), Integer.parseInt(PropertiesUtil.getValue("pageSize"))); examList = examDao.getExams(s_exam, pageBean); total = examDao.examCount(s_exam); pageCode = PageUtil.genPagation(request.getContextPath() + "/exam!examList", total, Integer.parseInt(page), Integer.parseInt(PropertiesUtil.getValue("pageSize"))); mainPage = "exam/examList.jsp"; return SUCCESS; } public void setServletRequest(HttpServletRequest request) { this.request = request; } }
ManagerAction
package com.java.yzl.action; import com.java.yzl.bean.Manager; import com.java.yzl.dao.ManagerDao; import com.opensymphony.xwork2.ActionSupport; import org.apache.struts2.interceptor.ServletRequestAware; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; public class ManagerAction extends ActionSupport implements ServletRequestAware { /** * */ private static final long serialVersionUID = 1L; private HttpServletRequest request; private ManagerDao managerDao = new ManagerDao(); private Manager manager; private String error; public Manager getManager() { return manager; } public void setManager(Manager manager) { this.manager = manager; } public String getError() { return error; } public void setError(String error) { this.error = error; } /** * 登录验证 * * @return * @throws Exception */ public String login() throws Exception { HttpSession session = request.getSession(); Manager currentUser = managerDao.login(manager); if (currentUser == null) { error = "用户名或者密码错误!"; return ERROR; } else { session.setAttribute("currentUser", currentUser); return SUCCESS; } } /** * 注销用户 * * @throws Exception */ public String logout() throws Exception { request.getSession().invalidate(); return "logout"; } public void setServletRequest(HttpServletRequest request) { this.request = request; } }
PaperAction
package com.java.yzl.action; import com.java.yzl.bean.Paper; import com.java.yzl.bean.Question; import com.java.yzl.dao.PaperDao; import com.java.yzl.dao.QuestionDao; import com.java.yzl.util.ResponseUtil; import com.java.yzl.util.StringUtil; import com.opensymphony.xwork2.ActionSupport; import net.sf.json.JSONObject; import org.apache.struts2.ServletActionContext; import java.util.*; /** * 试卷Action类 * * @author Administrator */ public class PaperAction extends ActionSupport { /** * */ private static final long serialVersionUID = 1L; private PaperDao paperDao = new PaperDao(); private QuestionDao questionDao = new QuestionDao(); private String mainPage; private String paperId; private List<Paper> paperList = new ArrayList<Paper>(); private List<Question> squestionList = new ArrayList<Question>(); private List<Question> mquestionList = new ArrayList<Question>(); private String title; // 标题 private Paper paper; public List<Paper> getPaperList() { return paperList; } public void setPaperList(List<Paper> paperList) { this.paperList = paperList; } public List<Question> getSquestionList() { return squestionList; } public void setSquestionList(List<Question> squestionList) { this.squestionList = squestionList; } public List<Question> getMquestionList() { return mquestionList; } public void setMquestionList(List<Question> mquestionList) { this.mquestionList = mquestionList; } public Paper getPaper() { return paper; } public void setPaper(Paper paper) { this.paper = paper; } public String getPaperId() { return paperId; } public void setPaperId(String paperId) { this.paperId = paperId; } public String getMainPage() { return mainPage; } public void setMainPage(String mainPage) { this.mainPage = mainPage; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } /** * 获取所有试卷 * * @return * @throws Exception */ public String list() throws Exception { paperList = paperDao.getPapers(); mainPage = "exam/selectPaper.jsp"; return SUCCESS; } /** * 获取所有试卷(管理) * * @return * @throws Exception */ public String paperList() throws Exception { paperList = paperDao.getPapers(); mainPage = "paper/paperList.jsp"; return SUCCESS; } /** * 通过id获取试卷实体 * * @return * @throws Exception */ public String getPaperById() throws Exception { paper = paperDao.getPaper(paperId); mainPage = "paper/paperSave.jsp"; return SUCCESS; } /** * 保存预操作 * * @return * @throws Exception */ public String preSave() throws Exception { if (StringUtil.isNotEmpty(paperId)) { paper = paperDao.getPaper(paperId); title = "修改试卷"; } else { title = "添加试卷"; } mainPage = "paper/paperSave.jsp"; return SUCCESS; } /** * 保存试卷 * * @return * @throws Exception */ public String savePaper() throws Exception { if (StringUtil.isNotEmpty(paperId)) { paper.setId(Integer.parseInt(paperId)); } else { paper.setJoinDate(new Date()); } paperDao.savePaper(paper); return "save"; } /** * 删除试卷 * * @return * @throws Exception */ public String deletePaper() throws Exception { paper = paperDao.getPaper(paperId); JSONObject resultJson = new JSONObject(); if (questionDao.existQuestionByPaperId(paperId)) { resultJson.put("error", "试卷下面有题目,不能删除"); } else { paperDao.paperDelete(paper); resultJson.put("success", true); } ResponseUtil.write(resultJson, ServletActionContext.getResponse()); return null; } /** * 获取指定试卷 * * @return * @throws Exception */ public String getDetailPaper() throws Exception { paper = paperDao.getPaper(paperId); Set<Question> questionList = paper.getQuestions(); Iterator<Question> it = questionList.iterator(); while (it.hasNext()) { Question q = it.next(); if ("1".equals(q.getType())) { squestionList.add(q); } else { mquestionList.add(q); } } squestionList = this.getRandomQuestion(squestionList, 3); mquestionList = this.getRandomQuestion(mquestionList, 2); mainPage = "exam/paper.jsp"; return SUCCESS; } /** * 获取随机试题 * * @param questionList * @param num * @return */ private List<Question> getRandomQuestion(List<Question> questionList, int num) { List<Question> resultList = new ArrayList<Question>(); Random random = new Random(); if (num > 0) { for (int i = 1; i <= num; i++) { int n = random.nextInt(questionList.size()); Question q = questionList.get(n); if (resultList.contains(q)) { i--; } else { resultList.add(questionList.get(n)); } } } return resultList; } }