基于JSP的航班机票预订与管理系统 - 源码深度解析

JavaJavaScriptHTMLCSSMySQLJSP+Servlet
2026-03-103 浏览

文章摘要

本项目是一款基于JSP技术栈构建的航班机票预订与管理系统,旨在为中小型航空公司或票务代理机构提供一个稳定、易用的核心业务平台。系统核心解决了传统线下售票模式效率低下、信息更新不及时以及管理混乱的痛点,通过集中化的在线处理,实现了票务信息的实时同步、订单流程的标准化与运营成本的有效控制。 在技术实现...

在传统航空票务领域,线下人工操作模式长期存在着信息更新滞后、业务流程繁琐、管理成本高昂等核心痛点。针对这些挑战,我们设计并实现了一套名为“航旅通”的在线票务管理平台。该系统采用成熟的JSP技术栈,构建了一个集航班查询、机票预订、订单管理、后台运营于一体的综合性解决方案,有效提升了票务处理的自动化水平和运营效率。

系统采用经典的三层架构模式,即表现层、业务逻辑层和数据持久层。表现层由JSP页面和前端技术(HTML, CSS, JavaScript)构成,负责用户界面的动态渲染和交互。业务逻辑层以Servlet作为控制器,接收并解析前端请求,调用相应的JavaBean组件处理核心业务。数据持久层则通过JDBC直接与MySQL数据库进行交互,完成数据的增删改查操作。这种MVC模式的清晰分离,确保了代码的可维护性和系统的可扩展性。

数据库架构深度解析

系统的稳定运行依赖于一套设计严谨的数据库模型,共包含5张核心数据表。以下重点分析其中两个关键表的设计亮点。

flights表是系统的中枢,存储了所有航班的基础信息。其设计不仅包含了航班号、起降城市、时间等基本字段,还通过seat_capacityavailable_seats两个字段实现了座位的动态库存管理。这种设计允许系统实时跟踪余票数量,为并发预订场景下的数据一致性提供了基础。

CREATE TABLE flights (
    flight_id INT AUTO_INCREMENT PRIMARY KEY,
    flight_number VARCHAR(20) NOT NULL UNIQUE,
    departure_city VARCHAR(50) NOT NULL,
    arrival_city VARCHAR(50) NOT NULL,
    departure_time DATETIME NOT NULL,
    arrival_time DATETIME NOT NULL,
    price DECIMAL(10, 2) NOT NULL,
    seat_capacity INT NOT NULL,
    available_seats INT NOT NULL,
    CONSTRAINT chk_available_seats CHECK (available_seats >= 0 AND available_seats <= seat_capacity)
);

orders表则记录了所有的交易记录,是业务逻辑最复杂的表之一。它通过flight_id外键与flights表关联,确保了订单数据的参照完整性。order_status字段使用枚举类型定义了订单的生命周期状态(如“待支付”、“已确认”、“已取消”),这种设计便于进行状态查询和流程控制。total_amount字段通过触发器或应用层逻辑与ticket_count和航班价格联动,保证了金额计算的准确性。

CREATE TABLE orders (
    order_id INT AUTO_INCREMENT PRIMARY KEY,
    user_id INT NOT NULL,
    flight_id INT NOT NULL,
    order_date DATETIME DEFAULT CURRENT_TIMESTAMP,
    ticket_count INT NOT NULL CHECK (ticket_count > 0),
    total_amount DECIMAL(10, 2) NOT NULL,
    order_status ENUM('pending', 'confirmed', 'cancelled') DEFAULT 'pending',
    contact_info VARCHAR(255),
    FOREIGN KEY (user_id) REFERENCES users(user_id) ON DELETE CASCADE,
    FOREIGN KEY (flight_id) REFERENCES flights(flight_id)
);

核心功能实现剖析

  1. 智能航班查询与筛选 用户进入系统后,首先使用的是航班查询功能。前端页面提供出发城市、到达城市、日期等筛选条件。当用户提交查询后,请求被发送到对应的Servlet控制器。

    // FlightQueryServlet.java 片段
    public class FlightQueryServlet extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            String departureCity = request.getParameter("departureCity");
            String arrivalCity = request.getParameter("arrivalCity");
            String date = request.getParameter("departureDate");
            
            FlightService flightService = new FlightService();
            List<Flight> flightList = flightService.searchFlights(departureCity, arrivalCity, date);
            
            request.setAttribute("flightList", flightList);
            RequestDispatcher dispatcher = request.getRequestDispatcher("flightResults.jsp");
            dispatcher.forward(request, response);
        }
    }
    

    Servlet调用FlightService这个业务Bean,后者构造SQL语句,通过JDBC查询数据库。查询结果以一个Flight对象列表的形式返回,并存储在request作用域中,最终由flightResults.jsp页面进行迭代渲染,以清晰的列表形式展示给用户。

    航班查询界面

  2. 事务性机票预订流程 机票预订是系统最核心、最需要保证数据一致性的功能。当用户选择航班并填写乘机人信息后,点击预订将触发一个包含多个数据库操作的事务。

    // BookingServlet.java 核心事务处理片段
    public class BookingServlet extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            Connection conn = null;
            try {
                conn = DatabaseUtil.getConnection();
                conn.setAutoCommit(false); // 开启事务
                
                int flightId = Integer.parseInt(request.getParameter("flightId"));
                int ticketCount = Integer.parseInt(request.getParameter("ticketCount"));
                
                // 1. 检查余票
                Flight flight = flightDAO.getFlightById(conn, flightId);
                if (flight.getAvailableSeats() < ticketCount) {
                    throw new Exception("Insufficient seats available");
                }
                
                // 2. 扣减库存
                flightDAO.updateAvailableSeats(conn, flightId, flight.getAvailableSeats() - ticketCount);
                
                // 3. 创建订单记录
                Order newOrder = new Order();
                newOrder.setUserId(loggedInUserId);
                newOrder.setFlightId(flightId);
                newOrder.setTicketCount(ticketCount);
                newOrder.setTotalAmount(flight.getPrice() * ticketCount);
                orderDAO.createOrder(conn, newOrder);
                
                conn.commit(); // 提交事务
                request.setAttribute("order", newOrder);
                request.getRequestDispatcher("bookingSuccess.jsp").forward(request, response);
                
            } catch (Exception e) {
                if (conn != null) {
                    try { conn.rollback(); } catch (SQLException ex) { ex.printStackTrace(); } // 回滚事务
                }
                request.setAttribute("errorMessage", "Booking failed: " + e.getMessage());
                request.getRequestDispatcher("booking.jsp").forward(request, response);
            } finally {
                DatabaseUtil.closeConnection(conn);
            }
        }
    }
    

    这个过程首先检查余票是否充足,然后原子性地执行库存扣减和订单创建。任何一步失败都会导致整个事务回滚,防止了超卖和数据不一致的问题。成功预订后,用户会跳转到订单确认页面。

    机票预订系统

  3. 后台航班信息管理 后台管理员拥有对航班信息的全面管理权限。管理员登录后,可以进入航班列表页面,进行增删改查操作。

    <%-- flightManagement.jsp 航班列表展示片段 --%>
    <table class="table">
        <thead>
            <tr>
                <th>航班号</th><th>出发城市</th><th>到达城市</th><th>出发时间</th><th>价格</th><th>余票</th><th>操作</th>
            </tr>
        </thead>
        <tbody>
            <c:forEach var="flight" items="${flightList}">
                <tr>
                    <td>${flight.flightNumber}</td>
                    <td>${flight.departureCity}</td>
                    <td>${flight.arrivalCity}</td>
                    <td><fmt:formatDate value="${flight.departureTime}" pattern="yyyy-MM-dd HH:mm"/></td>
                    <td>¥${flight.price}</td>
                    <td>${flight.availableSeats} / ${flight.seatCapacity}</td>
                    <td>
                        <a href="editFlight.jsp?id=${flight.flightId}" class="btn">编辑</a>
                        <a href="DeleteFlightServlet?id=${flight.flightId}" onclick="return confirm('确定删除?')" class="btn btn-danger">删除</a>
                    </td>
                </tr>
            </c:forEach>
        </tbody>
    </table>
    

    页面使用JSTL标签库循环显示航班列表,并提供了编辑和删除操作的链接。DeleteFlightServlet会处理删除请求,并在删除前进行必要的业务逻辑检查,如该航班是否存在未完成的订单。

    航班列表管理

  4. 订单管理与状态跟踪 系统为用户和管理员都提供了订单管理功能。用户可以查看自己的历史订单和当前状态,管理员则可以查看和管理所有订单。

    // OrderDAO.java 中的查询方法
    public class OrderDAO {
        public List<Order> getOrdersByUserId(Connection conn, int userId) throws SQLException {
            String sql = "SELECT o.*, f.flight_number, f.departure_city, f.arrival_city, f.departure_time " +
                         "FROM orders o JOIN flights f ON o.flight_id = f.flight_id " +
                         "WHERE o.user_id = ? ORDER BY o.order_date DESC";
            List<Order> orders = new ArrayList<>();
            try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
                pstmt.setInt(1, userId);
                ResultSet rs = pstmt.executeQuery();
                while (rs.next()) {
                    Order order = extractOrderFromResultSet(rs);
                    orders.add(order);
                }
            }
            return orders;
        }
        // ... 其他方法
    }
    

    该方法通过联表查询(JOIN),将订单信息与其对应的航班详细信息一次性取出,避免了N+1查询问题,提升了效率。查询结果在页面上清晰展示,方便用户跟踪行程。

    用户查看订单

实体模型与业务逻辑

系统的核心实体包括用户(User)、航班(Flight)、订单(Order)等。这些实体通过JavaBean进行建模,每个Bean都封装了属性、getter和setter方法,并在业务逻辑层被频繁使用。例如,Flight对象不仅在查询时使用,在预订过程中更是计算金额、判断库存的核心依据。业务逻辑层的方法,如FlightService.searchFlightsOrderService.placeOrder,通过组合调用多个DAO(数据访问对象)的方法,实现了复杂的业务规则,确保了系统的健壮性。

功能展望与优化方向

尽管“航旅通”系统已经实现了核心的票务功能,但在实际生产环境中仍有广阔的优化空间。

  1. 引入缓存机制提升性能:频繁被读取但更新不频繁的数据,如城市列表、热门航线信息,可以引入Redis等缓存中间件。将数据缓存起来,能显著减轻数据库压力,提高响应速度。实现上,可以在Servlet中先查询缓存,命中则直接返回,未命中再查数据库并写入缓存。
  2. 实现分布式会话管理:当前系统可能依赖服务器本地会话(HttpSession),这在单机部署时没有问题,但不利于水平扩展。可以将会话数据存储到外部存储(如Redis集群),实现会话共享,从而支持多机负载均衡部署,提高系统的可用性和伸缩性。
  3. 集成第三方支付与短信服务:集成支付宝、微信支付等主流支付接口,为用户提供便捷的支付体验。同时,集成短信服务平台,在用户注册、订单确认、航班变动等关键节点发送通知短信,提升服务质量。这通常需要调用第三方提供的API,并在系统中异步处理调用结果。
  4. 构建数据分析与报表系统:在后台增加数据分析模块,对历史订单数据进行挖掘,生成如销售额趋势图、热门航线排行榜、用户购票行为分析等报表。这可以使用专门的报表工具或通过ECharts等前端图表库可视化后端聚合计算出的数据,为运营决策提供更强大的数据支持。
  5. 前端框架现代化重构:当前前端基于原生JSP和JavaScript,交互体验有提升空间。可以考虑使用Vue.js或React等现代前端框架重构用户界面,实现前后端分离。后端则专注于提供RESTful API,前端通过AJAX调用API获取数据。这种架构能带来更好的用户体验和开发效率。

该系统作为传统JSP技术栈的典型应用,展示了如何通过清晰的分层架构和严谨的数据库设计,构建一个功能完备、稳定可靠的业务系统。其设计理念和实现细节,对于理解和实践基于Java的Web应用开发具有重要的参考价值。

本文关键词
JSP航班机票预订管理系统源码解析数据库设计

上下篇

上一篇
没有更多文章
下一篇
没有更多文章