zoukankan      html  css  js  c++  java
  • Ajax实例-购物车

    一、概述

    1.当添加或删除商品时,购物车会立即更新数据

    2.思路:

    (1)建立商品类Item.java,存有商品属性name,prince,code(商品编码)等

    (2)建立商品目录类Catalog.java,便于CRUD操作时,判断是否存在该品种商品

    (3)建立购物车类Cart.java,保存用户已选购的商品各类及其数量,HashMap<Item,Integer>存储,提供toXml()把存储的内容拼接成xml格式。把cart对象放在session中,以保存用户在会话期间的购物数据,且方便servlet的CRUD操作,及调用toXml()返回给request

    (4)建立CartServlet.java处理请求

    3.类图

    4.序列图

    二、代码

    1.Item.java

     1 package developerworks.ajax.store;
     2 
     3 import java.math.BigDecimal;
     4 
     5 //商品
     6 public class Item {
     7   private String code;
     8   private String name;
     9   private String description;
    10   private int price;
    11 
    12   public Item(String code,String name,String description,int price) {
    13     this.code=code;
    14     this.name=name;
    15     this.description=description;
    16     this.price=price;
    17   }
    18 
    19   public String getCode() {
    20     return code;
    21   }
    22 
    23   public String getName() {
    24     return name;
    25   }
    26 
    27   public String getDescription() {
    28     return description;
    29   }
    30 
    31   public int getPrice() {
    32     return price;
    33   }
    34 
    35   public String getFormattedPrice() {
    36     return "$"+new BigDecimal(price).movePointLeft(2);
    37   }
    38 
    39   public boolean equals(Object o) {
    40     if (this == o) return true;
    41     if (this == null) return false;
    42     if (!(o instanceof Item)) return false;
    43     return ((Item)o).getCode().equals(this.code);
    44   }
    45 }

    2.Catalog.java

     1 package developerworks.ajax.store;
     2 
     3 import java.util.*;
     4 
     5 //商品目录
     6 public class Catalog {
     7 
     8   private static Map<String,Item> items;
     9 
    10   static {
    11    items = new HashMap<String,Item>(); 
    12    items.put("hat001",new Item("hat001","Hat","Stylish bowler hat (SALE!)",1999));
    13    items.put("dog001",new Item("dog001","Dog","Chocolate labrador puppy",7999));
    14    items.put("sou001",new Item("sou001","Soup","Can of tasty tomato soup",199));
    15    items.put("cha001",new Item("cha001","Chair","Swivelling office chair", 4999));
    16    items.put("str001",new Item("str001","String","Metric tonne of bailing twine", 1999));
    17    items.put("qua001",new Item("qua001","Quark","Everyone's favorite sub-atomic particle", 49));
    18   }
    19 
    20   public Collection<Item> getAllItems() {
    21     return items.values();
    22   }
    23 
    24   public boolean containsItem(String itemCode) {
    25     return items.containsKey(itemCode);
    26   }
    27 
    28   public Item getItem(String itemCode) {
    29     return items.get(itemCode);
    30   }
    31 
    32 }

    3.Cart.java

      1 package developerworks.ajax.store;
      2 
      3 import java.math.BigDecimal;
      4 import java.util.*;
      5 
      6 /**
      7  * A very simple shopping Cart
      8  */
      9 public class Cart {
     10 
     11     //HashMap<Item,Integer>中,Item用来表示购物车的哪种物品,Integer表示该物品的数量
     12   private HashMap<Item,Integer> contents;
     13 
     14   /**
     15    * Creates a new Cart instance
     16    */
     17   public Cart() {
     18     contents = new HashMap<Item,Integer>();
     19   }
     20 
     21   /**
     22    * Adds a named item to the cart
     23    * @param itemName The name of the item to add to the cart
     24    */
     25   public void addItem(String itemCode) {
     26 
     27     Catalog catalog = new Catalog();
     28 
     29     if (catalog.containsItem(itemCode)) {
     30       Item item = catalog.getItem(itemCode);
     31 
     32       int newQuantity = 1;
     33 
     34       //查看要添加的item在现在的购物车中是否已经存在
     35       if (contents.containsKey(item)) {        
     36         Integer currentQuantity = contents.get(item);
     37         
     38         //若存在则数量加1就行
     39         newQuantity += currentQuantity.intValue();
     40       }
     41         //更新物品数量
     42       contents.put(item, new Integer(newQuantity));
     43     }
     44   }
     45 
     46   /**
     47    * Removes the named item from the cart
     48    * @param itemName Name of item to remove
     49    */
     50   public void removeItems(String itemCode) {
     51 
     52     contents.remove(new Catalog().getItem(itemCode));
     53   }
     54 
     55   /**
     56    * @return XML representation of cart contents
     57    */
     58   public String toXml() {
     59     StringBuffer xml = new StringBuffer();
     60     xml.append("<?xml version="1.0"?>
    ");
     61     xml.append("<cart generated=""+System.currentTimeMillis()+"" total=""+getCartTotal()+"">
    ");
     62 
     63     /*遍历购物车中的每种物品,取出各种物品的名称、数量,拼接xml
     64         <item code="xx">
     65             <name>xx</name>
     66             <quantity>xx</quantity>
     67         </item>
     68     */
     69     for (Iterator<Item> I = contents.keySet().iterator() ; I.hasNext() ; ) {
     70       Item item = I.next();
     71       int itemQuantity = contents.get(item).intValue();
     72 
     73       xml.append("<item code=""+item.getCode()+"">
    ");
     74       xml.append("<name>");
     75       xml.append(item.getName());
     76       xml.append("</name>
    ");
     77       xml.append("<quantity>");
     78       xml.append(itemQuantity);
     79       xml.append("</quantity>
    ");
     80       xml.append("</item>
    ");
     81     }
     82     
     83     xml.append("</cart>
    ");
     84     System.out.println(xml);
     85     return xml.toString();
     86   }
     87 
     88   //算总价
     89   private String getCartTotal() {
     90     int total = 0;
     91 
     92     //取出购物车的每种物品
     93     for (Iterator<Item> I = contents.keySet().iterator() ; I.hasNext() ; ) {
     94       Item item = I.next();
     95       //取出购物车中每种物品的数量
     96       int itemQuantity = contents.get(item).intValue();
     97 
     98       //每种物品的总价=单价*数量
     99       total += (item.getPrice() * itemQuantity);
    100     }
    101 
    102     return "$"+new BigDecimal(total).movePointLeft(2);
    103   }
    104 }

    4.CartServlet.java

     1 package developerworks.ajax.servlet;
     2 
     3 import developerworks.ajax.store.Cart;
     4 import javax.servlet.http.*;
     5 
     6 import java.util.Enumeration;
     7 
     8 public class CartServlet extends HttpServlet {
     9 
    10   /**
    11    * Updates Cart, and outputs XML representation of contents
    12    */
    13   public void doPost(HttpServletRequest req, HttpServletResponse res) throws java.io.IOException {
    14 
    15     Enumeration headers = req.getHeaderNames();
    16     while (headers.hasMoreElements()) {
    17       String header  =(String) headers.nextElement();
    18       System.out.println(header+": "+req.getHeader(header));
    19     }
    20 
    21     Cart cart = getCartFromSession(req);
    22 
    23     //接收在req.send("action=add&item="+itemCode)指定的参数
    24     String action = req.getParameter("action");
    25     String item = req.getParameter("item");
    26     
    27     if ((action != null)&&(item != null)) {
    28 
    29       if ("add".equals(action)) {
    30         cart.addItem(item);
    31 
    32       } else if ("remove".equals(action)) {
    33         cart.removeItems(item);
    34 
    35       }
    36     }
    37 
    38     String cartXml = cart.toXml();
    39     res.setContentType("text/xml");
    40     //cartXml的值会赋给responseXML属性返回给request
    41     res.getWriter().write(cartXml);
    42   }
    43 
    44   public void doGet(HttpServletRequest req, HttpServletResponse res) throws java.io.IOException {
    45     // Bounce to post, for debugging use
    46     // Hit this servlet directly from the browser to see XML
    47     doPost(req,res);
    48   }
    49 
    50   private Cart getCartFromSession(HttpServletRequest req) {
    51 
    52     //把购物车保存在session中
    53     HttpSession session = req.getSession(true);
    54     Cart cart = (Cart)session.getAttribute("cart");
    55    
    56     if (cart == null) {
    57       cart = new Cart();
    58       session.setAttribute("cart", cart);
    59     }
    60 
    61     return cart;
    62   }
    63 }

    5.cart.js

      1 // Timestamp of cart that page was last updated with
      2 var lastCartUpdate = 0;
      3 
      4 /*
      5  * Adds the specified item to the shopping cart, via Ajax call
      6  * itemCode - product code of the item to add
      7  */
      8 function addToCart(itemCode) {
      9 
     10  var req = newXMLHttpRequest();
     11 
     12  /*XMLHttpRequest的 readyState属性是一个数值,它指出请求生命周期的状态。它从 0(代表“未初始化”)变化到 4(代表“完成”)。每次 readyState变化时,readystatechange事件就触发,由 onreadystatechange属性指定的事件处理函数就被调用。*/
     13  req.onreadystatechange = getReadyStateHandler(req, updateCart);
     14  
     15  //在web.xml中有匹配了cart.do的servlet
     16  req.open("POST", "cart.do", true);
     17  
     18  /*
     19  HTTP 请求分为三个部分:状态行、请求头、消息主体。类似于下面这样:
     20 <method> <request-URL> <version>
     21 <headers>
     22 
     23 <entity-body>
     24 
     25 application/x-www-form-urlencoded是最常见的 POST 提交数据的方式了。浏览器的原生 form 表单,如果不设置 enctype 属性,那么最终就会以 application/x-www-form-urlencoded 方式提交数据。请求类似于下面这样(无关的请求头在本文中都省略掉了):
     26 
     27 POST http://www.example.com HTTP/1.1
     28 Content-Type: application/x-www-form-urlencoded;charset=utf-8
     29 
     30 title=test&sub%5B%5D=1&sub%5B%5D=2&sub%5B%5D=3
     31 首先,Content-Type 被指定为 application/x-www-form-urlencoded;其次,提交的数据按照 key1=val1&key2=val2 的方式进行编码,key 和 val 都进行了 URL 转码。大部分服务端语言都对这种方式有很好的支持。例如 PHP 中,$_POST['title'] 可以获取到 title 的值,$_POST['sub'] 可以得到 sub 数组。
     32 很多时候,我们用 Ajax 提交数据时,也是使用这种方式。例如 JQuery 和 QWrap 的 Ajax,Content-Type 默认值都是「application/x-www-form-urlencoded;charset=utf-8」。
     33  */
     34  req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
     35  req.send("action=add&item="+itemCode);
     36 }
     37 
     38 /*
     39  * 令一种产品的数量减1
     40  */
     41 function removeToCart(itemCode) {
     42 
     43  var req = newXMLHttpRequest();
     44 
     45  req.onreadystatechange = getReadyStateHandler(req, updateCart);
     46  
     47  //在web.xml中有匹配了cart.do的servlet
     48  req.open("POST", "cart.do", true);
     49  
     50   req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
     51  req.send("action=remove&item="+itemCode);
     52 }
     53 
     54 
     55 /*
     56  * Update shopping-cart area of page to reflect contents of cart
     57  * described in XML document.
     58  */
     59  /*由于servlet调用res.getWriter().write(cartXml);
     60  所以cartXml的值会赋给requestXML属性返回的给request,具体返回的xml格式如下:
     61     <car generated="xxxxxx" total="$xxxx"">
     62         <item code="xx">
     63             <name>xx</name>
     64             <quantity>xx</quantity>
     65         </item>
     66         <item code="xx">
     67             <name>xx</name>
     68             <quantity>xx</quantity>
     69         </item>
     70     </car>
     71 */
     72 /*更新购物车*/
     73 function updateCart(cartXML) {
     74  var cart = cartXML.getElementsByTagName("cart")[0];
     75  var generated = cart.getAttribute("generated");
     76  if (generated > lastCartUpdate) {
     77    lastCartUpdate = generated;
     78    var contents = document.getElementById("contents");
     79    //把次取出id为"contents"的UL时,都把它的html内容清空,否则旧内容与新内容会叠加
     80    contents.innerHTML = "";
     81 
     82    var items = cart.getElementsByTagName("item");
     83    for (var I = 0 ; I < items.length ; I++) {
     84 
     85      var item = items[I];
     86      
     87      //得到<name>xx</name>的值
     88      var name = item.getElementsByTagName("name")[0].firstChild.nodeValue;
     89      //得到<quantity>xx</quantity>的值
     90      var quantity = item.getElementsByTagName("quantity")[0].firstChild.nodeValue;
     91 
     92      var listItem = document.createElement("li");
     93      listItem.appendChild(document.createTextNode(name+" x "+quantity));
     94      contents.appendChild(listItem);
     95    }
     96 
     97  }
     98 
     99  document.getElementById("total").innerHTML = cart.getAttribute("total");
    100 }

    6.ajax1.js

     1 /*
     2  * Returns an new XMLHttpRequest object, or false if the browser
     3  * doesn't support it
     4  */
     5 function newXMLHttpRequest() {
     6 
     7   var xmlreq = false;
     8 
     9   // Create XMLHttpRequest object in non-Microsoft browsers
    10   if (window.XMLHttpRequest) {
    11     xmlreq = new XMLHttpRequest();
    12 
    13   } else if (window.ActiveXObject) {
    14 
    15     try {
    16       // Try to create XMLHttpRequest in later versions
    17       // of Internet Explorer
    18 
    19       xmlreq = new ActiveXObject("Msxml2.XMLHTTP");
    20       
    21     } catch (e1) {
    22 
    23       // Failed to create required ActiveXObject
    24       
    25       try {
    26         // Try version supported by older versions
    27         // of Internet Explorer
    28       
    29         xmlreq = new ActiveXObject("Microsoft.XMLHTTP");
    30 
    31       } catch (e2) {
    32 
    33         // Unable to create an XMLHttpRequest by any means
    34         xmlreq = false;
    35       }
    36     }
    37   }
    38 
    39 return xmlreq;
    40 }
    41 
    42  /*
    43     * Returns a function that waits for the specified XMLHttpRequest
    44     * to complete, then passes it XML response to the given handler function.
    45   * req - The XMLHttpRequest whose state is changing
    46   * responseXmlHandler - Function to pass the XML response to
    47   */
    48   
    49   /*getReadyStateHandler()像这样被调用:handlerFunction = getReadyStateHandler(req, updateCart)。在这个示例中,getReadyStateHandler()返回的函数将检查在 req变量中的 XMLHttpRequest是否已经完成,然后用响应的 XML 调用名为 updateCart的函数。*/
    50  function getReadyStateHandler(req, responseXmlHandler) {
    51 
    52    // Return an anonymous function that listens to the XMLHttpRequest instance
    53    return function () {
    54 
    55      // If the request's status is "complete"
    56        if (req.readyState == 4) {
    57        
    58        // Check that we received a successful response from the server
    59        if (req.status == 200) {
    60 
    61          // Pass the XML payload of the response to the handler function.
    62          responseXmlHandler(req.responseXML);
    63 
    64        } else {
    65 
    66          // An HTTP problem has occurred
    67          alert("HTTP error "+req.status+": "+req.statusText);
    68        }
    69      }
    70    }
    71  }

    7.index.jsp

     1 <%@ page import="java.util.*" %>
     2 <%@ page import="developerworks.ajax.store.*" %>
     3 <?xml version="1.0" encoding="utf-8"?>
     4 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
     5 <html xmlns="http://www.w3.org/1999/xhtml">
     6 <head>
     7 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
     8 <script type="text/javascript" language="javascript" src="ajax1.js"></script>
     9 <script type="text/javascript" language="javascript" src="cart.js"></script>
    10 </head>
    11 <body>
    12 <div style="float: left;  500px">
    13 <h2>Catalog</h2>
    14 <table border="1">
    15   <thead><th>Name</th><th>Description</th><th>Price</th><th></th></thead>
    16   <tbody>
    17   <%
    18     for (Iterator<Item> I = new Catalog().getAllItems().iterator() ; I.hasNext() ; ) {
    19       Item item = I.next();
    20   %>
    21     <tr><td><%= item.getName() %></td><td><%= item.getDescription() %></td><td><%= item.getFormattedPrice() %></td><td><button onclick="addToCart('<%= item.getCode() %>')">Add to Cart</button></td>
    22     <td><button onclick="removeToCart('<%= item.getCode() %>')">Delete to Cart</button></td></tr>
    23     <% } %>
    24   </tbody>
    25 </table>
    26 <div style="position: absolute; top: 0px; right: 0px;  250px">
    27 <h2>Cart Contents</h2>
    28 <ul id="contents">
    29 </ul>
    30 Total cost: <span id="total">$0.00</span>
    31 </div>
    32 </body>
    33 </html>

    8.web.xml

     1 <?xml version="1.0" encoding="ISO-8859-1"?>
     2 <web-app 
     3    xmlns="http://java.sun.com/xml/ns/j2ee" 
     4    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     5    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" 
     6    version="2.4"> 
     7 
     8   <display-name>Ajax Shopping-Cart WebApp</display-name>
     9 
    10   <servlet>
    11     <servlet-name>Cart</servlet-name>
    12     <servlet-class>developerworks.ajax.servlet.CartServlet</servlet-class>
    13     <load-on-startup>1</load-on-startup>
    14   </servlet>
    15 
    16   <servlet-mapping>
    17     <servlet-name>Cart</servlet-name>
    18     <url-pattern>/cart.do</url-pattern>
    19   </servlet-mapping>
    20 </web-app>

    三、运行结果

    转自:http://www.ibm.com/developerworks/cn/java/j-ajax1/

  • 相关阅读:
    【黑金动力社区】【原创博文集锦】《Verilog HDL那些事儿》导读
    [黑金原创教程][连载]关于《iBoard 电子学堂》的学习及进阶方式
    发布《iBoard 电子学堂》DEMO代码
    Cyclone III中LVDS的设计
    [黑金原创教程][连载][iBoard 电子学堂][第八卷 设计任意波发生器]第三篇 直接数字合成(DDS)原理
    专业级FPGA视频图像处理开发板发布
    [黑金原创教程][连载][iBoard 电子学堂][第〇卷 电子基础]第二篇 电路图与印刷电路板
    [黑金原创教程][连载][iBoard 电子学堂][第八卷 设计任意波发生器]第一篇 iBoard 任意波发生器简介
    [黑金原创教程][连载][iBoard 电子学堂][第〇卷 电子基础]第一篇 认识电子元器件
    ucgui 在《iBoard 电子学堂》上的移植
  • 原文地址:https://www.cnblogs.com/shamgod/p/4599796.html
Copyright © 2011-2022 走看看