ARTICLE DETAIL

资讯详情

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

JavaWeb学生宿舍管理系统开发解析:架构、数据库与部署避坑

JavaWeb学生宿舍管理系统开发解析:架构、数据库与部署避坑 简介这份javaweb学生宿舍管理系统源码与数据库合辑面向Java Web初/中级学习者、毕业设计及期末大作业需求者提供一套可直接运行的宿舍管理解决方案涵盖学生信息、楼栋房间、水电费、管理员等核心模块难度适中评审分高达98分。压缩包共133个文件约3.3MB主要包含20个Java源码与20个class编译文件、18个JSP页面、52个JavaScript脚本及5个CSS样式另有SQL数据库脚本与XML配置可直接导入IDE运行并还原数据库便于学习前后端交互与增删改查实现。目前已有144人学习适合用来快速搭建完整项目框架、理解业务逻辑也可作为课程设计参考。资源结构清晰源码均经本地编译验证无需二次调试即可运行能有效节省查阅与排错时间是完成高分课设或答辩的有力支撑。1. 这套 JavaWeb 学生宿舍管理系统不是凑数的课设代码学生宿舍管理系统是 JavaWeb 课程设计和毕业设计里出现频率最高的题目之一但很多人拿到的源码只能在答辩时点几下按钮问到底层逻辑就卡壳。这套系统之所以值得做是因为它的业务关系足够真实学生、楼栋、宿舍、报修、卫生检查是典型的多表关联再加上登录权限、状态流转、宿舍分配这类需要事务的写操作正好把 JavaWeb 的 Servlet、JSP、过滤器、数据库连接池全串起来比单纯做图书管理更能体现项目完整性。如果你手里已经有一份带数据库脚本的 javaweb 学生宿舍管理系统源码目标不应该只是把它跑通而是把里面的表结构、请求链路和分配逻辑读明白改成自己答辩能讲清楚的设计。这篇以一套常见的“管理员学生宿管”角色模型为例从架构、数据库、核心代码到 IDEA 运行配置和坑一步步拆开讲。新手能照着复现熟手也能直接绕过几个典型雷区。2. 技术栈与架构为什么 JavaWeb 宿舍管理系统多用 Servlet JSP MySQL2.1 三层架构在这个项目里的落点拿到源码后第一件事不是点运行而是先看包结构和 web.xml。学生宿舍管理系统虽然是课设体量但一套规范的分层代码通常会拆成四个包controllerServlet、service业务、dao持久层、model实体类再加上 filter 做登录拦截。我一般会把对应关系讲成三层模型JSP 页面负责输入输出Servlet 只做参数接收和页面转发Service 层处理宿舍分配、报修状态这些业务规则DAO 层用 JDBC 或 MyBatis 访问 MySQL。放进这个项目里就是层次在本项目里的具体落点典型类或文件表示层JSP 页面按角色文件夹拆分pages/admin、pages/student、pages/repair控制层Servlet FilterLoginServlet、StudentServlet、RepairServlet、LoginFilter业务层事务和规则校验StudentService、DormService、RepairService持久层SQL 读写StudentDao、DormDao、RepairDao这种分法的价值在于答辩时你可以直接画出来请求从 JSP 发给 ServletServlet 调 ServiceService 调 DAODAO 查 MySQL结果一层层返回。很多低分项目的问题就出在 JSP 里直接写 JDBC业务和展示揉在一起一旦换数据库或改表结构页面全崩。2.2 Servlet、JSP、MyBatis 的取舍与依赖版本选择市面上的 JavaWeb 学生宿舍管理系统源码主要有两类一类是纯 Servlet JSP JDBC另一类是 Servlet JSP MyBatis。我自己更推荐后者因为宿舍分配、报修列表都有动态查询条件MyBatis 的 where 标签和 resultMap 能少写很多拼接 SQL。如果你是准备交课程设计Maven 工程是最好的组织方式。下面是一份我常用的依赖清单版本不是越新越好要跟你的 JDK 和 Tomcat 匹配dependencies !-- Servlet APITomcat 8.5 对应 3.1Tomcat 9 对应 4.0 -- dependency groupIdjavax.servlet/groupId artifactIdjavax.servlet-api/artifactId version4.0.1/version scopeprovided/scope /dependency !-- JSP API编译时需要运行时由容器提供 -- dependency groupIdjavax.servlet.jsp/groupId artifactIdjavax.servlet.jsp-api/artifactId version2.3.3/version scopeprovided/scope /dependency !-- JSTL 标签库用来在 JSP 里做 forEach / if -- dependency groupIdjstl/groupId artifactIdjstl/artifactId version1.2/version /dependency !-- MySQL 驱动本地 MySQL 是 5.7 就用 5.1.498.0 就用 8.0.30 -- dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId version8.0.30/version /dependency !-- MyBatis 核心依赖 -- dependency groupIdorg.mybatis/groupId artifactIdmybatis/artifactId version3.5.10/version /dependency /dependencies参数说明这里有两个最容易翻车的版本点。第一servlet-api 的 scope 必须写成 provided否则 Tomcat 运行时会和你 WEB-INF/lib 下的同名包冲突报 ClassCastException。第二mysql-connector-java 用 8.0 时连接串里必须带 serverTimezoneAsia/Shanghai否则默认时区会差 8 小时而且 8.0 的驱动类名是 com.mysql.cj.jdbc.Driver不是老的 com.mysql.jdbc.Driver。2.3 从源码目录反推包结构拿到源码后我习惯先在 IDE 里把项目树展开对照这个结构看是不是分层。这里是一份常见的高分项目目录组织dormitory-management/ ├── pom.xml ├── src/main/java/com/dorm/ │ ├── controller/ │ │ ├── LoginServlet.java │ │ ├── StudentServlet.java │ │ ├── DormServlet.java │ │ ├── RepairServlet.java │ │ └── NoticeServlet.java │ ├── service/ │ │ ├── StudentService.java │ │ ├── DormService.java │ │ └── RepairService.java │ ├── dao/ │ │ ├── StudentDao.java │ │ ├── DormDao.java │ │ └── RepairDao.java │ ├── model/ │ │ ├── Student.java │ │ ├── Dorm.java │ │ └── Repair.java │ ├── filter/ │ │ └── LoginFilter.java │ └── util/ │ └── DBUtil.java ├── src/main/resources/ │ ├── mybatis-config.xml │ ├── db.properties │ └── mapper/ │ ├── StudentMapper.xml │ ├── DormMapper.xml │ └── RepairMapper.xml ├── src/main/webapp/ │ ├── WEB-INF/web.xml │ ├── jsp/ │ │ ├── login.jsp │ │ ├── admin/ │ │ ├── student/ │ │ └── repair/ │ ├── css/ │ └── js/ └── sql/ └── dorm.sql这个结构最直接的好处是答辩时能按层讲util 是公共工具filter 是权限入口controller 里每个实体一个 Servletservice 和 dao 一一对应。如果拿到的源码把所有类都塞在一个包里或 JSP 和 Java 混在根目录那项目质量基本要打折扣建议自己手动拆一下再交。3. 数据库设计是宿舍管理的高分区表结构、关系与初始化脚本3.1 核心表学生、宿舍、楼栋、报修、卫生检查、系统用户宿舍管理系统的数据库设计能不能拿高分关键在于你如何解释实体关系。学生和宿舍之间不是简单的直接外键通常还要通过“宿舍分配记录”来记录历史和换宿情况宿舍和楼栋是多对一报修单和宿舍是多对一卫生检查和宿舍也是多对一。一张好的数据库表设计至少要有六张核心表表名用途关键字段sys_user登录账号管理员、学生共用user_id, username, password, role, student_idstudent学生档案student_id, name, gender, major, dorm_idbuilding宿舍楼栋building_id, building_name, managerdorm宿舍房间dorm_id, building_id, room_no, capacity, used_count, gender_typerepair报修记录repair_id, dorm_id, user_id, content, status, create_timeinspection卫生检查记录inspection_id, dorm_id, score, comment, inspect_date这几张表里最值得答辩讲解的是 dorm 表的设计capacity 表示宿舍容量used_count 表示当前已住人数。性别通过 gender_type 限制整栋楼或整层不能只靠学生表里的 gender 字段做逻辑判断否则会出现男学生分进女生宿舍的严重 bug。3.2 建表 SQL 脚本与关系设计下面是我通常会在课程设计里用到的一套建表脚本核心部分注意看外键和唯一约束CREATE DATABASE IF NOT EXISTS dorm_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; USE dorm_db; CREATE TABLE building ( building_id INT PRIMARY KEY AUTO_INCREMENT, building_name VARCHAR(20) NOT NULL UNIQUE, manager VARCHAR(20) DEFAULT NULL ) ENGINEInnoDB AUTO_INCREMENT100; CREATE TABLE dorm ( dorm_id INT PRIMARY KEY AUTO_INCREMENT, building_id INT NOT NULL, room_no VARCHAR(10) NOT NULL, capacity INT NOT NULL DEFAULT 4, used_count INT NOT NULL DEFAULT 0, gender_type TINYINT NOT NULL DEFAULT 0 COMMENT 0男 1女, CONSTRAINT fk_dorm_building FOREIGN KEY (building_id) REFERENCES building(building_id), UNIQUE KEY uk_room (building_id, room_no) ) ENGINEInnoDB; CREATE TABLE student ( student_id VARCHAR(20) PRIMARY KEY, name VARCHAR(30) NOT NULL, gender TINYINT NOT NULL, major VARCHAR(50), phone VARCHAR(11), dorm_id INT DEFAULT NULL, CONSTRAINT fk_student_dorm FOREIGN KEY (dorm_id) REFERENCES dorm(dorm_id) ) ENGINEInnoDB; CREATE TABLE sys_user ( user_id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(30) NOT NULL UNIQUE, password VARCHAR(100) NOT NULL, role VARCHAR(10) NOT NULL DEFAULT STUDENT, student_id VARCHAR(20) DEFAULT NULL, CONSTRAINT fk_user_student FOREIGN KEY (student_id) REFERENCES student(student_id) ) ENGINEInnoDB; CREATE TABLE repair ( repair_id INT PRIMARY KEY AUTO_INCREMENT, dorm_id INT NOT NULL, user_id INT NOT NULL, content VARCHAR(500) NOT NULL, status TINYINT DEFAULT 0 COMMENT 0待处理 1处理中 2已完成 3已确认, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, CONSTRAINT fk_repair_dorm FOREIGN KEY (dorm_id) REFERENCES dorm(dorm_id), CONSTRAINT fk_repair_user FOREIGN KEY (user_id) REFERENCES sys_user(user_id) ) ENGINEInnoDB;这段 DDL 里有三个容易被忽略的细节。第一student_id 我用 VARCHAR(20)因为很多学校学号是数字加字母用 INT 会溢出或丢掉前导零。第二dorm 表里的唯一约束是 (building_id, room_no)而不是 room_no 单独唯一因为不同楼栋可能有相同的房间号。第三sys_user 通过 student_id 和 student 表关联而不是直接拷贝学生的姓名和性别这样可以保证改档案时登录信息不用动。实际运行脚本时如果 MySQL 版本是 5.5 或更老utf8mb4 可能不被支持那就退回 utf8。但如果能支持我建议优先 utf8mb4否则学生填的 emoji 或生僻字在报修内容里会变成问号。插入数据时password 字段不要存明文至少要做 MD5 加盐否则数据库文件一旦泄露账号全裸奔。3.3 数据库连接池参数和 MySQL 连接串很多源码跑不起来不是代码写错而是 db.properties 里的配置不对。下面是一份既能用纯 JDBC 也能给 MyBatis 引用的配置jdbc.drivercom.mysql.cj.jdbc.Driver jdbc.urljdbc:mysql://localhost:3306/dorm_db?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/ShanghaiuseSSLfalseallowPublicKeyRetrievaltrue jdbc.usernameroot jdbc.password123456 # 连接池参数 jdbc.initialSize5 jdbc.maxActive20 jdbc.maxWait10000 jdbc.minIdle2参数要说清楚答辩时老师很可能指着 url 问。useUnicodetrue 和 characterEncodingutf8 保证页面表单里提交的中文写入 MySQL 不乱码serverTimezoneAsia/Shanghai 解决 8.0 驱动的时区异常useSSLfalse 因为本机开发不需要加密否则 MySQL 5.7 的 SSL 警告会让人误以为连接失败allowPublicKeyRetrievaltrue 是 MySQL 8.0 配合 caching_sha2_password 时必加的不加就会看到 “Public Key Retrieval is not allowed”。连接池那里initialSize 是启动时创建的连接数maxActive 是最大连接数课设项目并发不超过 50 时maxActive 设 20 足够。maxWait 是拿连接时的最大等待毫秒数设 10000 表示等 10 秒后抛异常可以防止数据库卡死时请求全部堆积在多线程里。这里最常见的错误是有人把 maxActive 调到几百觉得性能好实际会耗尽 MySQL 的默认连接数导致其他客户端连不上。4. 把业务流程写成源码登录权限、宿舍分配与报修状态流转4.1 登录校验与权限拦截一个 Filter 顶掉所有重复判断学生宿舍管理系统的页面虽然不少但权限模型很简单未登录只能进 login.jsp管理员能进 admin 下所有页面学生只能进自己的页面。如果把这段判断写进每个 Servlet代码会非常臃肿。一个 LoginFilter 就能统一拦截所有 /pages 目录下的 JSP 请求。下面是一个精简版过滤器的核心逻辑package com.dorm.filter; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; WebFilter(/pages/*) public class LoginFilter implements Filter { Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req (HttpServletRequest) request; HttpServletResponse resp (HttpServletResponse) response; HttpSession session req.getSession(false); // 未登录用户统一跳回登录页不继续向下放行 if (session null || session.getAttribute(login_user) null) { resp.sendRedirect(req.getContextPath() /jsp/login.jsp); return; } // 已登录用户继续访问目标资源 chain.doFilter(request, response); } Override public void init(FilterConfig filterConfig) throws ServletException { System.out.println(登录过滤器初始化); } Override public void destroy() { System.out.println(登录过滤器销毁); } }逻辑说明WebFilter(/pages/*) 是 Servlet 3.0 之后的注解写法等价于在 web.xml 里配 filter-mapping。req.getSession(false) 这里传 false 很关键如果传 true过滤器会在没有 session 时自动创建一个那“未登录检测”就永远失效了。跳转时必须用 req.getContextPath() 拼出项目根路径否则部署在带名称的 context 下时redirect 地址会少一段路径。如果你拿到的源码没用注解而是在 web.xml 里配置也很正常。要注意的是 filter 的顺序如果有多个过滤器字符编码过滤器要放在 LoginFilter 之前因为要先设置 request 的编码否则登录页提交中文账号时后端拿到的是乱码。4.2 宿舍分配的并发与事务这是最值得讲的业务点宿舍管理系统里宿舍分配是核心难点也是答辩时最可能被追问的点。表面看只是更新学生表的 dorm_id 和宿舍 used_count但这里有两个隐藏问题一是宿舍可能已经满了分配前要判断 used_count capacity二是两个学生同时操作时如果没有事务和锁就可能把 4 人间分到第 5 个人。我一般建议在 Service 层手写一个分配方法逻辑要闭环public boolean assignDormitory(String studentId, int dormId) { // 第一步检查宿舍是否可住 Dorm dorm dormDao.selectById(dormId); if (dorm null) { return false; } if (dorm.getUsedCount() dorm.getCapacity()) { return false; // 宿舍已满 } // 第二步更新宿舍人数和学生归属后续可以包进事务 int rows dormDao.increaseUsedCount(dormId); if (rows 0) { int result studentDao.updateDorm(studentId, dormId); return result 0; } return false; }这段代码的核心逻辑是“先查后再更新”。但不能只说功能要说并发问题如果两个线程同时读到 used_count 3capacity 4它们都会认为还可以分配然后各自 update最终 used_count 变成 5超卖就发生了。所以更可靠的写法要么用数据库锁要么在 update 时带上 used_count 条件。-- 第一方案原子条件更新防止超卖 UPDATE dorm SET used_count used_count 1 WHERE dorm_id #{dormId} AND used_count capacity; -- 受影响行数为 0 时说明宿舍已满直接放弃这个 UPDATE 语句值得单独讲它把“检查”和“更新”合成了一个原子操作。InnoDB 下这条语句会锁定 dorm_id 对应的行后续事务必须等它提交才能继续所以从根上解决了并发分配超卖的问题。如果把这一步和 update student 一起放进事务就能保证要么宿舍加了人学生也分配成功要么都不变。事务边界要注意在 MyBatis 里你可以在 mapper 接口方法上配合使用 SqlSession也可以用 Spring 的 Transactional。课设源码如果没引入 Spring我建议在 Service 里统一获取 Connection、设置 setAutoCommit(false)报错时 rollback成功时 commit。很多项目只做了超卖判断没做回滚数据库出现学生 dorm_id 指向不存在宿舍的脏数据答辩时很容易被问穿。4.3 报修状态机的 Servlet 更新与 JSP 展示报修是宿舍管理系统里最能体现“状态流”的功能。一条报修记录从学生提交开始要经历待处理 - 处理中 - 已完成 - 学生确认。不同角色能执行的操作不一样当前状态宿舍管理员可执行学生可执行待处理设为处理中取消报修处理中设为已完成追加备注已完成无确认或重新报修已确认归档无Servlet 阶段处理这种状态最好用整型字段加校验不要允许任意跳状态。下面是一段常见的更新逻辑int status Integer.parseInt(req.getParameter(status)); int repairId Integer.parseInt(req.getParameter(repairId)); if (status ! Repair.STATUS_ACTIVE status ! Repair.STATUS_DONE) { request.setAttribute(error, 非法状态流转); request.getRequestDispatcher(/jsp/repair/list.jsp).forward(request, response); return; } boolean ok repairService.updateStatus(repairId, status, currentUser);逻辑说明先从 request 拿到目标和目标状态再判断状态值是否在白名单里。比较关键的是“当前状态”也要带进查询条件防止学生把别人报修单的状态乱改。updateStatus 的 SQL 最好带 user_id 条件属于当前用户才更新。JSP 展示时不要直接用数字显示“0、1、2”可以用一个小的 Map 做映射比如利用 JSTL 的 forEachc:forEach items${repairList} varr tr td${r.content}/td td c:choose c:when test${r.status 0}待处理/c:when c:when test${r.status 1}处理中/c:when c:when test${r.status 2}已完成/c:when c:otherwise已确认/c:otherwise /c:choose /td /tr /c:forEach这里想提醒一下JSP 里做业务判断会显得项目很业余但课设层次用 JSTL 做状态映射是可接受的。如果想让代码再干净一点可以在实体类加一个 getStatusText() 方法根据 status 返回中文描述页面直接写 ${r.statusText}。这也是加分点因为体现了对实体设计和表现层分离的理解。5. 在 IDEA 里运行 JavaWeb 项目完整配置与避坑排查5.1 拿到源码后的运行环境核对不管是自己写还是从别人那里拿到 javaweb 学生宿舍管理系统源码第一件事不是启动 IDEA而是先把运行环境对齐。否则你会在各种诡异的报错里消耗掉大半天最后发现是版本不匹配。我通常按下面这个顺序核对检查项推荐环境说明JDKJDK 8大多数课设源码基于 Java 8用 JDK 11 不一定会有问题但如果用了老版 Tomcat 会有坑TomcatTomcat 8.5 或 9.0对应 Servlet 3.1/4.0注解才能生效MySQLMySQL 5.7 或 8.0导入 sql 脚本时注意编码用 utf8mb4IDEAIntelliJ IDEA 2020Ultimate / Community 都行社区版要装 Smart Tomcat 插件Maven3.6如果源码没有 pom.xml 而是 lib 目录可以跳过这里有一个最常见的翻车点毕业设计源码年代比较早还在用 Eclipse 的 Dynamic Web Project拿到 IDEA 里后不会被直接识别为 Web 工程。正确的做法是在 Project Structure 里的 Modules 添加 Web 支持指定 web.xml 路径和 Web 根目录然后再配置 Artifact。如果什么都不加就点 RunIDEA 只能跑普通 Java 类根本找不到 Tomcat 的 Deploy 按钮。5.2 Tomcat 数据源与部署配置步骤如果你拿到的源码用的是纯 JDBC只有 db.properties没有 Spring 管理的数据源那配置相对简单。只要把 mysql-connector-java.jar 放进 WEB-INF/lib然后确认 db.properties 里密码正确即可。在 IDEA 里把 Tomcat 配好并成功跑起来核心是三步第一步打开 Run/Debug Configurations新增 Tomcat Server Local选择本机 Tomcat 目录。注意这里的 Tomcat Home 不能只填解压目录要能看到 conf/server.xml 和 bin/catalina.sh 才算有效。第二步切换到 Deployment 页签点击 添加 Artifact。如果你看到的是 Maven projectArtifact 类型一般是dorm-management:war exploded。选 Exploded 而不是打包后的 war因为这样改了 JSP 不用重启 Tomcat热部署体验好很多。第三步在 Application context 填/dorm这样访问地址就是 http://localhost:8080/dorm/jsp/login.jsp。同时检查 IDEA 默认给出的 Server port 和 HTTP port8080 若被你本机的其他服务占了改成 8081但要同步改后面跳转链接里的端口。配置完之后还有一个老生常谈的步骤在 Project Structure - Artifacts 里双击 main class 或 lib 不会自动把所有依赖打进 WEB-INF/lib。你需要检查 Output Layout 里有没有 Available Elements 下的 jar 包没有就右键选 Put into /WEB-INF/lib否则启动时会疯狂报 ClassNotFoundException。5.3 避坑JavaWeb 宿舍管理系统最常见的五个运行问题这部分是直接从实际运行经验里踩出来的按“现象 - 原因 - 解决”写遇到问题可以先对照自己是不是这些情况。问题一Tomcat 启动成功但浏览器访问 404。现象Tomcat 控制台出现Deploying web application archive后又快速结束访问项目路径却 404。原因IDEA 的 Artifact 没有正确生成或者 context path 设成了/ROOT访问时路径不对。解决检查 Deployment 里 Application context 是否包含模块名比如/dorm再确认 Artifact 名称和输出的 exploded war 目录存在。如果改完还 404把 Tomcat 和项目彻底 clean 后重启一次。问题二连接数据库报Public Key Retrieval is not allowed。现象日志堆栈里出现这条明确错误程序连不上 MySQL。原因MySQL 8.0 默认认证插件是 caching_sha2_password第一次连接时需要从服务器拉取公钥而连接串没允许。解决在 jdbc.url 末尾追加allowPublicKeyRetrievaltrueuseSSLfalse。不要改成useSSLtrue本机开发证书没配置反而会出现 SSL 握手失败。问题三页面中文全是问号或乱码。现象登录后学生姓名、报修内容里的中文显示成????。原因数据库连接串没设 characterEncoding或者 MySQL 表默认的字符集是 latin1也可能 JSP 页面没设 pageEncoding。解决第一步SQL 脚本建库时加上DEFAULT CHARSETutf8mb4第二步jdbc.url 加characterEncodingutf8第三步确认 JSP 头部有% page contentTypetext/html;charsetUTF-8 %。这三个地方缺一个都会乱。问题四报ClassNotFoundException: com.mysql.cj.jdbc.Driver。现象启动后调用 DAO 时直接抛 ClassNotFound。原因MySQL 驱动依赖没有打进 WEB-INF/lib。用 Maven 时不注意 exported 状态或者 IDEA 没有把 jar 放进 Artifact。解决检查 Project Structure 中 Artifact Output Layout 里有没有 mysql-connector-java.jar没有则手动加入。如果是手动添加的 jar 包最好把它复制到webapp/WEB-INF/lib目录而不是只放在 lib 库里。问题五过滤器导致无限重定向页面提示“无法访问”。现象登录页也进不去浏览器地址栏反复跳到 login.jsp。原因LoginFilter 把/pages/*全都拦截了但登录页本身放在/jsp/login.jsp通常不会死循环。陷入循环的常见原因是过滤器把 /jsp/* 也拦截而放行的 URL 又跳回登录页这个跳转再次被过滤。解决过滤器 Mapping 只拦截需要权限的路径放行 login.jsp、css、js、图片资源。最常见做法是WebFilter(urlPatterns *.jsp)然后在过滤器内部判断/login.jsp不拦截而不是把所有/都拦下来由自己判断放行。6. 做完再加分的三个技巧日志、并发验证和账号安全项目跑通后如果要让答辩老师觉得“这人是真做过的”别急着交。我会自己补三件小事每件都不复杂但效果很明显。第一是给关键业务留日志。尤其是在宿舍分配和报修状态流转这两处使用 slf4j log4j2哪怕只是在控制台输出也能在演示出 bug 时快速定位。我习惯在分配宿舍成功时打一行分配成功 studentId2023001, dormId101, 剩余床位1。不要小看这行字老师在答辩现场问“你怎么知道分配成功”这就是证据。第二是验证宿舍分配在并发下的表现。用一个简单脚本或者直接在数据库客户端开两个事务窗口同时执行UPDATE dorm SET used_count used_count 1 WHERE dorm_id1 AND used_count capacity;你会看到一个事务成功、一个受影响行数为 0。这就是前面说的原子条件更新的验证方式。这个结论比背一百遍“乐观锁”要扎实。第三是把自己写源码时的密码处理讲清楚。如果源码里还是明文密码建议改成 MD5 加盐哪怕只是简单拼接一个固定盐值再加密。课上项目不会真的上生产但你演示出 hash 后的密码字段老师的评价通常是“安全意识不错”。说回我自己的习惯每次拿到一个 JavaWeb 课设源码我都先看数据库脚本再看过滤器最后才看 Servlet。数据库和权限是学生宿舍管理系统最容易出现低级错误的两个地方只要这两块稳住这个高分项目基本就没跑了。希望这篇笔记能帮你把这份源码从“跑通”推到“讲透”的程度。本文还有配套的精品资源点击获取
返回列表