基于SSM和MySQL实现的在线考试系统

基于SSM和MySQL实现的在线考试系统 1,项目简介 1,1 优势 在线考试系统(Exam++)是基于 JAVA 与 MYSQL 开发的网络考试系统

本文包含相关资料包-----> 点击直达获取<-------

基于SSM和MySQL实现的在线考试系统

1.项目简介

1.1 优势

在线考试系统(Exam++)是基于 JAVA MYSQL 开发的网络考试系统。

  • 可以稳定、顺畅的运行在 Windows Linux 平台上

  • 可以通过它快捷方便的创建试题和题库、发布试卷、组织考试、系统自动批改

  • 高度的可配置性和灵活性使得它可以被应用于很多领域

1.2 功能模块

功能模块 子功能 详细介绍
用户功能模块 用户注册登陆 用户可以通过用户名邮箱注册网站,并且通过注册的用户登陆网站。
随机练习 从题库中随机取出指定数量的题目供学员练习。
强化练习 按照学员知识分布情况,分类进行练习,每次练习的结果会纳入到学员学习进度中。
错题练习 学员做错过的题库会记录在错题库中,学员可以从中进行学习。
模拟考试 学员可以从模拟考试的分类中选择试卷进行考试。
随机组卷 学员可以从随机组卷的分类中选择试卷进行考试。
专家试卷 学员可以从专家试卷的分类中选择试卷进行考试。
统计分析 用图表方式对学员知识体系下所有的题目做统计分析,学员可以清楚的知道自己的知识点掌握情况。
考试历史 参加过的考试会记录在考试历史中,通过点击可以查看答题情况,得分,和错题解答。
管理员/教师功能模块 题库管理 通过题库管理模块,教师可以增加、修改、删除题目,现在一共有6种题型,包括单选、多选、判断、简答、论述、分析、计算。
试卷管理 教师可以从题库中选择试题组成试卷供学员考试之用,组卷分为手动和自动两种。组卷完毕后还可以进一步调整试卷的分值,移除或添加试题。
用户管理 教师或管理员可以管理目前网站的注册用户。

1.3 安装部署

  • Exam++ 采用了mysql数据库,因此,请安装mysql(5.0以上版本),安装完毕后,请创建一个名为examxx的数据库,并将doc目录下的数据库文件 examxx.sql 导入到数据库

  • 请将examxx.war拷贝到tomcat目录下的webapps目录中

  • tomcat启动后,war包自动部署到tomcat,打开webapps\examxx\WEB-INF\spring\root-context.xml修改数据库配置,填写你自己的数据库信息,如下:

  • 启动tomcat服务器,输入 http://localhost:8080/examxx 进入到exam++主页面。如果能正常打开,则进度到第下一步,否则,请检查服务器配置或数据库配置是否正确

  • 点击右上角登录按钮,输入用户名admin和密码123456即可登录系统

2.数据库设计

2.1 表结构

试卷表

et_field

班组表

et_knowledge_point

et_news

试题表

et_question_2_point

et_question_2_tag

试题类型表

用户_角色 关联表

et_reference表

角色表

用户表

2.2 E-R图

3.项目实现

3.1工具类

拦截器

java @Intercepts({ @Signature(method = "prepare",type = StatementHandler.class,args = { Connection.class }) }) public class MyInterceptor implements Interceptor { private Page<?> page; private static Log log = LogFactory.getLog(MyInterceptor.class); @Override public Object intercept(Invocation invocation) throws Throwable { // TODO Auto-generated method stub try{ RoutingStatementHandler handler = (RoutingStatementHandler) invocation.getTarget(); StatementHandler delegate = (StatementHandler) ReflectUtil.getFieldValue(handler, "delegate"); BoundSql boundSql = delegate.getBoundSql(); log.info("拦截sql=" + boundSql.getSql()); //获取sql对应的参数 MapperParamMap<?> mapperParamMap = null; try{ mapperParamMap = (MapperParamMap<?>) boundSql.getParameterObject(); }catch(Exception ex){ } if(mapperParamMap == null){ Object result = invocation.proceed(); return result; } if(mapperParamMap.containsKey("page")){ page = (Page<?>) mapperParamMap.get("page"); //System.out.println(page.isGetAllRecord()); //page为空或者page的isGetAllRecord=true则不修改sql,返回所有的数据 if(page == null){ throw new Exception("page为空,拦截器不处理数据"); } else if(!page.isGetAllRecord()){ MappedStatement mappedStatement = (MappedStatement) ReflectUtil.getFieldValue(delegate, "mappedStatement"); Connection connection = (Connection) invocation.getArgs()[0]; String strSql = boundSql.getSql(); this.setTotalRecord(boundSql, mappedStatement, connection); StringBuffer sqlBuffer = new StringBuffer(strSql); String pageSql = this.getMySqlPageSql(page, sqlBuffer); ReflectUtil.setFieldValue(boundSql, "sql", pageSql); log.info("修改后的sql=" + pageSql); } } }catch(Exception e){ if(!e.getMessage().equals("page为空,拦截器不处理数据")) e.printStackTrace(); } Object result = invocation.proceed(); return result; } @Override public Object plugin(Object target) { // TODO Auto-generated method stub return Plugin.wrap(target, this); } @Override public void setProperties(Properties properties) { } /** * 更换数据库版本可以通过该方法来处理,这里只处理mysql,该方法暂时不用 * @return */ public String getPageSql(){ return null; } public String getMySqlPageSql(Page<?> page, StringBuffer sqlBuffer) { int offset = (page.getPageNo() - 1) * page.getPageSize(); if (!page.isGetAllRecord()) sqlBuffer.append(" limit ").append(offset).append(",").append(page.getPageSize()); return sqlBuffer.toString(); } public String getCountSql(String sql){ String countSql = "select count(1) from (" + sql + ") sb"; return countSql; } public void setTotalRecord(BoundSql boundSql,MappedStatement mappedStatement,Connection connection){ String sql = boundSql.getSql(); String countSql = this.getCountSql(sql); System.out.println(countSql); BoundSql countBoundSql = new BoundSql( mappedStatement.getConfiguration(), countSql, boundSql.getParameterMappings(), boundSql.getParameterObject()); ReflectUtil.setFieldValue(countBoundSql, "sql", sql); ReflectUtil.setFieldValue(countBoundSql, "parameterMappings", boundSql.getParameterMappings()); ReflectUtil.setFieldValue(countBoundSql, "parameterObject", boundSql.getParameterObject()); ReflectUtil.setFieldValue(countBoundSql, "additionalParameters", ReflectUtil.getFieldValue(boundSql, "additionalParameters")); ReflectUtil.setFieldValue(countBoundSql, "metaParameters", ReflectUtil.getFieldValue(boundSql, "metaParameters")); MapperParamMap<?> mapperParamMap = (MapperParamMap<?>) boundSql.getParameterObject(); ParameterHandler parameterHandler = new DefaultParameterHandler(mappedStatement, mapperParamMap, countBoundSql); PreparedStatement pstmt = null; ResultSet rs = null; try{ pstmt = (PreparedStatement) connection.prepareStatement(countSql); parameterHandler.setParameters(pstmt); rs = pstmt.executeQuery(); if(rs.next()){ int totalRecord = rs.getInt(1); page.setTotalRecord(totalRecord); } }catch(Exception e){ e.printStackTrace(); }finally{ } try { if (rs != null) rs.close(); if (pstmt != null) pstmt.close(); }catch(SQLException e) { e.printStackTrace(); } } }

分页

java /** * 返回anchor类型的分页 * @param currentPageNo * @param maxPageNo * @param parameters * @param url * @return */ public static String getPagelink(int currentPageNo, int maxPageNo, String parameters, String url) { currentPageNo = currentPageNo > maxPageNo ? maxPageNo : currentPageNo; int begainNo = currentPageNo - 5 > 0 ? currentPageNo - 5 : 1; int endNo = begainNo + 9 > maxPageNo ? maxPageNo : begainNo + 9; StringBuffer bf = new StringBuffer(); if (maxPageNo > 1) { bf.append(currentPageNo > 1 ? ("<li><a href = \"" + url + "?page=" + (currentPageNo - 1 > 1 ? currentPageNo - 1 : 1) + parameters + "\">上一页</a></li>") : "<li class=\"disabled\"><a>上一页</a></li>"); for (int i = begainNo; i <= endNo; i++) { if (i == currentPageNo) { bf.append("<li class=\"active\"><a href = \"" + url + "?page=" + i + parameters + "\" >" + i + "</a></li>"); } else bf.append("<li><a href = \"" + url + "?page=" + i + parameters + "\" >" + i + "</a></li>"); } bf.append(currentPageNo < maxPageNo ? ("<li><a href = \"" + url + "?page=" + (currentPageNo + 1 > maxPageNo ? maxPageNo : currentPageNo + 1) + parameters + "\">下一页</a></li>") : "<li class=\"disabled\"><a>下一页</a></li>"); return bf.toString(); } return ""; }

3.2 主要功能

java @RequestMapping(value = "/student/practice-test", method = RequestMethod.GET) public String practiceStartNew(Model model, HttpServletRequest request, @RequestParam(value = "kp", required = false) String knowledgepoint) { String strUrl = "http://" + request.getServerName() // 服务器地址 + ":" + request.getServerPort() + "/"; UserInfo userInfo = (UserInfo) SecurityContextHolder.getContext() .getAuthentication().getPrincipal(); List<Integer> fieldIdList = new ArrayList<Integer>(); fieldIdList.add(userInfo.getFieldId()); List<Integer> typeIdList = new ArrayList<Integer>(); typeIdList.add(1); typeIdList.add(2); typeIdList.add(3); typeIdList.add(4); List<QuestionQueryResult> qqrList = questionService.getQuestionQueryResultListByFieldIdList(fieldIdList,typeIdList, 20); String fieldName = ""; try{ fieldName = qqrList.get(0).getPointName().split(">")[1]; }catch(Exception e){ log.info(e.getMessage()); } int amount = qqrList.size(); StringBuilder sb = new StringBuilder(); for(QuestionQueryResult qqr : qqrList){ QuestionAdapter adapter = new QuestionAdapter(qqr,strUrl); sb.append(adapter.getStringFromXML()); } model.addAttribute("questionStr", sb.toString()); model.addAttribute("amount", amount); model.addAttribute("fieldName", "随机练习"); return "student/practice-improve"; } @RequestMapping(value = "student/practice-random", method = RequestMethod.GET) public String practice(Model model, HttpServletRequest request) { return "student/practice-testing"; } @RequestMapping(value = "student/practice-finished", method = RequestMethod.POST) public @ResponseBody Message practiceFinished(@RequestBody ExamFinishParam efp, HttpServletRequest request) { UserInfo userInfo = (UserInfo) SecurityContextHolder.getContext() .getAuthentication().getPrincipal(); HashMap<Integer, AnswerSheetItem> hm = efp.getAs(); Iterator<Integer> it = hm.keySet().iterator(); List<Integer> idList = new ArrayList<Integer>(); while (it.hasNext()) { int key = it.next(); idList.add(key); AnswerSheetItem as = hm.get(key); System.out.println(key + "=" + as.getPoint()); } PracticePaper practicePaper = new PracticePaper(); practicePaper.setAnswer_sheet(Object2Xml.toXml(hm)); practicePaper.setName("我的练习"); List<QuestionQueryResult> questionList = examService.getQuestionDescribeListByIdList(idList); practicePaper.setContent(Object2Xml.toXml(questionList)); practicePaper.setUserId(userInfo.getUserid()); practiceService.insertPracticePaper(practicePaper); Message message = new Message(); return message; } @RequestMapping(value = "student/practice-finished-page", method = RequestMethod.GET) public String practiceFinishedPage(Model model) { return "student/practice-finish"; } @RequestMapping(value = "student/exam-report", method = RequestMethod.GET) public String examFinishedReportPage(Model model, HttpServletRequest request) { String strUrl = "http://" + request.getServerName() // 服务器地址 + ":" + request.getServerPort() + "/"; UserInfo userInfo = (UserInfo) SecurityContextHolder.getContext() .getAuthentication().getPrincipal(); PracticePaper practicePaper = practiceService .getPracticePaperByUserID(userInfo.getUserid()); List<QuestionQueryResult> questionList = Object2Xml.toBean( practicePaper.getContent(), ArrayList.class); List<Integer> idList = new ArrayList<Integer>(); HashMap<Integer, AnswerSheetItem> hm = Object2Xml.toBean( practicePaper.getAnswer_sheet(), HashMap.class); List<String> htmlStr = new ArrayList<String>(); HashMap<Integer, QuestionQueryResult> questionMap = new HashMap<Integer, QuestionQueryResult>(); for (QuestionQueryResult qqr : questionList) { idList.add(qqr.getQuestionId()); QuestionAdapter adapter = new QuestionAdapter(hm.get(qqr.getQuestionId()),qqr,strUrl); htmlStr.add(adapter.getReportStringFromXML()); } model.addAttribute("htmlStr", htmlStr); return "student/exam-finish-report"; } @RequestMapping(value = "student/finish-exam", method = RequestMethod.GET) public String examFinishedPage(Model model) { UserInfo userInfo = (UserInfo) SecurityContextHolder.getContext() .getAuthentication().getPrincipal(); PracticePaper practicePaper = practiceService .getPracticePaperByUserID(userInfo.getUserid()); List<QuestionQueryResult> questionList = Object2Xml.toBean( practicePaper.getContent(), ArrayList.class); List<Integer> idList = new ArrayList<Integer>(); for (QuestionQueryResult q : questionList) { idList.add(q.getQuestionId()); } HashMap<Integer, AnswerSheetItem> hm = Object2Xml.toBean( practicePaper.getAnswer_sheet(), HashMap.class); int total = questionList.size(); int wrong = 0; int right = 0; HashMap<String, ReportResult> reportResultList = new HashMap<String, ReportResult>(); List<QuestionQueryResult> questionQueryList = examService .getQuestionDescribeListByIdList(idList); HashMap<Integer, Boolean> answer = new HashMap<Integer, Boolean>(); for (QuestionQueryResult q : questionQueryList) { String pointName = q.getPointName().split(">")[1]; if (q.getQuestionTypeId() != 1 && q.getQuestionTypeId() != 2 && q.getQuestionTypeId() != 3) continue; if (hm.get(q.getQuestionId()) != null) { if (q.getAnswer().equals(hm.get(q.getQuestionId()).getAnswer())) { answer.put(q.getQuestionId(), true); right++; if (reportResultList.containsKey(pointName)) { ReportResult r = reportResultList.get(pointName); r.sum++; r.rightTimes++; reportResultList.put(pointName, r); } else { ReportResult r = new ReportResult(); r.sum = 1; r.rightTimes = 1; reportResultList.put(pointName, r); } } else { answer.put(q.getQuestionId(), false); wrong++; if (reportResultList.containsKey(pointName)) { ReportResult r = reportResultList.get(pointName); r.sum++; r.wrongTimes++; reportResultList.put(pointName, r); } else { ReportResult r = new ReportResult(); r.sum = 1; r.wrongTimes = 1; reportResultList.put(pointName, r); } } hm.remove(q.getQuestionId()); } } model.addAttribute("total", total); model.addAttribute("wrong", wrong); model.addAttribute("right", right); model.addAttribute("reportResultList", reportResultList); model.addAttribute("create_time", practicePaper.getCreate_time()); model.addAttribute("answer", answer); model.addAttribute("idList", idList); return "student/exam-finished"; }

4.项目展示

4.1 普通用户

登录

注册

主页

选择试题

答题界面

切换模式

个人中心

数据统计分析

修改个人资料

4.2 管理员

主页

添加试题

导入试题

试卷管理

创建试卷

用户管理

题库管理、标签管理

管理员管理、数据备份

参考文献

  • 江西省商务学校在线考试系统(南昌大学·万萍)
  • 基于ASP.NET技术的开放式在线学习及考试系统的研究与实现(中国海洋大学·李娅)
  • 基于B/S架构的在线考试管理系统的设计与实现(吉林大学·綦晓杰)
  • 基于Ext JS的题库管理与考试系统(电子科技大学·夏汛)
  • 网上考试和查分系统设计与实现(国防科学技术大学·王腾)
  • 基于ASP.NET的在线考试系统设计与实现(吉林大学·范振钧)
  • 基于JSP的在线实时考试系统(长安大学·郑辉)
  • 基于.NET&XML的考试系统的设计与实现(武汉理工大学·丁建业)
  • 基于B/S架构的在线考试管理系统的设计与实现(吉林大学·綦晓杰)
  • 基于Web的在线考试系统(太原理工大学·林健)
  • 基于网络的考试系统(吉林大学·李宏俊)
  • 基于J2EE技术的在线考试系统(天津大学·雷妍)
  • 基于WebService的B/S架构的在线考试系统的设计与实现(西安科技大学·谢佳)
  • 在线考试系统的设计与实现(青岛大学·许光林)
  • 基于J2EE技术的考试系统的实现(大连海事大学·齐崧然)

本文内容包括但不限于文字、数据、图表及超链接等)均来源于该信息及资料的相关主题。发布者:毕设货栈 ,原文地址:https://m.bishedaima.com/yuanma/35479.html

相关推荐

发表回复

登录后才能评论