ARTICLE DETAIL

资讯详情

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

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

Java Web基础实战:JSP+Servlet+MySQL宿舍管理系统详解 简介这是一套面向Java Web初学者的宿舍管理实战项目基于ServletJSPMySQL技术栈实现原生界面开发聚焦Web基础架构与前后端协同逻辑适用于高校课程设计、自学入门及Web开发岗技能筑基。资源包共63个文件含18个Java源码核心Servlet业务逻辑、18个Class编译文件、5个JSP页面登录页、宿舍列表、增删改表单等视图层、1个SQL建库脚本nafeng.sql、1个功能说明文档及1个实操演示MP4视频辅以图片、配置文件与IDE工程元数据整体约10.01MB结构完整便于逐层理解MVC分层实践。已有1160人学习下载提供从数据库建模、JDBC连接、请求响应处理到页面动态渲染的全链路代码与可视化操作录屏特别适合通过真实CRUD场景掌握会话管理Session、表单交互、SQL嵌入及错误提示机制等关键能力。1. 这不是“过时技术堆砌”而是一套能跑通、能调试、能改出毕业设计的 Java Web 黑盒验证器你可能在头歌实训、课程设计选题表、Java Web 入门课 PPT 里反复见过它一个带登录页、宿舍列表页、增删改弹窗的 JSP 页面集合背后连着 MySQL 表用几个HttpServlet类撑起全部逻辑。它不炫技、没 Spring Boot 自动装配、没 Vue 响应式绑定——但正因如此它成了我带学生做第一个可部署 Web 项目时唯一敢让学生从零手敲、逐行 debug、改完立刻看到效果的“最小可运行闭环”。这个008_javajspmysql简单宿舍管理系统.zip不是教学幻灯片而是真实可执行的 WAR 包雏形nafeng.sql能一键建库建表sushe/目录下.jsp和.java文件一一对应请求路径web.xml里servlet-mapping明确绑定/login到LoginServlet连session.setAttribute(user, user)都写在doPost里没藏在工具类里。它解决的不是高并发或微服务拆分而是初学者最痛的三个问题HTTP 请求到底怎么从浏览器落到 Java 类里JSP 里的% request.getAttribute(msg) %怎么和 Servlet 的request.setAttribute()对上号MySQL 插入失败时到底是 SQL 写错了还是 JDBC URL 少了个?useSSLfalse适合谁不是想跳槽大厂的面试突击者而是刚学完 Java 面向对象、正卡在“写了代码却不知道怎么让网页动起来”的课程设计学生用 VS Code 或 IDEA 新建 JSP 项目时被webapp/WEB-INF/web.xml和src/目录结构绕晕的自学新手或者需要快速验证某个 Servlet 生命周期细节比如init()是否真只执行一次的调试者。它不教你怎么写八股文但教你亲手把“Java 代码 → HTTP 响应 → 浏览器渲染”这条链路抠断、再焊牢。2. 从数据库到页面五步还原这套系统的真实运行链条2.1 数据库初始化nafeng.sql不是脚本是状态快照这个 SQL 文件不是空库建表的 DDL 指令集而是包含数据的完整快照。直接执行会创建nafeng库并建三张表users用户账号密码、dormitory宿舍信息、student学生入住关联。关键点在于字段设计暴露了原始开发意图CREATE TABLE users ( id int(11) NOT NULL AUTO_INCREMENT, username varchar(50) NOT NULL, password varchar(50) NOT NULL, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8;注意密码明文存储varchar(50)无盐值、无哈希——这不是漏洞而是教学简化。实际部署必须替换为BCryptPasswordEncoder但此刻你要先理解Servlet 如何把表单提交的request.getParameter(password)直接拼进INSERT INTO users VALUES(...)。执行命令确保 MySQL 已启动且 root 密码已知mysql -u root -p nafeng.sql成功后验证USE nafeng; SELECT COUNT(*) FROM dormitory; -- 应返回 3 条预置宿舍数据2.2 Servlet 核心逻辑LoginServlet.java是整个系统的入口探针打开sushe/src/LoginServlet.java它不是抽象模板而是具体业务实现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. 直接 JDBC 查询无连接池教学简化 Connection conn null; PreparedStatement pstmt null; ResultSet rs null; try { Class.forName(com.mysql.jdbc.Driver); // 注意MySQL 5.x 驱动类名 conn DriverManager.getConnection( jdbc:mysql://localhost:3306/nafeng?useUnicodetruecharacterEncodingUTF-8useSSLfalse, root, your_password); pstmt conn.prepareStatement(SELECT * FROM users WHERE username? AND password?); pstmt.setString(1, username); pstmt.setString(2, password); rs pstmt.executeQuery(); if (rs.next()) { // 2. 登录成功存 session 并重定向 HttpSession session request.getSession(); session.setAttribute(user, username); response.sendRedirect(main.jsp); } else { // 3. 失败回传错误信息到 login.jsp request.setAttribute(msg, 用户名或密码错误); request.getRequestDispatcher(login.jsp).forward(request, response); } } catch (Exception e) { e.printStackTrace(); // 关键教学版保留此行方便你看到堆栈 request.setAttribute(msg, 系统异常请重试); request.getRequestDispatcher(login.jsp).forward(request, response); } finally { // 4. 手动关闭资源无 try-with-resources暴露资源管理逻辑 if (rs ! null) rs.close(); if (pstmt ! null) pstmt.close(); if (conn ! null) conn.close(); } } }参数说明与逻辑拆解useSSLfalseMySQL 8.0 默认强制 SSL本地开发必须显式关闭否则报错Access denied for userrequest.getRequestDispatcher(login.jsp).forward(...)服务器端跳转URL 不变request.setAttribute()传递的数据在login.jsp中可用response.sendRedirect(main.jsp)客户端重定向URL 变为/main.jspsession是跨请求共享的唯一凭证Class.forName(com.mysql.jdbc.Driver)MySQL 5.x 驱动类名若用 MySQL 8.x 需改为com.mysql.cj.jdbc.Driver否则ClassNotFoundException。2.3 JSP 页面渲染login.jsp里的% %不是魔法是 Servlet 的“快递员”login.jsp开头有标准声明% page languagejava contentTypetext/html; charsetUTF-8 pageEncodingUTF-8% % taglib prefixc urihttp://java.sun.com/jsp/jstl/core %但真正驱动页面的是这三行% String msg (String) request.getAttribute(msg); if (msg ! null !msg.isEmpty()) { % div classalert alert-danger% msg %/div % } %为什么不用 JSTLc:if因为这是原生 JSP 教学场景——让你看清request.getAttribute()返回的是Object必须强转String且null判断不能省。% msg %输出的不是变量名而是msg.toString()结果若msg为null会输出null字符串所以前置判空。表单提交指向LoginServletform actionlogin methodpost input typetext nameusername required input typepassword namepassword required button typesubmit登录/button /form注意actionlogin对应web.xml中url-pattern/login/url-pattern而非/LoginServlet——这是 Servlet 映射的本质URL 路径是逻辑标识不是文件路径。2.4 web.xml 配置servlet和servlet-mapping是请求路由的宪法WEB-INF/web.xml是整个系统的路由中枢必须严格匹配servlet servlet-nameLoginServlet/servlet-name servlet-classLoginServlet/servlet-class /servlet servlet-mapping servlet-nameLoginServlet/servlet-name url-pattern/login/url-pattern /servlet-mapping关键约束servlet-class值是类的全限定名如com.example.LoginServlet但本项目中所有 Servlet 都在默认包no package所以直接写LoginServlet若你在 IDE 中新建 Servlet 时勾选了 “Create servlet in package”则servlet-class必须写成com.nafeng.LoginServlet否则ClassNotFoundExceptionurl-pattern支持通配符如/admin/*但本项目用精确匹配/login避免路由歧义。2.5 项目结构验证sushe/目录不是随意摆放是 Tomcat 加载规则的具象化解压后sushe/目录结构即部署结构sushe/ ├── WEB-INF/ │ ├── web.xml ← 部署描述符Tomcat 启动时读取 │ └── lib/ │ └── mysql-connector-java-5.1.47.jar ← JDBC 驱动必须 ├── login.jsp ← 公开访问的 JSP无需映射 ├── main.jsp ← 登录后跳转页 ├── addDormitory.jsp ← 添加宿舍表单页 └── src/ ← Java 源码需编译为 .class 放入 WEB-INF/classes/ └── LoginServlet.javaTomcat 加载顺序启动时扫描WEB-INF/web.xml注册所有servlet接收/login请求匹配url-pattern找到LoginServlet类若WEB-INF/classes/下无编译好的.class则报HTTP Status 404若WEB-INF/lib/缺少mysql-connector-java-x.x.x.jar则Class.forName()抛ClassNotFoundException。提示IDEA 或 Eclipse 新建 Dynamic Web Project 时src/下的.java会自动编译到WEB-INF/classes/VS Code 用户需手动javac -cp WEB-INF/lib/mysql-connector-java-5.1.47.jar -d WEB-INF/classes/ src/LoginServlet.java。3. 避坑五个让新手卡住超过 2 小时的“玄学”问题及血泪解法3.1 现象页面显示HTTP Status 404 – Not Found但login.jsp文件明明存在原因Tomcat 未正确部署sushe目录或 URL 访问路径错误。常见误操作直接双击login.jsp用浏览器打开此时是file://协议Servlet 完全不生效访问http://localhost:8080/login.jsp正确但web.xml中未配置login.jsp的servlet-mapping其实不需要JSP 可直访实际想访问http://localhost:8080/sushe/login.jsp但 Tomcat 部署时 Context Path 设为/而非/sushe。解决确认 Tomcatwebapps/目录下存在sushe/文件夹非sushe.zip启动 Tomcat 后访问http://localhost:8080/sushe/login.jsp若仍 404检查catalina.out日志末尾是否有Deploying web application directory字样确认部署成功。3.2 现象登录时控制台打印java.lang.ClassNotFoundException: com.mysql.jdbc.Driver原因JDBC 驱动版本与 MySQL 版本不匹配或 JAR 包未放入WEB-INF/lib/。MySQL 5.7 及以下用mysql-connector-java-5.1.x.jar驱动类名com.mysql.jdbc.DriverMySQL 8.0用mysql-connector-java-8.0.x.jar驱动类名com.mysql.cj.jdbc.Driver且 URL 必须加serverTimezoneUTC。解决查看 MySQL 版本mysql --version下载对应驱动 MySQL 官网 Connector/J 放入WEB-INF/lib/修改LoginServlet.java中Class.forName()和 JDBC URL// MySQL 8.0 Class.forName(com.mysql.cj.jdbc.Driver); String url jdbc:mysql://localhost:3306/nafeng?useUnicodetruecharacterEncodingUTF-8useSSLfalseserverTimezoneUTC;3.3 现象登录成功后跳转main.jsp但页面显示java.lang.NullPointerException在% session.getAttribute(user) %原因session.setAttribute(user, username)执行了但main.jsp中未判断session是否为空。request.getSession()默认true创建新 session但若用户未登录直接访问main.jspsession.getAttribute(user)返回null% null %不报错但后续session.getAttribute(user).toString()会 NPE。解决在main.jsp顶部添加守卫逻辑% HttpSession session request.getSession(false); // false 表示不创建新 session if (session null || session.getAttribute(user) null) { response.sendRedirect(login.jsp); return; // 立即终止响应 } %3.4 现象添加宿舍时INSERT INTO dormitory报错Data truncation: Data too long for column dormNo at row 1原因dormNo字段定义为varchar(10)但表单提交了超长字符串如D1001-2023-001-A。nafeng.sql中建表语句为CREATE TABLE dormitory ( id int(11) NOT NULL AUTO_INCREMENT, dormNo varchar(10) NOT NULL, -- 关键长度仅 10 type varchar(20) DEFAULT NULL, capacity int(11) DEFAULT NULL, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8;解决前端限制输入长度在addDormitory.jsp的input中加maxlength10后端校验AddDormitoryServlet.java中添加String dormNo request.getParameter(dormNo); if (dormNo.length() 10) { request.setAttribute(msg, 宿舍号长度不能超过10位); request.getRequestDispatcher(addDormitory.jsp).forward(request, response); return; }3.5 现象中文乱码——登录页输入中文用户名数据库存入??页面显示????原因三处编码未统一MySQL 连接 URL、JSP 页面声明、Tomcatserver.xml。解决四步闭环nafeng.sql文件本身用 UTF-8 编码保存VS Code 右下角确认JDBC URL 加useUnicodetruecharacterEncodingUTF-8login.jsp顶部声明% page contentTypetext/html; charsetUTF-8 pageEncodingUTF-8%Tomcatconf/server.xml中Connector标签加URIEncodingUTF-8Connector port8080 protocolHTTP/1.1 connectionTimeout20000 redirectPort8443 URIEncodingUTF-8 /4. 从“能跑”到“能改”三个实战级改造技巧让系统脱离教学 Demo4.1 技巧一用ServletContext替代硬编码 JDBC 参数实现配置中心化当前所有 ServletLoginServlet,AddDormitoryServlet等都重复书写 JDBC URL、用户名、密码。一旦数据库迁移需修改 5 个文件。改造方案将连接参数提到web.xml由ServletContext统一注入。步骤修改WEB-INF/web.xml在web-app标签下添加context-param param-namejdbcUrl/param-name param-valuejdbc:mysql://localhost:3306/nafeng?useUnicodetrueamp;characterEncodingUTF-8amp;useSSLfalse/param-value /context-param context-param param-namejdbcUser/param-name param-valueroot/param-value /context-param context-param param-namejdbcPassword/param-name param-valueyour_password/param-value /context-param注意在 XML 中需转义为amp;否则解析失败。在任意 Servlet 的init()方法中读取以LoginServlet为例private String jdbcUrl; private String jdbcUser; private String jdbcPassword; public void init() throws ServletException { ServletContext context getServletContext(); jdbcUrl context.getInitParameter(jdbcUrl); jdbcUser context.getInitParameter(jdbcUser); jdbcPassword context.getInitParameter(jdbcPassword); } protected void doPost(...) { // 原 getConnection() 替换为 conn DriverManager.getConnection(jdbcUrl, jdbcUser, jdbcPassword); }价值下次换数据库只需改web.xml无需碰 Java 代码ServletContext在应用启动时加载一次性能无损。4.2 技巧二用Filter统一处理登录拦截告别每个 JSP 顶部的session判空当前main.jsp,dormList.jsp等页面都需手动校验session。改造方案编写LoginFilter对/main.jsp,/dormList.jsp等路径强制拦截。创建LoginFilter.javapublic class LoginFilter implements Filter { 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.contains(main.jsp) || uri.contains(dormList.jsp)) { HttpSession session request.getSession(false); if (session null || session.getAttribute(user) null) { response.sendRedirect(request.getContextPath() /login.jsp); return; } } chain.doFilter(req, resp); // 放行 } }在web.xml中注册filter filter-nameLoginFilter/filter-name filter-classLoginFilter/filter-class /filter filter-mapping filter-nameLoginFilter/filter-name url-pattern/*/url-pattern /filter-mapping价值权限控制逻辑集中新增页面无需改 JSPFilter是 Servlet 规范标准组件比 JSP 脚本更易维护。4.3 技巧三用PreparedStatement参数化查询防御 SQL 注入同时修复LIKE模糊搜索当前DormitorySearchServlet.java中搜索逻辑为String keyword request.getParameter(keyword); String sql SELECT * FROM dormitory WHERE dormNo LIKE % keyword %; pstmt conn.prepareStatement(sql); // 危险直接拼接改造方案使用?占位符setString()设置参数String sql SELECT * FROM dormitory WHERE dormNo LIKE ?; pstmt conn.prepareStatement(sql); pstmt.setString(1, % keyword %); // 关键% 符号在 Java 层拼接为防止keyword包含_或%被当作通配符添加转义// 转义字符\_ \% String escapedKeyword keyword.replace(_, \\_).replace(%, \\%); pstmt.setString(1, % escapedKeyword %); // SQL 中需指定 ESCAPE 字符 sql SELECT * FROM dormitory WHERE dormNo LIKE ? ESCAPE \\;价值一行代码升级安全等级PreparedStatement还能提升批量插入性能本系统暂未用但已铺好路。5. 验证你的修改是否生效一份可执行的“黑盒测试清单”不要依赖“看起来正常”用这 7 个原子操作验证每一处改动测试项操作步骤预期结果失败定位点数据库连接启动 MySQL执行mysql -u root -p -e USE nafeng; SELECT * FROM users LIMIT 1;返回一条用户记录如1, admin, 123456nafeng.sql未执行或密码错误Servlet 映射访问http://localhost:8080/sushe/login注意无.jsp返回HTTP Status 404因为/login是 Servlet 路径非静态文件web.xml中servlet-mapping缺失或 URL 错误JSP 渲染访问http://localhost:8080/sushe/login.jsp显示登录表单且右上角无乱码文字pageEncoding或contentType未设 UTF-8或 TomcatURIEncoding缺失登录流程输入admin/123456提交 → 查看浏览器地址栏URL 变为http://localhost:8080/sushe/main.jspresponse.sendRedirect()未执行或session未设置Session 保持登录后新开无痕窗口访问http://localhost:8080/sushe/main.jsp自动跳回login.jspLoginFilter未生效或getSession(false)逻辑错误中文存储在addDormitory.jsp输入宿舍号东区101→ 提交 → 查看数据库dormitory.dormNo字段值为东区101非??JDBC URL 缺characterEncoding或 MySQL 表字符集非utf8mb4SQL 注入防护在搜索框输入 OR 11→ 提交返回空结果集不报错也不返回所有宿舍PreparedStatement未使用仍用字符串拼接我的习惯每次改完一个功能如加了Filter就按此表顺序执行一遍。曾有一次Filter配置错写成url-pattern/main.jsp/url-pattern漏了*导致/dormList.jsp未被拦截花了 40 分钟才定位到web.xml的斜杠位置。从那以后我每次改配置文件都强制走一遍第 2 项和第 6 项测试——配置类修改永远比代码逻辑更容易翻车。希望帮到你。本文还有配套的精品资源点击获取
返回列表