我们平时网购时经常会接触到购物车(Shoppingcart)这个概念。说到底,购物车就是购买物品的小推车,盛放商品的一个容器。购物网站的购物车与生活中的超市购物车非常类似,顾客可以添加多种商品到购物车,然后统一结算。目前网上购物车主要通过Cookie和Session两种方式来实现。Cookie占用资源小,属于浏览器内置的,并且只要在Cooike定义的有效期内都不会失效。但Cookie有侵犯顾客隐私的争论。而Session将用户会话期间的信息存储在服务器端,提高了安全性。

今天我就来用代码实现一个基于Session简易的网上购物车。

功能分析:

l  商品的选择

l  添加商品,删除商品

l  购物车内商品的总价计算

l  各个页面之间的跳转。

先从模型对象入手。

 

购物车模型:内有多件商品,只能用集合或数组。由于集合能自动扩容,所以用集合来实现。

另外还应该有添加商品、删除商品、计算总价等功能。

 

商品模型:名称,单价,数量

 

第一步,建立模型对象.

 

商品类:

 

//购物车中的商品对象
publicclassCartItem {
   private String sn;//商品的唯一标识
   private String name;//商品的名称
   private Double price;//商品的单价
   private Integer num;//该商品在购物车中的数量
   public String getSn() {
      returnsn;
   }
   publicvoid setSn(String sn) {
      this.sn = sn;
   }
   public String getName() {
      returnname;
   }
   publicvoid setName(String name) {
      this.name = name;
   }
   public Double getPrice() {
      returnprice;
   }
   publicvoid setPrice(Double price){
      this.price = price;
   }
   public Integer getNum() {
      returnnum;
   }
   publicvoid setNum(Integer num) {
      this.num = num;
   }
}


购物车类

//购物车对象
publicclassShoppingCart {
   //购物车中多个商品对象
   private List<CartItem> items =  new ArrayList<>();
   public List<CartItem>getItems() {
      returnitems;
   }
   publicvoidsetItems(List<CartItem> items) {
      this.items = items;
   }
   
   //商品总价
   public Double getTotalPrice(){
      DoubletotalPrice = 0D;
      for (CartItem item : items) {
         totalPrice+= item.getPrice()*item.getNum();
      }
      return totalPrice;
   }
   //把商品添加进购物车
   publicvoid save(CartItem newItem){
      for (CartItem item : items) {
         if(item.getSn().equals(newItem.getSn())) {
            //若添加的商品在购物车中已有,则只加数量
            item.setNum(item.getNum()+newItem.getNum());
            return;
         }
      }
      //若商品第一次添加
      items.add(newItem);
   }
   //把商品从购物车中删除
   publicvoid delete(String sn){
      Iterator<CartItem>it =  items.iterator();
      while (it.hasNext()) {
         CartItemitem = it.next();
         if(item.getSn().equals(sn)) {
            it.remove();//用迭代器删除,线程更安全
         }
      }
   }
}

 

注意购物车总价:总价是算出来的,没必要提供SETTER方法,甚至不用设为成员变量。

 

第二步,构建前台界面。

 

 

至少需要以下三个页面

 

代码:

①  欢迎界面(Welcome.jsp)

<html>
<head>
<meta  http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>欢迎界面</title>
</head>
<body>
    欢迎<br/>
    <a href='/input.jsp'>购物</a><br/>
    <a href='/shoppingcart'>进入购物车</a><br/>
</body>
</html>

 

②  (购买界面)Input.jsp

<html>
<head>
<meta http-equiv="Content-Type"content="text/html; charset=UTF-8">
<title>购买界面</title>
</head>
<body>
    <h3>购买界面</h3>
    <form action="/shoppingcart?cmd=save" method="post">

    商品:

<select name="name">
    <option>笔记本</option>
    <option>鼠标</option>
    <option>键盘</option>
    </select><br/>
    数量:<input type="number" name="num"required="required"><br/>
    <input type="submit" value="添加进购物车">
    </form>
</body>
</html>

 

③  (列表界面)Items.jsp

<html>
<head>
<meta http-equiv="Content-Type"content="text/html; charset=UTF-8">
<title>购物车列表</title>
</head>
<body>
    <h3>购物车列表</h3>
    <c:if test="${empty items }">
       购物车为空
    </c:if>
    <c:iftest="${!empty items}">
    <table border="1" cellpadding="0"cellspacing="0" width="80%">
       <tr>
           <th>编号</th>
           <th>名称</th>
           <th>单价</th>
           <th>数量</th>
           <th>操作</th>
       </tr>
       <c:forEach items="${items}" var="i">
       <tr>
           <th>${i.sn}</th>
           <th>${i.name }</th>
           <th>${i.price }</th>
           <th>${i.num }</th>
           <th ><a  href='/shoppingcart?cmd=delete&sn=${i.sn}'>删除</a></th>
       </tr>
       </c:forEach>
       <tr align="right">
           <td colspan="5">总价:${sessionScope.SHOPPINGCART_IN_SESSION.totalPrice}</td>
       </tr>
       </c:if>
       <ahref='input.jsp'>继续购物</a><br/>
    </table>
</body>
</html>

 

 

 


第三步,控制界面跳转,实现购物车具体功能

 

代码:

@WebServlet("/shoppingcart")
publicclassShoppingCartServlet extends HttpServlet{
   privatestaticfinallongserialVersionUID= 1L;
   protectedvoidservice(HttpServletRequest req, HttpServletResponse resp)
         throws ServletException,IOException {
      req.setCharacterEncoding("utf-8");
      Stringcmd = req.getParameter("cmd");
      //请求分发
      if ("save".equals(cmd)) {
         this.save(req, resp);
      }elseif ("delete".equals(cmd)){
         this.delete(req, resp);
      }else {
         this.list(req, resp);
      }
   }
   //购物车列表
   protectedvoid list(HttpServletRequestreq, HttpServletResponse resp)
         throws ServletException,IOException {
      ShoppingCartcart = (ShoppingCart) req.getSession().getAttribute("SHOPPINGCART_IN_SESSION");
      if (cart!=null) {
         List<CartItem>items = cart.getItems();
         req.setAttribute("items",items);
      }
      req.getRequestDispatcher("/items.jsp").forward(req,resp);
   }
   //添加进购物车
   protectedvoid save(HttpServletRequestreq, HttpServletResponse resp)
         throws ServletException,IOException {
      Stringname = req.getParameter("name");
      Stringnum = req.getParameter("num");
      
      CartItemitem = newCartItem();
      item.setName(name);
      item.setNum(Integer.valueOf(num));
      if("笔记本".equals(name)){
         item.setSn("1");
         item.setPrice(2000D);
      }elseif("鼠标".equals(name)){
         item.setSn("2");
         item.setPrice(50D);
      }elseif("键盘".equals(name)){
         item.setSn("3");
         item.setPrice(200D);
      }
      //把商品保存到购物车中
      ShoppingCartcart = (ShoppingCart) req.getSession().getAttribute("SHOPPINGCART_IN_SESSION");
      if(cart==null){
         //若session中没有购物车对象,则先设置进去,供下次使用
         cart= newShoppingCart();
         req.getSession().setAttribute("SHOPPINGCART_IN_SESSION", cart);
      }
      cart.save(item);
      resp.sendRedirect("/shoppingcart");
   }
   //从购物车删除商品
   protectedvoiddelete(HttpServletRequest req, HttpServletResponse resp)
         throws ServletException,IOException {
      Stringsn = req.getParameter("sn");
      ShoppingCartcart = (ShoppingCart) req.getSession().getAttribute("SHOPPINGCART_IN_SESSION");
      cart.delete(sn);
      resp.sendRedirect("/shoppingcart");
   }
}

 

这只是一个基于Session简易的购物车,只能实现最基础的部分,还有许多功能待完善,欢迎大家补充讨论。