ARTICLE DETAIL

资讯详情

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

JSP机票预订系统源码部署与改造实战:从解压到跑通全流程

JSP机票预订系统源码部署与改造实战:从解压到跑通全流程 简介一份基于JSP与Java Web技术的机票预订系统源代码面向需要完成课程设计或入门Java Web开发的读者旨在演示在线机票预订流程中的用户登录、航班查询、订单管理等核心环节。项目采用MVC三层结构组织代码Servlet负责接收请求JavaBean封装业务数据DAO层执行数据库访问整体逻辑清晰便于维护扩展。压缩包共1644个文件大小38.59MB包含JSP页面、Java源码、XML配置文件、SQL数据库脚本以及js、css、gif、png等前端资源目录按WEB-INF、jsp、css、js、images、classes、lib等组织结构清晰便于分模块对照研究。已有156人浏览学习适合作为课程设计或毕业设计的参考通过阅读源码可理解用户认证、会话跟踪、参数校验、数据库增删改查等Java Web核心机制并学习如何整合前端资源与后端业务逻辑构建完整可运行的项目是非常适合初学者上手的实践案例。1. jsp机票预订系统源代码.zip这不是一个解压即用的黑匣子你可能刚下载完 jsp机票预订系统源代码.zip双击解压后盯着满屏的 xml、jsp、java 文件发懵。这个源码包是典型的 Java Web 课程设计/毕业设计形态JSP 写页面、Servlet 写控制、JavaBean 和 DAO 操作 MySQL覆盖航班查询、下单、订单管理、后台维护一条完整业务链。它适合三类人需要在一周内交作业的学生、刚入职要接手老 Java Web 项目的新人、想拿一套完整业务练手再迁移到 Spring Boot 的开发者。但我要先泼一盆冷水这类 zip 包九成不是“解压就能跑”而是“解压后还要花半天对齐环境”。本文就把这半天时间帮你省掉。2. 技术栈拆解JSPServletJavaBean 的老三样为什么至今还在课程设计里活着2.1 从标题到选型为什么机票预订系统还在用 JSP 写“jsp 机票预订系统源代码.zip”这个标题里的三个关键词——jsp、源代码、zip已经说明了它的出身教学场景下的完整工程而不是生产级商业项目。机票预订这个业务模型对教学来说是完美的航班查询带多条件筛选和分页下单涉及事务和库存扣减订单有状态流转用户有登录注册后台还有航班和票价管理。这一套下来增删改查、会话管理、分页、事务、JDBC 连接管理全都能练到正好覆盖课程设计的所有考点。那为什么还要用 JSP 而不是 Spring Boot答案很现实课程大纲还没更新教材还是 SSM 之前的体系更重要的是JSP 项目解压后扔进 Tomcat 就能跑不依赖 Maven 中央仓库断网环境下用 U 盘也能把环境凑齐。Spring Boot 项目则需要 Maven 拉依赖、配置 JDK 版本、处理 starter 兼容性对第一次做 Web 作业的学生来说门槛偏高。从我接手过的几个二手 JSP 项目看只要 lib 目录里 jar 包齐全、JDK 是 8、Tomcat 在 7 到 9基本都能在半小时内跑起来这就是它到现在还在 zip 包里流通的原因。选型上我的建议是如果这是你自己练手不用纠结“落不落后”重点是看懂三层架构里的数据怎么走如果你是给别人做维护先确认对方到底是 Servlet 3.0 还是 2.5 的写法这决定了 web.xml 里要写配置还是能直接用注解。2.2 源码包里通常有什么目录约定与三层结构解压后不要急着用 IDE 打开整个工程先按目录结构过一遍。绝大多数 JSP 课程设计源码是这样的形态目录/文件作用常见踩坑点src/com/xxx/bean实体类对应数据库表字段字段名得和数据库列名手工对齐src/com/xxx/servlet控制器接收请求调 DAO 再转发 JSP类没编译进 classes 时页面 404src/com/xxx/daoJDBC 操作SQL 全在这层连接没关闭会导致数据库连接耗尽src/com/xxx/utilDBUtil 数据库连接工具等连接参数写死在这里部署时常忘改WebContent/WEB-INF/web.xmlServlet 映射、欢迎页、过滤器新旧版本配置方式不同WebContent 下的 .jsp 文件页面直接放根目录或 jsp 子目录相对路径问题导致 JS/CSS/图片失效sql/*.sql建库建表语句加初始数据字符集不是 utf8mb4 时导入即乱码lib/*.jarJDBC 驱动、JSTL 标签库等MySQL 8 驱动下错版本会直接连不上README.txt部署步骤、账号密码很多时候是空的别指望这里我要多说一句关于源代码管理的建议。拿到 zip 的第一件事我一般会在目录里执行git init存个初始版本。原因很实在改代码改崩了有后悔药吃想对照原来的 Servlet 逻辑也有 diff 可看。“源代码管理”不是大厂才需要的流程一个人改二手项目时反而更需要因为你看不懂的地方太多手一抖删了半个方法可能要到跑起来才发现。2.3 一次请求在 JSP 项目里怎么走从 query 到最后渲染弄懂运行机制比读代码更重要。用户在前端页面输入出发城市、到达城市、日期点查询这个请求在传统 JSP 项目里的完整路径是这样的浏览器 POST 到 Servlet 的 doPostServlet 把参数取出来放入 DAO 层的方法参数DAO 通过 JDBC 拼 PreparedStatement 查 MySQL拿到 ResultSet 后转成 List 对象返回 ServletServlet 把这个 List 塞进 request 的 attribute然后 forward 到 List.jspJSP 在页面上用 JSTL 和 EL 表达式把数据渲染成表格。全程走完浏览器收到的才是完整 HTML。JSP 有一个特性在调试时特别容易坑人它第一次被访问时要翻译成 Java 文件再编译成 class所以首个访问者会明显感觉到慢。改 JSP 文件不需要重启 Tomcat刷新就生效但改 Servlet 就要重新编译并重启才能生效很多新手在这里反复“没生效啊”其实是没分清改的是哪一层。另外登录后的“jsp个人信息展示页面”本质上也是这个链路从 session 里拿 userId再查一次订单表渲染出来逻辑和航班列表几乎一致只是查询条件从城市换成了用户 ID。3. 部署到本机JDK8TomcatMySQL 的版本搭配与最小启动步骤3.1 环境选择JDK8、Tomcat 8/9 与 MySQL 5.7/8 的搭配原则老 JSP 项目对环境版本极度敏感这是部署环节最大的翻车来源之一。最常见的靠谱组合是 JDK 8 Tomcat 8.5 或 9 MySQL 5.7。JDK 8 之所以是绝对主流是因为这些源码编译时普遍用javax.servlet.*这套 APIJDK 8 的兼容性最稳JDK 11 往上移除了不少老 API很多课程设计代码一编译就是“找不到符号”。JDK 这边我推荐直接下载 jdk8 的 zip 包而不是用安装版解压后配一下JAVA_HOME和PATH就行卸载时删目录走人干净利落。Tomcat 版本和 JDK 有配套关系Tomcat 9 要求 JDK 8 及以上Tomcat 8.5 也是兼容 JDK 8 的这两个版本都能跑绝大多数 JSP 项目。MySQL 这块要注意驱动 jar 包如果源码的 lib 里是mysql-connector-java-5.x那配 MySQL 8.0 大概率报Public Key Retrieval is not allowed要么换驱动 jar 到 8.x要么在 JDBC URL 里加allowPublicKeyRetrievaltrue。我的建议是源码自带哪个驱动版本数据库就用对应版本源码没带驱动直接下载 MySQL 8 的 zip 版来做免安装初始化配 8.x 驱动。组件推荐版本互相约束JDK1.8.0_2xx不要上 11除非你确认源码无旧 APITomcat8.5/9.0需 JDK 89 的 servlet 规范更高MySQL5.7 或 8.0驱动 5.x 配 5.7驱动 8.x 配 8.0编码UTF-8页面、请求、数据库、JDBC URL 四个地方一致3.2 部署步骤把 zip 包变成可访问的 web 应用拿到 zip 包后在 Tomcat 的 webapps 目录下解压是最简单的“部署”方式。Linux 服务器上我常用命令行操作Windows 上直接把 zip 内容解压到 webapps 效果一样。# 进入 Tomcat 的 webapps 目录 cd /opt/tomcat/webapps # 解压源码包目录名将成为访问路径 unzip jsp_airline_ticket.zip # 确认解压出来的顶层目录结构注意有没有 WEB-INF ls -la jsp_airline_ticket/WEB-INF/ # 启动 Tomcat cd /opt/tomcat/bin ./startup.sh # 实时看启动日志出现 Server startup 才算成功 tail -f /opt/tomcat/logs/catalina.out这段命令里有两个关键点。第一zip 包的顶层目录名就是 context path浏览器访问地址是http://localhost:8080/jsp_airline_ticket/如果你把目录改名成airline访问路径也要跟着变。第二解压后要检查是否包含WEB-INF/web.xml和WEB-INF/classes或lib这是 Java Web 应用的身份证明如果解压出来只有一堆 jsp 而没有 WEB-INF说明这包本身不完整别浪费时间先回去找原作者要完整版。启动成功后访问首页若能看到登录框或查询框部署这步就算通关了。这里补充一个 Windows 上的差异Tomcat 的startup.bat一闪而过通常意味着 JAVA_HOME 没配好先在 cmd 里敲java -version验证再去改环境变量。另外很多压缩包解压后会有__MACOSX或.DS_Store这类垃圾文件不影响运行但建议顺手删掉免得以后排查问题时被无关文件干扰。3.3 数据库导入sql 脚本不是双击就能完事数据库导入是另一个高发翻车点。源码包里的airline.sql可能包含建库语句也可能没有常见做法是手动建库再用 source 导入。MySQL 8 zip 包初始化后用命令行操作如下# 登录 MySQL输入密码 mysql -uroot -p # 建库字符集一定要指定 utf8mb4 CREATE DATABASE airline DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; # 切库后执行脚本 USE airline; SOURCE /path/to/airline.sql; # 验证表是否建好 SHOW TABLES;这里有个容易忽略的坑很多课程设计的 sql 脚本是直接从 MySQL 5.x 导出的默认字符集是 latin1即使你建库用了 utf8mb4导入后页面中文照样乱码。所以导入之前先看 sql 文件头部有没有SET NAMES或DEFAULT CHARSET的注释如果看到 latin1把文件里所有latin1全局替换成utf8mb4再导入。还有一点脚本如果在执行过程中报Duplicate column name这种错千万别忽略这说明表没建完整后面页面报的“字段不存在”都是从这里开始的。导入完成后去源码里找到DBUtil.java或db.properties把 username、password、jdbc url 改成你本机的实际值。这三处不一致是后续所有连接报错的源头我建议一次性对清楚再启动 Tomcat而不是等到页面报了 500 再回头改。4. 核心链路走读航班查询分页、下单扣库存、支付回跳防重4.1 航班查询与分页JSP 里怎么写不出“优雅”但够用的查询先看查询链路这是整个系统的门面功能也是所有列表页面的模板。下面这段是一个典型的 SearchFlightServlet 核心代码保留了教学项目的常见写法注释里我会标出哪些地方是可改的。// SearchFlightServlet.java doGet 核心片段 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 接收三个查询条件 String fromCity req.getParameter(fromCity); String toCity req.getParameter(toCity); String flyDate req.getParameter(flyDate); // 页码默认 1用户传参不合法时也用 1 int pageNo 1; try { pageNo Integer.parseInt(req.getParameter(pageNo)); } catch (NumberFormatException ignored) { // 参数缺失或非数字时就当第一页处理 } int pageSize 10; ListFlight flights new ArrayList(); int total 0; try (Connection conn DBUtil.getConnection()) { // 先查总数供页面算总页数 String countSql select count(*) from flight where from_city? and to_city? and fly_date?; try (PreparedStatement ps conn.prepareStatement(countSql)) { ps.setString(1, fromCity); ps.setString(2, toCity); ps.setString(3, flyDate); try (ResultSet rs ps.executeQuery()) { if (rs.next()) { total rs.getInt(1); } } } // 再查当前页数据limit 的两个参数是偏移量和行数 String sql select * from flight where from_city? and to_city? and fly_date? order by depart_time limit ?,?; try (PreparedStatement ps conn.prepareStatement(sql)) { ps.setString(1, fromCity); ps.setString(2, toCity); ps.setString(3, flyDate); ps.setInt(4, (pageNo - 1) * pageSize); ps.setInt(5, pageSize); try (ResultSet rs ps.executeQuery()) { while (rs.next()) { Flight f new Flight(); f.setId(rs.getInt(id)); f.setFlightNo(rs.getString(flight_no)); // 省略其余字段的 get 赋值 flights.add(f); } } } } catch (SQLException e) { e.printStackTrace(); // 教学代码常见写法建议换成日志 } // 把数据塞进 request转发给 JSP 渲染 req.setAttribute(flights, flights); req.setAttribute(total, total); req.setAttribute(pageNo, pageNo); req.getRequestDispatcher(/flightList.jsp).forward(req, resp); }这段代码有几个值得细说的地方。PreparedStatement 用?占位而不是字符串拼接这是防御 SQL 注入的基本功即使课程设计也应该保持这个习惯。pageNo的解析没有直接抛异常而是回退到 1这是为了用户手滑把页码参数改成乱码时页面不至于 500代价是错误被静默吞掉了调试时不容易发现更稳妥的做法是解析失败时在页面上给个提示。分页用limit offset, size偏移量计算公式(pageNo-1)*pageSize初学者在这里常算错结果就是第二页和第一页数据一样。修改pageSize时记得页面上的分页组件也要同步否则用户看到 10 条数据却报“共 20 页”那大概率是哪里传参没对齐。真实的 zip 源码里这段代码可能更散Servlet 直接调 DAODAO 里再写两个方法没有 service 层。这不是错误而是教学项目的正常粒度。你自己往 Spring Boot 迁移时对应的就是 Controller、Service、Mapper 三层SQL 逻辑原样搬就行。4.2 下单与扣减库存事务里那点并发的事航班余票数为 0 时不能继续出票这个逻辑听起来简单但教学源码里十有八九没做并发控制。简单查一下余票再 UPDATE两个用户同时订最后一张票时就会超卖。代码层面要保证原子性常见做法是 SQL 层做条件更新。// OrderDAO.java 创建订单并扣减余票必须在同一个事务里 public boolean createOrder(Order order, int flightId) { Connection conn null; try { conn DBUtil.getConnection(); // 手动开启事务默认自动提交要关掉 conn.setAutoCommit(false); // 条件更新余票大于0才扣影响行数为0说明已没票 String sql update flight set remain_seat remain_seat - 1 where id ? and remain_seat 0; try (PreparedStatement ps conn.prepareStatement(sql)) { ps.setInt(1, flightId); int rows ps.executeUpdate(); if (rows 0) { conn.rollback(); return false; // 没票了 } } // 插入订单记录 String insertSql insert into order (order_no, user_id, flight_id, status) values (?,?,?,?); try (PreparedStatement ps conn.prepareStatement(insertSql)) { ps.setString(1, order.getOrderNo()); ps.setInt(2, order.getUserId()); ps.setInt(3, flightId); ps.setString(4, UNPAID); ps.executeUpdate(); } conn.commit(); // 两个操作都成功才提交 return true; } catch (Exception e) { // 任何一步异常都回滚保证数据和余票一致 if (conn ! null) { try { conn.rollback(); } catch (SQLException ignored) {} } e.printStackTrace(); return false; } finally { if (conn ! null) { try { conn.setAutoCommit(true); conn.close(); } catch (SQLException ignored) {} } } }这里最关键的一行是where id? and remain_seat0把“检查余票”和“扣减余票”合并成一次原子操作数据库的行锁会挡住并发比先 SELECT 再 UPDATE 安全得多。很多源码包里写的是update flight set remain_seat remain_seat - 1 where id?余票为 0 时继续减成负数这就是实打实的血泪教训。conn.setAutoCommit(false)是事务开始commit 是结束中途任何异常要 rollback顺序别搞反。order是 MySQL 的保留字表名和 SQL 里必须用反引号括起来否则报语法错误这个坑几乎每个 JSP 项目都会遇到。4.3 支付回跳与防重复提交状态机比 token 更皮实机票预订系统的“支付”一般是模拟的页面点去支付跳到内置的 fake 支付页几秒后回跳订单详情。回跳之后用户手痒按一下 F5如果代码没有幂等判断同一条订单会被重复处理两次票号生成两条余票被扣两次。防重复提交在传统 JSP 项目里的最常见做法是查订单状态再决定要不要继续执行。// OrderPayCallbackServlet.java 支付回跳处理 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String orderId req.getParameter(orderId); Order order orderDao.findById(Integer.parseInt(orderId)); if (order null) { resp.sendError(404, 订单不存在); return; } // 幂等判断状态已经是 PAID 就直接展示不再重复出票 if (PAID.equals(order.getStatus())) { resp.sendRedirect(orderDetail.jsp?orderId orderId); return; } // 只有 UNPAID 状态才执行支付确认流程 boolean ok orderDao.updateStatus(order.getId(), PAID, generateTicketNo(flightId, order.getId())); if (ok) { resp.sendRedirect(orderDetail.jsp?orderId orderId); } else { req.setAttribute(error, 支付确认失败请稍后重试); req.getRequestDispatcher(/payFail.jsp).forward(req, resp); } }以订单状态作为幂等键的做法比前端 token 更耐用原因很简单token 存在 session 里用户换个浏览器或 session 过期就没用了而订单状态在数据库里重试多少次结果都一样——第二次进来看到 PAID直接返回。要注意的是状态判断要在做任何改库操作之前否则判断等于白写。这里还有个常见误区有人会在 JSP 的 head 里写meta http-equivrefresh content0;url...来自动跳转这个写法在支付回跳场景会放大问题因为地址栏一直停在原页面刷新时会把 GET 再发一次配合没有幂等判断的后端就生成了两张票。支付回跳用resp.sendRedirect()是更稳妥的做法浏览器地址栏会变成最终地址F5 也只会刷订单详情页。4.4 图片与静态资源JSP 图片不显示和坐标定位的细节JSP 页面里图片不显示是高频问题十次里有八次是相对路径猜错了。比如页面在/airline/user/center.jsp里面写img srcimages/avatar.png浏览器会把它解析成/airline/user/images/avatar.png而这个目录根本不存在。解决方法是页面头部拼一个 basePath把图片地址写成绝对路径式% String path request.getContextPath(); String basePath request.getScheme() :// request.getServerName() : request.getServerPort() path /; % img src%basePath%images/avatar.png /如果你拿到的是 JSP 图片对坐标定位相关的需求比如给航班座位图做热区常见做法是把图片位置固定后用 CSS 绝对定位把座位坐标写在页面元素上而不是写死在 JSP 脚本里。这样后端换一张座位图时坐标逻辑不用跟着改。另外验证码或动态生成的图片刷不出来先确认是不是加了缓存给 img 的 src 拼一个?t%System.currentTimeMillis()%强制刷新这招在 JSP 里很实用也正好解释了你可能遇到的“页面加载后必须刷新一次才能看到新图片”的怪象。5. 避坑清单404、乱码、端口占用、连接失败的排查手册5.1 页面能打开一提交就 404 或 405现象首页正常显示点击登录或查询按钮浏览器地址变成了http://localhost:8080/airline/loginServlet然后报 404 或者 405。原因分三类第一web.xml里的servlet-mapping写的是/loginServlet而页面表单actionloginServlet没加前导斜杠请求路径对不上第二Servlet 类虽然写在 src 里但 IDE 没把它编译到WEB-INF/classes目录下Tomcat 找不到类第三405 意味着请求方法不对——Servlet 只重写了 doGet但表单用的是 POST。解决先看 web.xml 的url-pattern再和页面代码的 action 逐字对齐包括大小写和斜杠。然后去WEB-INF/classes目录确认.class文件在不在不在就重新编译。这些检查用命令行最直接# 查看编译产物是否存在 ls /opt/tomcat/webapps/airline/WEB-INF/classes/com/xxx/servlet/ # 看 Tomcat 日志里的具体报错 grep -A 10 HTTP Status 404 /opt/tomcat/logs/catalina.out5.2 中文乱码三连页面、请求、数据库现象打开页面中文全乱输入中文搜索查不到结果数据库里看订单客户名变成????页面上本来应该显示“北京”变成了“å\x8c\x97京”。原因这是一个复合问题任何一个环节断了都会乱码。JSP 页面没设置pageEncoding请求处理时没调用setCharacterEncoding(UTF-8)数据库表字符集是 latin1JDBC URL 没带characterEncodingutf8四处之间只要有一处不一致就乱。很多新手只改数据库页面还乱就会觉得这是“玄学”。解决把四处全对齐成 UTF-8。JSP 文件头写pageEncodingUTF-8在 Servlet 的 doPost 第一行加req.setCharacterEncoding(UTF-8)或者直接在 web.xml 里配一个 CharacterEncodingFilterJDBC URL 改成jdbc:mysql://localhost:3306/airline?useUnicodetruecharacterEncodingutf8数据库建表时指定 utf8mb4。按这个顺序排查三分钟能定位到断点。最隐蔽的是已存在的表字符集和建库语句不一致用SHOW CREATE TABLE flight;看一眼 CHARSET 就能确认。5.3 Tomcat 启动失败端口被占和 startup 脚本闪退现象双击 startup.bat 闪退或者./startup.sh后日志里报Address already in use: JVM_Bind。还有一种情况是 Tomcat 能起但访问 8080 看到一个陌生页面根本不是你的项目。原因8080 被占用是最高频的可能是之前启动的 Tomcat 残留进程也可能是其他开发工具占了端口。startup.bat闪退更常见的原因是 JAVA_HOME 没设对Tomcat 启动脚本找不到 jre。解决先确认 8080 端口被谁占了。Windows 下用netstat -ano | findstr :8080找到 PID再去任务管理器结束进程Linux 下用lsof -i:8080或fuser -k 8080/tcp。如果只想换个端口改conf/server.xml里的Connector port8080为别的端口改完重启。JAVA_HOME 的话确认环境变量指向的是 jdk 目录而不是 jre 目录Tomcat 需要的是 JDK 而不是 JRE。一个检查技巧在命令行跑%CATALINA_HOME%/bin/catalina.bat run前台运行日志直接打到控制台比 start 脚本更容易看到错误。5.4 JDBC 连接失败报错五花八门根源就五个地方现象系统能登录、能查航班一旦点进需要读写数据库的页面就报 500日志里有ClassNotFoundException或Access denied for user rootlocalhost也有报Communications link failure的。原因这几个报错的根源都在 DAO 的连接参数上。ClassNotFoundException 是驱动 jar 没进WEB-INF/libAccess denied 是用户名密码和 MySQL 实际账号不一致Communications link failure 的常见原因是 MySQL 服务没启动或 JDBC URL 里的端口写错成 3307。解决把下面五个地方一次性对齐驱动 jar 的版本、driverClassNameMySQL 5.x 配com.mysql.jdbc.DriverMySQL 8.x 配com.mysql.cj.jdbc.Driver、jdbc:mysql://的 IP 端口、username、password。特别提醒很多源码的 DBUtil 把账号密码硬编码在 Java 类里你改了db.properties但没重新编译改了等于白改。遇到连接类报错时先用命令行手工连一次 MySQLmysql -uroot -p -P 3306命令行能连上但程序连不上问题就在驱动和 URL 上命令行也连不上那就是 MySQL 服务本身没起来或密码不对按这个思路能少走很多弯路。6. 三个低成本改造让这份 JSP 源码更耐看也更好维护6.1 Scriptlet 换成 JSTL 标签外观最直接的改变打开 flightList.jsp如果满屏% %和out.println拼 HTML这是最不优雅的地方。换成 JSTL 后页面从五十行缩到十行结构也清楚很多头部引入% taglib prefixc urihttp://java.sun.com/jsp/jstl/core %循环用c:forEach状态判断用c:if或c:choose。JSP 2.x 默认支持 EL 表达式${flight.flightNo}不用额外配置比 scriptlet 里来回转型安全得多。改完之后建议先编译一次看有没有标签库缺包JSTL 的两个 jar 一般已经在源码的 lib 里没有的话从现有 Tomcat 示例应用里拷也很快。6.2 连接池替换 DBUtil一次改动解决连接耗尽原版的 DBUtil 每次请求都新建连接、用完关闭在本地跑没什么事但一旦演示时多开几个窗口就会看到Too many connections。换成 Druid 连接池是性价比最高的改造引入 druid.jar把 DBUtil 的静态块里建好连接池后续代码不用动// DBUtil.java 改造后的连接获取方式 static { DruidDataSource ds new DruidDataSource(); ds.setUrl(jdbc:mysql://localhost:3306/airline?characterEncodingutf8); ds.setUsername(root); ds.setPassword(123456); ds.setInitialSize(5); ds.setMaxActive(20); ds.setMaxWait(3000); }这里三个参数记一下initialSize启动时预建的连接数maxActive最大活跃连接数maxWait拿不到连接时的等待毫秒数。改造完观察一个小细节并发上来后页面响应变快是连接复用起的效果。6.3 打印登机牌一个能写进答辩的完整小功能在订单详情页加一个“打印登机牌”按钮弹窗打开一个只有基本信息的新页面再调用window.print()。这是一个完整的 JSPServlet 小循环取订单号、查航班、拼页面、调打印代码量不大但功能完整放在简历或答辩里比单纯改样式有说服力得多。做这个改造时踩过的坑我记忆很深打印页面里只要有一个 CSS 用了position: relative预览就可能多出一页空白页另一个就是打印页面引用了主站的导航栏打印出来丑到没法看。解决方法是打印页只用内联样式或单独一份极简 CSS不继承任何公共布局。这种每年都有人踩的细节就是传统 JSP 项目里最难系统化、只能靠经验积累的部分。这套源码跑通之后你就是从这类工程里一点点把经验攒起来的希望帮到你。本文还有配套的精品资源点击获取
返回列表