基于JSP+Servlet的在线空调销售平台 - 源码深度解析

JavaJavaScriptHTMLCSSMySQLJSP+Servlet
2026-03-284 浏览

文章摘要

本系统是一款基于JSP与Servlet技术构建的在线空调销售平台,旨在为消费者提供一站式的家电选购服务。其核心业务价值在于解决了传统线下家电购物流程繁琐、信息不透明及地域限制等痛点。通过将实体店铺的空调销售业务迁移至线上,平台实现了产品展示、搜索筛选、在线下单、支付集成及订单跟踪的全流程数字化,显著...

在传统家电零售行业向数字化转型的浪潮中,一个高效、直观的线上销售渠道已成为企业提升竞争力的关键。本系统正是基于这一背景,采用经典的JSP+Servlet技术栈,构建了一个功能完备的在线空调销售平台,我们可称其为“清风易购”。该系统不仅实现了商品展示、用户管理、购物车、订单处理等电商核心功能,还通过严谨的MVC架构设计,确保了系统的可维护性和可扩展性。

技术架构与设计模式

系统严格遵循模型-视图-控制器(MVC)设计模式,将业务逻辑、数据展示与用户请求处理清晰分离。Servlet作为系统的“大脑”——控制器(Controller),负责接收所有前端HTTP请求。它解析请求参数,调用相应的业务逻辑组件(Model,通常由JavaBean实现)进行数据处理,如用户身份验证、库存查询或订单生成。业务逻辑组件通过JDBC与MySQL数据库进行交互,完成数据的持久化操作。最终,处理结果被封装到请求对象或会话对象中,转发给JSP页面。JSP作为视图(View),利用JSTL和EL表达式动态渲染HTML,将最终的用户界面呈现给浏览器。这种架构有效降低了代码耦合度,提升了开发效率。

数据持久层采用标准的JDBC API直接连接MySQL数据库。通过数据库连接池(如DBCP或C3P0)管理连接资源,避免了频繁创建和关闭连接带来的性能开销。事务管理在Servlet或JavaBean层面进行控制,确保如“下单扣库存”这类操作的原子性。

核心数据库表结构设计

一个稳健的电商系统离不开精心设计的数据库。本系统包含20张数据表,支撑着从用户、商品到订单、评论等所有业务环节。以下是几个核心表的设计分析:

1. 用户表 (mall_member) 此表是系统用户体系的基石,设计上充分考虑了扩展性和安全性。

CREATE TABLE `mall_member` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '会员ID',
  `username` varchar(50) NOT NULL COMMENT '用户名',
  `password` varchar(32) NOT NULL COMMENT '密码,MD5加密',
  `mobile` varchar(11) DEFAULT NULL COMMENT '手机号',
  `email` varchar(50) DEFAULT NULL COMMENT '邮箱',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '注册时间',
  `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  `status` tinyint(1) DEFAULT '1' COMMENT '状态(0:禁用,1:启用)',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_username` (`username`),
  KEY `idx_mobile` (`mobile`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='会员表';

设计亮点分析:

  • 安全性: password字段使用MD5进行单向加密存储,即使数据库泄露,也无法直接获取用户明文密码。
  • 唯一性约束: 通过UNIQUE KEY确保用户名的唯一性,防止重复注册。
  • 索引优化:username(主键查询、登录)和mobile(手机号登录、找回密码)字段建立了索引,显著提升了高频查询的效率。
  • 审计字段: create_timeupdate_time字段自动记录数据的生命周期,便于问题追踪和数据分析。

2. 商品表 (mall_air_conditioner) 该表详细定义了空调商品的各项属性,是商品管理模块的核心。

CREATE TABLE `mall_air_conditioner` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '空调ID',
  `category_id` int(11) NOT NULL COMMENT '分类ID',
  `title` varchar(100) NOT NULL COMMENT '商品标题',
  `sub_title` varchar(200) DEFAULT NULL COMMENT '副标题',
  `main_image` varchar(500) DEFAULT NULL COMMENT '产品主图',
  `sub_images` text COMMENT '子图JSON数组',
  `spec` text COMMENT '规格参数JSON',
  `detail` text COMMENT '商品详情HTML',
  `price` decimal(10,2) NOT NULL COMMENT '价格',
  `stock` int(11) NOT NULL DEFAULT '0' COMMENT '库存',
  `status` tinyint(1) DEFAULT '1' COMMENT '商品状态(0:下架,1:上架)',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP,
  `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  KEY `fk_category_id` (`category_id`),
  KEY `idx_status` (`status`),
  CONSTRAINT `fk_category_id` FOREIGN KEY (`category_id`) REFERENCES `mall_category` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='空调商品表';

设计亮点分析:

  • 结构化与灵活性并存: 基础信息如titleprice使用固定字段。而多变的信息,如多张商品图sub_images和复杂的spec(规格参数,如制冷量、能效等级),则采用JSON格式存储在text字段中。这种设计既保证了核心查询性能,又提供了极大的灵活性,无需因增加新属性而频繁修改表结构。
  • 外键约束: 通过FOREIGN KEY关联商品分类表(mall_category),确保了数据的一致性和完整性。
  • 业务状态索引:status字段建立索引,使得前台只查询上架商品、后台按状态筛选等操作非常高效。

3. 订单主表 (mall_order) 订单表是交易流程的最终载体,其设计复杂且关键。

CREATE TABLE `mall_order` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '订单ID',
  `order_no` bigint(20) NOT NULL COMMENT '订单号(唯一)',
  `member_id` int(11) NOT NULL COMMENT '用户ID',
  `shipping_id` int(11) NOT NULL COMMENT '收货地址ID',
  `payment` decimal(10,2) DEFAULT NULL COMMENT '实际付款金额',
  `payment_type` tinyint(1) DEFAULT NULL COMMENT '支付类型(1:在线支付)',
  `postage` int(11) DEFAULT NULL COMMENT '运费',
  `status` tinyint(1) DEFAULT '0' COMMENT '订单状态(0:已取消,10:未付款,20:已付款,40:已发货,50:交易成功,60:交易关闭)',
  `payment_time` datetime DEFAULT NULL COMMENT '支付时间',
  `send_time` datetime DEFAULT NULL COMMENT '发货时间',
  `end_time` datetime DEFAULT NULL COMMENT '交易完成时间',
  `close_time` datetime DEFAULT NULL COMMENT '交易关闭时间',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP,
  `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_order_no` (`order_no`),
  KEY `idx_member_id` (`member_id`),
  KEY `idx_create_time` (`create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='订单表';

设计亮点分析:

  • 订单号独立设计: 主键id是自增ID,用于内部关联。而order_no是一个独立的、唯一的业务订单号,通常由时间戳、随机数等生成,避免暴露业务量和自增规律,更安全且易于同外部系统(如支付网关)对接。
  • 状态机设计: status字段使用数字代码定义清晰的订单状态流(如10->20->40->50),逻辑清晰,便于程序进行状态判断和流转控制。
  • 多时间戳记录: 记录了订单生命周期中各个关键节点的时间(创建、支付、发货、完成等),为后续的售后处理、数据分析和报表生成提供了完整的数据支持。

核心功能实现深度解析

1. 用户登录与会话管理

用户登录是系统的入口。Servlet控制器接收登录请求,与数据库中的加密密码进行比对。

// UserLoginServlet.java
public class UserLoginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        // MD5加密输入密码
        String md5Password = DigestUtils.md5DigestAsHex(password.getBytes());

        MemberService memberService = new MemberService();
        Member member = memberService.login(username, md5Password);

        if (member != null && member.getStatus() == 1) {
            // 登录成功,将用户信息存入Session
            HttpSession session = request.getSession();
            session.setAttribute("currentUser", member);
            response.getWriter().write("success");
        } else {
            // 登录失败
            response.getWriter().write("fail");
        }
    }
}

代码解析: 控制器获取用户名和密码后,使用Spring框架的DigestUtils(或类似工具)对密码进行MD5加密。然后调用MemberServicelogin方法进行验证。成功后,将完整的Member对象存入HttpSession中,键为"currentUser"。此后,在整个会话期间,任何页面或Servlet都可以通过session.getAttribute("currentUser")来获取当前登录用户的信息,无需重复查询数据库,实现了状态的保持。

用户登录界面

2. 购物车功能实现

购物车是电商的核心功能,本系统采用基于Session的实现方式,在用户登录前即可添加商品,用户体验连贯。

// CartServlet.java - 添加商品到购物车
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    Integer productId = Integer.parseInt(request.getParameter("productId"));
    Integer quantity = Integer.parseInt(request.getParameter("quantity"));
    
    // 从Session中获取购物车对象,如果为空则新建一个
    HttpSession session = request.getSession();
    Map<Integer, CartItem> cart = (Map<Integer, CartItem>) session.getAttribute("cart");
    if (cart == null) {
        cart = new HashMap<>();
        session.setAttribute("cart", cart);
    }
    
    // 判断商品是否已在购物车,是则增加数量,否则新增条目
    AirConditionerService productService = new AirConditionerService();
    AirConditioner product = productService.getProductById(productId);
    
    if (cart.containsKey(productId)) {
        CartItem item = cart.get(productId);
        item.setQuantity(item.getQuantity() + quantity);
    } else {
        CartItem newItem = new CartItem(product, quantity);
        cart.put(productId, newItem);
    }
    
    // 返回更新后的购物车信息(如总数量)
    int totalCount = cart.values().stream().mapToInt(CartItem::getQuantity).sum();
    response.getWriter().write("add_success," + totalCount);
}

代码解析: 此段代码展示了购物车的添加逻辑。购物车数据结构的核心是一个Map<Integer, CartItem>,以商品ID为键,CartItem(自定义的购物车项类,包含商品对象和数量)为值。这个Map被存储在用户的Session中。添加商品时,先从Session获取购物车Map,然后检查商品是否存在,进行数量叠加或新增项。这种方式将状态保存在服务器内存中,响应速度快,且与数据库解耦。

查看购物车

3. 订单生成与库存校验

下单是高并发场景下最需谨慎处理的功能,涉及事务和库存校验。

// OrderServlet.java - 生成订单
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    Member member = (Member) request.getSession().getAttribute("currentUser");
    Integer shippingId = Integer.parseInt(request.getParameter("shippingId"));
    
    // 1. 从Session中获取购物车
    Map<Integer, CartItem> cart = (Map<Integer, CartItem>) request.getSession().getAttribute("cart");
    if (cart == null || cart.isEmpty()) {
        response.getWriter().write("cart_empty");
        return;
    }
    
    // 2. 校验库存
    OrderService orderService = new OrderService();
    String stockCheckResult = orderService.checkStock(cart);
    if (!"success".equals(stockCheckResult)) {
        response.getWriter().write("stock_insufficient:" + stockCheckResult); // 返回具体缺货商品名
        return;
    }
    
    // 3. 创建订单(包含事务)
    try {
        String orderNo = orderService.createOrder(member.getId(), shippingId, cart);
        // 4. 清空购物车
        request.getSession().removeAttribute("cart");
        response.getWriter().write("order_success:" + orderNo);
    } catch (Exception e) {
        e.printStackTrace();
        response.getWriter().write("order_fail");
    }
}

代码解析: 订单生成是一个多步骤的原子操作。首先,从Session中获取已校验过的购物车数据。然后,关键的一步是调用orderService.checkStock进行库存校验,遍历购物车中的每一项,查询数据库实时库存,确保所有商品数量充足。如果库存不足,立即返回错误信息,避免超卖。校验通过后,在orderService.createOrder方法中,通常会开启数据库事务,执行以下操作:生成订单主记录、生成订单明细记录、扣减商品库存。这些操作必须在同一个事务中,要么全部成功,要么全部失败,保证数据一致性。成功后,清空Session中的购物车。

提交订单页面

4. 后台商品管理

后台管理提供了对商品的全面CRUD操作,以下是商品上架/下架的Servlet控制逻辑。

// AdminProductServlet.java - 商品状态管理
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String action = request.getParameter("action");
    Integer productId = Integer.parseInt(request.getParameter("id"));
    AirConditionerService productService = new AirConditionerService();
    boolean result = false;
    
    switch (action) {
        case "list": // 上架
            result = productService.updateProductStatus(productId, 1);
            break;
        case "unlist": // 下架
            result = productService.updateProductStatus(productId, 0);
            break;
        case "delete": // 删除(逻辑删除,设置标志位)
            result = productService.logicalDeleteProduct(productId);
            break;
        default:
            break;
    }
    
    if (result) {
        response.getWriter().write("success");
    } else {
        response.getWriter().write("fail");
    }
}

代码解析: 后台操作通过一个Servlet并传递action参数来区分不同的操作类型(上架、下架、删除)。这种设计减少了Servlet的数量,使代码更集中。updateProductStatus方法直接执行SQL更新商品的status字段。对于删除操作,最佳实践是进行逻辑删除(即软删除),通过更新一个如is_deleted的标志位为1,而不是物理删除记录。这样做可以保留历史数据,便于审计和恢复,避免了误操作带来的不可逆损失。

后台商品管理

实体模型与业务逻辑

系统的核心实体(Entity)通过JavaBean进行建模,例如MemberAirConditionerOrderOrderItem等。这些类通常属性与数据库表字段一一对应,并包含相应的getter和setter方法。业务逻辑集中在Service层(如MemberServiceOrderService),负责处理复杂的业务规则,如计算订单总价、优惠券应用、库存检查等。DAO(Data Access Object)层则封装了所有与数据库交互的细节,Service通过调用DAO来完成数据持久化。这种分层架构使得代码职责清晰,易于单元测试和维护。

功能展望与系统优化方向

尽管“清风易购”平台已经实现了电商核心功能,但在实际生产环境中,仍有多个方向可以优化和扩展:

  1. 引入缓存机制提升性能: 对于首页商品列表、分类信息、热点商品详情等读多写少的数据,可以引入Redis等缓存中间件。将数据缓存到内存中,可以极大减少数据库的访问压力,提高系统响应速度。例如,商品信息变更时,同步更新或失效缓存即可。

  2. 集成第三方支付与物流API: 当前系统支付和物流可能为模拟状态。未来可以集成支付宝、微信支付等官方SDK,实现真实的支付流程。同时,对接顺丰、中通等物流公司的API,实现自动获取物流单号和实时物流轨迹跟踪,提升用户体验。

  3. 实现全文搜索功能: 目前商品搜索可能基于数据库的LIKE语句,在数据量大时性能低下且功能单一。可以集成Elasticsearch或Solr等全文搜索引擎,实现商品标题、详情、参数的智能分词、高亮显示和复杂条件组合搜索,并支持按相关性、价格、销量等多维度排序。

  4. 服务化改造与分布式部署: 随着业务增长,单一的WAR包部署可能成为瓶颈。可以考虑进行服务化拆分,例如将用户服务、商品服务、订单服务拆分为独立的微服务。使用Spring Cloud、Dubbo等框架进行治理,并部署到多台服务器上,实现负载均衡和高可用。

  5. 增强后台数据分析与报表功能: 在现有基础上,可以构建更强大的数据看板。通过定时任务统计销售数据、用户行为数据,并利用ECharts等图表库可视化展示,如热销商品排行、用户增长趋势、销售额月度报表等,为运营决策提供数据支持。

平台数据统计

该系统作为一个采用经典J2EE技术栈的实现,其架构清晰,代码规范,很好地诠释了MVC模式在Web开发中的应用。它不仅是一个可用的电商平台,更是一个优秀的学习范例,展示了如何通过JSP和Servlet构建一个结构合理、功能完备的中小型Web应用。上述优化方向则为该系统从“

本文关键词
JSPServlet在线空调销售平台源码解析MVC架构

上下篇

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