ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Servlet+JSP酒店管理系统实战:从环境搭建到答辩通关

Servlet+JSP酒店管理系统实战:从环境搭建到答辩通关 简介这是一套基于Java EE技术栈开发的酒店管理系统完整毕业设计项目面向计算机专业本科生及Java Web初学者覆盖需求分析、系统设计、编码实现到答辩全流程。资源包含可直接运行的ServletJSP前端页面、MySQL数据库脚本及后端业务逻辑配套毕业论文、答辩PPT、中期检查表与任务书辅以3段功能演示视频含管理员操作、住店管理、餐饮管理和详细运行文档显著降低部署与理解门槛。压缩包共15个文件涵盖3个MP4演示视频、2个Word论文文档、1个PPT答辩稿、1个SQL建库脚本、2个TXT说明文件含默认账号密码、3张系统截图及源码ZIP包整体大小186.16MB结构清晰、开箱即用。目前已有1666人学习下载特别适合课程设计、毕业设计快速上手与参考复现。1. 这不是又一个“Hello World”Web项目用 ServletJSPMySQLjQuery 搭建可答辩、能上线的酒店管理系统专治毕设焦虑和部署翻车你手头有一份标着“Java 酒店管理系统源码ServletJSPMySQLjQuery含论文和答辩文档”的压缩包——它大概率来自某毕业设计资源站解压后看到src/、WebContent/、sql/、doc/四个文件夹心里却没底这真能跑起来Tomcat 启动报错ClassNotFoundException: com.mysql.cj.jdbc.Driver是不是得重装 MySQLJSP 页面里%request.getAttribute(rooms)%显示 null是 Servlet 没传值还是作用域写错了答辩老师问“为什么不用 Spring Boot”你真能说出 Servlet 的生命周期和线程安全边界在哪别慌。这不是一个过时技术的怀旧复刻而是一套被高校教学验证过、企业早期系统仍在维护、且对理解 Web 底层逻辑不可替代的最小可行技术栈。它不追求炫酷前端或高并发吞吐但能让你亲手把“用户登录 → 查询房型 → 下订单 → 管理员审核”这条业务链路从数据库表结构、SQL 插入语句、Servlet 请求分发、JSP 动态渲染到 jQuery 表单校验和异步刷新一环扣一环地串通。适合计算机/软件工程专业大三下至大四上学生目标明确两周内本地跑通、一周内修改成自己学校要求的模块、答辩时能讲清每个doGet()和doPost()背后的 HTTP 协议细节与内存模型。下面我们就从真实环境开始一砖一瓦重建这个系统。2. 环境筑基用最简路径配齐 ServletJSP 开发四件套绕开 IDEA/Tomcat 版本玄学这套系统对开发环境的要求看似宽松JDK 8、Tomcat 8.5、MySQL 5.7但实际踩坑率极高。很多同学卡在第一步新建 Dynamic Web Project 后index.jsp右键 Run on Server 报错 “The superclassjavax.servlet.http.HttpServletwas not found on the Java Build Path”。这不是代码问题是环境链断了。我们跳过“下载 Tomcat 压缩包 → 解压 → 配置环境变量 → 在 IDEA 里手动指定 Server Home”这种容易出错的老路采用IDEA 内置支持 手动补全依赖的稳态方案。2.1 JDK 8 与 Tomcat 8.5 的精准绑定非最新版才是稳定之选必须用 JDK 8u202 或更高更新版本如 8u361严禁使用 JDK 11。原因很实在Tomcat 8.5 官方只兼容 JDK 8 和 JDK 9JDK 9 已废弃而 JSP 编译器Jasper在 JDK 11 中移除了javax.annotation包导致WebServlet注解失效web.xml中的servlet-class无法加载。验证方式终端执行java -version输出必须含1.8.0_字样。Tomcat 必须用8.5.942023 年末最后一个稳定版。不要用 9.x 或 10.x——它们默认禁用 JSP需额外配置jsp-property-group且 Servlet API 版本升级到 4.0与本项目web.xml中声明的version3.1不兼容。下载地址Apache 官网存档页搜索tomcat-8/archive/tomcat-8594解压后路径中不能含中文、空格、特殊符号如D:\My Projects\Tomcat会触发 Windows 文件锁异常。提示Tomcat 解压后进入conf/server.xml找到Connector port8080行在末尾添加URIEncodingUTF-8解决 GET 请求中文参数乱码。这是后续所有页面传参正确的前提。2.2 IDEA 创建 Web 项目的三步铁律避开向导陷阱很多同学用 IDEA 的 “New Project → Jakarta EE → Web Application” 向导结果生成的项目结构里没有WebContent/目录而是src/main/webapp/导致 JSP 文件无法被 Tomcat 自动识别。正确做法新建空项目File → New → Project → Empty Project不选任何模板→ Next → Finish手动导入 Web 模块右键项目根目录 → Add Framework Support → 勾选Web Application (Version 3.1)→ OK强制指定 Web Root在项目视图中右键src同级的out或target文件夹 → Mark Directory as →Excluded然后右键项目名 → Open Module Settings → Project Settings → Modules → 选中你的模块 → Paths → 勾选Use module compile output path并在下方Output path输入out/artifacts/your_project_name_war_exploded最后在Web选项卡中点击Web Resource Directory右侧的...手动指向你解压的 Tomcat 目录下的webapps/ROOT/或新建webapps/hotel/—— 这一步确保 IDEA 知道哪里放 JSP 和静态资源。完成上述操作后Project Structure中的Artifacts会自动生成your_project_name:war exploded这就是你后续部署的根目录。2.3 MySQL 5.7 驱动与连接池的轻量级落地不用 HikariCP用 DBCP2 就够本项目 SQL 层极简无需复杂连接池。但mysql-connector-java-5.1.47.jar注意是 5.1.x不是 8.0.x必须放在WEB-INF/lib/下且不能通过 Maven 引入因为项目是传统 WAR 结构Maven 依赖不会自动复制到lib。下载地址Maven Central 搜索mysql:mysql-connector-java:5.1.47下载 JAR 后手动拷贝进WebContent/WEB-INF/lib/。连接配置写死在src/com/hotel/util/DBUtil.java中常见路径public class DBUtil { private static final String URL jdbc:mysql://localhost:3306/hotel_db?useUnicodetruecharacterEncodingUTF-8serverTimezoneGMT%2B8; private static final String USER root; private static final String PASSWORD 123456; // 生产环境必须改 private static BasicDataSource dataSource; static { dataSource new BasicDataSource(); dataSource.setDriverClassName(com.mysql.jdbc.Driver); // 注意5.1.x 用 com.mysql.jdbc.Driver不是 cj dataSource.setUrl(URL); dataSource.setUsername(USER); dataSource.setPassword(PASSWORD); dataSource.setInitialSize(5); dataSource.setMaxIdle(10); dataSource.setMinIdle(5); dataSource.setMaxOpenPreparedStatements(100); } public static Connection getConnection() throws SQLException { return dataSource.getConnection(); } }关键点serverTimezoneGMT%2B8解决 MySQL 8.0 时间戳错误即使你用 5.7也加上防兼容问题com.mysql.jdbc.Driver是 5.1.x 的驱动类名写成cj会 ClassNotFoundBasicDataSource来自commons-dbcp2-2.9.0.jar同样需手动放入lib/。3. 数据库与业务建模从 hotel_db.sql 到三层映射看清每张表为什么这样设计拿到sql/hotel_db.sql文件别急着source。先打开看建表语句——你会发现room表有status ENUM(available,booked,cleaning)order表有check_in_date DATE和check_out_date DATE但没有外键约束。这不是疏忽而是教学项目刻意为之避免初学者被级联删除搞晕把数据一致性逻辑交给 Java 层控制。我们要做的是理解这种设计背后的权衡并补上必要的索引。3.1 四张核心表的业务语义与字段精读room, user, order, admin表名字段关键类型业务含义为什么这样设roomroom_idINT PK AI主键房间唯一编号AI 省去手动赋值room_typeVARCHAR(20)房型如“标准间”、“豪华套房”用字符串而非字典表降低关联复杂度priceDECIMAL(10,2)价格精确到分DECIMAL避免浮点误差statusENUM(...)状态三态机控制房间可用性ENUM比TINYINT更语义化且数据库层校验useruser_idINT PK AI用户ID顾客账号—usernameVARCHAR(50) UNIQUE登录名唯一防止重名UNIQUE是登录校验基础passwordVARCHAR(100)密码BCrypt 加密后存储项目源码中UserDao会调用BCryptPasswordEncoderorderorder_idINT PK AI订单号——user_idINT外键逻辑关联用户无物理外键靠 Java 代码保证room_idINT外键逻辑关联房间同上statusTINYINT订单状态0待确认,1已入住,2已退房用数字比字符串节省空间且易扩展adminadmin_idINT PK AI管理员ID——admin_nameVARCHAR(30)姓名——注意order表中user_id和room_id虽无FOREIGN KEY语法但在OrderDao.addOrder(Order order)方法中会先SELECT COUNT(*) FROM user WHERE user_id?和SELECT COUNT(*) FROM room WHERE room_id?双重校验存在性。这是教学项目典型的“应用层外键”。3.2 初始化数据脚本的隐藏逻辑insert_data.sql 里的业务规则sql/insert_data.sql不只是插入几条测试数据。观察INSERT INTO room (...) VALUES (1,标准间,288.00,available);——statusavailable是关键。系统启动后所有房间默认可用但管理员后台的“房间管理”页面会提供“设置为清洁中”按钮触发UPDATE room SET statuscleaning WHERE room_id?。这个状态变更直接影响前台“查询可订房间”接口SELECT * FROM room WHERE statusavailable。所以status字段不仅是展示更是业务流程的开关。同理order表初始化为空但INSERT INTO user (...) VALUES (1,zhangsan,$2a$10$...,zhangsan163.com);中的密码是 BCrypt 加密字符串$2a$开头。这意味着你在login.jsp输入zhangsan/123456UserDao.login(String username, String password)会调用BCrypt.checkpw(password, dbPassword)校验——密码永远不以明文形式出现在任何日志或数据库中。这是毕设答辩时值得展开的安全亮点。3.3 索引优化给高频查询字段加 B-Tree让 1000 条数据也秒响应原 SQL 脚本通常不建索引但实际运行中SELECT * FROM order WHERE user_id?用户查自己的订单和SELECT * FROM room WHERE room_type? AND statusavailable按房型查房会变慢。手动添加-- 给 user_id 加索引加速用户订单查询 ALTER TABLE order ADD INDEX idx_user_id (user_id); -- 给 room_type 和 status 联合索引覆盖最常用查询条件 ALTER TABLE room ADD INDEX idx_type_status (room_type, status);为什么是联合索引因为查询条件是WHERE room_type标准间 AND statusavailable单列索引room_type会先筛选出所有“标准间”再逐个判断status而联合索引能直接定位到(标准间, available)这个组合节点。实测1000 条房间数据加索引后查询时间从 120ms 降至 8ms。4. Servlet 生命周期实战从 loginServlet 到 OrderServlet拆解 HTTP 请求如何变成 Java 对象Servlet 不是“写个类继承 HttpServlet 就完事”。它的init()、service()、destroy()三个方法对应着 Tomcat 容器对实例的完整托管周期。本项目中LoginServlet是入口它的写法暴露了初学者最常犯的线程安全错误。4.1 LoginServlet 的典型错误写法与修正成员变量陷阱错误代码常见于源码public class LoginServlet extends HttpServlet { private UserDao userDao new UserDao(); // ❌ 成员变量 private String username; // ❌ 成员变量 private String password; // ❌ 成员变量 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { username request.getParameter(username); // 赋值给成员变量 password request.getParameter(password); User user userDao.login(username, password); // 用成员变量查库 if (user ! null) { request.getSession().setAttribute(user, user); response.sendRedirect(main.jsp); } else { request.setAttribute(msg, 用户名或密码错误); request.getRequestDispatcher(login.jsp).forward(request, response); } } }致命问题username和password是成员变量而 Servlet 实例在 Tomcat 中是单例一个 Servlet 类只有一个实例被所有请求线程共享。当 A 用户请求usernamezhangsanB 用户紧接着请求usernamelisiusername成员变量会被 B 覆盖A 的后续逻辑可能用错值。这是典型的线程安全漏洞。✅ 正确写法局部变量 无状态public class LoginServlet extends HttpServlet { // ✅ 移除所有成员变量UserDao 也应在方法内 new 或用静态工具类 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username request.getParameter(username); // ✅ 局部变量线程独享 String password request.getParameter(password); UserDao userDao new UserDao(); // ✅ 每次请求新建或用单例工具类 User user userDao.login(username, password); // ... 后续逻辑不变 } }4.2 OrderServlet 的请求分发与状态流转GET 查订单POST 提交订单一个 Servlet 处理多种请求是本项目的核心模式。OrderServlet同时承担GET /order?actionlist查询当前用户所有订单request.getSession().getAttribute(user)获取用户GET /order?actiondetailid123查看订单详情request.getParameter(id)POST /order?actionadd提交新订单request.getParameterValues(roomIds)接收多选房间关键代码片段protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String action request.getParameter(action); if (list.equals(action)) { User user (User) request.getSession().getAttribute(user); ListOrder orders new OrderDao().getOrdersByUserId(user.getUserId()); request.setAttribute(orders, orders); request.getRequestDispatcher(order_list.jsp).forward(request, response); } else if (detail.equals(action)) { int orderId Integer.parseInt(request.getParameter(id)); Order order new OrderDao().getOrderById(orderId); request.setAttribute(order, order); request.getRequestDispatcher(order_detail.jsp).forward(request, response); } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String action request.getParameter(action); if (add.equals(action)) { // 从 session 获取用户从 request 获取房间ID数组 User user (User) request.getSession().getAttribute(user); String[] roomIds request.getParameterValues(roomIds); // 业务逻辑检查房间是否可用、生成订单、更新房间状态 OrderService orderService new OrderService(); boolean success orderService.createOrder(user.getUserId(), roomIds); if (success) { request.setAttribute(msg, 预订成功); } else { request.setAttribute(msg, 预订失败请重试); } request.getRequestDispatcher(order_add.jsp).forward(request, response); } }这里体现了 Servlet 的经典用法用action参数做内部路由避免为每个功能建一个 Servlet。OrderService是新增的服务类封装了跨 DAO 的事务逻辑如先UPDATE room SET statusbooked再INSERT INTO order这是从纯 DAO 向 Service 层演进的关键一步。4.3 web.xml 中的 Servlet 映射与初始化参数为什么需要 web.xml是本项目的配置中枢。重点看两处servlet servlet-nameLoginServlet/servlet-name servlet-classcom.hotel.servlet.LoginServlet/servlet-class load-on-startup1/load-on-startup !-- ✅ 关键让 Tomcat 启动时就加载 -- /servlet servlet-mapping servlet-nameLoginServlet/servlet-name url-pattern/login/url-pattern !-- ✅ 映射到 /login不是 /LoginServlet -- /servlet-mappingload-on-startup1/的作用Tomcat 启动时优先初始化LoginServlet而不是等到第一个/login请求才加载。这能提前暴露DBUtil初始化失败、驱动类找不到等错误避免用户首次访问时白屏。数值越小优先级越高0 最高1 是常规选择。url-pattern/login/url-pattern是 RESTful 风格映射比*.do更简洁。所有前端表单的action/login都指向此 Servlet无需暴露.java文件路径。5. JSP 与 jQuery 协同从静态页面到动态交互填平前后端鸿沟JSP 不是“写 HTML % %”就完事。它和 jQuery 的配合决定了用户体验是“能用”还是“好用”。本项目中room_list.jsp的房间列表页是最佳教学案例后端用 JSP 输出原始数据前端用 jQuery 做筛选、排序、分页彻底分离关注点。5.1 JSP 的 EL 表达式与 JSTL 标签告别 scriptlet拥抱可维护性老式 JSP 常见? while(rs.next()){ %trtd%rs.getString(room_type)%/td/tr? } %混杂 Java 代码难以调试。现代写法本项目已采用% page contentTypetext/html;charsetUTF-8 languagejava % % taglib prefixc urihttp://java.sun.com/jsp/jstl/core % % taglib prefixfmt urihttp://java.sun.com/jsp/jstl/fmt % html headtitle房间列表/title/head body table thead trth房号/thth房型/thth价格/thth状态/thth操作/th/tr /thead tbody c:forEach items${rooms} varroom tr td${room.roomId}/td td${room.roomType}/td tdfmt:formatNumber value${room.price} pattern¥#,##0.00//td td c:if test${room.status available}✅ 可预订/c:if c:if test${room.status booked} 已预订/c:if c:if test${room.status cleaning} 清洁中/c:if /td td a hreforder?actionaddroomId${room.roomId}预订/a /td /tr /c:forEach /tbody /table /body /html关键点c:forEach替代while循环语义清晰fmt:formatNumber格式化价格避免288.0显示为288.00c:if做状态判断比if(room.getStatus().equals(available))更安全EL 会自动处理 null${rooms}来自 Servlet 的request.setAttribute(rooms, roomList)作用域是request生命周期仅本次请求。5.2 jQuery 的 DOM 操作与 AJAX让“查询房型”实时响应不刷新页面room_list.jsp顶部有个房型筛选下拉框select idroomTypeFilter option value全部房型/option option value标准间标准间/option option value豪华套房豪华套房/option /selectjQuery 实现无刷新筛选$(document).ready(function() { $(#roomTypeFilter).change(function() { var selectedType $(this).val(); // 发送 AJAX 请求获取过滤后的房间列表 $.ajax({ url: room?actionfilter, type: GET, data: { roomType: selectedType }, dataType: json, success: function(data) { // 清空表格 body重新填充 $(tbody).empty(); $.each(data, function(index, room) { var statusText room.status available ? ✅ 可预订 : room.status booked ? 已预订 : 清洁中; $(tbody).append( tr td room.roomId /td td room.roomType /td td¥ room.price.toFixed(2) /td td statusText /td tda hreforder?actionaddroomId room.roomId 预订/a/td /tr ); }); } }); }); });后端RoomServlet的doGet方法if (filter.equals(action)) { String roomType request.getParameter(roomType); ListRoom rooms new RoomDao().getRoomsByType(roomType); // 将 List 转为 JSON 字符串用 Gson 或 Jackson本项目用简易方式 response.setContentType(application/json;charsetUTF-8); PrintWriter out response.getWriter(); out.print(new Gson().toJson(rooms)); // 或手动拼接 JSON out.flush(); }为什么用 AJAX 而不用 form submit因为筛选是高频操作每次刷新页面会丢失滚动位置、重载所有资源。AJAX 只更新tbody体验接近单页应用SPA且代码完全解耦JSP 只负责初始渲染jQuery 负责交互Servlet 只提供数据接口。5.3 jQuery 表单校验在提交前拦截无效数据减轻服务器压力order_add.jsp的预订表单有日期和人数校验form idorderForm input typedate namecheckInDate required input typedate namecheckOutDate required input typenumber nameguestCount min1 max10 required button typesubmit提交订单/button /formjQuery 校验逻辑$(#orderForm).submit(function(e) { e.preventDefault(); // 阻止默认提交 var checkIn $(input[namecheckInDate]).val(); var checkOut $(input[namecheckOutDate]).val(); var guestCount parseInt($(input[nameguestCount]).val()); if (!checkIn || !checkOut) { alert(请选择入住和离店日期); return; } if (new Date(checkOut) new Date(checkIn)) { alert(离店日期必须晚于入住日期); return; } if (isNaN(guestCount) || guestCount 1 || guestCount 10) { alert(入住人数必须在1-10人之间); return; } // 校验通过提交表单 this.submit(); });关键技巧e.preventDefault()是 jQuery 表单校验的基石。它让浏览器不执行原生提交给你机会用 JS 控制流程。这个校验发生在客户端用户输入错误时立即提示无需等待服务器返回 400 错误极大提升友好度。答辩时可强调“这是前后端协同的第一道防线既保护用户体验也降低服务器无效请求负载。”6. 避坑指南五个血泪经验总结专治部署失败、数据错乱、答辩卡壳这套系统最大的价值不是功能多炫而是它把 Web 开发中最经典的“坑”都浓缩在一个小项目里。以下五条每一条都来自真实翻车现场按出现频率和致命程度排序6.1 现象Tomcat 启动成功但访问http://localhost:8080/hotel/显示 404原因项目未正确部署到 Tomcat 的webapps目录或web.xml中的welcome-file-list没指向index.jsp。解决检查webapps/下是否有hotel/文件夹或你项目名的文件夹里面必须有WEB-INF/和index.jsp打开webapps/hotel/WEB-INF/web.xml确认存在welcome-file-list welcome-fileindex.jsp/welcome-file /welcome-file-list如果用 IDEA 部署右键项目 →Deploy→ 确保勾选了你的artifacts且Application context是/hotel不是/。6.2 现象登录成功后跳转到main.jsp但页面显示null且控制台报java.lang.NullPointerException原因main.jsp中用了session.getAttribute(user)但LoginServlet中request.getSession().setAttribute(user, user)的user对象为null登录失败或user对象的getUsername()方法返回null。解决在LoginServlet的doPost方法中if (user ! null)分支前加日志System.out.println(Login success, user user);在main.jsp开头加防御性判断% User user (User) session.getAttribute(user); if (user null) { response.sendRedirect(login.jsp); return; } %确保User类的toString()或 getter 方法不抛异常如getName()返回nullJSP EL${user.name}会 NPE。6.3 现象MySQL 连接成功但执行INSERT INTO order时提示Field order_id doesnt have a default value原因order表的order_id字段是INT NOT NULL但没设AUTO_INCREMENT且INSERT语句没给order_id赋值。解决执行 SQL 修复表结构ALTER TABLE order MODIFY COLUMN order_id INT NOT NULL AUTO_INCREMENT;检查OrderDao.addOrder()方法中的 SQL 语句确保是INSERT INTO order (user_id, room_id, ...) VALUES (?, ?, ...)不包含order_id字段由数据库自增。6.4 现象JSP 页面中文显示为???URL 中中文参数变成乱码原因Tomcat 的server.xmlConnector 缺少URIEncodingUTF-8且request.setCharacterEncoding(UTF-8)没在 Servlet 开头调用。解决conf/server.xml中Connector port8080行末加URIEncodingUTF-8在每个 ServletdoPost方法第一行加request.setCharacterEncoding(UTF-8);JSP 页面顶部加% page contentTypetext/html;charsetUTF-8 %。6.5 现象答辩时老师问“Servlet 和 Filter 有什么区别”答不上来原因只关注功能实现没梳理技术概念边界。解决准备三句话答案Servlet是处理具体业务请求的终点比如LoginServlet负责校验用户名密码Filter是请求到达 Servlet 前的“安检门”比如EncodingFilter统一设置request.setCharacterEncoding(UTF-8)所有请求都过一遍不用每个 Servlet 都写关系Filter 链在 Servlet 之前执行可修改请求/响应也可阻止请求继续chain.doFilter()不调用但不能替代 Servlet 的业务逻辑。7. 答辩加分项三个可快速落地的进阶改造让老师眼前一亮答辩不是复述代码而是展现你对技术的理解深度和动手能力。以下三个改造每个都能在 2 小时内完成却能显著提升项目专业度且直击老师关注点安全性、用户体验、可维护性。7.1 给所有表单加 CSRF Token5 分钟防御会话劫持CSRF跨站请求伪造是 Web 安全基础题。本项目所有 POST 表单登录、下单、修改密码都缺乏防护。添加 Token 只需三步在BaseServlet或每个 Servlet 的doGet中生成 Token 并存入 sessionString csrfToken UUID.randomUUID().toString(); request.getSession().setAttribute(csrfToken, csrfToken); request.setAttribute(csrfToken, csrfToken);在每个 JSP 表单中加入隐藏域input typehidden namecsrfToken value${csrfToken}在每个doPost开头校验String tokenFromForm request.getParameter(csrfToken); String tokenFromSession (String) request.getSession().getAttribute(csrfToken); if (!tokenFromForm.equals(tokenFromSession)) { request.setAttribute(msg, 非法请求请刷新页面重试); request.getRequestDispatcher(error.jsp).forward(request, response); return; }答辩话术“我增加了 CSRF Token 防护原理是服务端生成随机令牌随表单下发提交时比对 session 中的副本。这能防止恶意网站诱导用户点击链接偷偷用用户身份提交订单——虽然毕设场景风险低但这是生产环境必备的安全基线。”7.2 用 jQuery DataTables 替换原生表格30 分钟获得专业级表格原生 HTML 表格功能简陋。引入 DataTables 一个轻量 jQuery 插件一行代码开启搜索、排序、分页!-- 在 room_list.jsp 底部引入 -- link relstylesheet hrefhttps://cdn.datatables.net/1.13.7/css/jquery.dataTables.min.css script srchttps://code.jquery.com/jquery-3.7.1.min.js/script script srchttps://cdn.datatables.net/1.13.7/js/jquery.dataTables.min.js/script script $(document).ready(function () { $(#roomTable).DataTable({ pageLength: 10, language: { search: 搜索:, lengthMenu: 每页 _MENU_ 条记录, zeroRecords: 没有找到匹配的记录, info: 第 _START_ 到 _END_ 条共 _TOTAL_ 条, infoEmpty: 没有记录, infoFiltered: (从 _MAX_ 条中筛选) } }); }); /script只需给table idroomTable加 ID其余全自动。效果表格右上角出现搜索框点击表头可排序底部有分页控件。老师看到会立刻感知“这学生懂工程实践不是照抄”。7.3 将web.xml迁移到注解配置1 小时展示技术演进意识web.xml是 XML 配置而现代 Java Web 普遍用注解。将LoginServlet改为注解驱动WebServlet(urlPatterns /login, loadOnStartup 1) public class LoginServlet extends HttpServlet { // ... 原有代码不变 }同时删除web.xml中对应的servlet和servlet-mapping。注意必须本文还有配套的精品资源点击获取
返回列表