简易购物车---购物车的实现

今天来完成购物车的内容,首先呢,在买了东西之后要放在购物车里,当车子里的物品有相同时就叠加,不再创建物品对象,有了物品之后肯定要有价格,数量等等对象。这些对象我们要封装在JAVABEAN 中的!有了 JAVABEAN就需要建立SERVLET来进行与业务层连接,我们就需要有,增加购物车,删除购物车,
清楚购物车等一系列的SERVLET和SERVICE层连接!SERVICE层调用DAO层,这些步骤正体现出了MVC的设计模式!下面我们看具体的操作吧!
(1)  1. 代表购物车的 ShoppingCart 类
public class ShoppingCart {
 //装载 ShoppingCartItem 的数据结构: Map, 键: 书的 id, 值: 书对应的 ShoppingCartItem
 private Map<String, ShoppingCartItem> books = null;
 
 public ShoppingCart(){
  books = new HashMap<String, ShoppingCartItem>();
 }

 public Map<String, ShoppingCartItem> getBooks() {
  return books;
 }
 
 public Book getBook(String bookId){
  Book book = null;
  
  ShoppingCartItem sci = this.books.get(bookId);
  if(sci == null)
   return null;
  
  return sci.getBook();
 }
 
 public float getTotalPrice(){
  float totalPrice = 0.0f;
  
  //对 books 中的 value 进行遍历, 取其 price 属性的和
  Iterator<ShoppingCartItem> iterator = books.values().iterator();
  while(iterator.hasNext()){
   ShoppingCartItem sci = iterator.next();
   totalPrice += sci.getPrice();
  }
  
  return totalPrice;
 }
 
 public int getTotalQuantity(){
  int quantity = 0;
  
  //对 books 中的 value 进行遍历, 取其 quantity 属性的和
  Iterator<ShoppingCartItem> iterator = books.values().iterator();
  while(iterator.hasNext()){
   ShoppingCartItem sci = iterator.next();
   quantity += sci.getQuantity();
  }
  
  return quantity;
 }
 
 public boolean isExistInShoppingCart(String bookId){
  return this.books.get(bookId) != null;
 }
 
 public ShoppingCartItem getShoppingCartItemByBookId(String bookId){
  return this.books.get(bookId);
 }
 
 public void addNewItemToShoppingCart(ShoppingCartItem sci){
  this.books.put(sci.getBook().getId(), sci);
 }
}
    2. 代表购物车中的物品

public class ShoppingCartItem {
 //具体指向某本书
 private Book book;
 
 //当前商品在购物车中的数量
 private int quantity;
 
 public ShoppingCartItem(Book book) {
  this.book = book;
  this.quantity = 1;
 }

 //当前商品的总价格
 private float price;
 
 public void incrementQuantity(){
  this.quantity++;
 }

 public Book getBook() {
  return book;
 }

 public void setBook(Book book) {
  this.book = book;
 }

 public int getQuantity() {
  return quantity;
 }

 public void setQuantity(int quantity) {
  this.quantity = quantity;
 }

 public float getPrice() {
  return this.book.getPrice() * this.quantity;
 }

}
(2)建立DAO,此时有人会问,这次DAO为什么没有购物车呢,因为购物车是没有数据的,而是里面的物品才有数据的,当有更新购物车里面的物品时才会早DAO里面写方法!
public class BookDAO {
 
 //
 public void upadateBookQuantityByBookId(Connection conn, String bookId, int quantity){
  String sql = "UPDATE books SET saleAmount = saleAmount + ? WHERE id = ?";
  Object [] params = new Object[]{quantity, bookId};
  
  QueryRunner queryRunner = new QueryRunner();
  
  try {
   queryRunner.update(conn, sql, params);
  } catch (SQLException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
   throw new RuntimeException(MyBookStoreConstants.UPDATE_BOOK_SALEAMOUNT_BY_BOOK_ID_EXCEPTION);
  }
 }
(3)建立业务层,涉及到添加,清空等方法!这边佟刚老师的代码都有详细的解释!
public class BookService {
 //根据给定的 ShoppingCart 对象, 调用 DAO 方法进行数据库更新操作
 public void buyBooks(ShoppingCart sc){
  //对 sc 中的 ShoppingCartItem 对象进行遍历, 调用 BookDAO.upadateBookQuantityByBookId 方法
  Connection conn = null;
  conn = DBHelper.getConnection();
  
  try {
   Iterator<ShoppingCartItem> shoppingCartItemSet = sc.getBooks().values().iterator();
   BookDAO bookDAO = new BookDAO();
   
   while(shoppingCartItemSet.hasNext()){
    ShoppingCartItem sci = shoppingCartItemSet.next();
    
    String bookId = sci.getBook().getId();
    int quantity = sci.getQuantity();
    
    bookDAO.upadateBookQuantityByBookId(conn, bookId, quantity);
   }
  }finally{
   DBHelper.releaseDBSource(null, null, conn);
  }
  
  
 }
 
 //参数 items 中的键为 书的 id 号, 值为购物车中对应的 数量
 public void updateShoppingCart(Map<String,Integer> items, ShoppingCart sc){
  Set<String> keySet = null;
  keySet = items.keySet();
  
  for(Iterator<String> it = keySet.iterator(); it.hasNext(); ){
   String bookId = it.next();
   int quantity = items.get(bookId);
   
   if(quantity <= 0){
    sc.getBooks().remove(bookId);
   }else{
    sc.getShoppingCartItemByBookId(bookId).setQuantity(quantity);
   }
    
  }
 }
 
 //清空购物车
 public void clearShoppingCart(ShoppingCart sc){
  sc.getBooks().clear();
 }
 
 public void deleteShoppingCartItemById(String id, ShoppingCart sc){
  //删除 sc 中的 id 元素
  sc.getBooks().remove(id);
 }
 
 //把 id 对应的 ShoppingCartItem 对象放入购物车 ShoppingCart 对象中
 public void addToShoppingCart(String id, ShoppingCart sc){
  
  //1. 查看 sc 中有没有 id 对应的 ShoppingCartItem 对象
  if(sc.isExistInShoppingCart(id)){
   //1.1 有: 把该对象取出, 使其数量 + 1, 调用 sci.increseQuantity(); 方法
   ShoppingCartItem sci = sc.getShoppingCartItemByBookId(id);
   sci.incrementQuantity();
  }
  //1.2 没有: 创建一个新的 ShoppingCartItem 对象, 并将其放入 sc 中, 以书的 id 作为键
  else{
   //1.2.1 根据 id 获取相应的 Book 对象, 调用 BookDAO 的 selectBookByBookId() 方法
   Book book = null;
   BookDAO bookDAO = null;
   
   bookDAO = new BookDAO();
   book = bookDAO.selectBookByBookId(id);
   
   ShoppingCartItem sci = null;
   sci = new ShoppingCartItem(book);
   
   sc.addNewItemToShoppingCart(sci);
  }
 }
}
(4)这段是 检查购物车是有对象的,这里单独拿出来是可以很好的在WEB开发中很好的进行重用的。
public class MyBookStoreUtils {
 private MyBookStoreUtils(){}
 
 public static  ShoppingCart getShppingCartForCreateOrExist(HttpServletRequest request){
  ShoppingCart sc = null;
  //2.1 检查在 HttpSession 对象中有没有购物车对象, 即检查 session 中是否有 MyBookStoreConstants.SHOOPING_CART_KEY 属性
  //   若已经存在, 说明购物车存在, 直接取出
  HttpSession session = null;
  session = request.getSession();
  
  Object obj = session.getAttribute(MyBookStoreConstants.SHOOPING_CART_KEY);
  
  if(obj != null){
   sc = (ShoppingCart) obj;
  }
  //2.2 若不存在 MyBookStoreConstants.SHOOPING_CART_KEY 属性, 创建一个购物车对象, 并把该对象放入 Session 中
  else{
   sc = new ShoppingCart();
   session.setAttribute(MyBookStoreConstants.SHOOPING_CART_KEY, sc);
  }
  
  return sc;
 }
 
 public static  ShoppingCart getShppingCartForExist(HttpServletRequest request){
  ShoppingCart sc = null;
  //2.1 检查在 HttpSession 对象中有没有购物车对象, 即检查 session 中是否有 MyBookStoreConstants.SHOOPING_CART_KEY 属性
  //   若已经存在, 说明购物车存在, 直接取出
  HttpSession session = null;
  session = request.getSession();
  
  Object obj = session.getAttribute(MyBookStoreConstants.SHOOPING_CART_KEY);
  
  if(obj != null){
   sc = (ShoppingCart) obj;
  }
  //2.2 若不存在 MyBookStoreConstants.SHOOPING_CART_KEY 属性, 抛出异常, 提示用户还不存在购物车.
  else{
   throw new RuntimeException(MyBookStoreConstants.NO_SHOPPING_CART_EXCETPION);
  }
  
  return sc;
 }
}
(5)这里是所有与购物车相关的SERVLET.
 这个是更新数据的,需要在SERVICE中调用DAO 的!
public class UpdateShoppingCartServlet extends HttpServlet {

 public void doPost(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {
  //获取表单信息
  // request.getParameter(""); 方法行不通, 因为表单的 name 是随时变化的
  
  //获取表单中的所有 name
  Enumeration<String> nameEnums = request.getParameterNames();
  
  Map items = new HashMap<String, Integer>();
  //遍历 nameEnums, 再取出对应的 Value, 封装到 items 中
  
  try {
   while(nameEnums.hasMoreElements()){
    String bookId = nameEnums.nextElement();
    String quantity = request.getParameter(bookId);
    
    items.put(bookId, Integer.parseInt(quantity));
   }
  } catch (NumberFormatException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
   throw new RuntimeException(MyBookStoreConstants.QUANTITY_FORMAT_EXCEPTION);
  }
  
  //获取购物车对象
  ShoppingCart sc = null;
  sc = MyBookStoreUtils.getShppingCartForExist(request);
  
  //调用 Service 方法
  BookService bookService = new BookService();
  bookService.updateShoppingCart(items, sc);
  
  //派发页面: showShoppingCart.jsp 页面
  String forwardPage = "/WEB-INF/jsp/showShoppingCart.jsp";
  request.getRequestDispatcher(forwardPage).forward(request, response);
 }

}

public class ShowShoppingCartServlet extends HttpServlet {

 public void doGet(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {
  //做一个转发
  String forwardPage = null;
  
  forwardPage = "/WEB-INF/jsp/showShoppingCart.jsp";
  
  RequestDispatcher dispatcher = null;
  dispatcher = request.getRequestDispatcher(forwardPage);
  dispatcher.forward(request, response);
 }

}
public class ReceiptServlet extends HttpServlet {

 public void doPost(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {
  //1. 获取表单信息: name 和 cardId
  
  //2. 调用 Service 方法, 更新 books 表各条 book 的 saleAmount 字段
  
  //2.1 获取购物车
  ShoppingCart sc = MyBookStoreUtils.getShppingCartForExist(request);
  
  BookService bookService = new BookService();
  bookService.buyBooks(sc);
  
  //2.1 使 Session 失效
  HttpSession session = null;
  session = request.getSession();
  session.invalidate();
  
  //3. 派发页面: receipt.jsp 页面
  request.getRequestDispatcher("/WEB-INF/jsp/receipt.jsp").forward(request, response);
  
 }

}
 这段我先开始很纳闷老师为什么会这样写呢,其实很简单,写个专门的转发的SERVLET这样,在每次转发的时候就只连接一个servlet比连接多个更来的简洁!提高了效率!
public class ForwardServlet extends HttpServlet {

 public void doGet(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {
  //1. 获取 path
  String path = request.getParameter("path");
  
  //2. 派发页面
  request.getRequestDispatcher(path).forward(request, response);
 }

}
public class DeleteShoppingCartItemServlet extends HttpServlet {

 public void doGet(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {
  //1. 获取 id 号
  String id = request.getParameter("bookid");
  
  //2. 调用 BookService 方法 deleteShoppingCartItemById:, 进行删除操作
  ShoppingCart sc = MyBookStoreUtils.getShppingCartForExist(request);
  
  String bookTitle = sc.getBook(id).getTitle();
  
  BookService bookService = new BookService();
  bookService.deleteShoppingCartItemById(id, sc);
  
  //3. 派发页面
  request.setAttribute(MyBookStoreConstants.DELETE_FROM_SHOPPING_CART_BOOK_TITLE, bookTitle);
  
  String forwardPage = "/WEB-INF/jsp/showShoppingCart.jsp";
  //4. 判断购物车是否为空, 若为空则派发到 emptyCart.jsp 页面
  if(sc.getBooks().isEmpty())
   forwardPage = "/WEB-INF/jsp/emptyCart.jsp";
  
  RequestDispatcher dispatcher = null;
  dispatcher = request.getRequestDispatcher(forwardPage);
  dispatcher.forward(request, response);
 }
 

}
这里是清空购物车的SERVLET.
public class ClearShoppingCartServlet extends HttpServlet {

 public void doGet(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {
  //1. 调用方法
  BookService bookService = new BookService();
  
  ShoppingCart sc = null;
  sc = MyBookStoreUtils.getShppingCartForExist(request);
  
  bookService.clearShoppingCart(sc);
  
  //2. 派发页面
  String forwardPage = null;
  forwardPage = "/WEB-INF/jsp/emptyCart.jsp";
  
  RequestDispatcher dispatcher = request.getRequestDispatcher(forwardPage);
  dispatcher.forward(request, response);
 }

}
public class AddToShoppingCartServlet extends HttpServlet {

 public void doGet(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {
  
  
  //1. 获取书的 id 号
  String bookId = null;
  bookId = request.getParameter("bookId");
  
  //2. 获取购物车对象: 调用 getShppingCart 方法
  ShoppingCart sc = null;
  sc = MyBookStoreUtils.getShppingCartForCreateOrExist(request);
  
  //3. 调用 Service 方法把 id 对应的 ShoppingCartItem 对象放入购物车 ShoppingCart 对象中: addToShoppingCart(id, shoppingCart);
  BookService bookService = null;
  bookService = new BookService();
  
  bookService.addToShoppingCart(bookId, sc);
  
  //4. 派发页面
  String forwardPage = "/index.jsp";
  
  //4.1 获取书名
  String bookTitle = null;
  //bookTitle = sc.getBooks().get(bookId).getBook().getTitle();
  bookTitle = sc.getBook(bookId).getTitle();
  
  //4.2 将书名放入请求域中, 以让页面进行显示
  request.setAttribute(MyBookStoreConstants.ADD_TO_SHOPPING_CART_BOOK_TITLE, bookTitle);
  
  RequestDispatcher dispatcher = null;
  dispatcher = request.getRequestDispatcher(forwardPage);
  dispatcher.forward(request, response);
 }

}
(6)下面是显示层,对应着其相应的SERVLET.下面的JSP页面运用到了我们前段时间学的JSTL,EL表示.
 'cashier.jsp'
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>My JSP 'cashier.jsp' starting page</title>
  </head>
 
  <body>
    <center>
     <br><br>
     您一共购买了 ${sessionScope.shoppingcartkey.totalQuantity} 本书
     <br><br>
     您应付金额是:${sessionScope.shoppingcartkey.totalPrice} 元。
     <br><br>
     <form action="receiptServlet" method="POST">
      <table>
       <tr>
        <td>信用卡用户名:</td>
        <td><input type="text" name="userName"/></td>
       </tr>
       <tr>
        <td>信用卡帐号:</td>
        <td><input type="text" name="cardId"/></td>        
       </tr>
       <tr align="center">
        <td colspan="2">
         <input type="submit" value="递交"/>
        </td>
       </tr>
      </table>
     </form>
    </center>
  </body>
</html>
 'receipt.jsp'
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>My JSP 'emptyCart.jsp' starting page</title>
  </head>
 
  <body>
    <center>
     <br><br>
     您的购物车为空<br><br>
     <a href="${pageContext.request.contextPath }/index.jsp">继续购物<a>
    </center>
  </body>
</html>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>My JSP 'receipt.jsp' starting page</title>
  </head>
 
  <body>
    再见: ${param.userName }<br><br>
   <a href="${pageContext.request.contextPath }/index.jsp">继续购物</a>&nbsp;&nbsp;
  </body>
</html>

'showShoppingCart.jsp'
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>My JSP 'showShoppingCart.jsp' starting page</title>
  </head>
 
  <body>
    <center>
     <c:if test="${requestScope.deleteToShoppingCartBookTitle != null}">
      <br><br>
      您已经把 ${requestScope.deleteToShoppingCartBookTitle} 从购物车中删除了!
     </c:if>
     <br><br>
      您的购物车中一共有 ${sessionScope.shoppingcartkey.totalQuantity} 本书
     <br><br>
     <form action="updateShoppingCartServlet" method="POST">
      <table cellpadding="10" cellspacing="0">
       <tr>
        <th>书名</th>
        <th>价格</th>
        <th>数量</th>
        <td></td>
       </tr>
       <c:forEach items="${sessionScope.shoppingcartkey.books}" var="sci">
        <tr>
         <td>${sci.value.book.title }</td>
         <td>${sci.value.book.price }</td>
         <td><input type="text" value="${sci.value.quantity }" name="${sci.key }" size="2" /></td>
         <td><a href="${pageContext.request.contextPath }/deleteShoppingCartItemServlet?bookid=${sci.key }">删除</a></td>
        <td></td>
       </tr>
       </c:forEach>
      </table>
      <input type="submit" value="保存修改">
     </form>
     <br>
     总价格: ${sessionScope.shoppingcartkey.totalPrice}
     <br><br>
     <a href="${pageContext.request.contextPath }/index.jsp">继续购物</a>&nbsp;&nbsp;
     <a href="${pageContext.request.contextPath }/clearShoppingCartServlet">清空购物车</a>&nbsp;&nbsp;
     <a href="${pageContext.request.contextPath }/forwardServlet?path=cashier.jsp">付账</a>
    </center>
  </body>
</html>
    这样子简易购物车算是完成了,当然这个购物车只是简单的运用,没有涉及到大量的数据,作为入门的教学的例子是完全值得我们这些初学者消化的了!通过这次购物车的联系,我对
MVC 的设计模式有了深刻的了解!不过其中的一些细节,还是需要我自己去慢慢的体会的!比如分页就是一个值得我去好好去研究的例子!

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,以下是一个简单的HTML代码实现简易购物车的示例: ```html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>简易购物车</title> </head> <body> <h1>商品列表</h1> <ul> <li> <span>商品1</span> <span>100元</span> <button onclick="addToCart(1)">添加购物车</button> </li> <li> <span>商品2</span> <span>200元</span> <button onclick="addToCart(2)">添加购物车</button> </li> <li> <span>商品3</span> <span>300元</span> <button onclick="addToCart(3)">添加购物车</button> </li> <li> <span>商品4</span> <span>400元</span> <button onclick="addToCart(4)">添加购物车</button> </li> </ul> <h1>购物车</h1> <ul id="cart"> </ul> <p>总价:<span id="totalPrice">0</span>元</p> <script> // 初始化商品列表和购物车 const products = [ { id: 1, name: '商品1', price: 100 }, { id: 2, name: '商品2', price: 200 }, { id: 3, name: '商品3', price: 300 }, { id: 4, name: '商品4', price: 400 }, ] let cart = [] // 添加商品购物车 function addToCart(id) { const product = products.find(p => p.id === id) if (product) { cart.push(product) // 更新购物车页面 const cartList = document.getElementById('cart') const item = document.createElement('li') item.innerHTML = `${product.name}(${product.price}元)<button onclick="removeFromCart(${product.id})">移除</button>` cartList.appendChild(item) // 更新总价 const totalPrice = document.getElementById('totalPrice') totalPrice.innerText = getTotalPrice() } else { alert('商品不存在') } } // 从购物车中移除商品 function removeFromCart(id) { const index = cart.findIndex(p => p.id === id) if (index !== -1) { cart.splice(index, 1) // 更新购物车页面 const cartList = document.getElementById('cart') cartList.removeChild(cartList.childNodes[index]) // 更新总价 const totalPrice = document.getElementById('totalPrice') totalPrice.innerText = getTotalPrice() } else { alert('购物车中不存在该商品') } } // 计算购物车总价 function getTotalPrice() { return cart.reduce((total, product) => total + product.price, 0) } </script> </body> </html> ``` 在这个示例中,我们首先定义了一个商品列表和一个购物车数组,然后在页面中显示了商品列表和购物车。每个商品都有一个添加购物车”按钮,点击后调用`addToCart`函数将该商品添加购物车中。购物车中的每个商品都有一个“移除”按钮,点击后调用`removeFromCart`函数将该商品购物车中移除。同时,页面上会显示购物车中的商品列表和总价,这些数据会在添加或移除商品时动态更新。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值