基于JavaWeb的作业提交与批改系统:源码结构、数据库脚本与核心实现
2026/9/23 17:34:54 网站建设 项目流程

简介:这是一套基于JavaWeb的作业提交与批改系统项目源码,面向计算机相关专业正在做毕设的学生,以及需要项目实战练习的Java学习者,可直接作为毕业设计使用。系统采用B/S结构,后台基于JSP、Servlet与JDBC实现,以MySQL作为数据库,开发环境为JDK、Eclipse和Tomcat,并划分管理员、教师、学生三种角色。功能上覆盖班级、教师、学生、公告、留言、资料及系统管理七大模块,支持信息的录入、查询、删除与打印等操作,界面美观、操作简单,具有较高的实际应用价值。资源包共3个文件,包含项目源码压缩包、数据库脚本sql文件以及项目说明txt文档,整体约4.51MB,源码与建库脚本配套齐全,便于快速部署运行。目前已有3583人学习下载,适合希望掌握JavaWeb开发流程、积累完整项目经验的读者参考借鉴。

1. 从一份“能跑起来”的作业提交与批改系统说起

很多计算机毕设选题里,“作业提交与批改系统”看起来平平无奇,真正动手才发现它把 JavaWeb 的几块硬骨头全串在了一起:文件上传、角色权限、成绩状态流转、批量批改、数据库脚本初始化。它不像电商秒杀那样有炫技空间,但胜在业务闭环完整,答辩时老师随便点一个“学生重新提交后老师看到的还是旧附件吗”就能问出一身汗。

这篇围绕基于 JavaWeb 的作业提交与批改系统展开,把项目源码结构和数据库脚本怎么落地讲清楚。适合正在做 Java 毕设、需要一套能演示、能讲清权限与状态流转的同学,也适合想用 SpringBoot + Vue 重写一遍的熟手对照参考。核心不是堆功能,而是让“提交—批改—回看”这条链路在本地稳定跑通,并且数据库脚本能一键重建。

2. 作业提交与批改系统的技术选型与数据库脚本设计

2.1 为什么用 SpringBoot + MyBatis 而不是纯 Servlet

纯 Servlet + JSP 的 JavaWeb 项目能体现“底层”,但作业系统里文件上传、分页查询、登录拦截这些重复代码会迅速膨胀。常见做法是 SpringBoot 2.x 打底,MyBatis 做持久层,Thymeleaf 或前后端分离的 Vue 做视图。这样控制器只关心业务,文件流、事务、拦截器交给框架。

选型上要盯住三个点:一是文件存储,作业附件通常放本地磁盘目录或对象存储,数据库只存相对路径;二是权限模型,学生、教师、管理员三种角色用拦截器或 Spring Security 区分;三是状态字段,作业提交记录必须有status,否则“已批改/未批改/打回重做”没法表达。

2.2 数据库脚本的核心表与字段设计

数据库脚本是毕设里最容易被忽视、又最容易被追问的部分。作业系统的表不用多,但关系要清楚。下面是一份可直接执行的 MySQL 脚本片段,覆盖用户、课程、作业、提交记录四张核心表。

-- 用户表:用 role 区分学生/教师/管理员 CREATE TABLE `sys_user` ( `id` BIGINT NOT NULL AUTO_INCREMENT, `username` VARCHAR(50) NOT NULL COMMENT '登录名', `password` VARCHAR(100) NOT NULL COMMENT '加密后的密码', `real_name` VARCHAR(50) DEFAULT NULL, `role` TINYINT NOT NULL DEFAULT 0 COMMENT '0学生 1教师 2管理员', `class_id` BIGINT DEFAULT NULL COMMENT '学生所属班级', PRIMARY KEY (`id`), UNIQUE KEY `uk_username` (`username`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- 作业表:教师发布,含截止时间 CREATE TABLE `homework` ( `id` BIGINT NOT NULL AUTO_INCREMENT, `course_id` BIGINT NOT NULL, `title` VARCHAR(100) NOT NULL, `content` TEXT, `deadline` DATETIME NOT NULL COMMENT '截止提交时间', `create_by` BIGINT NOT NULL COMMENT '发布教师id', PRIMARY KEY (`id`), KEY `idx_course` (`course_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- 提交记录表:一个学生一份作业一条记录,status 驱动批改流程 CREATE TABLE `submit_record` ( `id` BIGINT NOT NULL AUTO_INCREMENT, `homework_id` BIGINT NOT NULL, `student_id` BIGINT NOT NULL, `file_path` VARCHAR(255) DEFAULT NULL COMMENT '附件相对路径', `submit_time` DATETIME DEFAULT CURRENT_TIMESTAMP, `status` TINYINT NOT NULL DEFAULT 0 COMMENT '0未批改 1已批改 2打回重做', `score` DECIMAL(5,1) DEFAULT NULL, `comment` VARCHAR(500) DEFAULT NULL COMMENT '教师评语', PRIMARY KEY (`id`), UNIQUE KEY `uk_hw_stu` (`homework_id`,`student_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

逻辑说明:submit_record上的唯一索引uk_hw_stu是关键,它保证同一学生对同一作业只有一条记录,重新提交走UPDATE而不是INSERT,避免出现多条脏数据。status用 0/1/2 三个值驱动前端按钮和教师列表筛选,比用字符串更省空间也更好索引。

参数说明:deadlineDATETIME而不是DATE,因为很多作业要求精确到分钟;scoreDECIMAL(5,1)支持 100.0 这种一位小数;file_path存相对路径,换服务器时只改配置不改数据。

提示:导出脚本时用mysqldump -u root -p --databases homework_db > homework.sql,把建库语句一起带上,别人拿到脚本能直接source导入,这在毕设验收时很加分。

2.3 用 IDEA 跑通 JavaWeb 项目的最小配置

拿到源码后第一步不是改代码,而是让环境先跑起来。常见做法是在 IDEA 里确认 JDK 版本、Maven 依赖和数据库连接三件事。

# 1. 导入数据库脚本 mysql -u root -p < homework.sql # 2. 修改 application.yml 里的数据库连接 # spring.datasource.url: jdbc:mysql://localhost:3306/homework_db?useUnicode=true&characterEncoding=utf8 # spring.datasource.username / password 改成自己的 # 3. Maven 拉依赖并启动 mvn clean package -DskipTests java -jar target/homework-system-0.0.1-SNAPSHOT.jar

逻辑说明:先导库再改配置最后启动,顺序反了会一直报连接失败。-DskipTests跳过测试加快打包,毕设阶段够用。启动后访问http://localhost:8080,用脚本里预置的管理员账号登录,先确认登录拦截器生效,再测文件上传。

3. 作业提交与批改系统的核心功能实现

3.1 文件上传与重新提交的覆盖逻辑

作业提交的核心是文件上传接口。用 Spring 的MultipartFile接收,存到配置的磁盘目录,再把相对路径写回submit_record。重新提交时不能新增记录,而是更新原记录并重置status为 0。

@PostMapping("/submit") public Result submit(@RequestParam Long homeworkId, @RequestParam("file") MultipartFile file, HttpSession session) { Long studentId = (Long) session.getAttribute("userId"); // 1. 校验截止时间,超时直接拒绝 Homework hw = homeworkMapper.selectById(homeworkId); if (new Date().after(hw.getDeadline())) { return Result.fail("已过截止时间,无法提交"); } // 2. 保存文件,文件名用 作业id_学号_时间戳 避免覆盖 String fileName = homeworkId + "_" + studentId + "_" + System.currentTimeMillis() + file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")); File dest = new File(uploadDir + fileName); file.transferTo(dest); // 3. 存在则更新,不存在则插入 SubmitRecord record = submitRecordMapper.selectByHwAndStu(homeworkId, studentId); if (record == null) { record = new SubmitRecord(); record.setHomeworkId(homeworkId); record.setStudentId(studentId); } record.setFilePath(fileName); record.setSubmitTime(new Date()); record.setStatus(0); // 重新提交后回到未批改 submitRecordMapper.saveOrUpdate(record); return Result.ok("提交成功"); }

逻辑说明:先查截止时间再存文件,避免存了文件又拒绝的浪费。文件名拼接时间戳是为了防止同名文件互相覆盖,同时保留扩展名。saveOrUpdate根据主键是否存在决定插入还是更新,配合数据库唯一索引双保险。

参数说明:uploadDir建议写在application.yml里,不要硬编码;status重置为 0 是重新提交的关键,否则教师端会一直显示“已批改”。

3.2 教师批改与成绩状态流转

教师端要能看到某份作业下所有学生的提交,按status筛选,逐条打分写评语。批改接口只更新statusscorecomment三个字段。

-- 教师批改列表:按作业查提交记录,关联学生姓名 SELECT s.id, u.real_name, s.submit_time, s.status, s.score, s.file_path FROM submit_record s JOIN sys_user u ON s.student_id = u.id WHERE s.homework_id = #{homeworkId} AND (#{status} IS NULL OR s.status = #{status}) ORDER BY s.submit_time DESC;

逻辑说明:#{status} IS NULL OR s.status = #{status}是常见的动态筛选写法,前端不传状态就查全部,传了就按状态过滤。关联sys_user拿学生姓名,避免前端再发一次请求。

参数说明:status传 0 查未批改,传 1 查已批改,传 2 查打回重做。批改时把status置 1 并写入scorecomment,打回则置 2 并清空score

3.3 角色权限拦截器的配置

三种角色看到的菜单和接口权限不同,用拦截器统一处理最省事。学生不能访问批改接口,教师不能访问用户管理接口。

public class AuthInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest req, HttpServletResponse resp, Object handler) throws Exception { String uri = req.getRequestURI(); Integer role = (Integer) req.getSession().getAttribute("role"); if (role == null) { resp.sendRedirect("/login"); return false; } // 批改相关接口只允许教师(1)和管理员(2) if (uri.startsWith("/teacher/") && role == 0) { resp.sendError(403, "无权限"); return false; } // 用户管理只允许管理员(2) if (uri.startsWith("/admin/") && role != 2) { resp.sendError(403, "无权限"); return false; } return true; } }

逻辑说明:按 URI 前缀做粗粒度控制,够毕设用。更细的可以上 Spring Security 注解,但拦截器更容易讲清楚。role从 session 取,登录时写入。

参数说明:/teacher/前缀对应批改、发布作业;/admin/对应账号管理。新增角色时只需加一个判断分支。

角色可访问前缀典型操作
学生/student/查看作业、提交附件、看成绩
教师/teacher/发布作业、批改、打回
管理员/admin/用户管理、班级管理

4. 作业提交与批改系统的排错与进阶技巧

4.1 文件上传失败的四个常见原因

上传报错先看后端日志的异常类型。常见的是MaxUploadSizeExceededException,说明文件超过 SpringBoot 默认的 1MB 限制,在application.yml里加spring.servlet.multipart.max-file-size: 50MBmax-request-size: 50MB。第二种是目录不存在,transferTo不会自动建目录,启动时用dest.getParentFile().mkdirs()兜底。第三种是中文文件名乱码,配置里加server.servlet.encoding.charset: UTF-8。第四种是路径写成了绝对路径导致换机器失效,统一用相对路径加配置前缀。

4.2 用状态机思路避免批改逻辑混乱

批改最容易出的 bug 是状态乱跳:学生重新提交后教师那边还显示已批改,或者打回后学生看不到评语。把status当成状态机,只允许 0→1、0→2、2→0 三种流转,其他情况在 service 层直接拒绝。这样即使前端传了非法状态,后端也能兜住。验证方法是写一个简单的单元测试,对每种流转断言结果,答辩演示时也更有底气。

4.3 数据库脚本的版本化与一键重建

毕设后期改表结构很频繁,建议把脚本拆成schema.sql(建表)和data.sql(初始数据),SpringBoot 配置spring.sql.init.mode: always后每次启动自动执行。改字段时同步改脚本,别只改数据库不更新文件,否则换台电脑导入就报错。导出时用mysqldump --no-data只导结构,数据单独维护,脚本体积小也更好读。最后把脚本和源码放同一目录,README 里写清导入顺序,验收时对方能独立跑起来,这套作业提交与批改系统才算真正交付。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询