首页 / 资讯中心 / 文章详情

SpringBoot+Vue在线考试系统前后端分离开发实战教程

SpringBoot+Vue在线考试系统前后端分离开发实战教程 ★ FEATURED ARTICLE
这次我们来看一个非常适合毕设、课设以及简历项目储备的完整系统SpringBoot Vue 在线考试与学习测评系统。项目是典型的前后端分离架构包含用户管理、题库管理、在线考试、自动评分、成绩统计、学习测评等核心模块覆盖了从后端接口到前端页面的完整开发链路。对于正在准备毕业设计、需要快速交付一个“能演示、能跑通、代码干净”的项目或者想系统学习 SpringBoot Vue 全家桶协作方式的开发者来说这个项目可以直接拿来做二次开发底座。文章不会停留在项目截图层面而是从部署环境、数据库设计、后端启动、前端联调、功能验证、接口调用、常见报错排查这几个维度完整过一遍。建议先确认你本机的 JDK、Maven、Node、MySQL 版本然后再按下面的步骤操作。1. 核心能力速览能力项说明项目类型前后端分离在线考试与学习测评系统后端技术栈SpringBoot、Spring MVC、MyBatis 或 MyBatis-Plus、MySQL、JWT 等前端技术栈Vue 2 / Vue 3、Vue Router、Vuex/Pinia、Element UI / Element Plus、Axios核心功能用户登录注册、题库管理、在线组卷、在线考试、自动评分、成绩统计、学习测评、增删改查架构特点前后端分离后端提供 RESTful API前端通过 Axios 调用接口运行环境JDK 8 或 11、Maven 3.6、Node 14、MySQL 5.7 或 8.0启动方式后端 SpringBoot 应用前端 npm 开发服务器是否需要 GPU不需要是否支持 API支持后端本身就是接口服务是否支持批量任务题库导入导出、批量组卷、批量阅卷可按业务扩展适合场景毕业设计、课程设计、面试项目演示、中小型在线学习平台原型从项目结构来看这是一个学习价值比较完整的全栈案例后端有统一返回结果、异常处理、登录拦截和数据库操作前端有路由守卫、状态管理、动态菜单和页面组件。如果你要写进简历可以重点突出“独立完成前后端设计与联调”这个点。2. 适用场景与使用边界2.1 这个项目适合谁第一类是在校学生。毕设需要交付一个完整可运行的系统这个项目比单纯的管理系统更有展示空间考试流程、倒计时交卷、自动判分、成绩统计这些功能演示起来更直观。第二类是准备校招或社招的开发者把项目跑通后可以针对 JWT 登录认证、试题随机抽取、答题记录保存、成绩聚合查询等模块深入讲实现思路。第三类是刚接触 SpringBoot Vue 的初学者项目是一个很好的“全流程参考样板”。2.2 使用边界与合规提醒项目用于学习、毕设和个人二次开发没有问题。但要注意几个边界不要直接替换成自己的名字拿去商用或提交到商业项目如果项目包含用户生成内容要考虑敏感信息过滤考试数据涉及学生个人信息时要注意隐私保护。图片素材、图标、字体等如果来自网络检查授权后再用于公开发布版本。整体来看这个项目适合做学习样本和简历素材不要在不确认来源与授权的情况下直接用于商业交付。3. 环境准备与前置条件3.1 软件环境清单软件推荐版本用途JDK1.8 / 11运行 SpringBoot 后端Maven3.6 及以上管理后端依赖与打包Node.js14 / 16 / 18 LTS运行前端开发环境npm/yarn/pnpmnpm 8安装前端依赖MySQL5.7 / 8.0存储业务数据数据库客户端Navicat / DataGrip / 命令行导入 SQL、查看数据IDEA2021 以上后端开发与调试VSCode最新稳定版前端开发安装顺序建议JDK - Maven - MySQL - Node。每个软件装完都在命令行验证一下版本避免后面排错时不知道问题出在哪一层。java -version mvn -version node -v npm -v mysql --version3.2 数据库准备拿到项目源码后先看sql目录或db目录下是否有.sql初始化脚本。一般会包含建库、建表和基础测试数据。直接在 MySQL 中执行mysql -u root -p source /your/path/exam.sql;如果没有现成脚本可以按下面的表结构手工建库。在线考试系统的核心表一般包括用户表、角色表、考试表、试题表、试题选项表、答题记录表、考试成绩表、学习资源表或测评记录表。建表脚本示例如下实际字段需要按项目源码调整CREATE DATABASE IF NOT EXISTS exam_system DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; USE exam_system; CREATE TABLE sys_user ( id bigint(20) NOT NULL AUTO_INCREMENT, username varchar(50) NOT NULL COMMENT 用户名, password varchar(100) NOT NULL COMMENT 加密密码, real_name varchar(50) DEFAULT NULL COMMENT 姓名, role varchar(20) DEFAULT student COMMENT 角色, status tinyint(1) DEFAULT 1, create_time datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), UNIQUE KEY uk_username (username) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; CREATE TABLE exam_paper ( id bigint(20) NOT NULL AUTO_INCREMENT, title varchar(100) NOT NULL COMMENT 试卷标题, duration_minutes int(11) DEFAULT 60 COMMENT 考试时长, total_score int(11) DEFAULT 100, start_time datetime DEFAULT NULL, end_time datetime DEFAULT NULL, status tinyint(1) DEFAULT 1, create_time datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; CREATE TABLE exam_question ( id bigint(20) NOT NULL AUTO_INCREMENT, paper_id bigint(20) DEFAULT NULL COMMENT 所属试卷, question_type varchar(20) DEFAULT single COMMENT 单选/多选/判断/简答, content text COMMENT 题干, options text COMMENT 选项 JSON, answer varchar(255) DEFAULT NULL COMMENT 参考答案, score int(11) DEFAULT 5, create_time datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; CREATE TABLE exam_record ( id bigint(20) NOT NULL AUTO_INCREMENT, user_id bigint(20) NOT NULL, paper_id bigint(20) NOT NULL, score_value decimal(10,2) DEFAULT 0 COMMENT 得分, status tinyint(1) DEFAULT 0 COMMENT 0考试中 1已交卷, submit_time datetime DEFAULT NULL, create_time datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;数据库字符集建议使用utf8mb4避免中文乱码和 Emoji 特殊字符导致的存储问题。4. 后端工程结构与启动方式4.1 后端工程目录参考一个标准的 SpringBoot 后端分层如下exam-backend/ ├── pom.xml ├── src/main/java/com/example/exam/ │ ├── ExamApplication.java │ ├── config/ # 跨域、拦截器、MyBatis配置 │ ├── controller/ # 接口层 │ ├── service/ # 业务逻辑层 │ ├── mapper/ # 数据访问层 │ ├── entity/ # 实体类 │ ├── dto/ # 请求/响应对象 │ ├── common/ # 统一返回、异常处理、常量 │ └── util/ # JWT、加密工具等 └── src/main/resources/ ├── application.yml └── mapper/ # MyBatis XML文件4.2 后端核心依赖pom.xml中通常会用到以下依赖按项目源码为准dependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency dependency groupIdorg.mybatis.spring.boot/groupId artifactIdmybatis-spring-boot-starter/artifactId version2.3.0/version /dependency dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId scoperuntime/scope /dependency dependency groupIdio.jsonwebtoken/groupId artifactIdjjwt/artifactId version0.9.1/version /dependency dependency groupIdorg.projectlombok/groupId artifactIdlombok/artifactId optionaltrue/optional /dependency /dependencies4.3 修改数据库连接配置application.yml或application.properties中需要修改数据库地址、账号、密码server: port: 8080 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/exam_system?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/Shanghai username: root password: your_password mybatis: mapper-locations: classpath:mapper/*.xml configuration: map-underscore-to-camel-case: true jwt: secret: your-secret-key expire: 7200000如果 MySQL 是 5.7注意驱动类名是否兼容如果是 MySQL 8.0必须保留serverTimezone参数否则会报时区错误。4.4 启动后端使用 IDEA 打开后端工程等待 Maven 依赖下载完成后直接运行ExamApplication主类。也可以命令行启动cd exam-backend mvn clean package -DskipTests java -jar target/exam-system.jar启动成功的标志是日志出现Tomcat started on port(s): 8080然后访问接口测试http://localhost:8080/api/ping如果没有/api/ping可以访问项目中的登录接口或者 Swagger 地址视项目配置而定。后端启动期间重点看两个问题端口是否被占用、数据库连接是否成功。5. 前端工程结构与启动方式5.1 前端工程目录参考exam-frontend/ ├── package.json ├── vite.config.js 或 vue.config.js ├── .env.development ├── src/ │ ├── main.js │ ├── App.vue │ ├── router/ # 路由配置 │ ├── store/ # Vuex/Pinia │ ├── api/ # Axios 请求封装 │ ├── views/ # 页面组件 │ ├── components/ # 公共组件 │ └── utils/ # 请求工具、token 处理5.2 安装依赖并启动进入前端目录后先安装依赖cd exam-frontend npm install如果npm install速度慢可以切换镜像源npm config set registry https://registry.npmmirror.com npm install依赖安装完成后启动开发服务器npm run dev如果是 Vue 3 Vite 项目启动后默认地址一般是http://localhost:5173如果是 Vue 2 Vue CLI 项目默认端口一般是8080所以本地联调时通常需要修改前端开发服务器端口或后端端口避免冲突。在vite.config.js中配置端口export default defineConfig({ server: { port: 5173, proxy: { /api: { target: http://localhost:8080, changeOrigin: true } } } })如果是 Vue CLI 项目则在vue.config.js中配置module.exports { devServer: { port: 8081, proxy: { /api: { target: http://localhost:8080, changeOrigin: true } } } }5.3 前端登录页验证浏览器打开前端地址后如果能正常显示登录页说明前端基础环境没有问题。输入账号密码前先确认后端接口通过代理地址可以访问。打开浏览器控制台 Network 面板提交登录请求观察请求路径、响应状态码和返回 JSON 结构。如果登录后页面没有跳转优先排查后端是否正常启动。前端代理指向的后端端口是否正确。登录接口返回的数据结构是否与前端代码期望一致。Token 是否写入 localStorage 或 sessionStorage。路由守卫是否拦截了跳转。6. 前后端核心接口与联调逻辑在线考试系统本质上是一组资源的增删改查加业务状态流转。以下接口路径是常见设计具体以项目源码为准但整体可以按这个思路去理解。模块接口说明认证POST /api/auth/login登录返回 JWT Token认证POST /api/auth/register注册用户管理GET /api/users分页查询用户列表用户管理PUT /api/users/{id}修改用户信息用户管理DELETE /api/users/{id}删除用户题库管理POST /api/questions新增试题题库管理GET /api/questions/page分页查询试题题库管理POST /api/questions/batch批量导入试题试卷管理POST /api/papers创建试卷试卷管理POST /api/papers/{id}/publish发布试卷考试管理POST /api/exam/start开始考试按策略随机抽题考试管理POST /api/exam/submit提交答案成绩管理GET /api/exam/records查询考试记录统计模块GET /api/statistics/score成绩分布统计6.1 JWT 登录认证示例后端登录成功后返回 Token前端在后续请求的请求头中携带import axios from axios const service axios.create({ baseURL: /api, timeout: 10000 }) service.interceptors.request.use(config { const token localStorage.getItem(token) if (token) { config.headers.Authorization Bearer token } return config }) export default service后端拦截器解析 Token 的伪代码思路Component public class JwtInterceptor implements HandlerInterceptor { Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String auth request.getHeader(Authorization); if (auth ! null auth.startsWith(Bearer )) { String token auth.substring(7); // 解析token校验签名和过期时间 // 把用户信息放入 request attribute return true; } response.setStatus(401); return false; } }6.2 在线考试提交答案示例考试提交是项目中最核心的业务点一般需要同时处理试卷 ID、用户 ID、答案列表。{ paperId: 1, recordId: 23, answers: [ { questionId: 101, userAnswer: A }, { questionId: 102, userAnswer: B,C }, { questionId: 103, userAnswer: 正确 } ] }后端在事务中完成答案保存、客观题自动评分、成绩写入三步。如果数据库表设计合理一次提交就是一个事务避免出现“答案保存了但成绩没算出来”的不一致问题。7. 核心功能测试与效果验证系统跑通不代表业务正确。下面按功能点给出一套可执行的验证流程建议从管理员端到学生端完整走一遍。7.1 登录注册测试管理员账号、教师账号、学生账号分别登录。重点验证不同角色登录后左侧菜单是否不同能否通过越权请求拿到其他角色的接口数据。判断标准学生账号直接请求管理员接口应返回 401 或 403。7.2 题库与试卷管理测试新增单选题、多选题、判断题、简答题各若干然后创建一张试卷设置总分、考试时长、发布时间。把试卷设置为“已发布”状态后用学生账号登录确认可以看到这场考试。增删改查测试时可以故意提交空标题、非法分值、不合法选项格式观察后端是否返回明确错误信息。一个合格的增删改查模块前端校验与后端校验必须都有。7.3 在线考试流程测试学生账号开始考试时接口应该根据组卷策略随机抽取试题。页面应显示考试倒计时到达时间自动交卷。中途刷新页面时已经保存的答案不应丢失交卷后页面提示成功并跳到成绩页。这里最容易出现的问题是题目随机抽取后试卷内容没固定导致提交时服务端无法回判答案。正确设计是开始考试时就把本次考试的题目快照保存到答题记录表中。CREATE TABLE exam_record_question ( id bigint(20) NOT NULL AUTO_INCREMENT, record_id bigint(20) NOT NULL, question_id bigint(20) NOT NULL, user_answer varchar(255) DEFAULT NULL, score_value decimal(10,2) DEFAULT NULL, create_time datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;7.4 自动评分与成绩统计测试客观题单选、多选、判断由后端比对答案自动评分。多选题建议采用“全对得分、漏选错选不得分”或“半对给部分分”的规则规则在代码中要提前明确。成绩统计页应展示平均分、最高分、最低分、通过率并用 ECharts 展示分数段分布。7.5 批量导入测试题库模块通常会提供 Excel 导入功能少量数据手工新增大批量数据走导入。导入模板一般有固定表头格式测试时用三份文件验证正确文件、空文件、格式错误文件。系统应返回“成功导入 50 条失败 2 条失败原因第 8 行题干为空”。批量导入的时间复杂度和事务一致性是关键。数据量大时建议分批插入避免一次事务提交过多数据导致数据库锁等待。7.6 学习测评模块测试如果系统加入了学习测评功能比如知识点练习、章节测评、错题本核心验证点是测评结果是否绑定到用户账号错题是否会汇总到错题本测评答题记录是否与考试答题记录隔离。这个模块是系统的加分项演示的时候可以作为差异化功能重点介绍。8. 常见问题与排查方法问题现象可能原因排查方式解决方案后端启动时报端口被占用8080 被其他进程使用netstat -anofindstr 8080 查看 PID后端提示数据库连接失败MySQL 未启动、账号密码错误、数据库名不对检查 application.yml 配置启动 MySQL修改连接配置MySQL 8 连接驱动报错驱动类名或时区参数问题检查 url 是否包含serverTimezoneAsia/Shanghai补充参数确认驱动版本前端 npm install 卡住网络原因、依赖源慢检查 npm 源切换 npmmirror 镜像源前端启动后页面空白路由配置问题、入口文件错误、依赖缺失打开浏览器 Console 看报错按报错定位组件或路由问题登录请求 404前端代理没有生效、接口路径不对打开 Network 面板查看实际请求 URL修改 vite/webpack 代理配置跨域报错后端未配置 CORS 或代理未生效看请求是否被浏览器拦截后端加跨域配置或用代理方式规避登录后菜单不显示用户角色字段与前端判断不一致查看返回的用户信息字段对齐角色字段交卷后成绩没算出来答案结构不对、评分规则有 bug打印提交参数与评分日志检查多选/判断题评分逻辑考试中途刷新答案丢失答案未实时保存查看保存接口调用时机切题时或定时保存答案中文乱码数据库字符集不对、连接配置缺编码参数查看表字符集使用 utf8mb4 并配置characterEncodingutf8前端编译内存溢出Node 环境内存不够报错含 Heap out of memoryNODE_OPTIONS--max-old-space-size4096后重新启动打包后静态资源 404前端构建产物路径配置错误检查 publicPathVue CLI 配置publicPath: ./Vite 配置base: ./9. 最佳实践与二次开发建议9.1 先把最小链路跑通不要一开始就追求功能全跑。本地验证顺序建议后端启动 - 数据库连接 - 登录接口 - 前端登录页 - 题库增删改查 - 创建试卷 - 学生端考试 - 成绩查询。这条链路通了说明项目主体没问题后面再扩展其他模块。9.2 按模块拆分理解代码做二次开发前先把请求链路理清楚。一个功能从页面点击到数据落库依次经过 Vue 组件 - Vuex/Pinia - API 模块 - Axios - 后端 Controller - Service - Mapper - SQL。画一张自己的请求链路图比通读全部代码更高效。观察现有代码时重点看三处后端统一返回结果类、异常处理类、JWT 拦截器。这三个地方理解透了加接口的效率会高很多。9.3 增加功能时保持现有规范新人经常犯的错误是后端用 Result 做统一返回自己新写的接口直接返回了一个 HashMap前端用封装好的 request 工具自己却直接调 axios 实例。加功能时先找最相似的已有模块照猫画虎不要另起炉灶。分页、异常、参数校验都参照既有写法。9.4 考试业务要保证事务与并发安全学生同时交卷时成绩更新必须有事务保护。推荐方式是在 Service 层方法上加Transactional一个学生一次交卷操作全部成功或全部回滚。如果做成绩排名和统计尽量用数据库聚合查询不要在 Java 代码里循环算。批量阅卷的扩展方向是把单选题、多选题评分做状态机交卷后先进入“待评分”队列简答题由教师人工评分后再合并总分。9.5 安全配置与部署建议开发环境可以关闭 HTTPS、放宽跨域但部署到公网前必须改掉默认密码、限制接口访问范围、为前端配置反向代理。后端生产环境配置建议单独使用application-prod.ymlserver: port: 8080 spring: datasource: url: jdbc:mysql://your-prod-db:3306/exam_system?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/Shanghai username: prod_user password: prod_strong_password jwt: expire: 7200000前端完成后构建npm run build构建产物在dist目录使用 Nginx 托管。将/api路径反向代理到后端服务server { listen 80; server_name your-domain.com; root /usr/share/nginx/html; index index.html; location / { try_files $uri $uri/ /index.html; } location /api/ { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }10. 总结与下一步这个 SpringBoot Vue 在线考试与学习测评系统最值得尝试的点在于它覆盖了完整的全栈开发链路并且业务场景贴近真实产品不是单纯的增删改查玩具。拿到项目后先花半天把数据库初始化、后端启动、前端联调这条链路跑通再用一天时间把“管理员创建试卷 - 学生考试 - 自动判分 - 成绩统计”这条核心业务链路走完就能在面试或答辩时把项目讲明白。最容易踩的坑有三个数据库字符集和时区配置不对导致启动失败、前端代理配置错误导致登录接口 404、考试答案实时保存逻辑不完整导致刷新丢数据。这三个问题在本地环境提前验证一遍比到时候现场排错要省事得多。后续可以往这几个方向扩展增加 PDF 试卷导出功能把考试结果导出为证书图片增加知识点标签实现弱项智能推荐练习把批量阅卷流程改造成 Redis 队列支持大并发交卷给管理端加数据看板用 ECharts 展示考试通过率和知识点掌握度。骨架已经做好了剩下的拼图可以根据自己的简历方向选择。
阅读完成 · 觉得有帮助?
咨询建站