基于JSP+Servlet的零食甜品在线销售系统 - 源码深度解析

JavaJavaScriptHTMLCSSMySQLJSP+Servlet
2026-02-114 浏览

文章摘要

本项目是一款基于JSP+Servlet技术栈构建的零食甜品在线销售系统,旨在为中小型食品零售商提供一个功能完整、易于维护的线上业务平台。系统核心解决了传统线下门店销售渠道单一、商品信息更新滞后以及订单处理效率低下的痛点,通过将商品展示与交易流程数字化,帮助商家快速建立线上门店,实现对商品库存、销售数...

在传统零售行业数字化转型的浪潮中,食品零售领域面临着商品信息更新滞后、订单处理效率低下等痛点。针对这一市场需求,我们设计并实现了一套专业的甜品零食电商平台,采用经典的J2EE架构,为中小型食品零售商提供完整的线上业务解决方案。

系统架构与技术栈

该平台基于Model 2设计模式构建,前端使用JSP进行动态页面渲染,结合HTML、CSS和JavaScript实现丰富的用户交互体验。后端核心采用Servlet作为控制器,负责业务逻辑处理和请求路由。数据持久层使用纯JDBC技术,通过DAO模式封装数据库操作,确保代码结构的清晰性和可维护性。

技术栈配置如下:

  • 服务器:Apache Tomcat 9.0
  • 数据库:MySQL 8.0
  • 前端技术:JSP 2.3、HTML5、CSS3、JavaScript
  • 后端技术:Servlet 4.0、JDBC
  • 开发环境:Java SE 11
<!-- web.xml配置示例 -->
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         version="3.1">
    <servlet>
        <servlet-name>GoodsServlet</servlet-name>
        <servlet-class>com.snackshop.servlet.GoodsServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>GoodsServlet</servlet-name>
        <url-pattern>/goods/*</url-pattern>
    </servlet-mapping>
</web-app>

数据库设计亮点分析

商品表设计优化

商品表(goods)的设计充分考虑了电商平台的业务特性:

CREATE TABLE `goods` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '商品ID',
  `name` varchar(45) DEFAULT NULL COMMENT '商品名称',
  `cover` varchar(45) DEFAULT NULL COMMENT '商品封面图',
  `image1` varchar(45) DEFAULT NULL COMMENT '商品图片1',
  `image2` varchar(45) DEFAULT NULL COMMENT '商品图片2',
  `price` float DEFAULT NULL COMMENT '商品价格',
  `intro` varchar(300) DEFAULT NULL COMMENT '商品介绍',
  `stock` int(11) DEFAULT NULL COMMENT '商品库存',
  `type_id` int(11) DEFAULT NULL COMMENT '商品类型ID',
  PRIMARY KEY (`id`),
  KEY `fk_type_id_idx` (`type_id`),
  CONSTRAINT `fk_type_id` FOREIGN KEY (`type_id`) REFERENCES `type` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=188 DEFAULT CHARSET=utf8 COMMENT='商品表'

设计亮点分析:

  1. 多图片存储设计:采用cover、image1、image2三个字段分别存储商品封面图和详情图片,支持多图展示需求
  2. 文本长度优化:商品介绍intro字段设置为300字符,平衡了存储空间与内容展示需求
  3. 索引策略:对type_id建立外键索引,优化按分类查询的性能
  4. 库存监控:stock字段实时跟踪商品库存,为库存预警提供数据基础

订单项表关系设计

订单项表(orderitem)的设计体现了电商系统核心的订单管理逻辑:

CREATE TABLE `orderitem` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '订单项ID',
  `price` float DEFAULT NULL COMMENT '商品单价',
  `amount` int(11) DEFAULT NULL COMMENT '商品数量',
  `goods_id` int(11) DEFAULT NULL COMMENT '商品ID',
  `order_id` int(11) DEFAULT NULL COMMENT '订单ID',
  PRIMARY KEY (`id`),
  KEY `fk_order_id_idx` (`order_id`),
  KEY `fk_orderitem_goods_id_idx` (`goods_id`),
  CONSTRAINT `fk_order_id` FOREIGN KEY (`order_id`) REFERENCES `order` (`id`),
  CONSTRAINT `fk_orderitem_goods_id` FOREIGN KEY (`goods_id`) REFERENCES `goods` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=56 DEFAULT CHARSET=utf8 COMMENT='订单项表'

关系设计优势:

  1. 价格快照:独立存储下单时的商品价格,避免后续价格变动影响历史订单
  2. 双重外键约束:确保订单项与商品、订单的完整性和一致性
  3. 复合索引优化:通过goods_id和order_id的索引优化查询性能

核心功能实现详解

用户认证与权限管理

系统采用基于角色的访问控制(RBAC)模型,用户表通过isadmin字段区分管理员和普通用户:

public class UserServlet 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.login(username, password);
        
        if (user != null) {
            HttpSession session = request.getSession();
            session.setAttribute("user", user);
            
            if (user.isAdmin()) {
                response.sendRedirect("admin/index.jsp");
            } else {
                response.sendRedirect("index.jsp");
            }
        } else {
            request.setAttribute("error", "用户名或密码错误");
            request.getRequestDispatcher("login.jsp").forward(request, response);
        }
    }
}

用户登录界面

商品展示与购物车功能

商品展示模块支持按分类浏览、关键词搜索等功能,购物车采用Session临时存储:

public class CartServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        int goodsId = Integer.parseInt(request.getParameter("goodsId"));
        int quantity = Integer.parseInt(request.getParameter("quantity"));
        
        HttpSession session = request.getSession();
        Map<Integer, CartItem> cart = (Map<Integer, CartItem>) session.getAttribute("cart");
        
        if (cart == null) {
            cart = new HashMap<>();
            session.setAttribute("cart", cart);
        }
        
        GoodsDAO goodsDAO = new GoodsDAO();
        Goods goods = goodsDAO.findById(goodsId);
        
        if (cart.containsKey(goodsId)) {
            CartItem item = cart.get(goodsId);
            item.setQuantity(item.getQuantity() + quantity);
        } else {
            CartItem newItem = new CartItem(goods, quantity);
            cart.put(goodsId, newItem);
        }
        
        response.sendRedirect("cart.jsp");
    }
}

添加到购物车功能

订单处理流程

订单处理包含下单、支付、发货等完整流程,采用事务保证数据一致性:

public class OrderService {
    public boolean createOrder(Order order, List<CartItem> cartItems) {
        Connection conn = null;
        try {
            conn = DBUtil.getConnection();
            conn.setAutoCommit(false);
            
            OrderDAO orderDAO = new OrderDAO(conn);
            OrderItemDAO orderItemDAO = new OrderItemDAO(conn);
            GoodsDAO goodsDAO = new GoodsDAO(conn);
            
            // 插入订单主记录
            int orderId = orderDAO.insert(order);
            order.setId(orderId);
            
            // 插入订单项并更新库存
            for (CartItem item : cartItems) {
                OrderItem orderItem = new OrderItem();
                orderItem.setOrderId(orderId);
                orderItem.setGoodsId(item.getGoods().getId());
                orderItem.setPrice(item.getGoods().getPrice());
                orderItem.setAmount(item.getQuantity());
                
                orderItemDAO.insert(orderItem);
                
                // 更新商品库存
                goodsDAO.updateStock(item.getGoods().getId(), 
                    -item.getQuantity());
            }
            
            conn.commit();
            return true;
        } catch (SQLException e) {
            if (conn != null) {
                try {
                    conn.rollback();
                } catch (SQLException ex) {
                    ex.printStackTrace();
                }
            }
            return false;
        } finally {
            DBUtil.closeConnection(conn);
        }
    }
}

订单确认页面

后台商品管理

管理员可以对商品进行全面的CRUD操作,支持图片上传和库存管理:

public class GoodsManageServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        String action = request.getParameter("action");
        GoodsDAO goodsDAO = new GoodsDAO();
        
        if ("add".equals(action)) {
            Goods goods = new Goods();
            goods.setName(request.getParameter("name"));
            goods.setPrice(Float.parseFloat(request.getParameter("price")));
            goods.setStock(Integer.parseInt(request.getParameter("stock")));
            goods.setTypeId(Integer.parseInt(request.getParameter("typeId")));
            goods.setIntro(request.getParameter("intro"));
            
            // 处理图片上传
            Part coverPart = request.getPart("cover");
            if (coverPart != null && coverPart.getSize() > 0) {
                String coverFileName = saveUploadedFile(coverPart);
                goods.setCover(coverFileName);
            }
            
            goodsDAO.insert(goods);
            response.sendRedirect("goods_list.jsp?msg=add_success");
        }
    }
    
    private String saveUploadedFile(Part part) throws IOException {
        String fileName = System.currentTimeMillis() + "_" + 
            getFileName(part);
        String filePath = getServletContext().getRealPath("/uploads") + 
            File.separator + fileName;
        
        try (InputStream input = part.getInputStream();
             FileOutputStream output = new FileOutputStream(filePath)) {
            IOUtils.copy(input, output);
        }
        
        return fileName;
    }
}

商品管理后台

实体模型设计

系统采用面向对象的设计思想,核心实体模型如下:

public class Goods {
    private int id;
    private String name;
    private String cover;
    private String image1;
    private String image2;
    private float price;
    private String intro;
    private int stock;
    private int typeId;
    private Type type;
    
    // 构造函数、getter和setter方法
    public Goods() {}
    
    public int getId() { return id; }
    public void setId(int id) { this.id = id; }
    
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    
    // 其他getter/setter方法...
}

public class Order {
    private int id;
    private float total;
    private int amount;
    private int status;
    private int paytype;
    private String name;
    private String phone;
    private String address;
    private Date datetime;
    private int userId;
    private List<OrderItem> itemList;
    
    // 业务方法
    public void calculateTotal() {
        this.total = 0;
        this.amount = 0;
        if (itemList != null) {
            for (OrderItem item : itemList) {
                this.total += item.getPrice() * item.getAmount();
                this.amount += item.getAmount();
            }
        }
    }
}

功能展望与优化方向

1. 引入Redis缓存层

当前系统每次商品查询都直接访问数据库,在高并发场景下存在性能瓶颈。建议引入Redis作为缓存层:

public class GoodsServiceWithCache {
    private Jedis jedis = new Jedis("localhost");
    private GoodsDAO goodsDAO = new GoodsDAO();
    
    public Goods findById(int id) {
        String key = "goods:" + id;
        String cached = jedis.get(key);
        
        if (cached != null) {
            return JSON.parseObject(cached, Goods.class);
        } else {
            Goods goods = goodsDAO.findById(id);
            if (goods != null) {
                jedis.setex(key, 3600, JSON.toJSONString(goods));
            }
            return goods;
        }
    }
}

2. 微服务架构改造

将单体应用拆分为商品服务、订单服务、用户服务等微服务,提高系统可扩展性:

// 商品服务接口定义
@RestController
@RequestMapping("/api/goods")
public class GoodsController {
    @Autowired
    private GoodsService goodsService;
    
    @GetMapping("/{id}")
    public ResponseEntity<Goods> getGoods(@PathVariable int id) {
        Goods goods = goodsService.findById(id);
        return ResponseEntity.ok(goods);
    }
    
    @PostMapping("/")
    public ResponseEntity<Goods> createGoods(@RequestBody Goods goods) {
        Goods created = goodsService.create(goods);
        return ResponseEntity.status(201).body(created);
    }
}

3. 增加弹性搜索支持

实现更强大的商品搜索功能,支持全文检索、拼音搜索、同义词匹配等:

public class GoodsSearchService {
    public List<Goods> search(String keyword, int page, int size) {
        SearchRequest searchRequest = new SearchRequest("goods");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        
        sourceBuilder.query(QueryBuilders.multiMatchQuery(keyword, 
            "name", "intro", "type.name"));
        sourceBuilder.from((page - 1) * size);
        sourceBuilder.size(size);
        
        searchRequest.source(sourceBuilder);
        
        // 执行搜索并返回结果
        return executeSearch(searchRequest);
    }
}

4. 消息队列异步处理

订单创建、库存扣减等操作可以通过消息队列实现异步处理,提高系统响应速度:

@Component
public class OrderMessageListener {
    @JmsListener(destination = "order.queue")
    public void processOrder(OrderMessage message) {
        // 异步处理订单库存扣减
        inventoryService.deductStock(message.getGoodsList());
        // 发送订单确认邮件
        emailService.sendOrderConfirmation(message.getUserId(), message.getOrderId());
    }
}

5. 移动端适配与PWA支持

开发响应式界面,支持PWA(渐进式Web应用)特性,提供接近原生应用的体验:

// 注册Service Worker
if ('serviceWorker' in navigator) {
    navigator.serviceWorker.register('/sw.js')
        .then(registration => {
            console.log('SW registered: ', registration);
        })
        .catch(registrationError => {
            console.log('SW registration failed: ', registrationError);
        });
}

总结

该甜品零食电商平台基于成熟的J2EE技术栈,实现了完整的电子商务功能。系统采用分层架构设计,数据库设计合理,具备良好的扩展性和维护性。通过深入分析核心功能实现代码,展示了如何利用Servlet和JSP技术构建稳健的Web应用。

未来通过引入缓存、微服务、搜索引擎等现代化技术,可以进一步提升系统性能和用户体验。该平台为传统食品零售商向数字化转型提供了可靠的技术基础,具有良好的市场应用前景。

本文关键词
JSPServlet零食甜品在线销售系统源码解析

上下篇

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