资讯动态

Java Web学生宿舍管理系统:从数据库设计到部署二次开发全解析

发布时间:2026/10/18 19:43:50 来源:尧图企业网站定制
简介这是一套基于Java的学生宿舍管理系统面向Java Web初学者、毕业设计学生及需要快速搭建宿舍管理应用的人员可用于学生信息管理、宿舍分配、资源调度等场景。压缩包共661个文件、约77.19MB涵盖Java源码35个java、40个class、前端资源400个js、46个css及less/scss样式、数据库脚本2个sql、部署文档docx/doc与5个mp4辅导视频文件类型覆盖从后端逻辑到前端展示的完整链路。目前已有144人学习下载。通过这套资料读者可获得可运行的完整项目源码结合部署文档完成环境搭建与MySQL5/MySQL8双版本配置配合视频教程理解登录验证、Excel导入导出、请求处理、数据访问及异常处理等核心实现还能借鉴模块划分和接口设计思路辅导视频以实例演示方式辅助初学者快速上手是用于课程设计、实战练习或项目二次开发的实用素材。1. 学生宿舍管理系统一套打包齐整的 Java Web 交付物到底该怎么用从压缩包的命名就能看出来这是一套完整的交付物源代码、数据库脚本、部署文档、辅导视频都齐了。它面向的典型场景是高校课程设计和毕业设计——学生宿舍管理系统确实是一个需求边界清晰、业务闭环完整的题目学生信息维护、宿舍分配与调换、报修、来访登记、晚归记录每一块都能独立成模块又互相有数据关联。对做毕设的同学来说这套系统的好处是技术栈传统、资料齐全、能快速跑通对想学习 Java Web 完整链路的人来说它也是一个可以反复拆解的样本工程——从数据库表设计到分层代码从本地运行到打包部署每一步都有现成参照。这篇文章会把这个压缩包拆开来看模块和表怎么设计、本地怎么跑通、源码怎么改、坑在哪、上线前要补哪些事。照着走一遍你不只是跑起来而是能讲清楚每一个环节为什么这么设计。2. 系统拆解宿舍管理系统的核心模块、数据库设计与权限模型2.1 业务模块边界从入住登记到退宿结算把需求收敛成可落地的功能清单先明确一个判断宿舍管理系统不能当成一个大系统来做否则很容易变成什么都想做的半成品。我见过的可运行版本功能都收敛在一条主线上——人、房、行为记录。人学生档案、宿管员。房宿舍楼、房间、床位。行为记录入住分配、退宿、调宿、报修、来访登记、晚归记录。围绕这三类前端界面通常分成学生端、宿管端、管理员端。学生端看自己的入住信息、报修进度宿管端管楼层、查寝、来访登记管理员端管全部数据字典和权限。这样的设计保证了三个角色打开系统只看到自己关心的内容正好贴合答辩时三种角色登录的演示点。为什么把表设计放在第一步因为代码分层再好表结构不合理后续所有查询都会别扭。比如宿舍分配如果不在学生表里冗余一个 dorm_id 字段而是每次实时连表查统计空床位时就会非常痛苦反过来如果只冗余当前 dorm_id、丢掉分配历史调宿记录就没法追溯。所以常见做法是学生表保留当前 dorm_id 作为冗余另建分配记录表存每次入住、调宿、退宿的动作。模块边界这件事还有个现实原因压缩包带辅导视频视频里的功能演示通常就是按这条主线走的。你跟着视频走一遍就能意识到哪些功能是必有项哪些是加分项。必有项做扎实加分项看时间——这是我对所有类似项目的建议。功能列表先写全再砍到能闭环的量级比一上来就想着做考勤、做评分、做消息推送靠谱得多。2.2 数据库表结构设计核心表字段、关系与一段可直接执行的建表 SQL标题里带数据库说明交付物里包含脚本。这类系统的数据库脚本形态通常有两种一个是 create.sql建表加插入初始数据一个是完整的整库 dump 文件。后者需要整库导入前者可以挑选执行。拿到压缩包先看一眼 sql 目录就能判断是哪一种。常见做法是建 8~12 张表最少不能少于 6 张用户表 t_user、学生表 t_student、宿舍楼表 t_building、宿舍表 t_dorm、分配记录表 t_assign_record、报修表 t_repair、来访登记表 t_visit_log。我一般先看 t_user 表的设计因为它决定权限模型。多数版本设计成一张用户表加 role 字段0 管理员、1 宿管、2 学生或者拆出角色表做 RBAC。小项目用前者足够答辩也容易讲清楚。下面给一段建表 SQL 的关键部分字段名可能与压缩包内脚本不完全一致但核心设计思想是通用的-- 学生表核心信息与当前宿舍冗余字段 CREATE TABLE t_student ( id BIGINT AUTO_INCREMENT PRIMARY KEY, student_no VARCHAR(20) NOT NULL UNIQUE COMMENT 学号, student_name VARCHAR(50) NOT NULL COMMENT 姓名, gender TINYINT DEFAULT 0 COMMENT 0男 1女, class_name VARCHAR(50) COMMENT 班级, phone VARCHAR(20) COMMENT 联系电话, dorm_id BIGINT COMMENT 当前宿舍ID冗余便于查询, status TINYINT DEFAULT 1 COMMENT 1在住 0已退宿, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, KEY idx_dorm (dorm_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; -- 宿舍表床位容量与已住人数容量字段用于分配校验 CREATE TABLE t_dorm ( id BIGINT AUTO_INCREMENT PRIMARY KEY, building_id BIGINT NOT NULL COMMENT 所属楼栋ID, room_no VARCHAR(20) COMMENT 房间号, capacity INT DEFAULT 4 COMMENT 床位总数, used INT DEFAULT 0 COMMENT 已住人数, remark VARCHAR(255) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; -- 分配记录表记录每次入住、调宿、退宿用于审计 CREATE TABLE t_assign_record ( id BIGINT AUTO_INCREMENT PRIMARY KEY, student_id BIGINT NOT NULL, dorm_id BIGINT NOT NULL, action_type TINYINT COMMENT 1入住 2调宿 3退宿, operator VARCHAR(50) COMMENT 操作人, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, KEY idx_student (student_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;这段 SQL 里有三个设计细节值得注意。student_no 加 UNIQUE是因为学号是业务主键一个学生只对应一行dorm_id 作为冗余字段是为了让查某个学生住哪和统计某宿舍住了谁都变成单表查询t_assign_record 的存在则给调宿和退宿留了审计轨迹。capacity 和 used 配合在分配逻辑里做容量校验——防止一间四人间住进第五个人。字段层面还要注意主键用 BIGINT 自增在这个量级足够不用纠结 INT 还是 BIGINTDATETIME 默认值用 CURRENT_TIMESTAMP插入时少写一行代码。外键我反而不建议建物理外键理由有两条一是这类系统经常要批量导入或先导数据、后建表物理外键会让导入顺序变得敏感二是代码里 Service 层软约束已经够用物理外键删数据时还会多出额外的顺序要求。逻辑关系靠查询关联体现物理外键能省则省这是在课程设计和中小型项目里比较务实的取舍。2.3 角色权限与数据隔离登录后端的角色判断与一个最小过滤器实现权限这块我见过最容易出问题的是前端把管理员按钮藏掉就算权限控制。等到演示现场评审直接绕过页面调接口数据就泄露了。所以正确做法是在后端做拦截。最轻量的方案是写一个过滤器拦截所有需要登录的路径从 Session 里取当前用户管理端接口再校验角色。下面是常见的过滤器核心逻辑很多 Spring Security 配置本质上在做同一件事// AuthFilter登录与角色校验的最小实现 public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest request (HttpServletRequest) req; HttpSession session request.getSession(false); String uri request.getRequestURI(); // 放行登录、静态资源、注册接口 if (uri.contains(/login) || uri.contains(/css/) || uri.contains(/js/)) { chain.doFilter(req, res); return; } Object user session ! null ? session.getAttribute(loginUser) : null; if (user null) { ((HttpServletResponse) res).sendRedirect(request.getContextPath() /login); return; } // 管理端接口检查角色防止越权 if (uri.startsWith(/admin/)) { // userRole: 0管理员 1宿管 2学生见 t_user.role String role (String) session.getAttribute(userRole); if (!0.equals(role)) { res.setContentType(application/json;charsetUTF-8); res.getWriter().write({\code\:403,\msg\:\no permission\}); return; } } chain.doFilter(req, res); }这个过滤器的优点是不用改动任何业务代码。参数层面userRole 在登录接口里写入 Sessionuri 前缀按模块划分/admin/ 开头只有 role0 能访问/dorm/ 开头宿管可见/student/ 开头学生可见。如果你的项目里用的是 Spring Security按角色配置 antMatchers 的实质完全一样无非是声明式配置替代了手工判断。权限模型还有一个隐藏细节宿管员只能管理自己所在楼栋的数据而不是全校。更细的设计会在 t_building 上挂 manager_id宿管登录时把 buildingId 放进 Session查询时 SQL 里带上 building_id 过滤。这一步不做数据隔离就是一句空话。答辩时能讲到这一层已经能证明你理解了权限的本质是数据范围控制不只是按钮显隐。3. 本地跑通项目从压缩包到可运行系统的完整落地步骤3.1 环境准备JDK、MySQL、IDE 的版本组合与快速自查命令打开压缩包第一步不是解压就跑而是先核对环境。Java 项目最怕的不是代码有问题而是 JDK 版本与编译目标不一致——源码在别人机器上用 JDK 8 编译你本地用 JDK 17 打开轻则警告重则编译失败。常见做法是JDK 优先 1.8对应 Java 8因为大部分这类项目的构建配置里把 source/target 设成 1.8MySQL 用 5.7 或 8.0 均可5.7 兼容性好8.0 需要注意驱动版本和时区参数IDE 用社区版或 Eclipse 都行数据库可视化工具用开源免费的 DBeaver 这类就够了不一定要装全家桶。环境自查命令如下# 检查 JDK 版本1.8.x 输出类似 java version 1.8.0_202 java -version # 检查 MySQL 服务是否在运行 # Windows 下 net start | findstr -i mysql # Linux / macOS 下 systemctl status mysqld # 检查构建工具如果是 Maven 工程且有 mvnw 则用脚本 mvn -version这三个命令输出的意义分别是第一行确定编译版本第二行确认数据库服务第三行确认构建工具能正常调用。如果发现 JDK 已经是 17 但项目是 1.8 编译不用着急换 JDK可以尝试把 IDE 的 Project Structure 里的 SDK 和 Language Level 都调成 8编译选项里的 target bytecode version 也同步改成 8。改完之后重新构建多数兼容问题能消掉。3.2 导入数据库脚本整库导入与分脚本执行的两种选择解压出的文件夹里通常会有一个 sql 目录或 doc 目录里面存着 .sql 文件。我有一次打开发现脚本既有 create.sql 也有中文名的整库导出文件两种的导入方式不一样。整库导出文件通常带 DROP TABLE 和 INSERT 语句适合用命令行整库导入# 先建库避免脚本里没有 CREATE DATABASE mysql -uroot -p -e CREATE DATABASE IF NOT EXISTS dormitory DEFAULT CHARSET utf8mb4; # 整库导入路径里有中文时用引号包住 mysql -uroot -p dormitory ./宿舍管理系统.sql如果是分脚本先执行建表脚本再执行数据脚本mysql -uroot -p dormitory ./sql/create.sql mysql -uroot -p dormitory ./sql/data.sql导入失败的常见原因集中在三个点一是脚本字符集和数据库不一致报 Incorrect string value二是脚本开头没有 USE dormitory导致表建到了默认库三是导入顺序不对先导数据后建表。解决办法也很直接导入前先 CREATE DATABASE导入时用 --default-character-setutf8mb4 指定字符集脚本里缺 USE 就手动补一行。验证导入成功的两个 SQL 我用得最多SHOW TABLES; -- 看表清单是否存在 SELECT COUNT(*) AS total FROM t_student; -- 检查数据量是否与文档描述一致这一步的价值在于把数据库 OK和代码有问题先切成两半。如果表和数据都验证过了后面启动出问题就只在配置和代码里找排查范围小很多。3.3 配置数据库连接并启动修改配置文件、运行源码与常见启动失败点标题里的源代码数据库意味着你会在某个 properties 或 xml 里配置数据库连接。常见位置Spring Boot 项目在 src/main/resources/application.propertiesSSM 项目在源码根目录的 jdbc.properties传统 Web 项目可能在 db.properties。打开后你会看到类似下面的配置# jdbc.properties 示例SSM 项目的数据源配置 jdbc.drivercom.mysql.cj.jdbc.Driver jdbc.urljdbc:mysql://localhost:3306/dormitory?useSSLfalseserverTimezoneAsia/ShanghaicharacterEncodingutf8 jdbc.usernameroot jdbc.password123456driverClassName 里的 cj 说明这是 MySQL 8 驱动serverTimezoneAsia/Shanghai 是针对 MySQL 8 必须加的不加会报时区相关的乱码错误characterEncodingutf8 保证中文字符不会乱码。如果你本地 MySQL 是 8.0而配置文件里还是老的 com.mysql.jdbc.Driver编译能过运行会报类找不到直接改成 com.mysql.cj.jdbc.Driver 即可。改完连接配置启动方式分成两种。方式一IDE 里直接运行。以 Maven 项目为例先让依赖解析完然后找到含 main 方法的启动类右键运行。如果是传统的 Web 项目非 Spring Boot有 web.xml则需要配置 TomcatRun Configurations 里添加一个 Tomcat Server - Local把 Deployment 指向项目然后启动。方式二Spring Boot 打包运行# 清理并打包skipTests 跳过单元测试加速打包 mvn clean package -DskipTests # 启动jar 会生成在 target 目录下 java -jar target/dormitory-system-1.0.jar --spring.profiles.activedev--spring.profiles.activedev是可选参数只有当项目里存在 application-dev.properties 时才需要。打包耗时如果超过两分钟大概率是卡在依赖下载上检查网络或者把 Maven 镜像配置为国内镜像地址。启动失败的三大排查看点日志第一屏是否有 Tomcat started on port(s): 8080浏览器访问 http://localhost:8080 是否有登录页如果端口被占用会报 Port 8080 was already in use.改 server.port 或换端口即可。3.4 部署文档的使用顺序先读目录再看视频按环境-数据库-配置-启动四步核对压缩包里带了部署文档和辅导视频。我的建议是不要一打开就双击视频因为视频拍摄时的数据库密码、端口和你本地大概率不一样照着敲字体会吃亏。正确用法是先看部署文档目录找环境要求再用视频辅助理解每个按钮在哪最后回到文档按步骤核对。部署文档常见的目录结构是一、环境要求二、数据库导入三、配置文件修改四、项目运行五、常见问题。如果在第三步里看到把密码改为你自己的这类字眼说明文档是活文档可以完全照做如果看到的是截图里有个密码就要警惕那只是作者的本地密码。还有一个小技巧文档里提到端口、访问路径、初始账号时我会先在文档里圈出来。这套系统的默认管理员账号十有八九是 admin/123456 或 admin/admin第一次登录后把默认密码改掉是上线前的第一步。这一步无关技术难度但最容易被人忽略——一个用默认密码的管理端和没设密码没什么区别。4. 源码阅读与二次开发从看懂分层结构到新增业务功能4.1 包结构导航先找到代码的入口顺序而不是逐行读打开源码先不要着急逐行读。找个分层规范的工程第一步是看包结构。典型结构是com.example.dormitory ├── controller # 控制层接收请求调用 service ├── service # 业务层写业务逻辑事务边界 ├── dao / mapper # 数据访问层SQL 与 ORM 映射 ├── entity / pojo # 实体类对应数据库表 ├── util # 工具类 └── config # 配置类Spring Boot 项目读代码的顺序我习惯是启动类 - 一个 controller - 它对应的 service - 它对应的 dao。这一段链路走通你就掌握了用户点按钮之后数据是怎么流转的。常见初学者翻车点是先去读工具类读半天不知道在干嘛等回到 controller 已经忘了上下文。实体类对应数据库表这个关系要看注解传统 SSM 用 TableName 或 XML 里的 resultMapSpring Data JPA 用 Entity Table(namet_student)。看到哪个注解就知道数据库的表名再去数据库确认字段完全一致。这一步不用动代码纯确认关系。确认完关系后再去找 session 的写入点——登录接口在哪里把 loginUser 放进 Session这决定了 3.3 节里过滤器的行为依据。4.2 新增一个晚归登记功能的最小改造路径从表到页面的五层改动二次开发是最能体现能不能动手的地方。以新增晚归登记为例我一般按表 - 实体 - DAO - Service - Controller - 页面的顺序加。这个顺序之所以固定是因为每一层都依赖下一层的产物没有表就没有实体没有实体就没有 DAO。第一步给数据库加一张表CREATE TABLE t_late_record ( id BIGINT AUTO_INCREMENT PRIMARY KEY, student_id BIGINT NOT NULL COMMENT 学生ID, record_date DATE NOT NULL COMMENT 晚归日期, reason VARCHAR(255) COMMENT 晚归原因, operator VARCHAR(50) COMMENT 登记人, create_time DATETIME DEFAULT CURRENT_TIMESTAMP ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;第二步新建实体类。字段与表一一对应使用 Long 对应 BIGINTLocalDate 对应 DATEpublic class LateRecord { private Long id; private Long studentId; private LocalDate recordDate; private String reason; private String operator; private LocalDateTime createTime; // getter / setter 略IDE 可一键生成 }第三步写 DAO 接口并使用注解写 SQL。这里的关键是参数名要和对象字段名完全一致public interface LateRecordDao { // Insert 把对象属性映射到 SQL 占位符 Insert(INSERT INTO t_late_record(student_id, record_date, reason, operator) VALUES(#{studentId}, #{recordDate}, #{reason}, #{operator})) int insert(LateRecord record); Select(SELECT * FROM t_late_record WHERE student_id #{studentId} ORDER BY record_date DESC) ListLateRecord findByStudentId(Long studentId); }第四步Service 层做事务与逻辑校验。晚归登记的校验点是学生必须是在住状态不能给已退宿的人登记。这个判断放在 Service 还是 DAOService因为要拿到 Student 对象再判断DAO 只负责单表数据Service public class LateRecordService { private final LateRecordDao lateRecordDao; private final StudentDao studentDao; public LateRecordService(LateRecordDao dao, StudentDao studentDao) { this.lateRecordDao dao; this.studentDao studentDao; } // Transactional 保证插入失败时自动回滚 Transactional public boolean addRecord(Long studentId, String reason, String operator) { Student stu studentDao.findById(studentId); if (stu null || stu.getStatus() ! 1) { // 非在住学生不能登记抛异常统一由 handler 处理 throw new BusinessException(该学生不在住无法登记晚归); } LateRecord record new LateRecord(); record.setStudentId(studentId); record.setRecordDate(LocalDate.now()); record.setReason(reason); record.setOperator(operator); return lateRecordDao.insert(record) 0; } }第五步Controller 层暴露接口。这里有一个最常见的坑前端传的是 studentId后端却定义成了 id导致 500。名字对齐了一切好说RestController RequestMapping(/late) public class LateRecordController { private final LateRecordService lateRecordService; PostMapping(/add) public Result add(RequestParam Long studentId, RequestParam String reason, RequestParam String operator) { boolean ok lateRecordService.addRecord(studentId, reason, operator); return ok ? Result.success() : Result.error(登记失败); } }最后是前端页面。在宿舍管理页面或学生详情页加一个晚归登记按钮通过 fetch 调用 /late/add!-- 前端页面晚归登记按钮 -- button onclickaddLateRecord()晚归登记/button script function addLateRecord() { const studentId document.getElementById(studentId).value; const reason prompt(请输入晚归原因); if (!reason) return; // 用 URLSearchParams 编码避免中文乱码 fetch(/late/add, { method: POST, headers: {Content-Type: application/x-www-form-urlencoded;charsetUTF-8}, body: studentId studentId reason encodeURIComponent(reason) operator document.getElementById(operator).value }).then(r r.json()).then(res { if (res.code 200) alert(登记成功); }); } /script这段前端逻辑说明一个细节请求头里的 charsetUTF-8 和 encodeURIComponent 同时使用才能保证中文原因不乱码。漏掉其中一个后端收到晚归原因就可能变成一串百分号编码。完成这一步一个从表到页面、纵向切穿的晚归登记功能就闭环了。4.3 前端页面的三处必改位置菜单、标签标题、接口地址拿到手的第一件事往往是改系统标题或 Logo但真正要让系统名正言顺有三处位置必须动。第一个是左侧菜单的菜单名在菜单管理配置或前端页面里把系统管理换成自己的模块名第二个是浏览器标签页的 title登录页和首页各一个第三个是页面底部或登录页的版权文案。这三处看似无关痛痒却在答辩演示时最先被人看到。如果前端是 JSP改 title 在 WEB-INF/views 下的布局页和各页面里的标签如果菜单写死在 sidebar.jsp 的 li 里直接搜索宿舍两个字全工程能搜出 10 到 30 处逐个替换即可如果前后端分离菜单往往是前端路由配置和后端没关系。/p p注意接口地址的修改要跟着后端上下文路径走。如果部署时 context path 从 / 改成了 /dormitory前端所有 /login、/student/list 这种绝对路径请求都要加上前缀不然页面上全是 404。部署文档若提到修改访问路径这一处是必查项。改完之后按 F12 看 Network 面板哪个接口红了就是哪个路径没跟上。/p h25. 避坑指南环境、配置、代码里的常见问题与排查记录/h2 h35.1 数据库连接失败从报错信息反推的三个常见原因/h3 p现象启动项目后页面报 500控制台日志里有 Communications link failure 或者 Access denied for user rootlocalhost。第一次遇到这种报错人很容易懵因为日志又长又乱看起来像代码爆炸其实链路很短。/p p原因大多不是项目问题而是本地服务状态或账号密码不匹配。我见过至少三次是 MySQL 服务压根没启动还有一次是密码改过但配置文件忘了同步另外一次是 MySQL 8 的认证插件和旧驱动不兼容。/p p解决按顺序排查三件事。第一确认 MySQL 服务状态Windows 用 codenet start | findstr mysql/codeLinux 用 codesystemctl status mysqld/code第二用命令行直接连库codemysql -uroot -p/code如果能连上再执行 codeSELECT 1;/code验证服务和账号都没问题第三确认配置文件里的账号、密码、库名和本地完全一致。这里有个细节MySQL 8 默认使用 caching_sha2_password 认证老驱动连不上需要把驱动升到 8.x 或把用户认证方式改回 mysql_native_password。这一套下来九成的连接失败都能定位到具体环节。/p h35.2 中文乱码字符集不一致的三个层面/h3 p现象登录后学生姓名、宿舍号显示成问号或者乱码存进数据库的内容也是花的。/p p原因乱码是字符集问题它可能发生在三个层面。第一个层面是数据库库、表、连接串三处的字符集不一致第二个层面是 JSP 或 HTML 页面编码第三个层面是 HTTP 请求参数在传输过程中没有被正确解码。很多人只改一处改完还是乱就是因为没意识到这是三层的串联。/p p解决数据库层面把整库改成 utf8mb4/p precode classlanguage-sqlALTER DATABASE dormitory CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; -- 只改个别表学生表为例 ALTER TABLE t_student CONVERT TO CHARACTER SET utf8mb4; /code/pre p如果改完还有乱码检查连接串是否带 code?characterEncodingutf8/code见 3.3 节再检查 JSP 文件第一行是否声明 code% page contentTypetext/html; charsetUTF-8 %/code。三层都要一致少一层都白改。这个排查顺序很关键先库、后连接、最后页面不要一上来就改代码否则会陷入改了好几次还是乱的死循环。/p h35.3 启动与编译异常端口占用、依赖下载失败、JDK 版本不一致/h3 p现象启动到一半报 Port 8080 was already in use或者构建工具卡在下载依赖不动又或编译报 java: 错误: 不支持发行版本 17。/p p原因端口被占用说明 8080 已经有别的进程在跑依赖下载失败通常是默认镜像源访问太慢发行版本报错是本机 JDK 太高而项目编译版本太低三者都是环境与项目预期不一致不是业务代码的问题。/p p解决端口问题改端口或用命令查占用进程。/p precode classlanguage-bash# 查看 8080 端口被谁占用 netstat -ano | findstr :8080 # 拿到 PID 后在任务管理器结束进程或直接改 server.port /code/pre p依赖下载问题在构建工具的 settings.xml 里配置国内镜像源这是国内最常见的加速手段。JDK 版本问题把 IDE 的 Project Structure - Project - SDK 改成 1.8Language Level 也改成 8或者干脆安装 JDK8 并切换系统环境变量。这一组问题看起来各有各的表现本质都是环境和项目预期不一致排查思路永远是让本地环境无限贴近项目作者的构建配置。/p h35.4 辅导视频与文档的差异版本、路径、密码三处误导/h3 p现象跟着辅导视频一步一步点到某一步就是跑不起来代码看着也没问题。/p p原因录屏有一个天然缺陷——录制时的环境和你本地不一样。我见过最典型的三处第一视频里点击运行的按钮位置可能和你的 IDE 版本不同新版 IDE 的 Run 按钮在右上角老版本在下方菜单位置也变了第二视频里的项目路径在某个中文目录下导致资源路径解析异常而你本地路径也可能带空格第三视频里输入的数据库密码是作者本机的不是你的照着输必败。/p p解决避开的方法很朴素——先把部署文档通读一遍再用视频对号入座。视频看到第几分钟在讲哪一步文档里对应的章节编号大概率相同。以文档为准、以视频为辅可以少走一小时弯路。如果文档和视频对不上记得以文档为准因为文档通常是最后一次整理环境的产物视频可能是更早时候录的。/p h26. 进阶验证与安全加固把能跑变成能交差的收尾操作/h2 h36.1 接口冒烟自测与密码加密的优先级/h3 p功能都跑通后建议做两件收尾的事接口自测和密码加密。接口自测不用发复杂工具直接用 curl 或浏览器开发者工具调登录接口先拿正常请求确认返回结构再拿错误密码确认返回业务错误码。下面的命令分别验证两种场景/p precode classlanguage-bash# 正确密码期望返回 code 200 和跳转路径 curl -X POST http://localhost:8080/login \ -d usernameadminpassword123456 \ -w \nHTTP_CODE:%{http_code}\n # 错误密码期望返回业务错误码而不是 500 curl -X POST http://localhost:8080/login \ -d usernameadminpasswordwrong \ -w \nHTTP_CODE:%{http_code}\n /code/pre p安全加固必改的一条是密码存储方式。如果源码里是明文比对或者简单 MD5演示前至少要改成加盐哈希。最小改动是在登录逻辑里加一个校验方法/p precode classlanguage-java// BCrypt 校验rawPassword 是用户输入encodedPassword 是数据库里存的哈希 if (BCrypt.checkpw(rawPassword, encodedPassword)) { // 校验通过写入 Session session.setAttribute(loginUser, user); } /code/pre p这是血泪经验数据库的 t_user 表密码不要再用明文。哪怕系统只在本地演示评审一句这个密码没有加密前面讲的功能再好也会减分。最后留下一个习惯关闭项目前手动把数据库脚本重新导出一份放到项目根目录保证重新打开也能一秒跑通。这个动作我每次接手别人的项目都会做一遍——既是对自己负责也是后面接手的人最快的后悔药。希望帮到你。/p p a hrefhttps://download.csdn.net/download/dwf1354046363/87787574 stylecolor:#ec7500;font-size:14px; 本文还有配套的精品资源点击获取 /a img altmenu-r.4af5f7ec.gif srchttps://csdnimg.cn/release/wenkucmsfe/public/img/menu-r.4af5f7ec.gif stylewidth:16px;margin-left:4px;vertical-align:text-bottom;cursor:text; /p

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑