基于JSP+Servlet的宁夏葡萄酒在线销售平台 - 源码深度解析

JavaJavaScriptHTMLCSSMySQLJSP+Servlet
2026-03-173 浏览

文章摘要

本项目是一款基于JSP与Servlet技术构建的宁夏葡萄酒在线销售平台,专注于为葡萄酒供应商与消费者提供便捷高效的B2C电商服务。平台核心解决了传统酒类销售渠道单一、信息不透明、跨地域购买不便等痛点,通过线上集中展示宁夏产区优质葡萄酒,帮助酒庄降低销售成本、拓展市场,同时让消费者能够直观对比产品详情...

在传统酒类销售领域,渠道单一、信息不对称、跨地域购买困难等问题长期制约着宁夏葡萄酒产业的发展。随着电子商务技术的成熟,构建一个专业化的在线销售平台成为打通产销链路、提升市场效率的关键路径。本系统采用经典的JSP+Servlet技术栈,打造了一个功能完备的B2C葡萄酒电商平台,为宁夏葡萄酒产区提供了数字化的销售解决方案。

系统采用分层架构设计,表现层使用JSP动态页面技术,通过JSTL标签库和EL表达式实现数据渲染,避免了在页面中嵌入Java代码,保证了视图层的纯净性。控制层由Servlet实现,负责请求分发、参数验证和业务逻辑调用。业务逻辑层封装了核心的电商功能,数据访问层采用DAO模式,通过JDBC与MySQL数据库进行交互。这种MVC架构确保了代码的可维护性和扩展性。

平台首页

平台首页采用响应式设计,展示了葡萄酒商品分类、热门推荐和促销信息。顶部导航栏提供了完整的用户交互入口,包括商品搜索、购物车、用户登录等功能模块。轮播图区域支持管理员动态配置,可以灵活展示最新的营销活动。

数据库架构设计

系统使用MySQL数据库,共设计了20张数据表,涵盖了用户管理、商品管理、订单处理等核心业务模块。数据库设计遵循第三范式,确保了数据的一致性和完整性。

用户表设计

CREATE TABLE users (
    user_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),
    real_name VARCHAR(50),
    gender ENUM('M','F','U') DEFAULT 'U',
    birth_date DATE,
    avatar_url VARCHAR(200),
    membership_level INT DEFAULT 1,
    registration_date DATETIME DEFAULT CURRENT_TIMESTAMP,
    last_login_date DATETIME,
    status ENUM('ACTIVE','INACTIVE','SUSPENDED') DEFAULT 'ACTIVE',
    shipping_address TEXT
);

用户表采用纵向扩展设计,包含了完整的用户基本信息、会员等级管理和状态控制。password字段使用加密存储,确保用户信息安全。membership_level字段支持会员等级体系,为后续的会员权益差异化提供了基础。shipping_address字段采用TEXT类型,支持存储复杂的收货地址信息。

商品表设计

CREATE TABLE products (
    product_id INT PRIMARY KEY AUTO_INCREMENT,
    product_name VARCHAR(200) NOT NULL,
    brand_id INT NOT NULL,
    category_id INT NOT NULL,
    vintage YEAR,
    alcohol_content DECIMAL(3,1),
    volume_ml INT,
    description TEXT,
    price DECIMAL(10,2) NOT NULL,
    original_price DECIMAL(10,2),
    stock_quantity INT DEFAULT 0,
    sales_volume INT DEFAULT 0,
    image_url VARCHAR(200),
    thumbnail_url VARCHAR(200),
    seo_keywords VARCHAR(300),
    seo_description VARCHAR(500),
    is_featured BOOLEAN DEFAULT FALSE,
    is_active BOOLEAN DEFAULT TRUE,
    created_date DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_date DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    FOREIGN KEY (brand_id) REFERENCES brands(brand_id),
    FOREIGN KEY (category_id) REFERENCES categories(category_id)
);

商品表设计充分考虑了葡萄酒产品的特殊性,包含年份(vintage)、酒精度(alcohol_content)、容量(volume_ml)等专业字段。价格体系支持原价和现价设置,便于促销活动管理。SEO相关字段为搜索引擎优化提供了支持,is_featured字段用于标识推荐商品。

订单表设计

CREATE TABLE orders (
    order_id VARCHAR(32) PRIMARY KEY,
    user_id INT NOT NULL,
    order_status ENUM('PENDING','PAID','SHIPPED','DELIVERED','CANCELLED','REFUNDED') DEFAULT 'PENDING',
    total_amount DECIMAL(10,2) NOT NULL,
    shipping_fee DECIMAL(8,2) DEFAULT 0,
    discount_amount DECIMAL(8,2) DEFAULT 0,
    final_amount DECIMAL(10,2) NOT NULL,
    shipping_address TEXT NOT NULL,
    recipient_name VARCHAR(50) NOT NULL,
    recipient_phone VARCHAR(20) NOT NULL,
    payment_method ENUM('ALIPAY','WECHAT','BANK_TRANSFER') DEFAULT 'ALIPAY',
    payment_status ENUM('UNPAID','PAID','REFUNDED') DEFAULT 'UNPAID',
    payment_time DATETIME,
    order_notes TEXT,
    created_time DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    FOREIGN KEY (user_id) REFERENCES users(user_id)
);

订单表采用业务主键设计,order_id使用32位字符串,便于分布式系统扩展。订单状态和支付状态分离管理,支持复杂的业务流程。金额字段细分设计,支持运费、折扣等复杂计算场景。

核心功能实现

用户认证与权限管理

系统采用基于Session的用户认证机制,支持用户和管理员双角色登录。认证流程通过Filter实现统一的访问控制。

public class AuthenticationFilter implements Filter {
    private static final List<String> EXCLUDE_URLS = Arrays.asList(
        "/login", "/register", "/static/", "/api/public/"
    );
    
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, 
                       FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        String path = httpRequest.getRequestURI();
        
        // 检查是否为排除路径
        if (isExcludedPath(path)) {
            chain.doFilter(request, response);
            return;
        }
        
        HttpSession session = httpRequest.getSession(false);
        if (session == null || session.getAttribute("currentUser") == null) {
            httpResponse.sendRedirect(httpRequest.getContextPath() + "/login");
            return;
        }
        
        // 权限验证
        User user = (User) session.getAttribute("currentUser");
        if (path.startsWith("/admin/") && !user.isAdmin()) {
            httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN);
            return;
        }
        
        chain.doFilter(request, response);
    }
    
    private boolean isExcludedPath(String path) {
        return EXCLUDE_URLS.stream().anyMatch(path::startsWith);
    }
}

用户登录

登录界面采用简洁的设计风格,支持用户名/邮箱登录。后端采用BCrypt密码加密,确保用户凭证安全。

public class UserService {
    private UserDAO userDAO = new UserDAO();
    private BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
    
    public User authenticate(String username, String password) {
        User user = userDAO.findByUsernameOrEmail(username);
        if (user != null && passwordEncoder.matches(password, user.getPassword())) {
            // 更新最后登录时间
            userDAO.updateLastLogin(user.getUserId());
            return user;
        }
        return null;
    }
    
    public boolean register(User user) {
        if (userDAO.existsByUsername(user.getUsername())) {
            throw new BusinessException("用户名已存在");
        }
        if (userDAO.existsByEmail(user.getEmail())) {
            throw new BusinessException("邮箱已被注册");
        }
        
        // 加密密码
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        return userDAO.save(user) > 0;
    }
}

商品展示与搜索功能

商品展示模块支持多维度分类浏览和全文搜索,采用分页技术优化大数据量下的性能表现。

public class ProductServlet extends HttpServlet {
    private ProductService productService = new ProductService();
    
    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        String action = request.getParameter("action");
        
        switch (action) {
            case "list":
                showProductList(request, response);
                break;
            case "detail":
                showProductDetail(request, response);
                break;
            case "search":
                searchProducts(request, response);
                break;
            default:
                showHomePage(request, response);
        }
    }
    
    private void showProductList(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        int categoryId = Integer.parseInt(request.getParameter("categoryId"));
        int page = Integer.parseInt(request.getParameter("page"));
        int pageSize = 12;
        
        ProductQuery query = new ProductQuery();
        query.setCategoryId(categoryId);
        query.setPage(page);
        query.setPageSize(pageSize);
        
        PageResult<Product> result = productService.getProductsByCategory(query);
        request.setAttribute("products", result.getData());
        request.setAttribute("totalPages", result.getTotalPages());
        
        request.getRequestDispatcher("/WEB-INF/views/product/list.jsp").forward(request, response);
    }
}

商品详情

商品详情页展示了完整的商品信息,包括多角度图片、详细参数、用户评价等。采用AJAX技术实现购物车添加操作,提升用户体验。

<%@ page contentType="text/html;charset=UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<div class="product-detail">
    <div class="product-images">
        <img src="${product.imageUrl}" alt="${product.productName}">
    </div>
    <div class="product-info">
        <h1>${product.productName}</h1>
        <div class="price-section">
            <span class="current-price">¥${product.price}</span>
            <c:if test="${product.originalPrice > product.price}">
                <span class="original-price">¥${product.originalPrice}</span>
            </c:if>
        </div>
        <div class="product-specs">
            <div class="spec-item">
                <label>年份:</label>
                <span>${product.vintage}</span>
            </div>
            <div class="spec-item">
                <label>酒精度:</label>
                <span>${product.alcoholContent}%vol</span>
            </div>
        </div>
        <div class="add-to-cart">
            <input type="number" id="quantity" value="1" min="1" max="${product.stockQuantity}">
            <button onclick="addToCart(${product.productId})">加入购物车</button>
        </div>
    </div>
</div>

<script>
function addToCart(productId) {
    const quantity = document.getElementById('quantity').value;
    fetch('/cart/add', {
        method: 'POST',
        headers: {'Content-Type': 'application/json'},
        body: JSON.stringify({productId: productId, quantity: quantity})
    }).then(response => response.json())
      .then(data => {
          if (data.success) {
              updateCartCount(data.cartCount);
              showMessage('添加成功');
          } else {
              showMessage('添加失败: ' + data.message);
          }
      });
}
</script>

购物车与订单管理

购物车模块采用Session存储临时数据,支持商品添加、数量修改、批量删除等操作。订单生成过程包含完整的库存验证和事务管理。

public class CartService {
    public void addItem(HttpSession session, int productId, int quantity) {
        Product product = productDAO.findById(productId);
        if (product == null || !product.isActive()) {
            throw new BusinessException("商品不存在或已下架");
        }
        if (product.getStockQuantity() < quantity) {
            throw new BusinessException("库存不足");
        }
        
        Map<Integer, CartItem> cart = getCart(session);
        CartItem item = cart.get(productId);
        if (item != null) {
            item.setQuantity(item.getQuantity() + quantity);
        } else {
            item = new CartItem(product, quantity);
            cart.put(productId, item);
        }
    }
    
    public Order createOrder(HttpSession session, OrderRequest orderRequest) {
        Map<Integer, CartItem> cart = getCart(session);
        if (cart.isEmpty()) {
            throw new BusinessException("购物车为空");
        }
        
        Connection conn = null;
        try {
            conn = DatabaseUtil.getConnection();
            conn.setAutoCommit(false);
            
            // 验证库存并锁定
            for (CartItem item : cart.values()) {
                int affected = productDAO.lockStock(conn, item.getProduct().getProductId(), 
                                                  item.getQuantity());
                if (affected == 0) {
                    throw new BusinessException("商品库存不足: " + item.getProduct().getProductName());
                }
            }
            
            // 创建订单
            Order order = buildOrder(orderRequest, cart);
            orderDAO.save(conn, order);
            
            // 创建订单项
            for (CartItem item : cart.values()) {
                OrderItem orderItem = new OrderItem(order.getOrderId(), item);
                orderItemDAO.save(conn, orderItem);
            }
            
            conn.commit();
            clearCart(session);
            return order;
            
        } catch (SQLException e) {
            if (conn != null) {
                try { conn.rollback(); } catch (SQLException ex) {}
            }
            throw new RuntimeException("创建订单失败", e);
        } finally {
            DatabaseUtil.closeConnection(conn);
        }
    }
}

提交订单

订单提交页面整合了收货地址选择、支付方式选择、优惠券使用等完整流程。采用事务确保数据一致性,防止超卖现象。

后台管理系统

后台管理模块采用RBAC权限模型,支持商品管理、订单处理、用户管理、内容管理等全方位功能。

public class AdminProductServlet extends HttpServlet {
    private ProductService productService = new ProductService();
    
    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        String action = request.getParameter("action");
        
        try {
            switch (action) {
                case "add":
                    addProduct(request, response);
                    break;
                case "update":
                    updateProduct(request, response);
                    break;
                case "delete":
                    deleteProduct(request, response);
                    break;
                case "batchUpdate":
                    batchUpdateProducts(request, response);
                    break;
            }
        } catch (BusinessException e) {
            sendErrorResponse(response, e.getMessage());
        }
    }
    
    private void addProduct(HttpServletRequest request, HttpServletResponse response) 
            throws IOException {
        Product product = parseProductFromRequest(request);
        productService.addProduct(product);
        sendSuccessResponse(response, "添加成功");
    }
}

商品管理

后台商品管理界面支持批量操作、Excel导入导出、富文本编辑等高级功能。采用AJAX实现无刷新操作,提升管理效率。

实体模型与业务逻辑

系统采用面向对象的设计思想,构建了完整的实体模型体系。核心实体包括User、Product、Order、Category等,通过Service层封装复杂的业务逻辑。

订单状态机设计

订单生命周期管理采用状态模式,确保状态流转的合法性。

public class Order {
    private String orderId;
    private OrderStatus status;
    private PaymentStatus paymentStatus;
    
    public void pay() {
        if (status != OrderStatus.PENDING) {
            throw new IllegalStateException("只有待支付订单可以支付");
        }
        if (paymentStatus != PaymentStatus.UNPAID) {
            throw new IllegalStateException("订单已支付");
        }
        
        this.paymentStatus = PaymentStatus.PAID;
        this.status = OrderStatus.PAID;
        this.paymentTime = new Date();
    }
    
    public void ship() {
        if (status != OrderStatus.PAID) {
            throw new IllegalStateException("只有已支付订单可以发货");
        }
        this.status = OrderStatus.SHIPPED;
        this.shippingTime = new Date();
    }
}

价格计算策略

支持多种促销策略的价格计算引擎,为营销活动提供技术支撑。

public interface PricingStrategy {
    BigDecimal calculatePrice(Product product, int quantity);
}

public class DefaultPricingStrategy implements PricingStrategy {
    public BigDecimal calculatePrice(Product product, int quantity) {
        return product.getPrice().multiply(BigDecimal.valueOf(quantity));
    }
}

public class DiscountPricingStrategy implements PricingStrategy {
    private BigDecimal discountRate;
    
    public DiscountPricingStrategy(BigDecimal discountRate) {
        this.discountRate = discountRate;
    }
    
    public BigDecimal calculatePrice(Product product, int quantity) {
        BigDecimal original = product.getPrice().multiply(BigDecimal.valueOf(quantity));
        return original.multiply(discountRate);
    }
}

性能优化与安全考虑

系统在性能和安全方面进行了多重优化。数据库连接池采用HikariCP,有效管理连接资源。SQL查询通过索引优化,提升查询效率。安全方面采用参数化查询防止SQL注入,XSS过滤防止跨站脚本攻击。

public class SecurityFilter implements Filter {
    public void doFilter(ServletRequest request, ServletResponse response,
                        FilterChain chain) throws IOException, ServletException {
        
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        
        // XSS防护
        XSSRequestWrapper wrappedRequest = new XSSRequestWrapper(httpRequest);
        
        // CSRF防护
        if ("POST".equalsIgnoreCase(httpRequest.getMethod())) {
            String csrfToken = wrappedRequest.getParameter("csrfToken");
            HttpSession session = httpRequest.getSession(false);
            String sessionToken = session != null ? 
                (String) session.getAttribute("csrfToken") : null;
                
            if (sessionToken == null || !sessionToken.equals(csrfToken)) {
                httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN, "无效的CSRF令牌");
                return;
            }
        }
        
        chain.doFilter(wrappedRequest, response);
    }
}

技术架构演进展望

基于当前技术实现,系统在未来可以从以下几个方面进行架构升级和功能扩展:

  1. **微服务架构
本文关键词
JSPServlet宁夏葡萄酒在线销售平台源码解析

上下篇

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