You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JSP Servlet购物车Bug:同ID商品添加时需更新数量而非新增行

购物车同ID商品重复添加未更新数量的Bug修复

问题概述

当前用JSP+Servlet开发的购物车,添加、删除功能正常,但存在Bug:添加ID相同的商品时,系统新增一行记录,而非更新现有商品的数量。

当前实际结果

|    Item ID    |     Item Name    |         Qty      |      Action      |
|---------------|------------------|------------------|------------------|
|       1       |        Bag       |         1        |    Remove Item   |
|       2       |     Pencil       |         5        |    Remove Item   |
|       1       |        Bag       |         3        |    Remove Item   |

预期结果

|    Item ID    |     Item Name    |         Qty      |      Action      |
|---------------|------------------|------------------|------------------|
|       1       |        Bag       |         4        |    Remove Item   |
|       2       |     Pencil       |         5        |    Remove Item   |

代码问题分析

问题核心出在addToCart.java的逻辑错误:

  1. 初始化时新建空ArrayList<Item>并添加当前商品,随后用arrayList.contains(id)判断是否存在同ID商品——但集合存储的是Item对象,contains默认调用Object.equals(),而Item类未重写equals,且传入的是String类型的id,永远返回false,导致逻辑全走新增分支。
  2. 获取已有购物车列表的时机错误,逻辑混乱,未正确遍历已有的cartItemList做检查。
  3. 跳转逻辑重复,同时使用forward和sendRedirect,引发不可预期的行为。

修复方案

1. 重写Item类的equals和hashCode方法

让系统能基于itemId判断两个商品是否为同一商品,修改Item.java:

public class Item {
    private String itemId;
    private String itemName;
    private int qty;
    private String submit;

    // 原有getter、setter方法保持不变

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Item item = (Item) o;
        return itemId.equals(item.itemId);
    }

    @Override
    public int hashCode() {
        return itemId.hashCode();
    }
}

2. 重构addToCart的doPost方法

修正逻辑,先获取已有购物车列表,遍历检查是否存在同ID商品,存在则更新数量,不存在则新增:

protected void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    
    processRequest(request, response);   
    String id = request.getParameter("id");
    String itemName = request.getParameter("itemName");
    int qty = Integer.parseInt(request.getParameter("qty"));

    // 获取已有的购物车列表
    ArrayList<Item> cartItemList = (ArrayList<Item>) request.getServletContext().getAttribute("cartItemList");
    if (cartItemList == null) {
        cartItemList = new ArrayList<>();
    }

    // 检查是否存在同ID商品
    boolean itemExists = false;
    for (Item existingItem : cartItemList) {
        if (existingItem.getItemId().equals(id)) {
            // 更新数量
            existingItem.setQty(existingItem.getQty() + qty);
            itemExists = true;
            break;
        }
    }

    // 不存在则新增商品
    if (!itemExists) {
        Item newItem = new Item();
        newItem.setItemId(id);
        newItem.setItemName(itemName);
        newItem.setQty(qty);
        cartItemList.add(newItem);
    }

    // 更新购物车列表到ServletContext
    request.getServletContext().setAttribute("cartItemList", cartItemList);
    // 重定向回购物车页面
    response.sendRedirect("index.jsp");
}

优化建议(可选)

如果购物车商品数量较多,ArrayList遍历查找效率较低,建议改用Map<String, Item>存储购物车,以itemId为键,查找同ID商品的时间复杂度为O(1):

// 修改存储结构为Map
Map<String, Item> cartMap = (Map<String, Item>) request.getServletContext().getAttribute("cartMap");
if (cartMap == null) {
    cartMap = new HashMap<>();
}

Item existingItem = cartMap.get(id);
if (existingItem != null) {
    existingItem.setQty(existingItem.getQty() + qty);
} else {
    Item newItem = new Item();
    newItem.setItemId(id);
    newItem.setItemName(itemName);
    newItem.setQty(qty);
    cartMap.put(id, newItem);
}

request.getServletContext().setAttribute("cartMap", cartMap);

同时需要修改index.jsp中的遍历逻辑,从Map的values中取出商品进行展示。

内容的提问来源于stack exchange,提问作者Dae

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 16:05:22