ARTICLE DETAIL

资讯详情

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

Java Web基础项目:JSP+Servlet+MySQL宿舍管理系统实战

Java Web基础项目:JSP+Servlet+MySQL宿舍管理系统实战 简介这是一份面向Java Web开发初学者的宿舍管理实战项目资源基于ServletJSPMySQL技术栈实现完整MVC架构聚焦基础Web应用开发全流程训练适用于课程设计、毕业设计入门及自学实践。资源包共63个文件含18个核心Java源码Servlet与DAO逻辑、18个编译后class文件、5个JSP页面登录、列表、增删改表单等原生界面、1个SQL建库脚本nafeng.sql及配套配置文档详细配置.docx和功能说明txt另有操作演示mp4视频与界面截图png整体压缩包约10.01MB。已有1160人学习下载内容覆盖数据库设计、Servlet请求处理、JSP动态渲染、JDBC连接与CRUD实现并附带Session登录状态管理与基础错误提示机制结构清晰、注释完整便于逐模块理解前后端交互与数据流转逻辑。1. 这不是“过时技术堆砌”而是一套能跑通、能调试、能改出毕业设计的 Java Web 黑盒验证系统你打开 Eclipse新建 Dynamic Web Project配好 Tomcat 9.0却卡在ClassNotFoundException: com.mysql.cj.jdbc.Driver你照着视频把login.jsp改了三遍表单提交后页面空白控制台没报错但doPost()根本没进你导出nafeng.sql到本地 MySQL执行完发现user表里password字段全是明文连 MD5 都没加——这些不是你水平问题是原生 JSPServlet 项目天然带的「调试黑匣子」。这个008_javajspmysql简单宿舍管理系统正是为这种状态量身定制它不炫技、不抽象、不依赖 Maven 或 Spring Boot所有代码都在sushe/目录下裸露可见JSP 里嵌的是request.getParameter()而不是 EL 表达式Servlet 里写的是response.sendRedirect()而不是WebServlet注解。它解决的不是“高并发”或“微服务”而是「从零部署一个能登录、能查宿舍、能增删数据的完整 Web 流程」——适合大三刚学完 JDBC 的学生也适合想快速验证 Servlet 生命周期的转行者。如果你正被 IDEA 里一堆红色波浪线折磨或者需要一份能直接粘贴进答辩 PPT 的可运行截图1.png到4.png就是登录页、宿舍列表、添加表单、修改弹窗那这份资源就是你的后悔药。2. 数据库与连接层MySQL 5.7 兼容性实测 JDBC 驱动版本踩坑闭环2.1 从nafeng.sql看真实建表逻辑与字段陷阱这个 SQL 文件共 3 张表user用户登录、dormitory宿舍主表、student学生入住关联。关键细节不在 DDL 语法而在字段设计意图dormitory表中dorm_no VARCHAR(20)是主键但dorm_type ENUM(四人间,六人间,八人间)没设默认值导致 INSERT 时若漏填会报错student表的dorm_id INT外键指向dormitory.id但 SQL 文件里没写FOREIGN KEY约束纯靠业务代码维护一致性——这是故意为之避免初学者被外键报错卡死所有DATETIME字段如create_time用的是NOW()默认值而非CURRENT_TIMESTAMP适配 MySQL 5.6 旧版本。提示别直接source nafeng.sql先用CREATE DATABASE nafeng CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;建库再USE nafeng;后执行否则中文会乱码。2.2web.xml中的 JDBC 配置与驱动加载路径项目没用context.xml或DataSource而是硬编码在DBUtil.java位于src/下public class DBUtil { private static final String URL jdbc:mysql://localhost:3306/nafeng?useSSLfalseserverTimezoneGMT%2B8; private static final String USER root; private static final String PASSWORD 123456; // 注意密码明文仅用于本地测试 private static Connection conn null; public static Connection getConnection() { try { Class.forName(com.mysql.cj.jdbc.Driver); // MySQL 8.0 驱动类名 conn DriverManager.getConnection(URL, USER, PASSWORD); } catch (Exception e) { e.printStackTrace(); // 关键这里必须打印异常否则静默失败 } return conn; } }这段代码暴露了两个致命兼容点若你用的是MySQL 5.7非 8.0com.mysql.cj.jdbc.Driver会报ClassNotFoundException必须改成com.mysql.jdbc.DriverserverTimezoneGMT%2B8是为解决时区报错但若你本地 MySQL 配置了default-time-zone08:00此参数可删否则可能引发The server time zone value ... is unrecognizeduseSSLfalse不是安全妥协而是因本地自签名证书未配置强行开启 SSL 会导致连接超时。2.3 连接池不存在的——为什么这里坚持用DriverManager有人问“都 2024 年了为啥不用 HikariCP”答案很现实这个项目要让你看清每一次数据库交互的完整链路。用连接池会隐藏Connection获取、Statement创建、ResultSet关闭的时机而原生DriverManager让你能在DormitoryServlet.java的doGet()里用System.out.println(SQL executed: sql);打印每条执行语句在DBUtil.close()方法中手动调用rs.close(); stmt.close(); conn.close();理解资源泄漏根源当NullPointerException报在rs.next()时立刻知道是conn为空而非 SQL 语法错。这不是反模式是教学必需的“减速带”。3. Servlet 层请求分发、参数校验与跳转逻辑的显式控制3.1web.xml中的 URL 映射与生命周期验证整个系统的入口由web.xml定义而非注解servlet servlet-nameLoginServlet/servlet-name servlet-classsushe.servlet.LoginServlet/servlet-class /servlet servlet-mapping servlet-nameLoginServlet/servlet-name url-pattern/login/url-pattern /servlet-mapping这种写法强制你理解/login是浏览器地址栏输入的路径不是LoginServlet.java的类名LoginServlet必须继承HttpServlet且doPost()处理表单提交methodpostdoGet()处理链接跳转如登出后重定向到登录页若你把url-pattern写成/login.do而 JSP 表单actionlogin则请求根本到不了 Servlet——这是新手最常翻车的点。3.2 登录流程中的三次校验前端、Servlet、数据库缺一不可以LoginServlet.java为例它的校验链是空值校验防 NPEString username request.getParameter(username); String password request.getParameter(password); if (username null || username.trim().isEmpty() || password null || password.trim().isEmpty()) { request.setAttribute(error, 用户名或密码不能为空); request.getRequestDispatcher(login.jsp).forward(request, response); return; // 关键return 阻止后续执行 }数据库校验查user表String sql SELECT * FROM user WHERE username? AND password?; PreparedStatement ps conn.prepareStatement(sql); ps.setString(1, username); ps.setString(2, password); // 注意此处明文比对无加密 ResultSet rs ps.executeQuery(); if (rs.next()) { // 存在匹配记录 HttpSession session request.getSession(); session.setAttribute(user, username); // 存入 session response.sendRedirect(main.jsp); // 重定向非 forward } else { request.setAttribute(error, 用户名或密码错误); request.getRequestDispatcher(login.jsp).forward(request, response); }Session 校验防未登录访问在main.jsp开头加% String user (String) session.getAttribute(user); if (user null) { response.sendRedirect(login.jsp); return; // JSP 中的 return 阻止后续 HTML 渲染 } %这三层校验不是冗余而是让你看清前端 JS 校验可绕过Servlet 校验是底线Session 校验是会话守门员。3.3 CRUD 操作中的 SQL 注入防护实操AddDormitoryServlet.java的插入逻辑看似简单String dormNo request.getParameter(dormNo); String dormType request.getParameter(dormType); // ...其他字段 String sql INSERT INTO dormitory (dorm_no, dorm_type, capacity, status) VALUES ( dormNo , dormType , capacity , status );这是典型注入漏洞项目实际代码用的是PreparedStatementString sql INSERT INTO dormitory (dorm_no, dorm_type, capacity, status) VALUES (?, ?, ?, ?); PreparedStatement ps conn.prepareStatement(sql); ps.setString(1, dormNo); ps.setString(2, dormType); ps.setInt(3, capacity); ps.setString(4, status); ps.executeUpdate();区别在哪拼接 SQLdormNo输入 OR 11会变成WHERE dorm_no OR 11查出所有宿舍PreparedStatement?占位符让 MySQL 将输入视为纯字符串 OR 11会被当作文本存入dorm_no字段毫无危害。这个对比必须亲手改一次代码、测一次漏洞才能刻进肌肉记忆。4. JSP 视图层原生标签、Java 脚本与 HTML 混合开发的边界控制4.1login.jsp中的表单结构与错误提示机制JSP 不是 HTML它的核心价值在于动态渲染。看login.jsp如何处理错误% String error (String) request.getAttribute(error); if (error ! null !error.isEmpty()) { % div stylecolor:red; font-weight:bold;% error %/div % } % form actionlogin methodpost 用户名input typetext nameusername requiredbr 密码input typepassword namepassword requiredbr input typesubmit value登录 /form这里的关键是request.getAttribute(error)是 Servletforward()传递的数据redirect()无法传递因重定向是新请求% error %是表达式标签等价于out.print(error)不能写成% error %那是脚本片段不输出required是 HTML5 属性但仅前端校验必须配合 Servlet 的空值检查否则绕过浏览器仍可提交。4.2dormList.jsp中的循环与数据绑定宿舍列表页用JSTL不它用最原始的while(rs.next())% Connection conn DBUtil.getConnection(); String sql SELECT * FROM dormitory ORDER BY id DESC; PreparedStatement ps conn.prepareStatement(sql); ResultSet rs ps.executeQuery(); % table border1 trth宿舍号/thth类型/thth容量/thth状态/thth操作/th/tr % while(rs.next()) { % tr td% rs.getString(dorm_no) %/td td% rs.getString(dorm_type) %/td td% rs.getInt(capacity) %/td td% rs.getString(status) %/td td a hrefeditDormitory?id% rs.getInt(id) %编辑/a | a hrefdeleteDormitory?id% rs.getInt(id) % onclickreturn confirm(确定删除)删除/a /td /tr % } DBUtil.close(rs, ps, conn); % /table这种写法暴露了 JSP 的本质它是 Servlet 的 HTML 模板所有 Java 代码最终编译成_jspService()方法。你看到的% %是脚本片段% %是表达式%! %是声明但本项目没用。好处是逻辑透明坏处是易写错DBUtil.close()位置——若放在while外rs未关闭就conn.close()下次查询会报Connection closed。4.3 图片与静态资源路径的绝对 vs 相对之争项目图片1.png到4.png放在WebContent/images/下JSP 中引用方式是img srcimages/1.png alt登录界面注意srcimages/1.png是相对路径相对于当前 JSP 文件所在目录WebContent/若你把图片移到WebContent/static/img/必须同步改所有src为static/img/1.pngsrc/images/1.png开头带/是绝对路径从应用根目录开始即http://localhost:8080/yourapp/images/1.png此时需确保images/在WebContent/下srcimages/1.png在login.jsp位于WebContent/中有效但在admin/dormList.jsp位于WebContent/admin/中会变成http://.../admin/images/1.png404解决方案统一用src% request.getContextPath() %/images/1.png。5. 避坑指南那些让项目跑不起来的 5 个玄学问题与血泪解法5.1 现象Tomcat 启动成功但访问http://localhost:8080/sushe/login.jsp报 404原因项目名sushe未正确部署。Eclipse 中右键项目 → Properties → Web Project Settings → Context root 必须设为sushe不能是默认的项目名或空若用外部 Tomcat需确认webapps/sushe/目录存在且包含WEB-INF/web.xml和login.jsp。解决在 Eclipse 的 Servers 视图中双击 Tomcat → Modules → 点击sushe→ Edit → 确保 Path 为/sushe或手动将sushe/文件夹复制到tomcat/webapps/下重启。5.2 现象登录时控制台打印java.lang.ClassNotFoundException: com.mysql.cj.jdbc.Driver原因MySQL 8.0 驱动类名变更且mysql-connector-java-8.0.x.jar未放入WEB-INF/lib/。解决下载mysql-connector-java-8.0.33.jar兼容 5.7 和 8.0放入WEB-INF/lib/若用 MySQL 5.7改DBUtil.java中Class.forName(com.mysql.jdbc.Driver)关键验证在DBUtil.getConnection()开头加System.out.println(Driver loaded);确认类加载成功。5.3 现象添加宿舍后页面跳转到addSuccess.jsp但列表页不刷新新数据不见原因AddDormitoryServlet中用了request.getRequestDispatcher(addSuccess.jsp).forward(request, response);但addSuccess.jsp里没重定向回列表页用户点击浏览器刷新会重复提交。解决在addSuccess.jsp结尾加 JavaScript 自动跳转script setTimeout(function(){ window.location.hrefdormList.jsp; }, 2000); /script或更规范地在 Servlet 中response.sendRedirect(dormList.jsp);——重定向Redirect才能清空表单数据避免 F5 重复提交。5.4 现象dormList.jsp中rs.getString(dorm_no)报SQLException: Column dorm_no not found原因SQL 查询字段名与数据库实际字段名大小写不一致。MySQL 在 Linux 下字段名区分大小写dorm_no写成DORM_NO或dorm_No会失败。解决用rs.getNString(dorm_no)替代getString()兼容性更好或在 SQL 中明确别名SELECT dorm_no AS dorm_no, dorm_type AS dorm_type FROM dormitory并确认nafeng.sql中建表语句确实是小写字段名。5.5 现象中文显示为??如宿舍类型显示????原因三个环节编码不一致MySQL 服务器、数据库、表、JSP 页面、Tomcat 配置。解决四步闭环MySQL 服务器my.ini中[mysqld]下加character-set-serverutf8mb4数据库CREATE DATABASE nafeng CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;JSP 页面% page contentTypetext/html;charsetUTF-8 %必须在第一行Tomcatconf/server.xml中Connector port8080 ... URIEncodingUTF-8/添加URIEncodingUTF-8。验证在login.jsp中写% 中文测试.length() %输出4即成功。6. 进阶技巧用git diff回溯修改痕迹 三步法验证功能完整性6.1 用 Git 版本控制做你的“后悔药”别把008_javajspmysql简单宿舍管理系统.zip解压后直接改正确姿势# 1. 初始化仓库在 sushe/ 目录下 git init git add . git commit -m initial commit: clean version from zip # 2. 修改前打快照 git commit -am before adding password encryption # 3. 加 MD5 加密后用 git diff 查看改动范围 git diff HEAD~1 -- src/sushe/servlet/LoginServlet.java你会看到原if (rs.next())条件里密码比对从password.equals(inputPwd)变成MD5Util.md5(inputPwd).equals(rs.getString(password))新增MD5Util.java工具类nafeng.sql中user表的password字段值已从明文改为e10adc3949ba59abbe56e057f20f883e123456 的 MD5。这种粒度控制让你敢改、敢试、敢回滚——而不是靠 CtrlZ 猜哪行错了。6.2 功能完整性验证的三步法表格每次新增功能如增加“按类型筛选宿舍”用这张表自查验证维度检查项通过标准工具/命令前端触达filter.jsp表单actionfilterDormitory是否存在浏览器开发者工具 Network 标签能看到 POST 请求Chrome DevTools后端接收FilterDormitoryServlet.java的doPost()是否被调用控制台打印System.out.println(Filter servlet invoked)Tomcat logs/catalina.out数据落地dormitory表查询结果是否按dorm_type过滤执行SELECT * FROM dormitory WHERE dorm_type四人间;对比 JSP 输出MySQL CLI 或 Navicat注意第三步必须用数据库直查不能只信 JSP 页面显示——因为rs.getString()可能因字段名错误返回 null而 JSP 的% %会输出空字符串掩盖问题。6.3 从那以后我每次改完 Servlet都强制走一遍「请求链路断点」在LoginServlet.java的doPost()第一行加System.out.println( LoginServlet doPost START );在DBUtil.getConnection()里加System.out.println(DB connection established);在dormList.jsp开头加% System.out.println(dormList.jsp rendered); %。然后启动 Tomcat用 Postman 发送POST /login观察控制台日志是否按顺序出现这三行。如果DB connection established没出现说明连接失败如果dormList.jsp rendered出现但页面空白说明 JSP 编译错误如%没闭合。这套链路日志不是为了炫技而是把“请求从浏览器发出到 HTML 返回”的黑盒切成可触摸的物理节点。希望帮到你。本文还有配套的精品资源点击获取
返回列表