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\"?>\n");
 61     xml.append("<cart generated=\""+System.currentTimeMillis()+"\" total=\""+getCartTotal()+"\">\n");
 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()+"\">\n");
 74       xml.append("<name>");
 75       xml.append(item.getName());
 76       xml.append("</name>\n");
 77       xml.append("<quantity>");
 78       xml.append(itemQuantity);
 79       xml.append("</quantity>\n");
 80       xml.append("</item>\n");
 81     }
 82     
 83     xml.append("</cart>\n");
 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; width: 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; width: 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/

posted @ 2015-06-25 13:48  shamgod  阅读(1853)  评论(0编辑  收藏  举报
haha