day09-功能实现08
家居网购项目实现08
以下皆为部分代码,详见 https://github.com/liyuelian/furniture_mall.git
19.功能18-添加家居到购物车
19.1需求分析/图解

- 会员登录后,可以添加家居到购物车
- 完成购物车的设计和实现
- 每添加一个家居,购物车的数量+1并显示
19.2思路分析
说明:这里实现的购物车是session版的,不是数据库版的。也就是说,用户购物车的数据在退出登录或者退出浏览器后将会清空。
如果希望将购物车放到mysql中,将Cart数据模型改成一张表即可,即Entity和表的一种映射概念,你可以使用Entity-DAO-Service。大概做法就是购物车表和CartItem实体映射,表的一行记录就是一个cartItem类。通过记录用户id和用户联系起来。
.png)
JavaEE+mvc模式:

19.3代码实现
19.3.1entity层
CartItem.java
package com.li.furns.entity; import java.math.BigDecimal; /** * CartItem 表示购物车的一项,就是某个家居数据 * * @author 李 * @version 1.0 */ public class CartItem { //定义属性->根据需求 private Integer id; //家居id private String name; //家居名 private BigDecimal price; //家居单价 private Integer count; //家居数量 private BigDecimal totalPrice; //总价格 public CartItem() { } public CartItem(Integer id, String name, BigDecimal price, Integer count, BigDecimal totalPrice) { this.id = id; this.name = name; this.price = price; this.count = count; this.totalPrice = totalPrice; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public BigDecimal getPrice() { return price; } public void setPrice(BigDecimal price) { this.price = price; } public Integer getCount() { return count; } public void setCount(Integer count) { this.count = count; } public BigDecimal getTotalPrice() { return totalPrice; } public void setTotalPrice(BigDecimal totalPrice) { this.totalPrice = totalPrice; } @Override public String toString() { return "CartItem{" + "id=" + id + ", name='" + name + '\'' + ", price=" + price + ", count=" + count + ", totalPrice=" + totalPrice + '}'; } }
Cart.java

package com.li.furns.entity; import java.math.BigDecimal; import java.util.HashMap; import java.util.Set; /** * Cart就是一个购物车,包含很多CartItem对象 * * @author 李 * @version 1.0 */ public class Cart { //定义属性 //包含多个CartItem对象,使用HashMap来保存 private HashMap<Integer, CartItem> items = new HashMap<>(); //添加家居CartItem到Cart public void addItem(CartItem cartItem) { //添加cartItem到Cart前要先判断-该item是第一次添加还是二次以后添加 //使用家居id在items中找有没有对应家居 CartItem item = items.get(cartItem.getId()); if (null == item) {//说明当前购物车还没有这个cartItem //添加该cartItem到购物车Cart中去 items.put(cartItem.getId(), cartItem); } else {//当前购物车已经有这个cartItem //数量增加1 item.setCount(item.getCount() + 1); //修改总价 //item.setTotalPrice(item.getPrice().multiply(new BigDecimal(item.getCount()))); item.setTotalPrice(item.getTotalPrice().add(item.getPrice())); } } @Override public String toString() { return "Cart{" + "items=" + items + '}'; } }
19.3.2test
CartTest.java
package com.li.furns.test; import com.li.furns.entity.Cart; import com.li.furns.entity.CartItem; import org.junit.jupiter.api.Test; import java.math.BigDecimal; /** * @author 李 * @version 1.0 */ public class CartTest { private Cart cart = new Cart(); @Test public void addItem() { cart.addItem(new CartItem(1, "沙发", new BigDecimal(10), 2, new BigDecimal(20))); cart.addItem(new CartItem(2, "小椅子", new BigDecimal(20), 2, new BigDecimal(40))); System.out.println("cart=>" + cart); } }
19.3.3web层
配置CartServlet
<servlet> <servlet-name>CartServlet</servlet-name> <servlet-class>com.li.furns.web.CartServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>CartServlet</servlet-name> <url-pattern>/cartServlet</url-pattern> </servlet-mapping>
CartServlet.java
package com.li.furns.web; import com.li.furns.entity.Cart; import com.li.furns.entity.CartItem; import com.li.furns.entity.Furn; import com.li.furns.service.FurnService; import com.li.furns.service.impl.FurnServiceImpl; import com.li.furns.utils.DataUtils; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * @author 李 * @version 1.0 */ public class CartServlet extends BasicServlet { //增加一个属性 private FurnService furnService = new FurnServiceImpl(); /** * 添加家居数据到购物车 * * @param req * @param resp * @throws ServletException * @throws IOException */ protected void addItem(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //得到添加的家居ID int id = DataUtils.parseInt(req.getParameter("id"), 0); //获取到id对应的Furn对象 Furn furn = furnService.queryFurnById(id); if (furn == null) {//说明没有查到对应的家居信息 return; //todo } //根据furn构建CartItem CartItem item = new CartItem(furn.getId(), furn.getName(), furn.getPrice(), 1, furn.getPrice()); //从session获取cart对象 Cart cart = (Cart) req.getSession().getAttribute("cart"); if (null == cart) {//说明当前的session没有cart对象 //创建一个cart对象 cart = new Cart(); //将其放入到session中 req.getSession().setAttribute("cart", cart); } //将cartItem加入到cart对象 cart.addItem(item); //添加完毕后需要返回到添加家居的页面 String referer = req.getHeader("Referer"); resp.sendRedirect(referer); } }
19.3.4修改前端接口
views/cutomer/index.jsp
点击add to cart按钮,添加家居信息到购物车中
<script type="text/javascript"> $(function () { //给add to cart绑定事件 $("button.add-to-cart").click(function () { //获取到点击的furn-id var furnId = $(this).attr("furnId"); //发出一个请求-添加家居=>后面改成ajax location.href = "cartServlet?action=addItem&id=" + furnId; }) }) </script>
显示购物车信息

19.4完成测试
未添加家居前购物车显示

点击add to cart,添加家居到购物车


添加多个家居信息

20.功能19-显示购物车
20.1需求分析/图解

- 查看购物车,可以显示如上信息
- 选中了哪些家居,名称,数量,金额
- 统计购物车共多少商品,总价多少
20.2思路分析

20.3代码实现
Cart.java
为了配合前端接口,增加一些方法
public HashMap<Integer, CartItem> getItems() { return items; } public BigDecimal getCartTotalPrice() { BigDecimal cartTotalPrice = new BigDecimal(0); //遍历购物车,返回整个购物车的商品总价格 Set<Integer> keys = items.keySet(); for (Integer id : keys) { CartItem item = items.get(id); //一定要把add后的值重新赋给cartTotalPrice cartTotalPrice = cartTotalPrice.add(item.getTotalPrice()); } return cartTotalPrice; } public int getTotalCount() { //因为前端每点击一次添加商品,购物车显示就会调用getTotalCount方法, //如果不置0,数量相当是重复添加 int totalCount = 0; //遍历购物车,返回商品总数量 Set<Integer> keys = items.keySet(); for (Integer id : keys) { totalCount += ((CartItem) items.get(id)).getCount(); } return totalCount; }
用foreach在cart.jsp循环显示购物车信息
<!-- Cart Area Start --> <div class="cart-main-area pt-100px pb-100px"> <div class="container"> <h3 class="cart-page-title">Your cart items</h3> <div class="row"> <div class="col-lg-12 col-md-12 col-sm-12 col-12"> <form action="#"> <div class="table-content table-responsive cart-table-content"> <table> <thead> <tr> <th>图片</th> <th>家居名</th> <th>单价</th> <th>数量</th> <th>金额</th> <th>操作</th> </tr> </thead> <tbody> <%--找到显示的购物车项,进行循环显示--%> <c:if test="${not empty sessionScope.cart.items}"> <%-- 1.items实际上是HashMap<Integer, CartItem> 2.所以通过foreach标签取出的每一个对象entry 是 HashMap<Integer, CartItem> 的k-v 3.因此var其实就是entry 4.所以要取出cartItem是通过entry.value --%> <c:forEach items="${sessionScope.cart.items}" var="entry"> <tr> <td class="product-thumbnail"> <a href="#"><img class="img-responsive ml-3" src="assets/images/product-image/1.jpg" alt=""/></a> </td> <td class="product-name"><a href="#">${entry.value.name}</a></td> <td class="product-price-cart"><span class="amount">${entry.value.price}</span></td> <td class="product-quantity"> <div class="cart-plus-minus"> <input class="cart-plus-minus-box" type="text" name="qtybutton" value="${entry.value.count}"/> </div> </td> <td class="product-subtotal">${entry.value.totalPrice}</td> <td class="product-remove"> <a href="#"><i class="icon-close"></i></a> </td> </tr> </c:forEach> </c:if> </tbody> </table> </div> <div class="row"> <div class="col-lg-12"> <div class="cart-shiping-update-wrapper"> <h4>共${sessionScope.cart.totalCount}件商品 总价 ${sessionScope.cart.cartTotalPrice}元</h4> <div class="cart-shiping-update"> <a href="#">购 物 车 结 账</a> </div> <div class="cart-clear"> <button>继 续 购 物</button> <a href="#">清 空 购 物 车</a> </div> </div> </div> </div> </form> </div> </div> </div> </div> <!-- Cart Area End -->
20.4完成测试

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!