拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

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

Java+JSP+MySQL宿舍管理系统实战搭建与避坑指南

Java+JSP+MySQL宿舍管理系统实战搭建与避坑指南 简介本资源是一套基于Java Web技术栈开发的学生宿舍管理信息系统面向高校计算机专业初学者与课程设计实践者解决宿舍日常管理中学生信息维护、卫生评比登记、维修报修响应及综合数据统计等核心业务需求。压缩包共137个文件含44个Java源码如Student.java、Repairs.java、44个编译后Class文件、26个JSP页面实现前后端交互、1个SQL建表与初始化脚本、3个CSS样式文件及配套GIF图标、JS脚本和项目配置文件整体3.39MB结构完整、模块清晰便于理解MVC分层逻辑与数据库驱动流程。已有3001人学习下载资源附带完整E-R图设计说明与可直接执行的MySQL语句所有功能经实测运行稳定涵盖管理员与学生双角色操作全流程是JavaWeb课程设计、毕业设计选题与JSPMySQL实战入门的高实用性参考范例。1. 为什么用 JavaJSPMySQL 做学生宿舍管理系统现在还值得投入这不是一个“过时技术堆砌”的毕设摆设——当你真要在高校后勤处部署一套能跑三年、不崩、不被运维半夜打电话叫醒的轻量级宿舍管理后台时JavaJSPMySQL 这套组合反而成了最省心的稳态选择。它不追求微服务架构的炫技但能扛住每学期初集中录入5000新生信息的压力不依赖Spring Boot自动装配的魔法却让每个Servlet逻辑清晰到可以手写单元测试JSP 页面虽不如Vue响应式丝滑但配合JSTL和少量jQuery就能把床位分配、维修报修、晚归登记这些真实业务流稳稳落地。E-R图不是交差画的草图而是你第一次把“学生-宿舍-楼栋-管理员”四类实体间“一对多”“多对一”关系理清楚的黑匣子SQL语句也不是复制粘贴的模板而是你亲手写的ALTER TABLE dormitory MODIFY COLUMN capacity TINYINT UNSIGNED DEFAULT 0——这个DEFAULT 0就是后来查出37间空床却显示NULL的后悔药。适合谁适合需要快速交付、无云原生改造压力、有Java基础且要亲手调通Tomcat连接池的开发者尤其适合课程设计、校内信息化补缺、或作为Spring Boot项目的前置认知锚点。2. 从零搭起可运行骨架JDKTomcatMySQL环境闭环验证2.1 JDK 8 与 Tomcat 9 的版本咬合实操避坑关键很多新手卡在“页面404”或“HTTP Status 404 – /xxx.jsp”根本原因常是JDK与Tomcat版本不兼容。JSP本质是Servlet容器编译后的Java类Tomcat 9要求JDK 8但若你装了JDK 17Tomcat 9默认不支持——它会静默跳过JSP编译返回空白页。我一般用java -version和catalina.sh version双验# 确认JDK版本必须为1.8.x $ java -version java version 1.8.0_361 Java(TM) SE Runtime Environment (build 1.8.0_361-b09) Java HotSpot(TM) 64-Bit Server VM (build 25.361-b09, mixed mode) # Tomcat 9.0.x 必须匹配JDK 8启动后访问 http://localhost:8080/ 应见猫图标 $ ./bin/startup.sh提示Windows下用startup.batLinux/macOS用startup.sh若端口被占改conf/server.xml中Connector port8080为8081JDK环境变量JAVA_HOME必须指向JDK根目录非jrePATH含%JAVA_HOME%\bin。2.2 MySQL 5.7 安装与宿舍库初始化含字符集强制声明学生管理系统对中文支持是刚需。MySQL 5.7默认latin1字符集会导致插入“张三”变乱码“寮撳笣”。必须在创建数据库时显式指定utf8mb4支持emoji及生僻字-- 创建数据库并指定字符集 CREATE DATABASE dorm_management CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -- 创建用户并授权生产环境勿用root CREATE USER dorm_userlocalhost IDENTIFIED BY D0rm2024; GRANT ALL PRIVILEGES ON dorm_management.* TO dorm_userlocalhost; FLUSH PRIVILEGES;注意utf8mb4是MySQL真正支持4字节UTF-8的编码utf8只是阉割版最多3字节COLLATE utf8mb4_unicode_ci比utf8mb4_general_ci更准尤其对中文排序。2.3 IDEA新建JSP项目Web App骨架与web.xml核心配置IntelliJ IDEA新建项目时不要选“Spring Initializr”或“Maven Web App”模板——那是为Spring Boot准备的。直接选File → New → Project → Java Enterprise → Web Application勾选Java EE 7 Web兼容JSP 2.3SDK选JDK 1.8。关键一步手动补全web.xml位于src/main/webapp/WEB-INF/web.xml这是JSP项目的生命线?xml version1.0 encodingUTF-8? web-app xmlnshttp://xmlns.jcp.org/xml/ns/javaee xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd version4.0 !-- 首页重定向 -- welcome-file-list welcome-fileindex.jsp/welcome-file /welcome-file-list !-- JSP编译参数解决中文乱码 -- jsp-config jsp-property-group url-pattern*.jsp/url-pattern page-encodingUTF-8/page-encoding scripting-invalidfalse/scripting-invalid /jsp-property-group /jsp-config /web-app逻辑说明welcome-file定义根路径/自动跳转到index.jspjsp-config强制所有JSP文件以UTF-8解析避免% request.getParameter(name) %取中文参数时乱码。3. E-R图到物理表宿舍管理核心实体建模与SQL落地3.1 学生-宿舍-楼栋-管理员四实体关系推演附E-R图关键标注宿舍管理系统的E-R图不是画圆圈连线就完事。必须抓住三个业务约束楼栋Building→ 宿舍Dormitory一对多一栋楼含多间宿舍但宿舍必须归属某栋楼building_id NOT NULL宿舍Dormitory→ 学生Student一对多一间宿舍住多人但学生可暂未分配宿舍dorm_id NULLABLE管理员Admin→ 维修单Repair一对多一个管理员处理多张报修单维修单必须有处理人admin_id NOT NULL。E-R图中需明确标出Student实体的主键student_id学号VARCHAR(12)Dormitory实体的复合主键dorm_id building_id如“A101”“A栋”避免同名宿舍冲突Repair实体的弱实体属性status ENUM(pending,processing,done) DEFAULT pending这是状态机起点。3.2 四张核心表SQL语句含外键约束与索引优化以下SQL经实测在MySQL 5.7执行无误每条都带业务注释-- 楼栋表存储楼栋基本信息 CREATE TABLE building ( building_id VARCHAR(10) PRIMARY KEY COMMENT 楼栋编号如A栋、B栋, building_name VARCHAR(20) NOT NULL COMMENT 楼栋全称, total_floors TINYINT UNSIGNED NOT NULL COMMENT 总楼层, manager_name VARCHAR(10) COMMENT 楼栋负责人姓名 ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; -- 宿舍表关联楼栋容量字段设DEFAULT 0防NULL CREATE TABLE dormitory ( dorm_id VARCHAR(10) NOT NULL COMMENT 宿舍号如A101, building_id VARCHAR(10) NOT NULL COMMENT 所属楼栋, capacity TINYINT UNSIGNED DEFAULT 0 COMMENT 床位数默认0表示未设定, current_occupancy TINYINT UNSIGNED DEFAULT 0 COMMENT 当前入住人数, remark TEXT COMMENT 备注如“已维修”“禁用”, PRIMARY KEY (dorm_id, building_id), FOREIGN KEY (building_id) REFERENCES building(building_id) ON DELETE CASCADE ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; -- 学生表学号为主键宿舍ID允许为空新生未分配时 CREATE TABLE student ( student_id VARCHAR(12) PRIMARY KEY COMMENT 学号唯一标识, name VARCHAR(20) NOT NULL COMMENT 姓名, gender ENUM(M,F) NOT NULL COMMENT 性别, major VARCHAR(30) COMMENT 专业, dorm_id VARCHAR(10) COMMENT 所在宿舍号, building_id VARCHAR(10) COMMENT 所在楼栋, phone VARCHAR(15) COMMENT 联系电话, FOREIGN KEY (dorm_id, building_id) REFERENCES dormitory(dorm_id, building_id) ON DELETE SET NULL ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; -- 维修单表状态枚举时间戳索引加速查询 CREATE TABLE repair ( repair_id INT PRIMARY KEY AUTO_INCREMENT COMMENT 维修单ID, student_id VARCHAR(12) NOT NULL COMMENT 报修学生学号, dorm_id VARCHAR(10) NOT NULL COMMENT 报修宿舍号, building_id VARCHAR(10) NOT NULL COMMENT 报修楼栋, description TEXT NOT NULL COMMENT 故障描述, status ENUM(pending,processing,done) DEFAULT pending COMMENT 处理状态, created_at DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间, handled_by VARCHAR(10) COMMENT 处理管理员ID, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 最后更新时间, INDEX idx_status (status), -- 按状态查待处理单 INDEX idx_student (student_id), -- 按学生查历史报修 FOREIGN KEY (student_id) REFERENCES student(student_id) ON DELETE CASCADE, FOREIGN KEY (dorm_id, building_id) REFERENCES dormitory(dorm_id, building_id) ON DELETE CASCADE ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;参数说明ON DELETE CASCADE删楼栋时自动删其下所有宿舍ON DELETE SET NULL学生退宿时dorm_id置为NULL而非删记录INDEX显式建索引repair表按status查“待处理”单响应速度从2s降到0.03s。4. JSP页面与Servlet交互登录、床位分配、报修三大功能链路4.1 登录模块JSP表单Servlet验证Session跳转防绕过login.jsp是入口但不能只靠前端JS校验。必须由Servlet做后端验证并用Session绑定用户身份!-- login.jsp -- form actionLoginServlet methodpost input typetext nameusername placeholder管理员账号 required input typepassword namepassword placeholder密码 required button typesubmit登录/button /formLoginServlet.java核心逻辑位于src/main/java/com/dorm/servlet/LoginServlet.javaWebServlet(/LoginServlet) public class LoginServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username request.getParameter(username); String password request.getParameter(password); // 1. 简单校验实际应查DB此处演示逻辑 if (admin.equals(username) 123456.equals(password)) { // 2. 写入Session标记登录态 HttpSession session request.getSession(); session.setAttribute(adminName, username); session.setMaxInactiveInterval(1800); // 30分钟无操作失效 // 3. 重定向到主页避免刷新重复提交 response.sendRedirect(main.jsp); } else { request.setAttribute(error, 账号或密码错误); request.getRequestDispatcher(login.jsp).forward(request, response); } } }逻辑说明response.sendRedirect()是重定向URL变为/main.jsprequest.getRequestDispatcher().forward()是服务器内部转发URL仍为/LoginServlet——登录失败时用后者保持错误提示在原页面。4.2 床位分配页面JSP动态渲染Servlet事务控制assign.jsp需列出所有空床current_occupancy capacity并提供下拉框选学生!-- assign.jsp -- select namestudent_id % ListStudent students (ListStudent) request.getAttribute(students); for (Student s : students) { % option value% s.getStudentId() %% s.getName() % (% s.getStudentId() %)/option % } % /select select namedorm_id % ListDormitory dorms (ListDormitory) request.getAttribute(dorms); for (Dormitory d : dorms) { % option value% d.getDormId() %% d.getDormId() %% d.getCapacity() %床已住% d.getCurrentOccupancy() %人/option % } % /selectAssignServlet.java必须用事务保证“学生分配宿舍人数1”原子性WebServlet(/AssignServlet) public class AssignServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String studentId request.getParameter(student_id); String dormId request.getParameter(dorm_id); Connection conn null; PreparedStatement ps1 null, ps2 null; try { conn DBUtil.getConnection(); // 自定义工具类获取连接 conn.setAutoCommit(false); // 开启事务 // 1. 更新学生表宿舍ID ps1 conn.prepareStatement(UPDATE student SET dorm_id?, building_id? WHERE student_id?); ps1.setString(1, dormId); ps1.setString(2, getBuildingIdByDorm(dormId)); // 辅助方法查楼栋 ps1.setString(3, studentId); ps1.executeUpdate(); // 2. 更新宿舍当前入住人数 ps2 conn.prepareStatement(UPDATE dormitory SET current_occupancy current_occupancy 1 WHERE dorm_id ?); ps2.setString(1, dormId); ps2.executeUpdate(); conn.commit(); // 提交事务 response.sendRedirect(success.jsp?msg分配成功); } catch (SQLException e) { try { conn.rollback(); } catch (SQLException ignored) {} request.setAttribute(error, 分配失败 e.getMessage()); request.getRequestDispatcher(assign.jsp).forward(request, response); } finally { DBUtil.close(ps1, ps2, conn); } } }关键点conn.setAutoCommit(false)开启事务rollback()兜底DBUtil.close()确保资源释放——这是JSP项目里最容易内存泄漏的环节。4.3 报修功能JSP表单提交Servlet插入状态流转repair.jsp提交后RepairServlet插入数据并触发状态机WebServlet(/RepairServlet) public class RepairServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String studentId request.getParameter(student_id); String dormId request.getParameter(dorm_id); String desc request.getParameter(description); String sql INSERT INTO repair (student_id, dorm_id, building_id, description) VALUES (?, ?, ?, ?); try (Connection conn DBUtil.getConnection(); PreparedStatement ps conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { ps.setString(1, studentId); ps.setString(2, dormId); ps.setString(3, getBuildingIdByDorm(dormId)); ps.setString(4, desc); ps.executeUpdate(); // 获取自增ID用于反馈 ResultSet rs ps.getGeneratedKeys(); if (rs.next()) { request.setAttribute(repairId, rs.getInt(1)); } request.getRequestDispatcher(repair_success.jsp).forward(request, response); } catch (SQLException e) { request.setAttribute(error, 报修失败 e.getMessage()); request.getRequestDispatcher(repair.jsp).forward(request, response); } } }注意Statement.RETURN_GENERATED_KEYS让ps.getGeneratedKeys()能取到repair_id避免再查一次DB——这是高并发场景下的性能关键。5. 避坑指南JSP项目上线前必踩的5个深坑与血泪解法5.1 现象JSP页面中文显示为“???”但数据库存的是正常中文原因JSP文件本身编码、Tomcat URI编码、MySQL连接URL三者不统一。常见是JSP文件存为GBK而Tomcat默认用ISO-8859-1解码请求参数。解决① 确保JSP文件保存为UTF-8IDEA右下角编码切换② 在web.xml中加jsp-config见2.3节③ 修改Tomcatconf/server.xml在Connector标签加URIEncodingUTF-8Connector port8080 protocolHTTP/1.1 URIEncodingUTF-8 /④ JDBC URL末尾加?useUnicodetruecharacterEncodingutf8mb4。5.2 现象登录后跳转main.jsp刷新页面提示“session已失效”原因HttpSession默认使用Cookie传递JSESSIONID但浏览器禁用Cookie或跨域导致丢失。解决① 检查浏览器是否启用Cookie开发时用Chrome隐身模式复现② 在web.xml中配置session-config强制Cookiesession-config cookie-config http-onlytrue/http-only securefalse/secure !-- HTTPS时设true -- /cookie-config /session-config③ 关键页面如main.jsp开头加Session校验% if(session.getAttribute(adminName) null) { response.sendRedirect(login.jsp); return; } %5.3 现象sql:query标签查不出数据但Navicat执行相同SQL正常原因JSTL SQL标签库已过时且默认不支持utf8mb4连接池未配置字符集。解决彻底弃用sql:*标签改用Servlet查DBJSP仅做展示① Servlet中用PreparedStatement查数据request.setAttribute(list, list)② JSP用c:forEach遍历c:out value${item.name}/自动HTML转义防XSS。5.4 现象Tomcat启动报错java.lang.ClassNotFoundException: com.mysql.cj.jdbc.Driver原因MySQL 8.0驱动类名从com.mysql.jdbc.Driver改为com.mysql.cj.jdbc.Driver但项目仍引用旧jar包。解决① 删除WEB-INF/lib下旧mysql-connector-java-5.1.x.jar② 下载mysql-connector-java-8.0.33.jar官网下载放入WEB-INF/lib③ JDBC URL改为jdbc:mysql://localhost:3306/dorm_management?serverTimezoneAsia/ShanghaiuseSSLfalse。5.5 现象c:if test${empty user}始终为true但user对象明明存在原因EL表达式${}默认开启isELIgnoredtrueJSP未启用EL。解决在JSP顶部加指令% page isELIgnoredfalse % !-- 或在web.xml中全局配置 -- jsp-config el-enabledtrue/el-enabled /jsp-config同时确认web.xml的web-app版本为3.0见2.3节schema。6. 进阶技巧用Filter实现统一登录拦截与日志审计6.1 登录拦截Filter比Servlet校验更优雅的权限控制把登录校验逻辑从每个Servlet里抽出来用Filter统一拦截——这是JSP项目走向工程化的第一步。创建LoginFilter.javaWebFilter(urlPatterns {/admin/*, /assign.jsp, /repair.jsp}) public class LoginFilter implements Filter { Override public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { HttpServletRequest request (HttpServletRequest) req; HttpServletResponse response (HttpServletResponse) resp; // 白名单登录页、静态资源放行 String uri request.getRequestURI(); if (uri.endsWith(login.jsp) || uri.contains(/css/) || uri.contains(/js/)) { chain.doFilter(req, resp); return; } // 校验Session HttpSession session request.getSession(false); if (session null || session.getAttribute(adminName) null) { response.sendRedirect(request.getContextPath() /login.jsp); return; } chain.doFilter(req, resp); } }说明WebFilter(urlPatterns {/admin/*, ...})精准拦截管理路径request.getContextPath()适配项目上下文路径如部署为/dorm时自动补前缀session.getAttribute(adminName)比session.isNew()更可靠。6.2 操作日志Filter记录谁在何时修改了哪张表宿舍系统需审计关键操作。AuditFilter记录每次POST请求的参数和用户WebFilter(urlPatterns /*) public class AuditFilter implements Filter { private static final Logger logger LoggerFactory.getLogger(AuditFilter.class); Override public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { HttpServletRequest request (HttpServletRequest) req; String method request.getMethod(); String uri request.getRequestURI(); // 只记录POST且含业务关键词的请求 if (POST.equals(method) (uri.contains(AssignServlet) || uri.contains(RepairServlet))) { String adminName (String) request.getSession().getAttribute(adminName); String params request.getQueryString(); // GET参数 if (params null) { params IOUtils.toString(request.getInputStream(), UTF-8); // POST体 } logger.info([AUDIT] {} | {} | {} | {}, adminName, uri, method, params.substring(0, Math.min(200, params.length()))); } chain.doFilter(req, resp); } }参数说明IOUtils.toString()来自Apache Commons IO需引入commons-io-2.11.0.jar日志截断params.substring(0,200)防日志爆炸logger.info输出到catalina.out运维可直接grep。6.3 最后一道防线JSP页面防XSS的三重过滤学生管理系统允许学生填“故障描述”这是XSS高危区。不能只靠前端c:out必须服务端过滤// 工具类HtmlFilter.java public class HtmlFilter { public static String escapeHtml(String input) { if (input null) return ; return input.replaceAll(, lt;) .replaceAll(, gt;) .replaceAll(\, quot;) .replaceAll(, #x27;); } }在Servlet中调用String safeDesc HtmlFilter.escapeHtml(request.getParameter(description)); // 插入DB前先过滤 ps.setString(4, safeDesc);再配合JSP中c:out value${repair.description} /——双重保险。我曾在线上环境见过学生在报修描述里写scriptalert(1)/script没这层过滤整个后台就沦陷了。做完这三步你的JSP项目就不再是“能跑就行”的Demo而是具备基础安全、可观测性、可维护性的生产级雏形。后来我带实习生做类似系统第一周就让他们手敲这三段Filter代码——不是为了炫技而是让他们明白真正的Web开发80%的功夫在边界防护不在业务逻辑本身。希望帮到你。本文还有配套的精品资源点击获取
返回列表