基于JSP的航班机票销售管理系统 - 源码深度解析

JavaJavaScriptHTMLCSSMySQLJSP+Servlet
2026-03-173 浏览

文章摘要

本项目是一款基于JSP技术构建的航班机票销售管理系统,旨在为航空公司或大型票务代理机构提供一体化的航班运营与票务销售解决方案。其核心业务价值在于解决了传统人工处理航班信息和售票业务中存在的效率低下、信息更新不及时、易出错等痛点。系统通过数字化整合航班动态、座位库存和销售数据,实现了业务流程的自动化,...

在航空旅行日益普及的今天,高效、准确的票务管理成为航空公司运营的核心竞争力。传统的人工处理方式面临着信息更新滞后、操作效率低下、差错率高等挑战,亟需数字化解决方案来提升业务处理能力。航空票务通系统应运而生,采用成熟的JSP技术栈构建,为中小型航空公司和票务代理机构提供全面的航班管理和销售服务。

系统采用经典的三层架构模式,严格遵循MVC设计理念。表示层由JSP页面构成,负责用户界面渲染和数据展示;控制层使用Servlet处理所有业务请求,实现核心逻辑的集中管理;模型层通过JavaBean封装数据实体和数据库操作。这种分层设计确保了代码的模块化和可维护性,为系统功能的扩展奠定了坚实基础。

管理员登录界面

数据库设计是系统稳定运行的基石。系统采用MySQL关系型数据库,通过精心设计的表结构确保数据的一致性和完整性。航班信息表(flights)作为核心业务表,采用以下结构设计:

CREATE TABLE flights (
    flight_id INT PRIMARY KEY AUTO_INCREMENT,
    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,
    total_seats INT NOT NULL,
    available_seats INT NOT NULL,
    price DECIMAL(10,2) NOT NULL,
    status ENUM('scheduled','boarding','departed','cancelled') DEFAULT 'scheduled',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

该表设计充分考虑了业务需求,flight_number字段建立唯一索引确保航班号的唯一性,status字段使用枚举类型严格限制航班状态,departure_time和arrival_time采用DATETIME类型精确记录起降时间。available_seats字段的实时更新为票务库存管理提供了可靠保障。

用户订单表(orders)的设计体现了事务处理的严谨性:

CREATE TABLE orders (
    order_id INT PRIMARY KEY AUTO_INCREMENT,
    user_id INT NOT NULL,
    flight_id INT NOT NULL,
    passenger_name VARCHAR(100) NOT NULL,
    passenger_idcard VARCHAR(18) NOT NULL,
    seat_number VARCHAR(10),
    order_amount DECIMAL(10,2) NOT NULL,
    order_status ENUM('pending','confirmed','cancelled','completed') DEFAULT 'pending',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (user_id) REFERENCES users(user_id),
    FOREIGN KEY (flight_id) REFERENCES flights(flight_id)
);

通过外键约束确保数据引用完整性,order_status字段完整记录订单生命周期,索引优化大幅提升查询效率。这种设计为高并发下的订单处理提供了可靠支撑。

系统的航班查询模块展现了高效的数据检索能力。FlightSearchServlet通过多条件组合查询满足用户的灵活需求:

public class FlightSearchServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        
        String departureCity = request.getParameter("departureCity");
        String arrivalCity = request.getParameter("arrivalCity");
        String departDate = request.getParameter("departDate");
        
        FlightDAO flightDAO = new FlightDAO();
        List<Flight> flightList = flightDAO.searchFlights(departureCity, arrivalCity, departDate);
        
        request.setAttribute("flights", flightList);
        RequestDispatcher dispatcher = request.getRequestDispatcher("flightResults.jsp");
        dispatcher.forward(request, response);
    }
}

对应的FlightDAO类实现了精确的数据库查询逻辑:

public class FlightDAO {
    public List<Flight> searchFlights(String departureCity, String arrivalCity, String departDate) {
        List<Flight> flights = new ArrayList<>();
        String sql = "SELECT * FROM flights WHERE departure_city = ? AND arrival_city = ? " +
                    "AND DATE(departure_time) = ? AND available_seats > 0 AND status = 'scheduled'";
        
        try (Connection conn = DBUtil.getConnection();
             PreparedStatement stmt = conn.prepareStatement(sql)) {
            
            stmt.setString(1, departureCity);
            stmt.setString(2, arrivalCity);
            stmt.setString(3, departDate);
            
            ResultSet rs = stmt.executeQuery();
            while (rs.next()) {
                Flight flight = extractFlightFromResultSet(rs);
                flights.add(flight);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return flights;
    }
}

航班搜索界面

机票预订功能实现了完整的业务流程。BookingServlet处理用户提交的预订请求,确保数据的完整性和一致性:

public class BookingServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        
        HttpSession session = request.getSession();
        Integer userId = (Integer) session.getAttribute("userId");
        if (userId == null) {
            response.sendRedirect("login.jsp");
            return;
        }
        
        int flightId = Integer.parseInt(request.getParameter("flightId"));
        String passengerName = request.getParameter("passengerName");
        String passengerIdcard = request.getParameter("passengerIdcard");
        
        OrderDAO orderDAO = new OrderDAO();
        boolean success = orderDAO.createOrder(userId, flightId, passengerName, passengerIdcard);
        
        if (success) {
            response.sendRedirect("bookingSuccess.jsp");
        } else {
            request.setAttribute("error", "预订失败,请重试");
            request.getRequestDispatcher("booking.jsp").forward(request, response);
        }
    }
}

订单处理采用事务机制确保数据一致性:

public class OrderDAO {
    public boolean createOrder(int userId, int flightId, String passengerName, String passengerIdcard) {
        Connection conn = null;
        boolean success = false;
        
        try {
            conn = DBUtil.getConnection();
            conn.setAutoCommit(false);
            
            // 检查航班余票
            String checkSeatsSql = "SELECT available_seats FROM flights WHERE flight_id = ? FOR UPDATE";
            PreparedStatement checkStmt = conn.prepareStatement(checkSeatsSql);
            checkStmt.setInt(1, flightId);
            ResultSet rs = checkStmt.executeQuery();
            
            if (rs.next() && rs.getInt("available_seats") > 0) {
                // 创建订单
                String insertOrderSql = "INSERT INTO orders (user_id, flight_id, passenger_name, " +
                                       "passenger_idcard, order_amount) VALUES (?, ?, ?, ?, ?)";
                PreparedStatement orderStmt = conn.prepareStatement(insertOrderSql);
                orderStmt.setInt(1, userId);
                orderStmt.setInt(2, flightId);
                orderStmt.setString(3, passengerName);
                orderStmt.setString(4, passengerIdcard);
                orderStmt.setDouble(5, getFlightPrice(conn, flightId));
                orderStmt.executeUpdate();
                
                // 更新座位数
                String updateSeatsSql = "UPDATE flights SET available_seats = available_seats - 1 WHERE flight_id = ?";
                PreparedStatement updateStmt = conn.prepareStatement(updateSeatsSql);
                updateStmt.setInt(1, flightId);
                updateStmt.executeUpdate();
                
                conn.commit();
                success = true;
            }
        } catch (SQLException e) {
            if (conn != null) {
                try { conn.rollback(); } catch (SQLException ex) { ex.printStackTrace(); }
            }
            e.printStackTrace();
        } finally {
            DBUtil.closeConnection(conn);
        }
        return success;
    }
}

机票预订模块

用户钱包管理系统提供了安全的资金管理功能。WalletServlet处理充值、消费和余额查询操作:

public class WalletServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        
        String action = request.getParameter("action");
        HttpSession session = request.getSession();
        Integer userId = (Integer) session.getAttribute("userId");
        
        WalletDAO walletDAO = new WalletDAO();
        
        switch (action) {
            case "recharge":
                double amount = Double.parseDouble(request.getParameter("amount"));
                boolean rechargeResult = walletDAO.recharge(userId, amount);
                request.setAttribute("message", rechargeResult ? "充值成功" : "充值失败");
                break;
                
            case "payment":
                double paymentAmount = Double.parseDouble(request.getParameter("amount"));
                boolean paymentResult = walletDAO.makePayment(userId, paymentAmount);
                request.setAttribute("message", paymentResult ? "支付成功" : "余额不足");
                break;
        }
        
        request.getRequestDispatcher("wallet.jsp").forward(request, response);
    }
}

钱包管理界面

管理员功能模块提供了完善的系统管理能力。航班管理Servlet实现航班的增删改查操作:

public class FlightManagementServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        
        String action = request.getParameter("action");
        FlightDAO flightDAO = new FlightDAO();
        
        if ("add".equals(action)) {
            Flight flight = extractFlightFromRequest(request);
            boolean result = flightDAO.addFlight(flight);
            request.setAttribute("message", result ? "航班添加成功" : "航班添加失败");
            
        } else if ("update".equals(action)) {
            Flight flight = extractFlightFromRequest(request);
            flight.setFlightId(Integer.parseInt(request.getParameter("flightId")));
            boolean result = flightDAO.updateFlight(flight);
            request.setAttribute("message", result ? "航班更新成功" : "航班更新失败");
        }
        
        List<Flight> allFlights = flightDAO.getAllFlights();
        request.setAttribute("flights", allFlights);
        request.getRequestDispatcher("flightManagement.jsp").forward(request, response);
    }
}

航班管理界面

数据统计功能为管理决策提供支持。StatisticsServlet生成各类业务报表:

public class StatisticsServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        
        StatisticsDAO statsDAO = new StatisticsDAO();
        
        // 获取销售额统计
        Map<String, Double> salesStats = statsDAO.getSalesStatistics();
        // 获取航线热度统计
        Map<String, Integer> routeStats = statsDAO.getRoutePopularity();
        // 获取用户行为分析
        Map<String, Object> userBehavior = statsDAO.getUserBehaviorAnalysis();
        
        request.setAttribute("salesStats", salesStats);
        request.setAttribute("routeStats", routeStats);
        request.setAttribute("userBehavior", userBehavior);
        
        request.getRequestDispatcher("statistics.jsp").forward(request, response);
    }
}

数据统计界面

系统在数据模型设计上体现了良好的面向对象特性。Flight实体类完整封装了航班业务属性:

public class Flight {
    private int flightId;
    private String flightNumber;
    private String departureCity;
    private String arrivalCity;
    private Date departureTime;
    private Date arrivalTime;
    private int totalSeats;
    private int availableSeats;
    private double price;
    private String status;
    
    // 构造函数
    public Flight() {}
    
    public Flight(String flightNumber, String departureCity, String arrivalCity, 
                 Date departureTime, Date arrivalTime, int totalSeats, double price) {
        this.flightNumber = flightNumber;
        this.departureCity = departureCity;
        this.arrivalCity = arrivalCity;
        this.departureTime = departureTime;
        this.arrivalTime = arrivalTime;
        this.totalSeats = totalSeats;
        this.availableSeats = totalSeats;
        this.price = price;
        this.status = "scheduled";
    }
    
    // Getter和Setter方法
    public int getFlightId() { return flightId; }
    public void setFlightId(int flightId) { this.flightId = flightId; }
    
    public String getFlightNumber() { return flightNumber; }
    public void setFlightNumber(String flightNumber) { this.flightNumber = flightNumber; }
    
    // 其他getter/setter方法...
    
    // 业务方法
    public boolean isAvailable() {
        return "scheduled".equals(status) && availableSeats > 0;
    }
    
    public double calculateDuration() {
        long diff = arrivalTime.getTime() - departureTime.getTime();
        return diff / (1000.0 * 60 * 60); // 返回小时数
    }
}

订单实体类设计了完整的业务逻辑方法:

public class Order {
    private int orderId;
    private int userId;
    private int flightId;
    private String passengerName;
    private String passengerIdcard;
    private String seatNumber;
    private double orderAmount;
    private String orderStatus;
    private Date createdAt;
    
    // 订单状态常量
    public static final String STATUS_PENDING = "pending";
    public static final String STATUS_CONFIRMED = "confirmed";
    public static final String STATUS_CANCELLED = "cancelled";
    public static final String STATUS_COMPLETED = "completed";
    
    // 业务逻辑方法
    public boolean canBeCancelled() {
        return STATUS_PENDING.equals(orderStatus) || STATUS_CONFIRMED.equals(orderStatus);
    }
    
    public boolean isRefundable() {
        return canBeCancelled(); // 可取消的订单即可退款
    }
    
    // Getter和Setter方法
    public int getOrderId() { return orderId; }
    public void setOrderId(int orderId) { this.orderId = orderId; }
    
    // 其他getter/setter方法...
}

数据库连接工具类采用连接池技术优化性能:

public class DBUtil {
    private static DataSource dataSource;
    
    static {
        try {
            Context initContext = new InitialContext();
            Context envContext = (Context) initContext.lookup("java:/comp/env");
            dataSource = (DataSource) envContext.lookup("jdbc/flightDB");
        } catch (NamingException e) {
            e.printStackTrace();
        }
    }
    
    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }
    
    public static void closeConnection(Connection conn) {
        if (conn != null) {
            try { conn.close(); } 
            catch (SQLException e) { e.printStackTrace(); }
        }
    }
}

系统在安全性方面实现了多重保障。用户认证模块采用安全的密码存储机制:

public class AuthenticationFilter implements Filter {
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        HttpSession session = httpRequest.getSession(false);
        
        String loginURI = httpRequest.getContextPath() + "/login.jsp";
        boolean loggedIn = (session != null && session.getAttribute("userId") != null);
        boolean loginRequest = httpRequest.getRequestURI().equals(loginURI);
        
        if (loggedIn || loginRequest) {
            chain.doFilter(request, response);
        } else {
            httpResponse.sendRedirect(loginURI);
        }
    }
}

密码工具类采用BCrypt加密算法:

public class PasswordUtil {
    private static final int BCRYPT_STRENGTH = 12;
    
    public static String hashPassword(String plainPassword) {
        return BCrypt.hashpw(plainPassword, BCrypt.gensalt(BCRYPT_STRENGTH));
    }
    
    public static boolean checkPassword(String plainPassword, String hashedPassword) {
        return BCrypt.checkpw(plainPassword, hashedPassword);
    }
}

系统未来可从以下几个方向进行优化升级。首先,引入Redis缓存层提升系统性能,将频繁访问的航班信息、热门航线数据缓存至内存中:

// 伪代码示例:缓存实现
public class FlightServiceWithCache {
    private Jedis redisClient;
    private FlightDAO flightDAO;
    
    public Flight getFlightById(int flightId) {
        String cacheKey = "flight:" + flightId;
        String cachedData = redisClient.get(cacheKey);
        
        if (cachedData != null) {
            return deserializeFlight(cachedData);
        } else {
            Flight flight = flightDAO.getFlightById(flightId);
            redisClient.setex(cacheKey, 300, serializeFlight(flight)); // 缓存5分钟
            return flight;
        }
    }
}

其次,实现微服务架构改造,将系统拆分为用户服务、航班服务、订单服务等独立模块,通过Spring Cloud实现服务治理。第三,集成第三方支付平台,支持支付宝、微信支付等多种支付方式,提升用户体验。第四,开发移动端应用,采用React Native技术实现跨平台移动客户端。第五,引入大数据分析平台,对用户行为、航线效益进行深度挖掘,为精准营销和航线规划提供数据支持。

在系统性能优化方面,可实施数据库读写分离策略,将查询请求分发至只读副本,减轻主数据库压力。同时,采用Elasticsearch实现智能搜索功能,支持同义词识别、拼音搜索等高级特性。

系统通过严谨的架构设计、完善的业务功能、可靠的数据管理,为航空票务行业提供了成熟的数字化解决方案。其模块化设计和清晰的代码结构为后续功能扩展和技术升级奠定了良好基础,具备持续演进的能力。

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

上下篇

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