基于JSP+Servlet的在线旅游预订服务平台 - 源码深度解析

JavaJavaScriptHTMLCSSMySQLJSP+Servlet
2026-03-212 浏览

文章摘要

基于JSP+Servlet的在线旅游预订服务平台,致力于解决传统线下旅游服务信息不透明、预订流程繁琐、用户选择有限的行业痛点。该平台通过整合旅游资源,为游客提供一个集信息查询、产品比较、在线预订与支付于一体的综合性服务窗口,其核心业务价值在于显著提升了旅游产品交易的效率与透明度,降低了用户的决策成本...

在传统旅游行业数字化转型的浪潮中,一个高效、透明的在线服务平台对于提升用户体验和行业效率至关重要。本文介绍的“智慧旅程”一站式预订平台,正是基于经典JSP+Servlet技术栈构建的解决方案,旨在通过技术手段解决信息不对称和流程繁琐等行业痛点。

系统采用经典的Model-View-Controller架构模式,确保各层职责分离。模型层由JavaBean组件构成,负责封装核心业务数据和数据库操作逻辑。视图层使用JSP技术结合HTML/CSS进行动态页面渲染,控制层通过自定义Servlet处理HTTP请求,协调模型与视图之间的交互。数据库采用MySQL,通过JDBC实现稳定的数据持久化操作。

数据库架构设计深度解析

系统的数据库设计体现了完整的业务逻辑闭环。其中几个核心表的设计颇具亮点:

用户表设计采用分层权限管理机制,通过role字段区分管理员和普通用户,确保系统安全:

CREATE TABLE users (
    id INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(50) UNIQUE NOT NULL,
    password VARCHAR(100) NOT NULL,
    email VARCHAR(100) UNIQUE NOT NULL,
    phone VARCHAR(20),
    role ENUM('admin','user') DEFAULT 'user',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    last_login TIMESTAMP NULL
);

旅游产品表设计支持灵活的产品管理,包含价格策略、库存控制和状态管理:

CREATE TABLE travel_products (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(200) NOT NULL,
    description TEXT,
    price DECIMAL(10,2) NOT NULL,
    discount_price DECIMAL(10,2),
    stock INT DEFAULT 0,
    category ENUM('hotel','attraction','tour','guide') NOT NULL,
    status ENUM('active','inactive') DEFAULT 'active',
    image_url VARCHAR(500),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

订单表设计实现完整的交易追踪,包含订单状态流转和财务信息记录:

CREATE TABLE orders (
    id INT PRIMARY KEY AUTO_INCREMENT,
    user_id INT NOT NULL,
    product_id INT NOT NULL,
    quantity INT DEFAULT 1,
    total_amount DECIMAL(10,2) NOT NULL,
    order_status ENUM('pending','confirmed','paid','completed','cancelled') DEFAULT 'pending',
    payment_method VARCHAR(50),
    payment_status ENUM('pending','success','failed') DEFAULT 'pending',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    FOREIGN KEY (user_id) REFERENCES users(id),
    FOREIGN KEY (product_id) REFERENCES travel_products(id)
);

核心功能实现技术剖析

1. 用户认证与权限管理

系统采用安全的密码加密和会话管理机制。用户登录Servlet处理认证逻辑:

@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    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.authenticate(username, password);
        
        if (user != null) {
            HttpSession session = request.getSession();
            session.setAttribute("currentUser", user);
            session.setMaxInactiveInterval(30 * 60); // 30分钟超时
            
            if ("admin".equals(user.getRole())) {
                response.sendRedirect("admin/dashboard.jsp");
            } else {
                response.sendRedirect("user/home.jsp");
            }
        } else {
            request.setAttribute("errorMessage", "用户名或密码错误");
            request.getRequestDispatcher("login.jsp").forward(request, response);
        }
    }
}

用户登录界面

2. 旅游产品动态展示与筛选

产品展示页面支持多条件筛选和分页显示,JSP页面通过EL表达式动态渲染数据:

<%@ page import="com.travel.model.TravelProduct" %>
<%@ page import="com.travel.dao.ProductDAO" %>
<%@ page import="java.util.List" %>

<%
    String category = request.getParameter("category");
    String keyword = request.getParameter("keyword");
    int page = Integer.parseInt(request.getParameter("page") != null ? 
                request.getParameter("page") : "1");
    
    ProductDAO productDAO = new ProductDAO();
    List<TravelProduct> products = productDAO.searchProducts(category, keyword, page, 12);
    int totalCount = productDAO.getProductCount(category, keyword);
%>

<div class="product-grid">
    <c:forEach var="product" items="${products}">
        <div class="product-card">
            <img src="${product.imageUrl}" alt="${product.name}">
            <h3>${product.name}</h3>
            <p class="price">
                <c:if test="${product.discountPrice > 0}">
                    <span class="original-price">¥${product.price}</span>
                    <span class="discount-price">¥${product.discountPrice}</span>
                </c:if>
                <c:if test="${product.discountPrice == 0}">
                    <span class="current-price">¥${product.price}</span>
                </c:if>
            </p>
            <a href="productDetail.jsp?id=${product.id}" class="btn-book">立即预订</a>
        </div>
    </c:forEach>
</div>

景点展示页面

3. 购物车与订单处理系统

购物车功能采用Session存储临时数据,订单处理包含完整的业务流程验证:

@WebServlet("/addToCart")
public class AddToCartServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        HttpSession session = request.getSession();
        User user = (User) session.getAttribute("currentUser");
        
        if (user == null) {
            response.sendRedirect("login.jsp");
            return;
        }
        
        int productId = Integer.parseInt(request.getParameter("productId"));
        int quantity = Integer.parseInt(request.getParameter("quantity"));
        
        ProductDAO productDAO = new ProductDAO();
        TravelProduct product = productDAO.getProductById(productId);
        
        if (product != null && product.getStock() >= quantity) {
            Map<Integer, CartItem> cart = (Map<Integer, CartItem>) session.getAttribute("cart");
            if (cart == null) {
                cart = new HashMap<>();
            }
            
            if (cart.containsKey(productId)) {
                CartItem item = cart.get(productId);
                item.setQuantity(item.getQuantity() + quantity);
            } else {
                cart.put(productId, new CartItem(product, quantity));
            }
            
            session.setAttribute("cart", cart);
            response.sendRedirect("cart.jsp");
        } else {
            request.setAttribute("errorMessage", "库存不足");
            request.getRequestDispatcher("productDetail.jsp?id=" + productId).forward(request, response);
        }
    }
}

订单管理界面

4. 后台管理系统功能

管理员后台提供完整的业务管理功能,包括产品管理、用户管理和订单处理:

@WebServlet("/admin/productManagement")
public class ProductManagementServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        // 权限验证
        HttpSession session = request.getSession();
        User user = (User) session.getAttribute("currentUser");
        
        if (user == null || !"admin".equals(user.getRole())) {
            response.sendError(HttpServletResponse.SC_FORBIDDEN);
            return;
        }
        
        ProductDAO productDAO = new ProductDAO();
        List<TravelProduct> products = productDAO.getAllProducts();
        request.setAttribute("products", products);
        request.getRequestDispatcher("/admin/productManagement.jsp").forward(request, response);
    }
    
    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        // 处理产品新增、编辑、删除操作
        String action = request.getParameter("action");
        ProductDAO productDAO = new ProductDAO();
        
        switch (action) {
            case "add":
                // 处理新增逻辑
                break;
            case "edit":
                // 处理编辑逻辑
                break;
            case "delete":
                int productId = Integer.parseInt(request.getParameter("productId"));
                productDAO.deleteProduct(productId);
                break;
        }
        
        response.sendRedirect("productManagement");
    }
}

旅游路线管理

核心业务实体模型设计

系统采用面向对象的设计思想,构建了完整的业务实体模型:

public class TravelProduct {
    private int id;
    private String name;
    private String description;
    private BigDecimal price;
    private BigDecimal discountPrice;
    private int stock;
    private String category;
    private String status;
    private String imageUrl;
    private Date createdAt;
    
    // 构造方法、getter和setter
    public TravelProduct() {}
    
    public TravelProduct(int id, String name, BigDecimal price) {
        this.id = id;
        this.name = name;
        this.price = price;
    }
    
    // 业务方法
    public boolean isAvailable() {
        return "active".equals(status) && stock > 0;
    }
    
    public BigDecimal getFinalPrice() {
        return discountPrice.compareTo(BigDecimal.ZERO) > 0 ? discountPrice : price;
    }
}

public class Order {
    private int id;
    private User user;
    private TravelProduct product;
    private int quantity;
    private BigDecimal totalAmount;
    private String orderStatus;
    private String paymentMethod;
    private String paymentStatus;
    private Date createdAt;
    private Date updatedAt;
    
    // 订单状态管理方法
    public boolean canBeCancelled() {
        return "pending".equals(orderStatus) || "confirmed".equals(orderStatus);
    }
    
    public void calculateTotal() {
        this.totalAmount = product.getFinalPrice().multiply(new BigDecimal(quantity));
    }
}

数据访问层优化实现

采用DAO模式实现数据持久化,确保数据库操作的安全性和效率:

public class ProductDAO {
    private Connection getConnection() throws SQLException {
        return DataSourceManager.getConnection();
    }
    
    public List<TravelProduct> searchProducts(String category, String keyword, int page, int pageSize) {
        List<TravelProduct> products = new ArrayList<>();
        String sql = "SELECT * FROM travel_products WHERE status = 'active'";
        List<Object> params = new ArrayList<>();
        
        if (category != null && !category.isEmpty()) {
            sql += " AND category = ?";
            params.add(category);
        }
        
        if (keyword != null && !keyword.isEmpty()) {
            sql += " AND (name LIKE ? OR description LIKE ?)";
            params.add("%" + keyword + "%");
            params.add("%" + keyword + "%");
        }
        
        sql += " ORDER BY created_at DESC LIMIT ?, ?";
        params.add((page - 1) * pageSize);
        params.add(pageSize);
        
        try (Connection conn = getConnection();
             PreparedStatement stmt = conn.prepareStatement(sql)) {
            
            for (int i = 0; i < params.size(); i++) {
                stmt.setObject(i + 1, params.get(i));
            }
            
            ResultSet rs = stmt.executeQuery();
            while (rs.next()) {
                products.add(extractProductFromResultSet(rs));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        
        return products;
    }
    
    private TravelProduct extractProductFromResultSet(ResultSet rs) throws SQLException {
        TravelProduct product = new TravelProduct();
        product.setId(rs.getInt("id"));
        product.setName(rs.getString("name"));
        product.setDescription(rs.getString("description"));
        product.setPrice(rs.getBigDecimal("price"));
        product.setDiscountPrice(rs.getBigDecimal("discount_price"));
        product.setStock(rs.getInt("stock"));
        product.setCategory(rs.getString("category"));
        product.setStatus(rs.getString("status"));
        product.setImageUrl(rs.getString("image_url"));
        product.setCreatedAt(rs.getTimestamp("created_at"));
        return product;
    }
}

酒店信息管理

系统性能与安全优化策略

系统在性能和安全方面实施了多项优化措施:

数据库连接池管理

public class DataSourceManager {
    private static DataSource dataSource;
    
    static {
        MysqlDataSource mysqlDS = new MysqlDataSource();
        mysqlDS.setURL("jdbc:mysql://localhost:3306/travel_booking");
        mysqlDS.setUser("username");
        mysqlDS.setPassword("password");
        mysqlDS.setCachePrepStmts(true);
        mysqlDS.setPrepStmtCacheSize(250);
        mysqlDS.setPrepStmtCacheSqlLimit(2048);
        dataSource = mysqlDS;
    }
    
    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }
}

输入验证与XSS防护

<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>

<c:set var="safeComment" value="${fn:escapeXml(comment.content)}" />
<div class="comment-content">${safeComment}</div>

<script>
// 客户端验证
function validateForm() {
    var username = document.getElementById('username').value;
    var password = document.getElementById('password').value;
    
    if (username.length < 3 || username.length > 50) {
        alert('用户名长度必须在3-50个字符之间');
        return false;
    }
    
    var passwordRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d]{8,}$/;
    if (!passwordRegex.test(password)) {
        alert('密码必须包含大小写字母和数字,且长度至少8位');
        return false;
    }
    
    return true;
}
</script>

技术架构扩展与优化方向

基于当前系统架构,未来可以从以下几个方向进行深度优化:

  1. 微服务架构迁移:将单体应用拆分为用户服务、产品服务、订单服务等独立微服务,提升系统可扩展性和维护性。采用Spring Cloud框架实现服务治理、配置中心和链路追踪。

  2. 缓存层引入:集成Redis作为分布式缓存,缓存热点数据和会话信息,显著提升系统响应速度。实现多级缓存架构,减少数据库访问压力。

  3. 全文搜索优化:集成Elasticsearch实现旅游产品的智能搜索和推荐功能,支持同义词扩展、拼音搜索和相关性排序等高级搜索特性。

  4. 支付系统增强:对接多家支付渠道(支付宝、微信支付、银联),实现支付路由和自动对账功能。引入分布式事务确保支付数据的一致性。

  5. 移动端适配:开发React Native或Flutter移动应用,提供原生的移动端体验。实现PWA渐进式Web应用,支持离线访问和推送通知功能。

  6. 大数据分析集成:构建用户行为分析平台,通过数据挖掘技术实现个性化推荐和精准营销。使用Apache Spark进行实时数据处理和机器学习模型训练。

  7. 容器化部署:采用Docker和Kubernetes实现应用的容器化部署和自动化运维,提高资源利用率和系统可靠性。

该系统作为传统J2EE技术的经典实践,展现了成熟技术栈在业务系统构建中的稳定性和可靠性。通过持续的技术演进和架构优化,能够为旅游行业数字化转型提供坚实的技术支撑。

本文关键词
JSPServlet在线旅游预订源码解析MVC架构

上下篇

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