ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

JavaWeb教研室管理系统:从Servlet到JDBC的课设实战解析

JavaWeb教研室管理系统:从Servlet到JDBC的课设实战解析 简介基于Java webmysql的教研室管理系统是一套完整的Java Web项目实例面向高校学生及Java Web初学者聚焦教师信息管理、课程安排、学生档案等教研室日常事务。项目基于MyEclipseTomcatMySQL环境开发包含源码与数据库脚本读者通过实际部署可深入理解Servlet、JSP等后端技术以及MySQL表结构设计思路。压缩包共2个文件包括1个SQL数据库脚本和1个源码压缩包整体大小10.02MB结构简洁便于直接导入开发环境。目前已有258人学习下载适合系统练习Java Web项目从搭建到部署的完整流程。通过研读源码与tams.sql可掌握教研室管理系统的数据表关系、业务逻辑分层及Tomcat下的调试方法附带gcp文件可能涉及云端部署配置适合希望拓展云环境部署经验的开发者参考。1. 教研室管理系统一个典型的 JavaWeb 课设项目为什么还值得拆开看打开压缩包之前先想清楚你要什么。这个「基于 Java web MySQL 的教研室管理系统源码 数据库」是一个标准的 JavaWeb 课程设计/毕业设计级项目技术栈走的是 JSP Servlet JDBC MySQL 这条最传统也最稳的路线。它解决的问题一句话能说清把教研室的教师信息、教学任务、教研活动、公告通知从 Excel 和纸质台账里搬进数据库并通过浏览器完成增删改查配套登录鉴权。适合谁一方面是刚学完 JavaWeb 基础、需要一个完整项目练手的学生另一方面是准备面试、想快速回顾经典三层架构的初级工程师。这类项目没有微服务、没有分布式但它把 Servlet 生命周期、Filter 过滤、JDBC 封装、表结构设计这些最值钱的基础一次讲透了把这套源码跑通并改造一遍JavaWeb 的主干知识基本就能串起来。2. 数据模型与建表脚本教研室核心表的设计与五个完整性约束2.1 表结构设计先画清楚实体关系再动手建库写代码前先在草稿纸上画一下实体关系。教研室系统最常见的核心实体有五类管理员或系统用户、教师、课程、教研活动、公告通知。它们之间的关系是管理员维护教师账号教师关联课程教师参加教研活动管理员发布公告。用 ER 图表达就是一对多为主——一个教师可以带多门课一个教研活动有多个教师参与参与关系用中间表记录。这个关系理顺了后面写 SQL 和 Java 代码都会通顺很多。我一般会在 MySQL 里用 utf8mb4 字符集建库避免后面中文乱码问题。下面是核心建表脚本的骨架包含用户表、教师表、课程表和教研活动参与表。你在自己的环境里直接执行即可注意先建库再建表并把默认存储引擎设置为 InnoDB——因为后面有外键约束MyISAM 不支持。CREATE DATABASE IF NOT EXISTS teaching_office DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_general_ci; USE teaching_office; CREATE TABLE sys_user ( id INT PRIMARY KEY AUTO_INCREMENT COMMENT 主键, username VARCHAR(50) NOT NULL UNIQUE COMMENT 登录名, password VARCHAR(64) NOT NULL COMMENT 密码(MD5摘要), role VARCHAR(20) NOT NULL DEFAULT teacher COMMENT 角色: admin/teacher, teacher_id INT COMMENT 关联教师ID可为空, create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间 ) ENGINEInnoDB COMMENT系统用户表; CREATE TABLE teacher ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50) NOT NULL COMMENT 姓名, gender CHAR(1) DEFAULT 男, title VARCHAR(30) COMMENT 职称: 助教/讲师/副教授/教授, phone VARCHAR(20), email VARCHAR(100), hired_date DATE COMMENT 入职日期 ) ENGINEInnoDB COMMENT教师基本信息表; CREATE TABLE course ( id INT PRIMARY KEY AUTO_INCREMENT, course_name VARCHAR(100) NOT NULL, course_code VARCHAR(30) NOT NULL UNIQUE, credit DECIMAL(3,1) DEFAULT 2.0 COMMENT 学分, teacher_id INT NOT NULL, semester VARCHAR(30) COMMENT 开课学期如 2025-2026-1, CONSTRAINT fk_course_teacher FOREIGN KEY (teacher_id) REFERENCES teacher(id) ) ENGINEInnoDB COMMENT课程表; CREATE TABLE activity_teacher ( activity_id INT NOT NULL COMMENT 教研活动ID, teacher_id INT NOT NULL COMMENT 教师ID, join_time DATETIME DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (activity_id, teacher_id), CONSTRAINT fk_at_teacher FOREIGN KEY (teacher_id) REFERENCES teacher(id) ) ENGINEInnoDB COMMENT教研活动参与中间表;这段脚本里有几个地方是容易被新手忽略的需要单独说明第一sys_user里的UNIQUE约束能直接挡住重复用户名比在 Java 代码里判断更可靠第二course表里course_code的唯一约束保证同一课程编号不会重复开课第三外键fk_course_teacher写在建表语句后面属于表级约束这样在课程表创建时就能强制保证不会出现“无主教师”的脏数据。如果你在后续导入数据时外键报错先查是不是教师 ID 在 teacher 表里不存在。另一个值得注意的设计是activity_teacher中间表——很多课设项目会在这里偷懒直接在 activity 表里存一个teacher_ids字符串字段比如“1,2,3”这虽然省事但是你要统计某个教师参与活动次数时就只能用 LIKE 去模糊匹配数据一多就卡死而且没法用 JOIN 查询教师姓名。既然目标是让人照着做就按规范来多一张中间表换来的是查询和扩展的从容。系统模块再多表的数量控制在六到八张左右就够了不要为了凑功能无限加表。2.2 初始化数据为什么必须带一个默认管理员账号建完表之后第一件事是插入管理员账号。压缩包里通常会带一个init.sql之类的文件但如果你只有建表语句也可以自己在命令行补上。这里有一个必须考虑的问题密码不能明文存储。课设项目虽然不要求多高的安全等级但老师在验收时看到明文密码印象分会打折扣而且这是写入简历的项目习惯要从一开始养成。常见的做法是存 MD5 摘要登录时对输入密码做同样处理再比对代码层和数据库层都能接受。注意 MD5 现在做安全性校验已经不够了课设阶段够用工作项目中至少要换成 BCrypt。-- 默认管理员: admin / admin123 INSERT INTO sys_user (username, password, role) VALUES (admin, MD5(admin123), admin); -- 插入一位教师示例数据方便前端页面有内容可展示 INSERT INTO teacher (name, gender, title, phone, email, hired_date) VALUES (张建国, 男, 副教授, 13800001111, zhangjgexample.edu.cn, 2015-09-01);初始化的逻辑是先有用户才能登录进系统先有教师数据才能让课程管理页面点开就有内容否则你第一次打开系统看到的全是空表格容易误以为程序跑挂了。这里还可以把sys_user与teacher_id关联起来让教师账号登录后只能看到自己的课表这是权限控制的后话但建表时预留字段位置就说明你想清楚了。2.3 数据库连接配置写死在代码里还是放配置文件数据库连接信息放到db.properties配置文件里而不是硬编码在 Java 类中这是这类项目最值得坚持的底线。原因很现实你源码里写的密码、IP 地址和负责验收的老师本机环境往往不一样如果每次都要打开 Java 文件改代码再重新编译排错成本高得离谱。配置文件则改了立刻生效重启 Tomcat 即可。下面是一个典型配置放在src/db.properties下。jdbc.drivercom.mysql.cj.jdbc.Driver jdbc.urljdbc:mysql://localhost:3306/teaching_office?useUnicodetruecharacterEncodingutf8useSSLfalseserverTimezoneAsia/Shanghai jdbc.usernameroot jdbc.password123456这段配置里最重要的不是那四个键名而是 URL 参数。useUnicodetruecharacterEncodingutf8管中文写入读出的编码一致useSSLfalse是为了避免本地 MySQL 8.x 默认开启 SSL 导致连接时报警告serverTimezoneAsia/Shanghai则是 MySQL 8.x 的硬性要求不加它会直接报The server time zone value错误。很多同学下载源码后连不上数据库八成是卡在时区参数上。版本方面MySQL 5.7 与 8.0 都可以跑驱动依赖注意选对应的版本就好。3. 从 JDBC 到 Servlet登录模块的核心代码与请求流转3.1 封装 JDBC 工具类把连接和关闭的样板代码收拢登录功能看着简单但它能串起整个 JavaWeb 的请求链路浏览器发请求、Servlet 接收、Service 处理、DAO 查数据库、再把结果返回页面。前提是把数据访问这层先理顺。我见过不少课设代码每个 DAO 方法里都写一遍Class.forName、DriverManager.getConnection、conn.close()改了密码要全局替换加一个字段要牵扯五六个文件。所以第一步永远是写一个DBUtil工具类把获取连接和关闭资源的逻辑统一收拢。package com.example.util; import java.io.InputStream; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Properties; public class DBUtil { private static String url; private static String username; private static String password; // 静态代码块: 类加载时执行一次读取配置文件并注册驱动 static { try (InputStream in DBUtil.class.getClassLoader().getResourceAsStream(db.properties)) { Properties props new Properties(); props.load(in); url props.getProperty(jdbc.url); username props.getProperty(jdbc.username); password props.getProperty(jdbc.password); String driver props.getProperty(jdbc.driver); Class.forName(driver); } catch (Exception e) { throw new ExceptionInInitializerError(数据库配置加载失败: e.getMessage()); } } public static Connection getConnection() throws SQLException { return DriverManager.getConnection(url, username, password); } public static void close(Connection conn, Statement st, ResultSet rs) { if (rs ! null) { try { rs.close(); } catch (SQLException ignored) {} } if (st ! null) { try { st.close(); } catch (SQLException ignored) {} } if (conn ! null) { try { conn.close(); } catch (SQLException ignored) {} } } }这个类最关键的三个点是一用getResourceAsStream读取 classpath 下的配置文件这样打包成 war 也能正常加载二Class.forName注册驱动写在静态块里保证只执行一次三close方法把ResultSet、Statement、Connection三个资源的关闭顺序做了标准化处理避免 DAO 层每处都写 try-catch-finally。注意Connection的关闭必须放在最外层否则关闭顺序不对会报ORA-01000之类的连接数超限错误MySQL 也会耗光连接池。参数说明DBUtil.class.getClassLoader().getResourceAsStream(db.properties)是路径的常见约定如果你的配置文件放在src/main/resources下Maven 工程这个写法能直接命中。若用 Eclipse 传统 Web 工程且放在 src 根目录因为构建时会复制到 classes 目录所以同样有效。3.2 DAO 层实现用 PreparedStatement 挡住 SQL 注入登录校验的本质就是一次按用户名查库并比对密码的查询。DAO 层我习惯按实体写一个SysUserDao把登录方法命名为findByUsernameAndPassword。这里要强调一个底线拼 SQL 字符串是课设项目里最常见的翻车现场比如SELECT * FROM sys_user WHERE username name 只要用户在用户名框里输入 or 11你的系统就被直接穿破。对应做法是使用PreparedStatement的占位符参数。public SysUser login(String username, String password) { String sql SELECT id, username, password, role, teacher_id FROM sys_user WHERE username ? AND password ?; try (Connection conn DBUtil.getConnection(); PreparedStatement ps conn.prepareStatement(sql)) { ps.setString(1, username); ps.setString(2, MD5Util.md5(password)); // 对前端传入的密码做摘要后再比对 try (ResultSet rs ps.executeQuery()) { if (rs.next()) { return new SysUser(rs.getInt(id), rs.getString(username), rs.getString(password), rs.getString(role), rs.getObject(teacher_id) ! null ? rs.getInt(teacher_id) : null); } } } catch (SQLException e) { e.printStackTrace(); } return null; }这段代码的写法有几个细节值得解释try-with-resources是 Java 7 引入的语法它保证PreparedStatement和Connection在 try 块结束后自动关闭比手写 finally 少出遗漏?占位符由PreparedStatement做转义处理用户的输入再刁钻也只能作为字符串值传递而不是 SQL 结构的一部分密码传入前先经过MD5Util.md5方法做一次摘要与建表时插入的密文格式对应。rs.getObject(teacher_id)返回Object是因为该字段可空直接getInt会得到 0无法区分“没关联教师”和“关联了 ID 为 0 的教师”。这里还能做一个优化就是只传 username 查询、在 Java 里比对密码——虽然多了几步但好处是用户不存在和密码错误可以返回不同提示而且不会把密码摘要带进 SQL。对课设而言一条 SQL 完成校验也完全够用按自己的项目管理习惯选就好。3.3 Servlet 控制层登录成功后 session 和重定向怎么配合Servlet 是 MVC 里的控制器它从请求中取参数、调用 DAO、再决定页面跳转方向。写 Servlet 的一个老问题是注解路径和 web.xml 二选一现在的主流做法是直接使用WebServlet注解省去 XML 配置的繁琐。下面是登录接口的典型写法注意这里刻意把业务判空和页面跳转分离让代码读起来像说话。package com.example.web; import com.example.dao.SysUserDao; import com.example.entity.SysUser; import com.example.util.MD5Util; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; WebServlet(/login) public class LoginServlet extends HttpServlet { private SysUserDao userDao new SysUserDao(); Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding(UTF-8); String username request.getParameter(username); String password request.getParameter(password); if (username null || password null || username.trim().isEmpty()) { request.setAttribute(errorMsg, 用户名和密码不能为空); request.getRequestDispatcher(/login.jsp).forward(request, response); return; } SysUser user userDao.login(username, password); if (user ! null) { HttpSession session request.getSession(); session.setAttribute(loginUser, user); session.setMaxInactiveInterval(30 * 60); // 30分钟不操作则失效 response.sendRedirect(request.getContextPath() /index.jsp); } else { request.setAttribute(errorMsg, 用户名或密码错误请重新输入); request.getRequestDispatcher(/login.jsp).forward(request, response); } } }request.setCharacterEncoding(UTF-8)这行放在 doPost 第一行是必须的否则 POST 提交的中文参数会乱码。登录失败用forward而不是sendRedirect是为了把errorMsg带到页面展示浏览器地址栏保持/login不变刷新会重新提交表单——这是课设里最常见的表现争议点登录成功用sendRedirect是为了防止刷新页面时重复提交登录请求。request.getContextPath()是访问路径的前缀如果你的应用名是teaching_office那么最终跳转地址是/teaching_office/index.jsp用这个 API 就不用在前端写死上下文路径。session 里存放loginUser之后其他页面就能通过session.getAttribute(loginUser)判断是否登录以及通过role字段区分管理员和普通教师。还有一点容易漏掉POST 请求才需要setCharacterEncodingGET 请求的编码在 Tomcat 的server.xml里配置URIEncodingUTF-8解决。如果你只写了 POST 的编码然后网页却用 GET 传参中文大概率乱码。3.4 登录页与后台首页表单提交细节与当前用户展示前端的登录页在整个项目里虽然只承担一个入口职责但仍有两个容易踩的坑一是表单的action写绝对路径导致部署后改不了应用名二是密码框的name属性与 Servlet 里getParameter的字段不一致。我见过因为把namepassword写成了namepwdServlet 拿到 null怎么调都报空指针的案例。下面是一个可用的login.jsp关键片段。% page contentTypetext/html;charsetUTF-8 languagejava % html head title教研室管理系统 - 登录/title /head body form action${pageContext.request.contextPath}/login methodpost label用户名: input typetext nameusername required/label label密 码: input typepassword namepassword required/label button typesubmit登 录/button span stylecolor:red${errorMsg}/span /form /body /html${pageContext.request.contextPath}是 JSP EL 表达式它等价于request.getContextPath()在 HTML 里直接输出应用上下文路径。这样做的好处是应用即使改名为别的 war 包名登录表单依然能正确指向/改名/login。required属性是 HTML5 自带的前端校验能挡掉空提交减少 Servlet 里的空值判断压力但依然不能替代后端校验——因为绕过浏览器发请求太容易了。登录成功后的首页通常放一句“欢迎你[[name]]”对应的 EL 表达式是${sessionScope.loginUser.username}即使不写% page isELIgnoredfalse %在 Servlet 3.0 的容器里默认也是开启的。需要提醒的是检查用户是否已登录的代码应该放在所有需要权限的页面里最规范的做法是写一个LoginFilter在web.xml里拦截所有.jsp和/admin/*路径而不是在每一个 Servlet 里复制粘贴三段重复的 session 判断。4. 跑通整套源码从压缩包到浏览器打开系统的完整部署路径4.1 环境准备JDK、Tomcat、MySQL 的版本搭配和安装重点这类源码压缩包默认的运行环境是 JDK 8 Tomcat 8.5/9 MySQL 5.7/8.0这是 JavaWeb 课设项目最经典的组合。如果你的机器上装的是 JDK 17 或更高版本得注意 Tomcat 版本必须选 9 或 10 以上旧 Tomcat 在编译 JSP 时对 JDK 新版本的支持有限。MySQL 的安装教程网上很多这里只说几个关键点安装时选Server only模式端口保持默认的 3306认证方式在 8.0 下建议选Use Legacy Authentication兼容旧的 mysql-connector-java 驱动账号设置完先别急着关直接勾选配置环境变量方便后面用命令行导 SQL。Tomcat 下载 ZIP 包后解压即可用不需要安装程序。环境变量方面需要新增一个CATALINA_HOME指向 Tomcat 的根目录再把%CATALINA_HOME%\bin加入 PATH。JDK 装好后在命令行敲java -version能输出版本号即可。这三个环境变量看起来基础但部署失败有相当一部分原因就是JAVA_HOME没配对启动脚本找不到 Java 运行环境。版本搭配的建议是如果系统是 64 位 Windows尽量用 JDK 8 Tomcat 8.5 MySQL 5.7或 MySQL 8.0。这套组合的兼容性最广网上能搜到的同类源码几乎都可以直接跑。想把这个系统挪到 Linux 服务器上的时候注意 MySQL 的用户权限配置方式不同root默认只能 localhost 登录远程访问需要单独授权这是部署上最常见的拦路虎。4.2 导入项目Eclipse/IDEA 中避免源码文件丢失的导入方式拿到压缩包后先解压到没有中文和空格的路径比如D:\workspace\teaching_office这是很多踩坑的开端。路径带中文时Tomcat 的编译目录和 Maven 的本地仓库会偶发无法创建临时文件的错误。如果你的压缩包解压后是一个 Eclipse 工程目录带有.classpath和.project文件那么在 IDEA 里直接用Open打开该目录即可被识别为 JavaWeb 工程如果在 IDEA 里选了New → Project from Existing Sources并且一路 Next反而容易丢失 Web 资源目录的标记。导入后在 IDEA 里需要检查三处Project Structure 里的 SDK 是否为 JDK 8Artifacts 的 Output Layout 里是否有lib目录下的 MySQL 驱动 jarFacets 里是否已添加 Web 并指定了webapp目录。Eclipse 用户相对简单直接File → Import → Existing Projects into Workspace但要注意不要勾选Copy projects into workspace否则文件位置变化容易造成路径混乱。这两个 IDE 的导入逻辑不同但核心目标一致——让工程保持它原本的目录结构不要自动迁移。如果源码包里还带了.sql文件和 README先把它们单独放好。数据库脚本文件不要用记事本打开并另存为因为会把 utf8 编码破坏掉在命令行导入的时候指定编码导入才是最稳妥的。4.3 导入数据库命令行导入 SQL 的正确姿势与常见报错准备好数据库环境后打开命令行窗口登录 MySQL再使用 source 命令导入源码包里的 SQL 文件。下面这组命令是标准操作注意顺序先登录再建库如果 SQL 里没有建库语句最后导入。mysql -u root -p # 输入密码后进入 mysql 提示符 mysql CREATE DATABASE IF NOT EXISTS teaching_office DEFAULT CHARSET utf8mb4; mysql USE teaching_office; mysql SET NAMES utf8mb4; mysql SOURCE D:/workspace/teaching_office/sql/teaching_office.sql; mysql SHOW TABLES; mysql EXIT;SET NAMES utf8mb4的作用是告诉 MySQL 客户端本次会话的传输字符集如果你不管三七二十一直接 source而 SQL 文件里含有中文注释和数据导入后查询出来的数据可能是乱码这个命令可以避免大多数此类问题。SOURCE是 MySQL 自带命令它逐条执行文件中的 SQL 语句报错时会打印具体行号和原因方便定位是语法问题还是表已经存在的冲突。导入完成后用SHOW TABLES确认表的数量再用SELECT * FROM sys_user验证管理员账号是否存在。如果报ERROR 1046 (3D000): No database selected说明 SQL 文件里没有USE语句你自己手动指定一下即可。如果你更习惯用图形化工具Navicat 或 DBeaver 都支持直接运行 SQL 文件。但要注意Navicat 导入时如果文件里有CREATE DATABASE语句可能会因为字符集设置与你使用的连接不一致而产生警告这时候直接忽略即可因为表数据本身不会受影响。还有一点如果 SQL 文件是从别人那里拿来的很可能包含DROP TABLE IF EXISTS语句所以不要在已经有数据的库上瞎试确认没问题再导到正式环境。4.4 部署到 TomcatIDEA 与 Eclipse 下的启动参数和访问路径部署方式取决于你用的 IDE。IDEA 的做法是打开Run → Edit Configurations点击左上角号选择Tomcat Server → Local在Deployment标签页点击选择Artifact选出带war exploded后缀的那个然后Application context填/teaching_office。这里的上下文就是 URL 访问的根路径填错了会导致项目能启动但页面 404。Eclipse 的方式类似在Servers视图里右键Add and Remove把项目加入 Tomcat 即可Application context 在项目属性里设置。启动前再回头检查db.properties里的用户名密码是否与本地 MySQL 一致这是部署时最常被遗漏的一步——很多人项目里默认写的是root/123456而自己 MySQL 的密码是admin888于是 Tomcat 启动后点击登录直接报数据库连接失败的白屏。把配置改好后启动 Tomcat控制台输出INFO: Server startup in 8000 ms即表示成功。然后在浏览器输入http://localhost:8080/teaching_office/login.jsp用初始化脚本里的管理员账号登录。如果看到的是目录列表而不是登录页说明 Tomcat 没有把项目上下文默认页设为login.jsp检查web.xml里的welcome-file配置。4.5 常见启动失败信号从 Tomcat 日志定位三类典型报错第一次启动很容易出问题但不用慌Tomcat 控制台的日志信息足够帮你定位。通常有三类高频报错一是数据库驱动找不到报ClassNotFoundException: com.mysql.cj.jdbc.Driver原因是 MySQL 驱动 jar 没放进WEB-INF/lib目录直接在 IDEA 里加依赖是不够的部署时不会自动带进去二是数据库连接失败报Access denied for user rootlocalhost核对 db.properties 里的用户名密码三是端口被占用报Port 8080 was already in use要么改 Tomcat 的server.xml端口要么结束占用进程。看到长长的堆栈先别着急从最上面一行找原因通常第三到第五行就是真正的错误摘要。这三个问题按排除法处理90% 的启动失败都能解决。剩下 10% 是 JSP 编译错误报错信息里会直接指出xxx.jsp第几行有问题对照源码检查标签是否闭合即可。注意localhost:8080能打开 Tomcat 默认首页并不代表你的项目部署成功必须访问到项目上下文路径才会触发应用代码的加载。5. 运行期避坑五个高频问题与排查顺序5.1 页面 404项目能启动但访问路径不对现象Tomcat 正常启动但输入http://localhost:8080/能看到默认猫头鹰页访问/teaching_office却 404。 原因应用上下文路径与实际部署名不匹配或者没有把项目添加到 Tomcat 的部署清单中。 解决在 IDEA 的 Deployment 标签页核对 Application context 是否设置为/teaching_office如果是 Eclipse检查Servers视图里项目是否处于Configured一列。URL 路径大小写以及 Web 目录下是否真的存在login.jsp也要一并确认。浏览器访问时用http://localhost:8080/teaching_office/login.jsp而不是记错成http://localhost:8080/login.jsp——这是最常见的 404 来源。5.2 点击登录直接空白/500MySQL 服务与账号不匹配现象Tomcat 日志刷出Communications link failure或Access denied页面显示 500 错误。 原因一是 MySQL 服务根本没启动Windows 服务管理器里MySQL状态为已停止二是 db.properties 里的密码与本地 MySQL root 密码不一致三是 MySQL 8.0 的默认认证插件是caching_sha2_password而驱动版本太老5.1.x无法完成认证。 解决先确认net start mysql能点亮服务再核对配置文件的jdbc.password字段如果是驱动太老的问题访问 MySQL 官网下载mysql-connector-java 8.0.x替换进WEB-INF/lib如果项目的代码里用了旧版驱动的类名com.mysql.jdbc.Driver在 8.x 中要改成com.mysql.cj.jdbc.Driver。最后用命令行mysql -u root -p验证同一套账号密码能登录排除数据库本身的问题。5.3 中文数据显示为问号三层编码不统一现象从页面录入一条中文通知数据库里存的是????或者从数据库读出来显示为乱码。 原因数据库连接 URL 的characterEncoding参数、JSP 页面的pageEncoding、MySQL 表字符集三者不一致。比如 JSP 用GBK写入MySQL 表是utf8mb4写入时失败或编码错乱。 解决统一改为 UTF-8。MySQL 连接 URL 加上useUnicodetruecharacterEncodingutf8JSP 顶部设置contentTypetext/html;charsetUTF-8和pageEncodingUTF-8已有表执行ALTER TABLE xxx CONVERT TO CHARACTER SET utf8mb4;转换编码。写操作入口的 Servlet 也要有request.setCharacterEncoding(UTF-8)三层都统一后乱码问题基本绝迹。数据已被污染的表需要清理后重新插入。5.4 登录成功后点击退出又跳回登录页session 失效规则没理顺现象登录后在首页停留一会儿再点页面里的功能按钮直接被弹回登录页。 原因session 默认过期时间太短或者session.setMaxInactiveInterval设置成很小的值比如 5 分钟也可能是浏览器禁用了 Cookie 导致 JSESSIONID 无法保存。 解决在登录 Servlet 里把过期时间设为 30 分钟或更长确认代码里没有在 header 中手动清除 Cookie如果功能页面是前端 iframe 嵌套注意某些浏览器对第三方 Cookie 的默认阻止策略会导致 session 丢失这时候需要用 URL 重写方式传递 session id即response.encodeURL()生成链接。课设项目里最常见的是没有设置过期时间使用容器默认的 30 分钟看着正常但给演示时讲太久就突然失效演示前记得刷新操作。5.5 数据库数据改错/删错有什么后悔药现象手动执行 SQL 把某条教师记录误删系统页面里数据没了又没做备份。 原因没有养成在操作数据前备份的习惯命令行里执行 UPDATE/DELETE 没有自动事务保护。 解决MySQL 命令行中先执行START TRANSACTION;再执行修改语句检查SELECT结果无误后COMMIT;发现不对立刻ROLLBACK;。这习惯比任何工具都好用尤其是课设验收前一天半夜改数据时事务是唯一的后悔药。日常开发则建议导出teaching_office.sql备份文件保存到压缩包外避免源码包重新解压把数据库覆盖回去。这五个问题的排查顺序可以固定下来先看 Tomcat 日志的第一行异常类型再确认配置文件的数据库连接参数接着检查编码三件套最后看 session 与 Cookie 是否被浏览器拦截。按这个顺序来九成运行期问题都能在一刻钟内定位。还有一点提醒不要把 Tomcat 控制台打印出的堆栈信息整段贴到搜索引擎去搜——先找到以Caused by开头的那一行那才是根因。6. 从课设到可用系统一个改造技巧与验证清单源码跑通只是第一步真正拉开差距的是你做了哪些针对性的改造。这里给你一个值得优先投入的方向把 JDBC 连池换成数据库连接池Druid 或 HikariCP。虽然课设项目的数据量不大但连接池会让代码的健壮性上一个台阶面试被问到“高并发下连接管理怎么做”时也有话可讲。改造步骤不复杂引入 druid jar 包写一个DruidDataSourceFactory初始化数据源把DBUtil.getConnection()的DriverManager.getConnection替换成dataSource.getConnection()。配置文件里多配几条initialSize5、maxActive20这样的参数代码结构不变但连接复用和释放行为完全不同。这项工作在原有代码上花半小时就能完成却是项目从“能跑”走向“像样”的分水岭。验证方面建议按一份简单清单走一遍用管理员账号登录、新增一名教师、分配一门课程、发布一条公告、退出登录、再用教师账号登录并确认看不到管理菜单。这六个动作覆盖了权限控制、增删改查和 session 生命周期任何一步走不通就直接定位到对应模块。如果压缩包里没有单元测试也不必强求但至少手动把主流程串一遍并截图留档对后续写报告或准备答辩都有用。我之前带过一个学生他拿到一套类似的源码花了一晚上把全部功能页面点击一遍发现“删除教师”按钮点到之后课程表里的外键直接报错因为没做删除前约束检查——这就是手动验证的价值。最后分享一个个人习惯拿到任何一个源码压缩包第一步不是打开 IDE而是先把压缩包复制一份留底再到干净目录里解压并按 README 或建库脚本重建数据库。曾经因为手滑执行了带DROP TABLE的脚本把一个本地攒了两个月数据的库清空从那以后备份永远放在第一优先级。希望帮到你。本文还有配套的精品资源点击获取
返回列表