简介:基于JavaWeb的作业管理网站源码,来自个人毕业设计项目,答辩得分95分,代码已完成调试与测试,下载后即可运行。资源面向计算机、通信、人工智能、自动化等相关专业的学生、老师或从业者,尤其适合期末课程设计、课程大作业和毕业设计参考,也便于JavaWeb初学者学习项目搭建与代码结构,并可根据实际需求二次改动扩展。压缩包共54个文件,大小7.73MB,包含9个Java源文件、9个JSP页面、7个CSS样式、5个JavaScript脚本以及9个JAR依赖库和数据库配置,并附有README介绍文档。前端采用Bootstrap和jQuery,界面围绕登录、作业发布、提交、汇总、信息展示等页面展开;后端包含作业管理核心逻辑,目录划分清晰,可快速定位到不同功能模块。目前已有237人学习下载。通过该源码可理解JavaWeb项目分层设计、JSP/Servlet交互、前端资源整合等核心思路,整体学习借鉴价值较高。
1. 这个作业管理网站源码能帮你省下什么:先想清楚再解压
学期末的课程设计又到验收节点,你手里这个“基于JavaWeb的作业管理网站源码(课程设计).zip”,在下载列表里属于最不容易踩雷的那一类:功能边界清楚——老师发布作业、学生在线提交、老师批改给分;技术栈也是教科书级的 JavaWeb——JSP + Servlet + MySQL + Tomcat。它要解决的是两件事:一是让课程设计验收有个能演示的完整站点,二是让你在短时间里把 Servlet、JDBC、会话管理这些课内概念落成代码,而不是只背概念。
但这类源码的坑也藏在“能下载”三个字后面:环境版本不匹配、数据库连不上、端口被占、中文乱码,任何一个都能让演示现场翻车。适合同等水平人群:基础尚可但没独立做过完整项目的在校生,以及想快速起步做课程设计的人。本文把一个 JavaWeb 作业管理网站从解压到跑通、再改成自己的东西这条路径完整走一遍,该抄的配置直接抄,该躲的坑提前躲。
2. 跑通 JavaWeb 作业管理系统的环境底座:JDK、Tomcat、MySQL 的版本搭配与 IDEA 配置
2.1 版本选型:为什么 JDK8、Tomcat8.5、MySQL5.7 是最稳妥的组合
JavaWeb 课程设计源码最大的特点是对新版本不友好。写这份代码的人当年用的,大概率是 JDK8 + Tomcat8.5 + MySQL5.7 这个组合;你手里这台机器如果装了 JDK17 + Tomcat10 + MySQL8,代码大概率没法直接跑。先说 Tomcat:10.x 把 javax.servlet 包改成了 jakarta.servlet,只差一个字母,源码里所有import javax.servlet.http.HttpServlet全部失效,IDEA 里满屏飘红。判断方法很简单:打开 Tomcat 的 lib 目录,看到 servlet-api.jar 说明版本在 9 以下;看到 jakarta.servlet-api.jar 说明是 10+,直接换回 8.5.x 再谈别的。
MySQL 版本同样重要。课程设计源码的 lib 下面如果只有老版本的 mysql-connector-java,而你的 MySQL 是 8.x 的默认认证插件 caching_sha2_password,连接时会报Unable to load authentication plugin;换 8.0.x 的驱动再改驱动类名也能用,但老代码把驱动类名写死在配置里,等于又要多改一处。所以我的建议顺序是:驱动 jar 是老的,就优先 MySQL 5.7;只有 MySQL 8 可用时,才考虑换新驱动这条麻烦路。
这套组合不是最时髦的,却是兼容率最高的一套。你在搜索引擎里搜“idea运行javaweb项目配置”,翻出来的教程截图里几乎清一色是 JDK8 + Tomcat8.5 的长相,黑马javaweb笔记里默认的组合也基本是这个方向。不是大家不更新,是这个组合能把你手里的源码以最低成本跑起来。下面这张表是我常用的选型依据:
| 组件 | 首选版本 | 理由 | 换了要注意什么 |
|---|---|---|---|
| JDK | 8 | 兼容javax.*老代码和各家课程设计 jar | JDK9+ 部分反射接口报错,乱报错概率高 |
| Tomcat | 8.5 | Servlet 3.1 + JSP 2.3,覆盖绝大部分课程设计 | Tomcat10 换 jakarta 包名,代码要改 import |
| MySQL | 5.7 | 认证插件兼容老驱动 | MySQL8 要换驱动并处理时区、SSL 参数 |
| mysql-connector-java | 随源码 lib 自带 | 版本匹配最省事 | 连不上时优先怀疑它,而不是怀疑代码 |
动手前先在命令行把现状查清楚,再决定要不要补环境:
java -version mysql --version echo $CATALINA_HOME逻辑说明:前两条看 JDK 和 MySQL 的已装版本;第三条看系统有没有配置过 Tomcat 的环境变量,没有也不影响,IDEA 里可以单独指定 Tomcat 目录。如果你的java -version显示的是 17 或 21,不一定要重装系统 JDK,在 IDEA 里只给这个项目指定 JDK8 即可:下载 JDK8 解压到纯英文路径,然后在 Project Structure 里新增一个 SDK 指向它,别动系统全局配置。
2.2 装好 MySQL 并导入数据库:建库脚本与字符集设置
作业管理网站的库一般不大,常见 3~5 张表足够,命名一般是 t_user、t_homework、t_submission 这类「t_ 前缀 + 业务名」。zip 里通常带一个 .sql 文件,可能是 init.sql 或 db.sql,不要双击运行,命令行 source 导入更可控,报错也看得清。先建库再导入,两步拆开:
CREATE DATABASE IF NOT EXISTS homework_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; USE homework_db; SOURCE /path/to/init.sql;参数说明:第三行的路径要换成你实际解压出来的 SQL 文件路径,注意路径里不要带中文,Windows 下容易触发编码问题。utf8mb4是 utf8 的超集,中文和 emoji 都能存,MySQL 5.7 及以上都支持,比直接建库用 utf8 省心。导入成功验证也简单:
SHOW TABLES; DESC t_user;逻辑说明:SHOW TABLES确认表进来了;DESC t_user看用户表字段结构,能出来列信息说明文件本身没问题。如果报ERROR 1064或ERROR 1366,问题多半出在 SQL 文件的字符集或行尾,第五章专门讲这个,这里先确保表建出来。
数据库准备好之后,把连接信息在代码里对应上。这类源码的连接配置通常集中在一个 properties 文件里,也可能直接写在 JDBCUtils.java,搜索关键字jdbc:mysql://或getConnection(就能定位。这个动作做完,第三章的配置才有意义。
2.3 配置 IDEA 运行环境:比黑匣子少一点玄学
IDEA 打开工程有两种路径,取决于工程里有没有 pom.xml。有 pom.xml 是 Maven 工程,右键 pom.xml → Maven → Reload Project,等依赖下载完再继续;没有 pom.xml 是普通 JavaWeb 工程,需要手动把 WEB-INF/lib 下的 jar 全部识别成依赖。具体做法:项目结构(快捷键 Ctrl+Shift+Alt+S)→ Libraries → 加 lib 目录。这一步漏了,后面满屏红字不是代码坏了,是依赖没进编译环境。
另一个容易忽略的是路径。把 zip 解压到纯英文路径再打开,比如D:\javaweb\homework,中文路径不是说一定跑不了,但课程设计源码问题排查成本本来就高,不值得拿玄学赌。如果你在用 macOS 或 Linux,记得给 Tomcat 的 bin/catalina.sh 加执行权限,不然启动脚本直接 Permission denied;Windows 上则注意把工程从受保护的系统目录拷出来,放到非系统盘再操作。
到这里,环境底座就绪了:JDK8 指定给项目、Tomcat 8.5 解压待用、MySQL 建好库并导入了 SQL。这三件事任何一件没做扎实,后面跑源码都会以各种奇怪姿势失败。接下来进入真正把 zip 变成站点的一步。
3. 把 zip 变成能跑起来的站点:导入工程、改数据库配置、在 IDEA 里启动 Tomcat
3.1 解压后先认目录:src、webapp、WEB-INF 和 sql 文件的约定
这类基于 JavaWeb 的课程设计源码,多数走经典分层:com.xxx.servlet(或 controller)、service、dao、entity、util 五层。页面放在 webapp 或 WebRoot 下,JSP 按角色分文件夹是常见做法,比如 student、teacher 目录各放各的页面,一眼能看出哪部分是学生端、哪部分是教师端。先别急着点开某个 Servlet,把 WEB-INF/web.xml 打开看一眼——这是整个项目的总开关,里面注册了哪些 Servlet、默认首页是哪个、有没有编码过滤器,一眼可见。
Maven 工程和非 Maven 工程的长相完全不同:Maven 工程最上层是 pom.xml,主代码在 src/main/java,页面在 src/main/webapp;传统工程最上层是 src、webapp、README 这一类,没有 pom.xml 依赖就是 WEB-INF/lib 下的 jar。我一般会先确认这一点,因为它决定了后面依赖怎么加载——直接决定 IDEA 会不会满屏红字。
还有一个小习惯值得养成:zip 下载下来先解压,再 File → Open 选目录,不要拿着 zip 文件直接让 IDEA 认。如果解压后 IDEA 识别不出来,检查是不是多了一层嵌套目录,比如解压出的是xxx/xxx/src,把内层目录作为工程根打开即可。
3.2 改 db.properties:连接 MySQL 的四个必改项
数据库连接配置通常集中在一个 properties 文件里,名字常见的有 db.properties、jdbc.properties 或 database.properties,也可能直接在 JDBCUtils.java 里写死。不管放在哪,改的无非是下面四个值:
# db.properties 常见内容,库名和密码按你的实际情况改 jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/homework_db?useSSL=false&useUnicode=true&characterEncoding=UTF-8 jdbc.username=root jdbc.password=你的密码参数说明:homework_db要换成你自己建的库名;username和password换成你本机 MySQL 的账号;driver这一行在 MySQL 5.7 + 老驱动时保持com.mysql.jdbc.Driver不变。如果你只有 MySQL 8,需要改成下面这样:
jdbc.driver=com.mysql.cj.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/homework_db?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=UTF-8&allowPublicKeyRetrieval=true逻辑说明:MySQL 8 的驱动类名变了,新增了时区和公钥检索参数;allowPublicKeyRetrieval=true是连接 MySQL 8 时常见的报错解决方案。另外注意:properties 文件里别写中文注释,Java 读取 properties 默认用的是 ISO-8859-1,中文注释会乱码,有些人顺手在密码后面加了中文备注,密码本身反而被 IDAE 或工具改坏了,这类“明明改对了却连不上”的玄学现场多半就是这么来的。
改完先做一次自验:写一个几行的测试类调用 JDBCUtils.getConnection(),能打印出连接对象就算配置成功。新手最容易在这个地方卡住——IDEA 编译过了,运行时报 ClassNotFoundException,说明驱动 jar 没进 WEB-INF/lib 或 Maven 依赖没加载完,优先补依赖而不是怀疑配置。
3.3 在 IDEA 里启动 Tomcat:两种工程的配置方式
配置 Tomcat 运行目标:IDEA 顶部 Run → Edit Configurations → 左上角加号 → Tomcat Server → Local。如果这个选项灰的,说明 Application Server 里还没指定 Tomcat 主目录,先指向解压后的 apache-tomcat-8.5.x 目录。在 Deployment 标签页把项目加入,Application context 填/,这样启动后的访问路径就是http://localhost:8080/,不会出现带_war_exploded后缀的长路径。
启动时关注日志里的这一行,看到才算成功:
INFO [main] org.apache.catalina.startup.Catalina.start Server startup in [1,234] milliseconds逻辑说明:没看到 startup 成功信息,说明启动中断;Tomcat 的 logs 目录下有 catalina.日期.log 和 localhost.日期.log,异常堆栈在那里,不要盯着 IDEA 控制台前几行就下结论。页面 404 时按两个顺序排查:一是 Application context 是否真的设成了/;二是 form 表单或链接里的访问路径是否带项目名前缀。老代码习惯写/projectName/servletName,如果你把 context 设成/,这个路径就会 404;统一去掉项目名,或者让 context 保持和代码一致,二选一。
到这里站点已经能打开了,能登录、能看页面,下一步才是理解它内部的业务组织方式。源码价值不在能跑,在你能跟完一条完整请求链路,然后改得动它。
4. 作业发布、提交、评分是怎么串起来的:从 JSP 到 Servlet 再到 DAO 的代码链路
4.1 用户与角色:学生、教师、管理员怎么共用一张用户表
作业管理系统最核心的设计决策是用户表:一张表加 role 字段,0 管理员、1 教师、2 学生,而不是拆成三张表。对课程设计这个体量,拆表是过度设计,一张表加权限拦截器完全够用。常见的建表语句长这样:
CREATE TABLE t_user ( id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(50) NOT NULL UNIQUE, password VARCHAR(100) NOT NULL, real_name VARCHAR(50), role TINYINT NOT NULL DEFAULT 2 COMMENT '0管理员 1教师 2学生' ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;逻辑说明:role 字段决定了登录后跳转到哪个页面、能访问哪些接口;password按明文还是 MD5 存取决于源码实现,课程设计一般不会做强密码学,但你在答辩时能说出来这个设计将来可以换 BCrypt,就是一个加分点。登录逻辑是所有 Servlet 里最值得先读的一个:
@WebServlet("/login") public class LoginServlet extends HttpServlet { protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("UTF-8"); String username = req.getParameter("username"); String password = req.getParameter("password"); User user = new UserDao().findByUsernameAndPassword(username, password); if (user == null) { resp.sendRedirect(req.getContextPath() + "/login.jsp?error=1"); return; } req.getSession().setAttribute("user", user); if (user.getRole() == 1) { resp.sendRedirect(req.getContextPath() + "/teacher/homeworkList.jsp"); } else { resp.sendRedirect(req.getContextPath() + "/student/homeworkList.jsp"); } } }逻辑说明:前三行分别是编码、取参数、查数据库;查到用户就把 user 对象塞进 session,之后所有页面都能从 session 拿当前登录人;查不到就回登录页并带一个 error 参数。req.getContextPath()是拿部署路径的规范写法,前面说的 404 问题在这样写时不会出现。角色分流是这段代码的灵魂:教师端和学生端直接分开跳转。
只有登录校验还不够,目录级的权限拦截靠过滤器。@WebFilter("/teacher/*")拦截所有教师端页面,核心逻辑就四行:
User user = (User) request.getSession().getAttribute("user"); if (user == null || user.getRole() != 1) { ((HttpServletResponse) resp).sendRedirect(request.getContextPath() + "/login.jsp"); return; } chain.doFilter(req, resp);逻辑说明:第一个条件拦截未登录的人,第二个条件拦住“学生用 URL 直接访问教师页面”的操作,这是验收时经常被老师试探的点。如果这个 filter 只写了登录判断、漏了角色判断,那你作为学生登录后直接改 URL 就能进教师后台,属于安全漏洞,能答出来怎么补就说明你读懂了。
4.2 一次作业提交的完整请求链路:JSP → Servlet → DAO
学生提交作业整条链路,是这类项目最核心的部分,也是演示时最容易翻车的环节。前端是一个带 enctype 的 form,后端是一个处理文件上传的 Servlet,再往下是 DAO 和一条 INSERT。前端页面的关键代码:
<form action="${pageContext.request.contextPath}/submitHomework" method="post" enctype="multipart/form-data"> <input type="hidden" name="homeworkId" value="${hw.id}"> <input type="file" name="file"> <button type="submit">提交作业</button> </form>逻辑说明:enctype="multipart/form-data"是文件上传必需的三处之一(另外两处是 method 必须是 post、要有 file 输入框)。它带来的副作用是:一旦设置了 multipart,request.getParameter("homeworkId")就永远拿不到值了。这是 JavaWeb 文件上传最常见的坑,很多人折腾半天报空指针,原因就是没走 multipart 解析器。后端 Servlet 的常见写法如下:
// 基于 commons-fileupload 的通用写法 DiskFileItemFactory factory = new DiskFileItemFactory(); ServletFileUpload upload = new ServletFileUpload(factory); upload.setFileSizeMax(10 * 1024 * 1024); // 单个文件最大 10MB List<FileItem> items = upload.parseRequest(request); String homeworkId = null; FileItem uploadFile = null; for (FileItem item : items) { if (item.isFormField()) { if ("homeworkId".equals(item.getFieldName())) { homeworkId = item.getString("UTF-8"); } } else { uploadFile = item; } } // 后续调用 SubmissionDao.insert(homeworkId, studentId, storedName, originalName)参数说明:所有普通表单字段都藏在FileItem列表里,isFormField()区分是文本字段还是文件;getString("UTF-8")是拿文本字段值的规范写法,不传编码容易乱码。setFileSizeMax限制单文件大小,防止有人传个大视频把服务器拖垮。写完这段后,保存成功要使用sendRedirect而不是forward:forward 是服务器内部转页,用户刷新浏览器会重新提交表单,造成作业重复入库;redirect 之后刷新的是新地址,天然避险。这个细节在课程设计答辩中经常被老师追问。
4.3 作业文件上传与重命名:防止同名覆盖和时间戳方案
上传文件最怕两件事:同名覆盖和文件名中文乱码。两个学生都传作业.doc,如果不重命名,后传的人会直接覆盖前一个,数据库里那条记录指向的文件就没了。处理方式一句话:保存时用系统生成的唯一名,原文件名单独存库。核心代码:
String originalName = uploadFile.getName(); // 去掉浏览器可能自动带上的路径 originalName = originalName.substring(originalName.lastIndexOf("\\") + 1); // 落盘用唯一名,展示用原文件名 String ext = originalName.substring(originalName.lastIndexOf(".")); String storedName = System.currentTimeMillis() + "_" + UUID.randomUUID().toString().replace("-", "") + ext; String savePath = getServletContext().getRealPath("/upload") + File.separator + storedName; uploadFile.write(new File(savePath)); // 入库字段:homeworkId, studentId, storedName, originalName参数说明:时间戳保证同一毫秒内不撞;UUID 去掉横线后补一道随机性,多线程并发也不会重;保留ext后缀是为了下载时能打开,很多课程设计栽在“存了文件忘了后缀”。getRealPath("/upload")是传统 JavaWeb 惯用存储位置,把文件放到 webapp/upload 下,但你要知道它的软肋——Tomcat 清理 work 目录或重新部署时 upload 目录有清空风险,答辩时能说出“生产环境应该把 upload.dir 配在 Tomcat 外部”这句话,就已经站在源码作者的认知之上了。
如果要对提交类型做限制,加一个扩展名白名单,只允许 doc、docx、pdf、zip、rar,其它格式直接拒绝。这个校验放前端做会被绕过,放 Servlet 做才是后端该有的态度;课程设计阶段做到后端校验,已经超过大部分同组作品了。
5. 常见翻车点排查:版本、编码、端口、时区与数据库的六个血泪经验
5.1 Tomcat 启动崩溃:先查 web.xml 头与 Servlet 版本匹配
现象:IDEA 点启动后控制台报LifecycleException: Failed to start component [StandardEngine...],或者提示某个类的 NoSuchMethodError。原因基本在两个方向:web.xml 头声明的版本和 Tomcat 版本不匹配,或者项目 lib 里混进了 Tomcat 自带 servlet-api 的老版本 jar。解决办法是打开 WEB-INF/web.xml,把头改成和 Tomcat 8.5 对应的 3.1:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">逻辑说明:这个头配 Tomcat 8.5 最稳;如果项目用的是 @WebServlet 注解且没有 web.xml,通常不存在这个问题。另外排查一遍 lib 目录里有没有 servlet-api.jar 和 jsp-api.jar,这两个 jar 必须删掉,因为 Tomcat 自己带,把它们放进工程就会出现两个实现打架。这是 JavaWeb 项目里出现频率最高的“莫名其妙启动失败”来源,没有之一。
5.2 中文全是问号:请求、响应、数据库连接三处编码要一致
现象:学生在提交框里输入的中文作业名,存进数据库变成??,页面上显示也是乱码。原因不是数据库坏了,是三处编码不一致:请求没按 UTF-8 解码、响应没按 UTF-8 输出、JDBC 连接 URL 没声明 characterEncoding。解决这道题最省事的方式是建一个编码过滤器,让所有请求先过一遍:
@WebFilter("/*") public class EncodingFilter implements Filter { public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { req.setCharacterEncoding("UTF-8"); resp.setCharacterEncoding("UTF-8"); chain.doFilter(req, resp); } }逻辑说明:req.setCharacterEncoding("UTF-8")必须在第一次调用getParameter()之前执行,否则已经按 ISO-8859-1 解析过中文了,后面再设也白搭;用 Filter 就是为了保证这个时序。与此同时,JSP 页头保持pageEncoding="UTF-8",数据库连接 URL 带上characterEncoding=UTF-8,三处对齐,中文问题基本绝迹。还有一个细节:数据库表本身字段的 charset 也检查一下,表建成了 utf8mb4 就没问题,建表时用了 latin1 就只能重建表。
5.3 导入 init.sql 失败:字符集、分隔符和行尾的坑
现象:用SOURCE导入 SQL 文件时,建表到一半报ERROR 1064,或者报ERROR 1366 (HY000): Incorrect string value。原因通常有三个:SQL 文件是 GBK 编码但建库用了 utf8mb4,SQL 文件里有中文注释造成的解析错乱,或者表定义里没有显式指定字符集。解决路径:用文本编辑器打开这个 .sql,另存为 UTF-8 无 BOM 编码;把文件里中文注释删掉或改成英文;建表语句的表尾加一行默认字符集:
CREATE TABLE t_homework ( id INT PRIMARY KEY AUTO_INCREMENT, title VARCHAR(100) NOT NULL, content TEXT, teacher_id INT, deadline DATETIME ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;逻辑说明:最后一行DEFAULT CHARSET=utf8mb4是兜底,MySQL 5.7 的默认字符集可能是 latin1,不声明就按默认建表,中文存不进去。Windows 上还有一个隐藏坑:SQL 文件如果是 UTF-8 带 BOM,部分 MySQL 版本会把 BOM 当作第一个字段的一部分,报错信息根本看不出来,直接无 BOM 保存能消掉。这个排查路径经历过一次,后面导入任何 SQL 都有后悔药可吃。
5.4 驱动类找不到或拒绝连接:mysql-connector-java 版本与驱动类名不匹配
现象:运行时报ClassNotFoundException: com.mysql.jdbc.Driver,或Unable to load authentication plugin 'caching_sha2_password'。前者是驱动 jar 没进 WEB-INF/lib 或 Maven 依赖缺失,后者是驱动版本太老碰上 MySQL 8。解决时先区分环境:MySQL 5.7 用com.mysql.jdbc.Driver,MySQL 8 必须换com.mysql.cj.jdbc.Driver且驱动 jar 升级到 8.0.x。这个报错信息里的两个类名只差一个.cj.,但它们的兼容边界完全不同,改配置时最容易改错位置——改错成com.mysql.cj.jdbc.Driver配老 jar,照样报 ClassNotFoundException。
如果确认驱动 jar 没问题,还报Access denied for user 'root'@'localhost',那八成是密码和账号的问题,别怀疑代码。到这一步时要养成一个习惯:先在命令行用同样的账号密码连一次 MySQL,能连上再回来看代码,把环境问题和代码问题在第一步就分开,能节约大量排查时间。
5.5 端口被占用与热部署失效:8080 不一定是你的
现象:IDEA 启动 Tomcat 报Port 8080 was already in use,或者改了 Java 代码重新部署后页面还是旧效果。前者很好理解,某个早就跑着的进程占了 8080;后者是因为 Tomcat 进程根本没杀掉,IDEA 里的旧实例还活着,你改的代码没被真正加载。解决办法,Windows 命令行敲:
netstat -ano | findstr 8080 taskkill /PID 你的进程号 /F逻辑说明:第一行查出占用 8080 的进程号,第二行强制结束。macOS/Linux 用lsof -i :8080看占用然后kill。如果 8080 是别的系统服务占用的,不想杀它就在 IDEA 的 Run Configuration 里把 HTTP port 改成 8081,Tomcat 配置文件 conf/server.xml 里也能改。至于热部署失效,我一般会养成一个习惯:改完 Java 代码后手动点一下重启按钮,而不是依赖 Tomcat 自动 reload——IDEA 对 JSP 的热部署相对可靠,Java 代码的热部署在传统 Web 工程里经常翻车,多花五秒重启一次,比等到演示现场再发现问题划算得多。
5.6 时区与 SSL 报错:MySQL 8 的 URL 里必须带的两个参数
现象:连接 MySQL 8 时,控制台报The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more than one time zone。这段乱码其实是“中国标准时间”被错误解码之后的显示,核心信息是:MySQL 8 的驱动要求连接时显式指定时区,不指定就报错。解决方式是在连接 URL 里追加参数:
jdbc.url=jdbc:mysql://localhost:3306/homework_db?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=UTF-8&allowPublicKeyRetrieval=true参数说明:serverTimezone=Asia/Shanghai解决时区报错;useSSL=false关闭 SSL 警告;allowPublicKeyRetrieval=true配合 MySQL 8 的 caching_sha2_password 认证,否则可能报 Public Key Retrieval is not allowed。这三个参数是 MySQL 8 连接的默认三件套,缺哪个就报哪个错。顺带说一句,遇到这类报错先复制完整日志再搜,不要只看第一行——第一次见时我以为是中文乱码问题,折腾了半小时才发现是时区参数,血泪经验。
6. 把课程设计改成能交差的作业:三个扩展方向加验收自测
6.1 能让演示效果明显提升的三个扩展方向
代码能跑只是及格,想要在答辩时让老师觉得你确实“做过”,建议在原有功能上挑一个方向加深。我总结过三个性价比最高的扩展方向。第一个是给作业列表加分页:原功能八成是SELECT * FROM t_homework一次性全部查出,你把它改成LIMIT offset, pageSize,前端加页码按钮,这个改动涉及 DAO 和 JSP 两处,量小但能讲清楚 SQL 的 limit 语义。第二个是防重复提交:前端在提交后把按钮置灰禁用,后端在 t_submission 表给 homework_id 和 student_id 加唯一索引,双保险,能应对“连点两次提交出两条记录”这类现场翻车。第三个是成绩分布可视化:老师端新增一个统计页,按分数段分组SELECT score, COUNT(*) FROM t_submission GROUP BY score,前端拼一个简单的条形图或对接 ECharts,演示效果比干巴巴的列表强一个量级。
6.2 验收前照着跑的清单与数据验证
扩展做再多,最终呈现靠的还是主流程稳。我每次演示前会按这张表过一遍,走过一条就算数,不过就提前修:
| 场景 | 操作步骤 | 预期结果 |
|---|---|---|
| 教师登录 | 教师账号登录 → 发布一条新作业 | 学生端能看到这条作业,页面上有标题和截止时间 |
| 学生提交 | 学生账号登录 → 上传一个 doc 文件 | 提交成功,刷新后不重复插入,文件在 upload 目录 |
| 教师评分 | 教师账号登录 → 打开提交列表 → 打分 | 分数持久化,学生端能看到自己的分数和评语 |
| 权限拦截 | 学生账号直接访问 /teacher/homeworkList.jsp | 被过滤器拦回登录页,而不是看到教师内容 |
流程走完后,再用一条 SQL 验证数据确实落库,这个习惯能帮你提前发现“页面显示成功但数据库没写”这类隐蔽问题:
SELECT h.title, s.student_id, s.score, s.submit_time FROM t_submission s JOIN t_homework h ON s.homework_id = h.id;逻辑说明:这条关联查询把作业、提交记录、成绩和提交时间一次带出来,如果查询结果里出现重复记录,说明防重复提交没做全;如果 score 是 NULL,说明评分链路有断层。这个动作一分钟就能完成,却能把前面改代码留下的隐患暴露清楚。我自己的教训是:每次演示都提前十分钟重启一遍 Tomcat、连一次数据库,把主流程从头到尾走完再上台,因为出问题的永远是环境而不是逻辑。环境问题永远比逻辑问题先来,希望帮到你。
本文还有配套的精品资源,点击获取