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的逻辑错误:
- 初始化时新建空
ArrayList<Item>并添加当前商品,随后用arrayList.contains(id)判断是否存在同ID商品——但集合存储的是Item对象,contains默认调用Object.equals(),而Item类未重写equals,且传入的是String类型的id,永远返回false,导致逻辑全走新增分支。 - 获取已有购物车列表的时机错误,逻辑混乱,未正确遍历已有的
cartItemList做检查。 - 跳转逻辑重复,同时使用
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
相关产品推荐
相关产品推荐

