系统功能
基于Spring Boot框架的在线考试系统是一个集用户管理、权限控制[4]、试题管理、在线考试、成绩管理等功能于一体的综合性系统。该系统在构建时充分考虑了现代Web应用的最佳实践,采用了前后端分离架构,使得前端与后端能够各自独立开发、部署和扩展,通过恰当的注释和规范的编码来增强代码的可维护性。
在后端方面,使用Spring Boot框架来处理业务逻辑和数据交互。Spring Boot凭借其“约定大于配置”的理念,通过大量的自动配置和开箱即用的功能,极大地简化了Java Web应用的开发过程。开发者可以专注于业务逻辑的实现,而无需过多关注底层技术细节。Spring Boot还支持多种数据库连接和事务管理,使得与MySQL数据库的交互变得简单而高效。
在前端方面,使用Vue框架来实现界面展示和用户交互。Vue以其简洁、轻量、高效的特点,赢得了众多开发者的喜爱。它采用组件化的设计思想,使得开发者可以构建可复用的界面元素,提高代码的可维护性和可重用性。Vue还支持数据驱动的视图更新,使得前端界面能够实时反映数据的变化,增强了用户体验。
为了实现前后端的数据交互,系统采用了JSON作为数据交换格式。JSON具有轻量级、易读易写的特点,能够在不同平台和语言之间实现数据的无障碍传输。后端将数据以JSON格式返回给前端,前端通过解析JSON数据来展示用户界面和更新用户状态。这种基于JSON的数据交互方式使得前后端之间的耦合度降低,提高了系统的可扩展性和可维护性。
在数据持久化存储方面,系统选择了MySQL作为关系型数据库。MySQL以其稳定、可靠、高效的特点,在Web应用中得到了广泛应用。
系统使用Mybatis作为持久层框架,通过ORM(对象关系映射)的方式将Java对象与数据库表进行映射。Mybatis还支持自定义SQL语句和结果映射,使得开发者能够灵活地进行数据库操作。
综上所述,该系统通过采用前后端分离架构、Spring Boot框架、Vue框架、Mybatis框架、JSON数据交换格式以及MySQL数据库等技术栈实现在线考试系统,在该是一个集先进性、高效性、可扩展性与用户友好性于一体的综合性管理平台。该系统凭借其强大的功能和先进的技术,不仅满足了现代教育对考试管理的严苛要求,而且显著提升了考试管理的效率和公正性,为学校、教师和学生提供了前所未有的便捷和优质服务。随着技术的不断进步和应用的深入,我们有理由相信该系统将在未来继续发挥更加重要的作用,推动教育事业的持续发展和进步。
- 概要设计
本系统对学生用户和教师用户、管理员用户分别开发,其中学生用户登录后可以参加教师用户发表的考试、练习并且可以对于已经考试完的成绩进行查看,并且可以对系统留言。教师用户可以登录后添加考试、习题,也能添加学生信息。管理员登录后可以对学生和教师进行统一管理。系统功能结构图如1所示。
图1 系统功能结构图
- 详细设计(重点)
系统用户角色分为三种,分别是:管理员、教师和学生。管理员功能包含,创建、更新和删除学生和教师信息,题目的录入、更新和分类以及下发考试功能。学生功能包含,修改自身账号信息、进入教师或者管理员下发的考试中进行在线答题和查询自身所有的历史考试成绩。教师功能包含,试题管理,支持试题的录入、更新和分类、修改自身账号信息和查看所有学生的历史考试的所有成绩。
本系统采用的后端开发工具为 IntelliJ IDEA(简称 IDEA)和前端开发工具Visual Studio Code(简称 VSCode),后端使用的是基于Java语言的SpringBoot框架,前端使用 Vue.js 框架,在数据的持久化存储方面,选择了关系型数据库MySQL,使用持久层框架Mybatis通过ORM(对象关系映射)的方式将Java对象映射为数据库的行,实现简单操作操作数据库实现增删改查,使用Maven作为项目自动化构建工具来简化了 Java 项目的开发、构建和部署过程,提高了开发效率和系统质量。
3.1 前端设计
3.2 后端接口设计
3.3 数据库设计
系统用户角色分为三种,分别是:管理员、教师和学生。管理员功能包含,创建、更新和删除学生和教师信息,题目的录入、更新和分类以及下发考试功能。学生功能包含,修改自身账号信息、进入教师或者管理员下发的考试中进行在线答题和查询自身所有的历史考试成绩。教师功能包含,试题管理,支持试题的录入、更新和分类、修改自身账号信息和查看所有学生的历史考试的所有成绩。
(1)管理员信息表:存储管理员的相关信息,如表4.1所示。
表4.1 管理员信息表
字段名 | 字段类型 | 宽度 | 索引 | 标题 |
adminId | int | 9 | 主索引 | 管理员ID |
adminName | varchar | 20 | 管理员名 | |
sex | varchar | 2 | 性别 | |
pwd | varchar | 50 | 密码 | |
cardId | varchar | 18 | 身份证号 | |
role | varchar | 1 | 角色 |
(2)留言回复信息表:存储回复的留言的信息,如表4.2所示。
表4.2留言回复信息表
字段名 | 字段类型 | 宽度 | 索引 | 标题 |
replayId | int | 9 | 主索引 | 回复编号 |
messaheId | int | 255 | 留言编号 | |
replay | varchar | 255 | 回复内容 | |
replaytime | date | 10 | 回复时间 |
(3)学生信息表:存储学生的相关信息,如表4.3所示。
表4.3 学生信息表
字段名 | 字段类型 | 宽度 | 索引 | 标题 |
studentId | int | 9 | 主索引 | 学号 |
studentName | varchar | 20 | 姓名 | |
grade | varchar | 4 | 年级 | |
major | varchar | 20 | 专业 | |
clazz | varchar | 10 | 班级号 | |
institute | varchar | 30 | 学院 | |
pwd | varchar | 50 | 密码 | |
sex | varchar | 2 | 性别 | |
role | varchar | 1 | 角色 |
(4)教师信息表:存储教师的相关信息,如表4.4所示。
表4.4 教师信息表
字段名 | 字段类型 | 宽度 | 索引 | 标题 |
teacherId | int | 9 | 主索引 | 教师编号 |
teacherName | varchar | 20 | 姓名 | |
institute | varchar | 20 | 学院 | |
sex | varchar | 2 | 性别 | |
tel | varchar | 11 | 电话 | |
| varchar | 20 | 邮箱 | |
pwd | varchar | 50 | 密码 | |
cardId | varchar | 18 | 身份证号 | |
type | varchar | 20 | 职称 | |
role | varchar | 1 | 性别 |
(5)填空题信息表:存储填空题目的相关信息,如表4.5所示。
表4.5 填空题信息表
字段名 | 字段类型 | 宽度 | 索引 | 标题 |
questionId | int | 9 | 主索引 | 试题编号 |
subject | varchar | 20 | 考试科目 | |
question | varchar | 255 | 题目内容 | |
answer | varchar | 255 | 正确答案 | |
analysis | varchar | 255 | 答案解析 | |
score | int | 2 | 分值 | |
level | varchar | 5 | 难度等级 | |
section | varchar | 20 | 所属章节 |
(6)判断题信息表:存储判断题的相关信息,如表4.6所示。
表4.6 判断题信息表
字段名 | 字段类型 | 宽度 | 索引 | 标题 |
questionId | int | 9 | 主索引 | 试题编号 |
subject | varchar | 20 | 考试科目 | |
question | varchar | 255 | 试题内容 | |
answer | varchar | 255 | 答案 | |
analysis | varchar | 255 | 解析 | |
score | int | 2 | 分数 | |
level | varchar | 1 | 难度等级 | |
section | varchar | 20 | 所属章节 |
(7)选择题信息表:存储选择题的相关信息,如表4.7所示。
表4.7 选择题信息表
字段名 | 字段类型 | 宽度 | 索引 | 标题 |
questionId | int | 9 | 主索引 | 试题标号 |
subject | varchar | 20 | 考试科目 | |
question | varchar | 255 | 问题题目 | |
answerA | int | 255 | 选项A | |
answerB | varchar | 255 | 选项B | |
answerC | int | 255 | 选项C | |
answerD | varchar | 255 | 选项D | |
rightAnswer | varchar | 10 | 正确答案 | |
analysis | varchar | 255 | 题目解析 | |
score | int | 2 | 分数 | |
section | varchar | 20 | 所属章节 | |
level | varchar | 1 | 难度等级 |
(8)留言信息表:存储留言信息,如表4.8所示。
表4.8 留言信息表
字段名 | 字段类型 | 宽度 | 索引 | 标题 |
id | int | 9 | 主索引 | 留言编号 |
title | varchar | 20 | 标题 | |
content | varchar | 255 | 留言内容 | |
time | date | 10 | 留言时间 | |
name | varchar | 255 | 留言者 |
(9)考试管理信息表:存储类型的考试相关信息,如表4.9所示。
表4.9 考试管理信息表
字段名 | 字段类型 | 宽度 | 索引 | 标题 |
examCode | bigint | 9 | 主索引 | 考试编号 |
source | varchar | 20 | 课程名称 | |
paperId | int | 10 | 试卷编号 | |
examDate | varchar | 10 | 考试日期 | |
totalTime | int | 3 | 持续时长 | |
major | varchar | 20 | 专业 | |
institute | varchar | 20 | 学院 | |
totalScore | int | 4 | 总分 |
(10)试卷管理信息表:存储试卷和题目的对应信息,如表4.10所示。
表4.10 试卷管理信息表
字段名 | 字段类型 | 宽度 | 索引 | 标题 |
paperId | int | 9 | 主索引 | 试卷编号 |
questionType | int | 1 | 题目类型 | |
questionId | int | 9 | 题目标号 |
(11)分数信息表:存储考试的分数信息,如表4.11所示。
表4.11 分数信息表
字段名 | 字段类型 | 宽度 | 索引 | 标题 |
scoreId | int | 9 | 主索引 | 分数编号 |
examCode | int | 9 | 考试编号 |
续表4.11 分数信息表
字段名 | 字段类型 | 宽度 | 索引 | 标题 |
studentId | int | 9 | 学号 | |
subject | varchar | 20 | 课程名称 | |
ptScore | int | 5 | 平时成绩 | |
etScore | int | 5 | 期末成绩 | |
score | int | 5 | 总成绩 | |
answerDate | varchar | 10 | 答题日期 |
(12)课程信息表:存储课程的相关信息,如表4.12所示。
表4.12 课程信息表
字段名 | 字段类型 | 宽度 | 索引 | 标题 |
subjectId | int | 9 | 主索引 | 课程编号 |
subjectName | varchar | 20 | 课程名称 | |
institute | varchar | 20 | 学院 | |
instituteId | varchar | 20 | 学院编号 | |
teacherId | int | 9 | 教师编号 |
- 核心代码
Md5加密信息代码结构实现:
package com.lixianhe.onlineexam.util;
import java.security.MessageDigest;
public class MD5EncodingUtil {
public static String getMD5(String key) {
char[] hexDigits = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
};
try {
byte[] btInput = key.getBytes();
MessageDigest mdInst = MessageDigest.getInstance("MD5");
mdInst.update(btInput);
byte[] md = mdInst.digest();
int j = md.length;
char str[] = new char[j * 2];
int k = 0;
for (int i = 0; i < j; i++) {
byte byte0 = md[i];
str[k++] = hexDigits[byte0 >>> 4 & 0xf];
str[k++] = hexDigits[byte0 & 0xf];
}
return new String(str);
} catch (Exception e) {
return null;
}
}
}
判断题目核心代码块:
package com.lixianhe.onlineexam.controller;
import com.lixianhe.onlineexam.pojo.Answer;
import com.lixianhe.onlineexam.pojo.FillQuestion;
import com.lixianhe.onlineexam.pojo.JudgeQuestion;
import com.lixianhe.onlineexam.pojo.MultiQuestion;
import com.lixianhe.onlineexam.service.FillQuestionService;
import com.lixianhe.onlineexam.service.JudgeQuestionService;
import com.lixianhe.onlineexam.service.MultiQuestionService;
import com.lixianhe.onlineexam.service.AnswerService;
import com.lixianhe.onlineexam.util.ApiResultHandler;
import com.lixianhe.onlineexam.util.PageBean;
import com.lixianhe.onlineexam.util.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
public class AnswerController {
@Autowired
private AnswerService answerService;
@Autowired
private MultiQuestionService multiQuestionService;
@Autowired
private FillQuestionService fillQuestionService;
@Autowired
private JudgeQuestionService judgeQuestionService;
@GetMapping("/answers/{page}/{size}")
public R answers(@PathVariable("page") Integer page, @PathVariable("size") Integer size) {
PageBean<Answer> answerPageInfo = answerService.selectAnswerByPage(page, size);
return ApiResultHandler.buildApiResult(200, "所有数据", answerPageInfo);
}
@GetMapping("question/{questionId}/{type}")
public R selectQuestion(@PathVariable("questionId") Integer questionId, @PathVariable("type") String type) {
return answerService.selectQuestion(questionId, type);
}
@PutMapping("questionMulti")
public R updateQuestionMulti(@RequestBody MultiQuestion multiQuestion) {
int res = multiQuestionService.updateQuestion(multiQuestion);
if (res == 1) return ApiResultHandler.buildApiResult(200, "更新选择题成功", res);
return ApiResultHandler.buildApiResult(400, "更新选择题成功", res);
}
@PutMapping("questionFill")
public R updateQuestionFill(@RequestBody FillQuestion fillQuestion) {
int res = fillQuestionService.updateQuestion(fillQuestion);
if (res == 1) return ApiResultHandler.buildApiResult(200, "更新填空题成功", res);
return ApiResultHandler.buildApiResult(400, "更新填空题成功", res);
}
@PutMapping("questionJudge")
public R updateQuestionJudge(@RequestBody JudgeQuestion judgeQuestion) {
int res = judgeQuestionService.updateQuestion(judgeQuestion);
if (res == 1) return ApiResultHandler.buildApiResult(200, "更新判断题成功", res);
return ApiResultHandler.buildApiResult(400, "更新判断题成功", res);
}
@DeleteMapping("question/{questionId}/{type}")
public R deleteQuestion(@PathVariable("questionId") Integer questionId, @PathVariable("type") String type) {
return answerService.deleteQuestion(questionId, type);
}
}
浏览核心代码块:
package com.lixianhe.onlineexam.controller;
import com.lixianhe.onlineexam.pojo.Message;
import com.lixianhe.onlineexam.service.MessageService;
import com.lixianhe.onlineexam.util.ApiResultHandler;
import com.lixianhe.onlineexam.util.PageBean;
import com.lixianhe.onlineexam.util.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
public class MessageController {
@Autowired
private MessageService messageService;
@PostMapping("message")
public R addMessage(@RequestBody Message message) {
int res = messageService.addMessage(message);
if (res == 1) return ApiResultHandler.buildApiResult(200, "添加留言成功", res);
return ApiResultHandler.buildApiResult(400, "添加留言失败", res);
}
@GetMapping("messages/{page}/{size}")
public R messages(@PathVariable("page") Integer page, @PathVariable("size") Integer size) {
PageBean<Message> messagePageBean = messageService.MessageByPage(page, size);
return ApiResultHandler.buildApiResult(200, "分页查找成功", messagePageBean);
}
@GetMapping("/message/{id}")
public R selectById(@PathVariable("id") Integer id) {
Message message = messageService.selectById(id);
return ApiResultHandler.buildApiResult(200, "查询消息", message);
}
}
- 系统截图
本系统采用的后端开发工具为 IntelliJ IDEA(简称 IDEA)和前端开发工具Visual Studio Code(简称 VSCode),后端使用的是基于Java语言的SpringBoot框架,前端使用 Vue.js 框架,在数据的持久化存储方面,选择了关系型数据库MySQL,使用持久层框架Mybatis通过ORM(对象关系映射)的方式将Java对象映射为数据库的行,实现简单操作操作数据库实现增删改查,使用Maven作为项目自动化构建工具来简化了 Java 项目的开发、构建和部署过程,提高了开发效率和系统质量。
5.1 系统主页
本网站采用了一种独特的方式来管理用户,与传统的在线平台不同,它不直接支持用户自行注册,相反,它借鉴了Linux系统的用户管理方式,即管理员具有创建新用户的权限。这种方式为网站管理者提供了更高的控制权和安全性,因为他们可以精确控制哪些用户可以访问系统,并为他们分配相应的权限,通过采用这种有创建用户权限的管理员账户来管理用户的方式,本网站确保了系统的安全性和稳定性,同时也为用户提供了更加灵活和个性化的访问体验。主页是整个系统的登录界面,可以通过输入不同角色的用户名和密码分别进入到管理员、学生和教师的管理系统。登录页面如图5.1所示。
管理员登录后,可以对本系统的内的绝大部分的资源进行操作,包括试卷和题目数据修改、教师和学生的创建和信息修改,管理员系统界面如图5.2所示。
图5.2管理员登录界面图
学生登录后,可以对学生账户数据进行修改操作和进入教师或者管理员下发的考试中进行答题,交卷后,可以在系统中查看历史考试的成绩,学生系统界面如图5.3所示。
教师登录后,可以对本系统的内的部分的资源进行操作,包括试卷创建、更新、删除,题目数据修改、教师自身账户的信息修改,教师登录后的界面如图5.4所示。
图5.4教师登录界面图
教师或者管理员登录后,在对应的系统中可以创建、修改和删除,创建考试试卷完成后,学生登录学生系统可以查看到试卷并进入系统在线答题,考试管理界面如图5.5所示。
图5.5考试管理界面图
5.6 题目管理模块
教师和管理员可以分别在各自的系统中对考试题目进行创建、更新和删除,并指定题目归属某个试卷,试卷下发后学生就可以登录学生系统进行在线答题,题目管理界面如图5.6所示。
图5.6考试管理界面图
5.7 学生管理模块
管理员可以在管理员系统中创建、更新和删除学生,学生登录后在学生系统,也可以修改自身信息,学生管理界面如图5.7所示。
5.8 教师管理模块
管理员可以在管理员系统中创建、更新和删除教师,教师登录后在教师系统,也可以修改自身信息,学生管理界面如图5.8所示。
图5.8教师管理界面图
5.9 考试模块
教师或者管理员在对应系统创建考试和试题后,学生即可在学生的系统中进入考试,并答题,题目分为选择题、判断题和填空题,学生填写完全部题目后即可提交结果,考试倒计时结束后也会自动提交答题,学生可以查看到分数,答题界面如图5.9所示。
图5.9 学生考试界面图
六、 总结展望
基于SpringBoot框架的在线考试系统,虽然在开发过程之中虽然遇到了一些难解决的问题,但都通过研究,查阅文档和资料都得到了解决。系统实现的功能都是对大学对所学知识的复习和总结。在线考试系统的开发主要是为了能够解决线上考试的问题,系统的三个使用者:管理员、老师、学生,每个角色都用于对应了不同的权限和功能,相互之间的信息交互完成了整体的系统功能,使用不同身份的账户和密码登录时,可以进入对应的权限的管理系统界面。每个角色在使用本系统时也能够达到一个分工明确的状态。
系统虽然整体完成了基本的功能实现,但是仍是有一些不足之处,整体的设计并没有涉及到在线监考相关业务功能。这次的系统设计与实现是对自己的知识作为一个汇总和总结,检验自己的知识的掌握程度。虽然在其中遇到了一些技术性问题,但是最终成功解决。
本作者接软件专业大作业设计,代码开发,项目定制等需求。VX:YCKJ2023
标签:varchar,SpringBoot,考考试,信息,int,源码,管理员,import,考试 From: https://blog.csdn.net/qq_43043777/article/details/140001966