ARTICLE DETAIL

资讯详情

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

JSP+Servlet宿舍管理系统实战:从部署到事务控制

JSP+Servlet宿舍管理系统实战:从部署到事务控制 简介这是一套基于JSPServlet技术栈开发的宿舍管理系统完整课设资源面向计算机、软件工程、电子信息等专业本科生适用于JavaWeb课程设计、期末大作业及毕业设计参考。资源包含可直接运行的源码、MySQL数据库脚本、详细设计说明书及配套前端资源覆盖学生管理、宿舍分配、报修处理等核心业务模块代码结构清晰分层合理便于理解MVC模式在Web应用中的实践。压缩包共281个文件含44个Java业务类、16个JSP页面、32个HTML静态页、24个JS交互脚本、7个CSS样式文件及1个SQL建库脚本辅以GIF动图说明和Class编译文件整体大小仅4.66MB轻量易部署。目前已有164人学习下载读者可获得从需求分析、数据库设计、前后端交互到部署调试的全流程参考尤其适合初学JavaWeb但需完成高分课设的学生快速上手与二次开发。1. 这不是“过时技术”的课设而是 JavaWeb 工程能力的显性标尺你打开一个名为基于jspservlet的宿舍管理系统源码数据库设计说明书javaweb高分课设.zip的压缩包第一眼看到的是web.xml、index.jsp、StudentServlet.java和mysql.sql——没有 Spring Boot 自动装配没有 Vue 前端框架甚至没有 Maven 的pom.xml。但恰恰是这套“看起来像教科书”的组合正在高校课程设计评审中持续拿高分它不依赖黑盒框架所有请求流转路径清晰可溯数据库操作直连 JDBC事务边界一目了然JSP 页面内嵌 Java 逻辑虽不推荐生产使用却能精准暴露学生对 EL 表达式、JSTL 标签、Servlet 生命周期的理解深度。这不是复古而是对 JavaWeb 底层能力的硬性验证——当request.getRequestDispatcher(/list.jsp).forward(request, response)执行时你能说出RequestDispatcher如何触发容器级跳转、forward与sendRedirect的线程上下文差异、以及web.xml中url-pattern/servlet/*/url-pattern如何影响匹配优先级吗适合刚学完《Java Web 编程基础》的学生复现调试也适合三年经验工程师快速搭建轻量管理后台原型——只要 Tomcat 8.5、JDK 8、MySQL 5.7 环境就绪5 分钟内就能跑通登录校验流程。2. 用 JSP Servlet 搭建宿舍管理系统的最小可行路径2.1 为什么选原生 JSP/Servlet 而非 Spring Boot在课设场景下Spring Boot 的自动配置会掩盖关键细节比如WebServlet(/login)注解背后实际注册的是ServletRegistrationBean而原生web.xml中servletservlet-classcom.example.LoginServlet/servlet-class/servlet强制要求开发者理解 Servlet 容器启动时如何加载类、初始化实例、调用init()方法。更关键的是部署约束——Tomcat 对WEB-INF/web.xml的解析顺序直接影响 Filter 链执行时机而Filter正是宿舍系统中实现统一登录拦截如检查session.getAttribute(user) ! null的核心机制。若用 Spring Boot学生可能只写PreAuthorize(hasRole(ADMIN))却不知其底层依赖SecurityFilterChain的 Bean 注册顺序而原生方案中一个filter-mappingurl-pattern/admin/*/url-pattern/filter-mapping就迫使你思考 URL 匹配规则与路径通配符的优先级/admin/*/admin//*。这种“被迫显式”的设计正是高分课设的底层逻辑。2.2 从零部署解压后三步启动系统提示该源码默认使用 MySQL 5.7若本地为 MySQL 8.0需修改jdbc:mysql://localhost:3306/dorm?useSSLfalseserverTimezoneUTC连接字符串中的useSSLfalse参数并确认驱动类名是否为com.mysql.cj.jdbc.Driver8.0 版本而非com.mysql.jdbc.Driver5.x 版本2.2.1 数据库初始化执行 SQL 脚本并验证表结构解压后找到dorm_db.sql文件用 MySQL 客户端执行-- 创建数据库若不存在 CREATE DATABASE IF NOT EXISTS dorm CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -- 切换数据库 USE dorm; -- 执行建表语句此处仅展示核心表实际脚本含 dormitory、student、room、repair 等 6 张表 CREATE TABLE student ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50) NOT NULL, gender ENUM(男,女) DEFAULT 男, dorm_id INT, phone VARCHAR(11), create_time DATETIME DEFAULT CURRENT_TIMESTAMP ); -- 插入测试数据确保登录功能可用 INSERT INTO student (name, gender, dorm_id, phone) VALUES (张三, 男, 101, 13800138000), (李四, 女, 202, 13900139000);执行后验证表结构是否完整mysql -u root -p -e USE dorm; SHOW TABLES; | grep -E (student|dormitory|repair) # 应输出 student、dormitory、repair 等表名2.2.2 Tomcat 配置将项目部署为 ROOT 应用将解压后的dorm_system目录或WebContent文件夹复制到 Tomcat 的webapps/目录下重命名为ROOT覆盖默认首页# Linux/macOS 示例 cp -r /path/to/dorm_system $CATALINA_HOME/webapps/ROOT # Windows 示例PowerShell Copy-Item C:\dorm_system $env:CATALINA_HOME\webapps\ROOT -Recurse -Force启动 Tomcat 后访问http://localhost:8080/若显示宿舍管理系统登录页则部署成功。此时可通过浏览器开发者工具 Network 面板观察点击“登录”按钮时POST /login请求被LoginServlet处理响应头中Set-Cookie: JSESSIONIDxxx证明 Session 已创建。2.3 Servlet 请求处理链以学生信息查询为例2.3.1StudentListServlet的标准处理流程该 Servlet 位于src/com/example/servlet/StudentListServlet.java核心逻辑如下public class StudentListServlet extends HttpServlet { Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 1. 从数据库获取学生列表此处简化为直接调用 DAO ListStudent students new StudentDAO().findAll(); // 2. 将数据存入 request 域供 JSP 访问 request.setAttribute(studentList, students); // 3. 转发到 list.jsp 页面注意forward 不改变浏览器 URL request.getRequestDispatcher(/list.jsp).forward(request, response); } }注意request.getRequestDispatcher()返回的RequestDispatcher对象执行forward()时请求对象request和响应对象response会被传递到目标资源且整个过程在同一个请求线程内完成。这意味着list.jsp中可通过${studentList}直接访问request.setAttribute()设置的数据而无需重新查询数据库。2.3.2list.jsp中的 JSP 标准动作与 JSTL 使用list.jsp文件通常包含以下关键片段% page contentTypetext/html;charsetUTF-8 languagejava % % taglib prefixc urihttp://java.sun.com/jsp/jstl/core % html headtitle学生列表/title/head body table border1 tr th学号/thth姓名/thth性别/thth宿舍号/thth操作/th /tr !-- 使用 JSTL 的 forEach 标签遍历 studentList -- c:forEach items${studentList} varstu tr td${stu.id}/td td${stu.name}/td td${stu.gender}/td td${stu.dormId}/td td a hrefedit?id${stu.id}编辑/a | a hrefdelete?id${stu.id} onclickreturn confirm(确定删除)删除/a /td /tr /c:forEach /table /body /html提示若页面出现${studentList}未解析为表格需检查web.xml中是否声明了web-app版本为 2.4JSTL 1.2 要求并在WEB-INF/lib/下存在jstl-1.2.jar和standard-1.1.2.jar。常见错误是忘记将 JSTL JAR 包放入WEB-INF/lib导致c:forEach标签被当作纯文本输出。3. 关键参数与配置陷阱让系统稳定运行的 5 个必调项3.1web.xml中的 Servlet 映射优先级设置宿舍管理系统常需同时支持/login登录、/admin/*管理员路径、/static/*静态资源三类请求。若映射顺序不当会导致静态 CSS/JS 文件被错误路由到 Servlet。正确配置如下!-- 1. 最具体的路径优先精确匹配 -- servlet-mapping servlet-nameLoginServlet/servlet-name url-pattern/login/url-pattern /servlet-mapping !-- 2. 路径前缀匹配/admin/* 必须在 /* 之前 -- servlet-mapping servlet-nameAdminServlet/servlet-name url-pattern/admin/*/url-pattern /servlet-mapping !-- 3. 默认 Servlet 处理静态资源Tomcat 内置 DefaultServlet -- servlet-mapping servlet-namedefault/servlet-name url-pattern/static/*/url-pattern /servlet-mapping !-- 4. 最后才是通配符兜底 -- servlet-mapping servlet-nameDefaultServlet/servlet-name url-pattern//url-pattern /servlet-mapping注意url-pattern的匹配规则严格遵循 Tomcat 规范精确匹配 路径匹配/admin/* 扩展名匹配*.jsp 默认匹配/。若将/映射放在/admin/*之前所有请求都会被DefaultServlet拦截导致AdminServlet永远不会执行。3.2 JSP 页面编码与中文乱码解决方案3.2.1 请求参数乱码GET 与 POST 的不同处理GET 请求如/edit?id101URL 中中文参数需在 Tomcat 的conf/server.xml中为Connector添加URIEncodingUTF-8Connector port8080 protocolHTTP/1.1 connectionTimeout20000 redirectPort8443 URIEncodingUTF-8 /POST 请求如登录表单提交必须在每个 Servlet 的doPost()方法开头调用request.setCharacterEncoding(UTF-8)Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding(UTF-8); // 必须在 getParameter() 之前调用 String username request.getParameter(username); String password request.getParameter(password); // ...后续逻辑 }3.2.2 响应页面乱码JSP 页面的三重声明list.jsp顶部必须同时声明三处编码% page contentTypetext/html;charsetUTF-8 languagejava % % page pageEncodingUTF-8 % % taglib prefixc urihttp://java.sun.com/jsp/jstl/core % html head meta charsetUTF-8 !-- HTML5 meta 声明 -- title学生列表/title /head提示contentType决定服务器发送响应时的Content-Type头如text/html;charsetUTF-8pageEncoding决定 JSP 引擎编译.jsp文件为.java时的读取编码meta charset则影响浏览器渲染时的解码方式。三者缺一不可否则会出现“数据库存的是中文页面显示方框”的经典问题。3.3 数据库连接池配置避免高并发下的连接耗尽原始源码多采用DriverManager.getConnection()直连数据库但在多用户同时访问宿舍报修模块时易触发连接超时。推荐替换为DBCP2连接池在WEB-INF/web.xml中添加资源引用resource-ref descriptionDB Connection/description res-ref-namejdbc/DormDB/res-ref-name res-typejavax.sql.DataSource/res-type res-authContainer/res-auth /resource-ref并在conf/context.xml中配置具体参数Resource namejdbc/DormDB authContainer typejavax.sql.DataSource maxTotal20 !-- 最大连接数 -- maxIdle10 !-- 空闲连接数上限 -- minIdle5 !-- 最小空闲连接数 -- initialSize5 !-- 初始化连接数 -- timeBetweenEvictionRunsMillis30000 minEvictableIdleTimeMillis60000 validationQuerySELECT 1 testWhileIdletrue usernameroot passwordyour_password driverClassNamecom.mysql.cj.jdbc.Driver urljdbc:mysql://localhost:3306/dorm?useSSLfalseamp;serverTimezoneUTC/注意maxTotal20是关键阈值——若宿舍楼有 200 名学生同时报修连接池会拒绝第 21 个请求并抛出SQLException此时应在RepairServlet中捕获异常并返回友好提示如“系统繁忙请稍后再试”而非让 Tomcat 报 500 错误。4. JSP 个人信息展示页面的动态优化技巧4.1 使用 EL 表达式安全输出用户信息宿舍系统中常见的“个人信息页”profile.jsp需根据当前登录用户动态显示数据。原始代码可能直接写!-- 危险未校验空指针且未转义 XSS -- p姓名${sessionScope.user.name}/p p电话${sessionScope.user.phone}/p应改为带空值判断和 HTML 转义的写法% taglib prefixfn urihttp://java.sun.com/jsp/jstl/functions % c:if test${not empty sessionScope.user} p姓名c:out value${sessionScope.user.name} //p p电话c:out value${sessionScope.user.phone} //p p最后登录时间fmt:formatDate value${sessionScope.user.lastLoginTime} patternyyyy-MM-dd HH:mm:ss//p /c:if c:if test${empty sessionScope.user} p请先a hreflogin.jsp登录/a/p /c:if提示c:out标签默认对输出内容进行 HTML 转义如将script转为lt;scriptgt;防止存储型 XSS 攻击fmt:formatDate需在页面顶部声明% taglib prefixfmt urihttp://java.sun.com/jsp/jstl/fmt %且lastLoginTime字段类型应为java.util.Date或java.time.LocalDateTime后者需配合 JSTL 1.2。4.2 屏蔽 JSP 离开页面提示的两种场景4.2.1 表单未保存时的通用提示当用户编辑宿舍信息后未提交就关闭页面需触发浏览器原生提示。在edit.jsp中添加script let isFormModified false; // 监听表单输入变化 document.addEventListener(DOMContentLoaded, function() { const form document.getElementById(studentForm); if (form) { form.addEventListener(input, function() { isFormModified true; }); } }); // 页面卸载前检查 window.addEventListener(beforeunload, function(e) { if (isFormModified) { e.returnValue 您有未保存的修改确定要离开吗; return e.returnValue; } }); /script注意此脚本必须放在/body标签前确保 DOM 加载完成后执行。若使用 jQuery需替换为$(document).on(input, #studentForm *, function(){...})但原生 JS 更轻量且无依赖。4.2.2 用户主动点击“取消”按钮时禁用提示在编辑页的“取消”按钮上添加onclick清除状态input typebutton value取消 onclickisFormModified false; window.location.hreflist.jsp;这样用户点击取消时beforeunload事件中isFormModified为false不会触发提示体验更符合直觉。4.3 Servlet 中调用数据库操作的事务控制宿舍管理系统中“分配宿舍”操作需同时更新学生表设置dorm_id和宿舍表减少available_count必须保证原子性。在AssignDormServlet中使用 JDBC 事务protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Connection conn null; try { conn DataSourceFactory.getDataSource().getConnection(); conn.setAutoCommit(false); // 关闭自动提交 // 1. 更新学生宿舍 ID String updateStudentSql UPDATE student SET dorm_id ? WHERE id ?; PreparedStatement ps1 conn.prepareStatement(updateStudentSql); ps1.setInt(1, Integer.parseInt(request.getParameter(dormId))); ps1.setInt(2, Integer.parseInt(request.getParameter(studentId))); ps1.executeUpdate(); // 2. 更新宿舍剩余床位 String updateDormSql UPDATE dormitory SET available_count available_count - 1 WHERE id ?; PreparedStatement ps2 conn.prepareStatement(updateDormSql); ps2.setInt(1, Integer.parseInt(request.getParameter(dormId))); ps2.executeUpdate(); conn.commit(); // 提交事务 response.sendRedirect(success.jsp?msg分配成功); } catch (SQLException e) { if (conn ! null) { try { conn.rollback(); // 回滚事务 } catch (SQLException ex) { ex.printStackTrace(); } } request.setAttribute(error, 分配失败 e.getMessage()); request.getRequestDispatcher(error.jsp).forward(request, response); } finally { if (conn ! null) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } }提示conn.setAutoCommit(false)是事务起点conn.commit()是成功终点conn.rollback()是失败终点。若省略rollback()连接归还连接池时可能携带未提交的脏数据导致后续请求读到不一致状态。本文还有配套的精品资源点击获取
返回列表