简介:这是一套面向高校计算机相关专业学生的JavaWeb学生宿舍管理系统完整源码与配套使用教程,采用Servlet+JSP+MySQL技术栈开发,适合作为期末大作业、毕业设计或课程设计参考方案,难度适中,对刚接触JavaWeb开发的学习者较为友好。资源包共202个文件,压缩后约7.21MB,其中包含21个Java源文件、22个JSP页面、73个JavaScript脚本、16个CSS样式表以及7个jar依赖包,另附SQL建库脚本、yml配置文件与说明文档,前端还整合了Bootstrap与jQuery DataTables等常用组件,便于理解分层结构与页面交互逻辑。目前已有248人学习下载。整套代码经过本地编译验证可正常运行,评审分达到98分,并配有使用教程,读者可据此快速掌握宿舍信息管理、学生入住登记等模块的实现思路,理清Servlet控制层、JSP视图层与MySQL数据层的协作方式,为后续独立开发同类项目提供可复用的参考模板。
1. 从零跑通学生宿舍管理系统:Servlet+jsp+mysql 这套老组合为什么还值得动手
如果你手头正好有一套「基于 Servlet+jsp+mysql 开发 javaWeb 学生宿舍管理系统」的源码,却卡在环境跑不起来、数据库连不上、页面 404 上,那这篇就是写给你的。这套技术栈看着老,但它是理解 JavaWeb 请求流转最直白的路径:浏览器发请求,Servlet 接住,调 MySQL 拿数据,再把结果交给 JSP 渲染成页面。学生宿舍管理系统这个场景又足够具体——楼栋、宿舍、学生、入住、报修、退宿,每张表都能对应一个真实业务动作,不像那些纯演示的增删改查那样悬空。适合两类人:一是课程设计或毕设需要一套能讲清楚、能改得动的完整案例;二是想补 JavaWeb 基础、把 Servlet 生命周期和 JSP 作用域真正跑一遍的开发者。下面按「环境怎么搭 → 数据库怎么建 → 后端怎么写 → 前端怎么接 → 坑在哪」的顺序拆开讲,每一步都给可复现的命令和参数。
2. 环境搭建:IDEA 运行 javaweb 项目配置与 Tomcat 版本对齐
2.1 为什么这套组合对 JDK 和 Tomcat 版本特别敏感
Servlet 和 JSP 的 API 是绑在 Tomcat 版本上的。javax.servlet 包名在 Tomcat 9 及以前是主流,Tomcat 10 之后换成了 jakarta.servlet,源码里如果写的是import javax.servlet.*,放到 Tomcat 10 上直接编译不过。学生宿舍管理系统这类老案例,绝大多数是按 Tomcat 8 或 9 写的,所以第一件事不是急着导入项目,而是先确认 JDK 和 Tomcat 的搭配。JDK 建议 8 或 11,JDK 17 配 Tomcat 9 也能跑,但部分老 jar 会有反射警告。我一般会先看项目里WEB-INF/lib下的 servlet-api 版本,或者看web.xml的version属性,4.0对应 Tomcat 9,3.1对应 Tomcat 8。
2.2 IDEA 导入项目并配置 Artifact 的完整步骤
导入后最容易翻车的地方是 Artifact 没配,导致 Tomcat 启动后访问 404。按下面步骤走:
# 1. 确认 JDK java -version # 期望输出 1.8.x 或 11.x # 2. 确认 Tomcat 版本(解压目录下) cat apache-tomcat-9.0.x/RELEASE-NOTES | head -5在 IDEA 里依次操作:File → Project Structure → Modules,把src标记为 Sources;Facets 里添加 Web,指向web目录和web.xml;Artifacts 里新增 Web Application: Exploded,Output Layout 里把WEB-INF/lib的依赖全部加进去。然后在 Run → Edit Configurations 里新增 Tomcat Server → Local,Deployment 选项卡选刚才的 Artifact,Application context 设成/dorm。
<!-- web.xml 里这段决定欢迎页,路径写错就是 404 --> <welcome-file-list> <welcome-file>login.jsp</welcome-file> </welcome-file-list>逻辑说明:Artifact 的 Exploded 模式会把编译后的 class 和 jsp 按目录结构展开到 Tomcat 的 webapps 下,改 JSP 不用重启。参数说明:Application context 就是访问前缀,设成/dorm后地址是http://localhost:8080/dorm/login.jsp;如果设成/,直接http://localhost:8080/login.jsp。这一步配错,后面所有页面都进不去。
2.3 依赖 jar 的放置位置与常见缺失
WEB-INF/lib下通常需要 mysql-connector-java、jstl、standard 这几个。mysql 驱动版本要和 MySQL 服务端匹配,MySQL 8.0 用mysql-connector-java-8.0.x,5.7 用5.1.x也能连。jstl 缺失会导致 JSP 里<c:forEach>标签直接报错。检查方法:启动 Tomcat 后看日志有没有ClassNotFoundException,有就是 jar 没进 Artifact。
3. 数据库落地:mysql 安装配置教程与学生宿舍表结构设计
3.1 MySQL 安装后必须确认的三件事
不管你是用安装包还是压缩包,装完先确认服务在跑、端口对、字符集对。Windows 下net start mysql如果报「服务无法启动」,八成是 data 目录初始化有问题或者 my.ini 路径写错。Linux 下用 rpm 或 tar 包安装后,要手动systemctl start mysqld。
-- 登录后先看版本和字符集 SELECT VERSION(); SHOW VARIABLES LIKE 'character_set%';字符集必须是utf8mb4,否则学生姓名里的生僻字、报修备注里的特殊符号会变问号。MySQL 8.0 默认就是 utf8mb4,5.7 需要手动在 my.cnf 里改。改完重启服务再验证。
3.2 学生宿舍管理系统的核心表与建表语句
这套系统的表不用多,五张就够撑起完整业务:学生表、宿舍楼表、宿舍房间表、入住记录表、报修表。下面给可直接执行的建表语句:
CREATE DATABASE dorm_db DEFAULT CHARACTER SET utf8mb4; USE dorm_db; CREATE TABLE student ( id INT PRIMARY KEY AUTO_INCREMENT, sno VARCHAR(20) NOT NULL UNIQUE COMMENT '学号', sname VARCHAR(50) NOT NULL COMMENT '姓名', gender TINYINT DEFAULT 1 COMMENT '1男2女', phone VARCHAR(20), room_id INT COMMENT '当前宿舍' ) ENGINE=InnoDB; CREATE TABLE building ( id INT PRIMARY KEY AUTO_INCREMENT, bname VARCHAR(50) NOT NULL, floors INT DEFAULT 6 ) ENGINE=InnoDB; CREATE TABLE room ( id INT PRIMARY KEY AUTO_INCREMENT, building_id INT NOT NULL, rno VARCHAR(10) NOT NULL, capacity INT DEFAULT 4, occupied INT DEFAULT 0, FOREIGN KEY (building_id) REFERENCES building(id) ) ENGINE=InnoDB; CREATE TABLE checkin ( id INT PRIMARY KEY AUTO_INCREMENT, student_id INT NOT NULL, room_id INT NOT NULL, in_date DATE, out_date DATE, status TINYINT DEFAULT 1 COMMENT '1在住0已退' ) ENGINE=InnoDB; CREATE TABLE repair ( id INT PRIMARY KEY AUTO_INCREMENT, room_id INT NOT NULL, content VARCHAR(255), create_time DATETIME DEFAULT CURRENT_TIMESTAMP, status TINYINT DEFAULT 0 COMMENT '0待处理1已处理' ) ENGINE=InnoDB;逻辑说明:room表用occupied字段冗余记录已住人数,避免每次查入住记录去 count,这是宿舍管理里最常用的优化。参数说明:capacity默认 4 是标准四人间,改成 6 就是六人间;status用 tinyint 而不是 varchar,查询和索引都更快。外键约束保证不会出现孤儿记录,但如果你导入的测试数据顺序不对,插入会失败,可以先SET FOREIGN_KEY_CHECKS=0再导。
3.3 连接配置与 mysql ssl 连接错误处理
JDBC 连接串写在工具类里,MySQL 8.0 必须显式关掉 SSL 或者配好证书,否则报javax.net.ssl.SSLException。
// DBUtil.java 核心片段 private static final String URL = "jdbc:mysql://localhost:3306/dorm_db?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf8mb4"; private static final String USER = "root"; private static final String PWD = "你的密码"; public static Connection getConn() throws SQLException { return DriverManager.getConnection(URL, USER, PWD); }逻辑说明:useSSL=false是本地开发最省事的做法,生产环境应该配证书而不是关掉。serverTimezone不写会报时区错误,MySQL 8.0 的驱动对时区校验很严。参数说明:characterEncoding=utf8mb4要和建库时一致,否则中文乱码。如果连的是远程库,把 localhost 换成 IP,同时确认防火墙放行 3306。
4. 后端实现:Servlet 处理请求与 JSP 个人信息展示页面
4.1 Servlet 的请求流转与三层结构划分
一个宿舍管理系统的后端,按 Servlet + Service + DAO 三层分最清晰。Servlet 只负责收参数、调 Service、转发或重定向;Service 做业务判断,比如「房间满了不能再入住」;DAO 只做 SQL。这样改需求时不会牵一发动全身。Servlet 的生命周期是 init → service → destroy,doGet和doPost分别处理两种请求,登录用 POST,列表查询用 GET。
@WebServlet("/student") public class StudentServlet extends HttpServlet { private StudentService service = new StudentService(); @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String action = req.getParameter("action"); if ("list".equals(action)) { List<Student> list = service.findAll(); req.setAttribute("students", list); req.getRequestDispatcher("/student_list.jsp").forward(req, resp); } } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("UTF-8"); String sno = req.getParameter("sno"); String sname = req.getParameter("sname"); service.add(new Student(sno, sname)); resp.sendRedirect("student?action=list"); } }逻辑说明:@WebServlet注解替代了 web.xml 里的 servlet 配置,Tomcat 7 以上都支持。forward是服务器内部跳转,URL 不变,能带 request 作用域数据;sendRedirect是让浏览器重新发请求,URL 会变,适合增删改之后防重复提交。参数说明:req.setCharacterEncoding("UTF-8")必须在取参数之前调用,否则 POST 中文乱码;GET 中文乱码要在 Tomcat 的 server.xml 里给 Connector 加URIEncoding="UTF-8"。
4.2 JSP 个人信息展示页面与作用域数据绑定
JSP 里取 Servlet 放进去的数据,用 EL 表达式最干净。个人信息展示页面通常从 session 里拿登录用户,再查详细字段。
<%@ page contentType="text/html;charset=UTF-8" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <body> <h3>个人信息</h3> <table border="1"> <tr><td>学号</td><td>${sessionScope.user.sno}</td></tr> <tr><td>姓名</td><td>${sessionScope.user.sname}</td></tr> <tr><td>宿舍</td><td>${sessionScope.user.roomNo}</td></tr> </table> <h3>我的报修</h3> <c:forEach items="${repairs}" var="r"> <p>${r.content} - ${r.status == 0 ? '待处理' : '已处理'}</p> </c:forEach> </body> </html>逻辑说明:${sessionScope.user.sno}等价于session.getAttribute("user").getSno(),EL 会自动调 getter。c:forEach遍历 request 作用域里的 repairs 列表。参数说明:session 作用域跨请求有效,适合存登录态;request 作用域只在一次转发内有效,适合存列表数据。两者混用是新手最常见的错误,把列表放 session 会导致数据串号。
4.3 用 Filter 统一处理编码与登录拦截
每个 Servlet 都写一遍编码设置太啰嗦,用 Filter 统一处理。
@WebFilter("/*") public class EncodingFilter implements Filter { public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { req.setCharacterEncoding("UTF-8"); resp.setContentType("text/html;charset=UTF-8"); HttpServletRequest request = (HttpServletRequest) req; String uri = request.getRequestURI(); // 登录页和登录接口放行 if (uri.endsWith("login.jsp") || uri.contains("/login")) { chain.doFilter(req, resp); return; } if (request.getSession().getAttribute("user") == null) { resp.getWriter().write("<script>alert('请先登录');location.href='login.jsp'</script>"); return; } chain.doFilter(req, resp); } }逻辑说明:Filter 在 Servlet 之前执行,chain.doFilter是放行到下一个过滤器或目标资源。参数说明:@WebFilter("/*")拦截所有路径,放行规则按 URI 后缀判断。注意登录接口的路径要写对,否则会死循环重定向到登录页。
5. 避坑排查:这套学生宿舍管理系统最容易翻车的五个地方
5.1 现象:Tomcat 启动报 ClassNotFoundException: com.mysql.jdbc.Driver
原因:驱动 jar 没放进WEB-INF/lib,或者只加到了 IDEA 的 Libraries 但没进 Artifact。解决:Project Structure → Artifacts → Output Layout,把 mysql-connector 的 jar 显式加进去,重新部署。MySQL 8.0 的驱动类名是com.mysql.cj.jdbc.Driver,老代码写com.mysql.jdbc.Driver会警告但不影响,建议改新类名。
5.2 现象:页面中文全是问号
原因:三个环节任一字符集不对——数据库、连接串、JSP 页面。解决:按顺序查,SHOW VARIABLES LIKE 'character_set_database'确认库是 utf8mb4;连接串加characterEncoding=utf8mb4;JSP 顶部pageEncoding="UTF-8"。三处都对了才不会乱码。
5.3 现象:JSP 里 c:forEach 标签原样输出不解析
原因:jstl 和 standard 两个 jar 缺失,或者 taglib 的 uri 写错。解决:确认WEB-INF/lib下有jstl.jar和standard.jar,uri 用http://java.sun.com/jsp/jstl/core。Tomcat 10 环境下这套 uri 会失效,需要换 jakarta 版本的 jstl。
5.4 现象:mysql 服务无法启动,net start mysql 报错
原因:data 目录被误删、my.ini 里 basedir 路径含中文或空格、3306 端口被占用。解决:先看错误日志data/主机名.err,端口占用用netstat -ano | findstr 3306查,路径问题就把 MySQL 装到纯英文无空格目录。初始化失败可以删掉 data 目录重新mysqld --initialize。
5.5 现象:修改 JSP 后刷新页面没变化
原因:IDEA 的 Artifact 是 Exploded 模式但没开自动更新,或者浏览器缓存。解决:Run Configuration 里 On 'Update' action 选 Update classes and resources,浏览器用 Ctrl+F5 强刷。如果还不行,看 Tomcat 的 work 目录下有没有旧的编译产物,清掉重启。
6. 进阶技巧:用 JSP 页面加载完后刷新一次做数据同步
有个实际场景:宿舍报修状态在后台被管理员改了,学生端页面还显示旧状态。除了轮询接口,最简单的做法是让 JSP 页面加载完后自动刷新一次,把最新数据拉回来。用setTimeout配合location.reload就能实现,但要注意别写成死循环。
// 放在 JSP 底部,页面加载完 3 秒后刷新一次 window.onload = function () { if (!sessionStorage.getItem('refreshed')) { sessionStorage.setItem('refreshed', '1'); setTimeout(function () { location.reload(); }, 3000); } };逻辑说明:sessionStorage标记本次会话是否已经刷新过,避免无限刷新。参数说明:3000 是毫秒,按需改成 5000 或 10000。这个技巧适合数据变化不频繁、又不想上 WebSocket 的场景。如果要做真正的实时,还是得用轮询或长连接。
另一个值得掌握的技巧是 JSP 图片坐标定位。宿舍楼平面图里标注房间位置时,用绝对定位把图片当背景,房间热区用position:absolute加left/top百分比,这样换分辨率也不会错位。
.floor-map { position: relative; width: 800px; } .floor-map img { width: 100%; } .room-hotspot { position: absolute; width: 8%; height: 10%; border: 1px solid #f00; }逻辑说明:百分比定位相对父容器,父容器宽度随图片缩放,热区跟着走。参数说明:width/height按房间在图上占的比例算,left/top同理。这套做法比固定像素稳,适配不同屏幕时不用改代码。
我自己踩过的最大一个坑,是早期把数据库连接写在每个 Servlet 里,改一次密码要翻十几个文件。后来统一抽成 DBUtil 加连接池,才算把后悔药吃上。做这类老技术栈的项目,别嫌分层麻烦,层分对了,后面加功能才不痛苦。希望帮到你。
本文还有配套的精品资源,点击获取