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.类图

Ajax实例-购物车

4.序列图

Ajax实例-购物车

二、代码

1.Item.java

 package developerworks.ajax.store;

 import java.math.BigDecimal;

 //商品
public class Item {
private String code;
private String name;
private String description;
private int price; public Item(String code,String name,String description,int price) {
this.code=code;
this.name=name;
this.description=description;
this.price=price;
} public String getCode() {
return code;
} public String getName() {
return name;
} public String getDescription() {
return description;
} public int getPrice() {
return price;
} public String getFormattedPrice() {
return "$"+new BigDecimal(price).movePointLeft(2);
} public boolean equals(Object o) {
if (this == o) return true;
if (this == null) return false;
if (!(o instanceof Item)) return false;
return ((Item)o).getCode().equals(this.code);
}
}

2.Catalog.java

 package developerworks.ajax.store;

 import java.util.*;

 //商品目录
public class Catalog { private static Map<String,Item> items; static {
items = new HashMap<String,Item>();
items.put("hat001",new Item("hat001","Hat","Stylish bowler hat (SALE!)",1999));
items.put("dog001",new Item("dog001","Dog","Chocolate labrador puppy",7999));
items.put("sou001",new Item("sou001","Soup","Can of tasty tomato soup",199));
items.put("cha001",new Item("cha001","Chair","Swivelling office chair", 4999));
items.put("str001",new Item("str001","String","Metric tonne of bailing twine", 1999));
items.put("qua001",new Item("qua001","Quark","Everyone's favorite sub-atomic particle", 49));
} public Collection<Item> getAllItems() {
return items.values();
} public boolean containsItem(String itemCode) {
return items.containsKey(itemCode);
} public Item getItem(String itemCode) {
return items.get(itemCode);
} }

3.Cart.java

 package developerworks.ajax.store;

 import java.math.BigDecimal;
import java.util.*; /**
* A very simple shopping Cart
*/
public class Cart { //HashMap<Item,Integer>中,Item用来表示购物车的哪种物品,Integer表示该物品的数量
private HashMap<Item,Integer> contents; /**
* Creates a new Cart instance
*/
public Cart() {
contents = new HashMap<Item,Integer>();
} /**
* Adds a named item to the cart
* @param itemName The name of the item to add to the cart
*/
public void addItem(String itemCode) { Catalog catalog = new Catalog(); if (catalog.containsItem(itemCode)) {
Item item = catalog.getItem(itemCode); int newQuantity = 1; //查看要添加的item在现在的购物车中是否已经存在
if (contents.containsKey(item)) {
Integer currentQuantity = contents.get(item); //若存在则数量加1就行
newQuantity += currentQuantity.intValue();
}
//更新物品数量
contents.put(item, new Integer(newQuantity));
}
} /**
* Removes the named item from the cart
* @param itemName Name of item to remove
*/
public void removeItems(String itemCode) { contents.remove(new Catalog().getItem(itemCode));
} /**
* @return XML representation of cart contents
*/
public String toXml() {
StringBuffer xml = new StringBuffer();
xml.append("<?xml version=\"1.0\"?>\n");
xml.append("<cart generated=\""+System.currentTimeMillis()+"\" total=\""+getCartTotal()+"\">\n"); /*遍历购物车中的每种物品,取出各种物品的名称、数量,拼接xml
<item code="xx">
<name>xx</name>
<quantity>xx</quantity>
</item>
*/
for (Iterator<Item> I = contents.keySet().iterator() ; I.hasNext() ; ) {
Item item = I.next();
int itemQuantity = contents.get(item).intValue(); xml.append("<item code=\""+item.getCode()+"\">\n");
xml.append("<name>");
xml.append(item.getName());
xml.append("</name>\n");
xml.append("<quantity>");
xml.append(itemQuantity);
xml.append("</quantity>\n");
xml.append("</item>\n");
} xml.append("</cart>\n");
System.out.println(xml);
return xml.toString();
} //算总价
private String getCartTotal() {
int total = 0; //取出购物车的每种物品
for (Iterator<Item> I = contents.keySet().iterator() ; I.hasNext() ; ) {
Item item = I.next();
//取出购物车中每种物品的数量
int itemQuantity = contents.get(item).intValue(); //每种物品的总价=单价*数量
total += (item.getPrice() * itemQuantity);
} return "$"+new BigDecimal(total).movePointLeft(2);
}
}

4.CartServlet.java

 package developerworks.ajax.servlet;

 import developerworks.ajax.store.Cart;
import javax.servlet.http.*; import java.util.Enumeration; public class CartServlet extends HttpServlet { /**
* Updates Cart, and outputs XML representation of contents
*/
public void doPost(HttpServletRequest req, HttpServletResponse res) throws java.io.IOException { Enumeration headers = req.getHeaderNames();
while (headers.hasMoreElements()) {
String header =(String) headers.nextElement();
System.out.println(header+": "+req.getHeader(header));
} Cart cart = getCartFromSession(req); //接收在req.send("action=add&item="+itemCode)指定的参数
String action = req.getParameter("action");
String item = req.getParameter("item"); if ((action != null)&&(item != null)) { if ("add".equals(action)) {
cart.addItem(item); } else if ("remove".equals(action)) {
cart.removeItems(item); }
} String cartXml = cart.toXml();
res.setContentType("text/xml");
//cartXml的值会赋给responseXML属性返回给request
res.getWriter().write(cartXml);
} public void doGet(HttpServletRequest req, HttpServletResponse res) throws java.io.IOException {
// Bounce to post, for debugging use
// Hit this servlet directly from the browser to see XML
doPost(req,res);
} private Cart getCartFromSession(HttpServletRequest req) { //把购物车保存在session中
HttpSession session = req.getSession(true);
Cart cart = (Cart)session.getAttribute("cart"); if (cart == null) {
cart = new Cart();
session.setAttribute("cart", cart);
} return cart;
}
}

5.cart.js

 // Timestamp of cart that page was last updated with
var lastCartUpdate = 0; /*
* Adds the specified item to the shopping cart, via Ajax call
* itemCode - product code of the item to add
*/
function addToCart(itemCode) { var req = newXMLHttpRequest(); /*XMLHttpRequest的 readyState属性是一个数值,它指出请求生命周期的状态。它从 0(代表“未初始化”)变化到 4(代表“完成”)。每次 readyState变化时,readystatechange事件就触发,由 onreadystatechange属性指定的事件处理函数就被调用。*/
req.onreadystatechange = getReadyStateHandler(req, updateCart); //在web.xml中有匹配了cart.do的servlet
req.open("POST", "cart.do", true); /*
HTTP 请求分为三个部分:状态行、请求头、消息主体。类似于下面这样:
<method> <request-URL> <version>
<headers> <entity-body> application/x-www-form-urlencoded是最常见的 POST 提交数据的方式了。浏览器的原生 form 表单,如果不设置 enctype 属性,那么最终就会以 application/x-www-form-urlencoded 方式提交数据。请求类似于下面这样(无关的请求头在本文中都省略掉了): POST http://www.example.com HTTP/1.1
Content-Type: application/x-www-form-urlencoded;charset=utf-8 title=test&sub%5B%5D=1&sub%5B%5D=2&sub%5B%5D=3
首先,Content-Type 被指定为 application/x-www-form-urlencoded;其次,提交的数据按照 key1=val1&key2=val2 的方式进行编码,key 和 val 都进行了 URL 转码。大部分服务端语言都对这种方式有很好的支持。例如 PHP 中,$_POST['title'] 可以获取到 title 的值,$_POST['sub'] 可以得到 sub 数组。
很多时候,我们用 Ajax 提交数据时,也是使用这种方式。例如 JQuery 和 QWrap 的 Ajax,Content-Type 默认值都是「application/x-www-form-urlencoded;charset=utf-8」。
*/
req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
req.send("action=add&item="+itemCode);
} /*
* 令一种产品的数量减1
*/
function removeToCart(itemCode) { var req = newXMLHttpRequest(); req.onreadystatechange = getReadyStateHandler(req, updateCart); //在web.xml中有匹配了cart.do的servlet
req.open("POST", "cart.do", true); req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
req.send("action=remove&item="+itemCode);
} /*
* Update shopping-cart area of page to reflect contents of cart
* described in XML document.
*/
/*由于servlet调用res.getWriter().write(cartXml);
所以cartXml的值会赋给requestXML属性返回的给request,具体返回的xml格式如下:
<car generated="xxxxxx" total="$xxxx"">
<item code="xx">
<name>xx</name>
<quantity>xx</quantity>
</item>
<item code="xx">
<name>xx</name>
<quantity>xx</quantity>
</item>
</car>
*/
/*更新购物车*/
function updateCart(cartXML) {
var cart = cartXML.getElementsByTagName("cart")[0];
var generated = cart.getAttribute("generated");
if (generated > lastCartUpdate) {
lastCartUpdate = generated;
var contents = document.getElementById("contents");
//把次取出id为"contents"的UL时,都把它的html内容清空,否则旧内容与新内容会叠加
contents.innerHTML = ""; var items = cart.getElementsByTagName("item");
for (var I = 0 ; I < items.length ; I++) { var item = items[I]; //得到<name>xx</name>的值
var name = item.getElementsByTagName("name")[0].firstChild.nodeValue;
//得到<quantity>xx</quantity>的值
var quantity = item.getElementsByTagName("quantity")[0].firstChild.nodeValue; var listItem = document.createElement("li");
listItem.appendChild(document.createTextNode(name+" x "+quantity));
contents.appendChild(listItem);
} } document.getElementById("total").innerHTML = cart.getAttribute("total");
}

6.ajax1.js

 /*
* Returns an new XMLHttpRequest object, or false if the browser
* doesn't support it
*/
function newXMLHttpRequest() { var xmlreq = false; // Create XMLHttpRequest object in non-Microsoft browsers
if (window.XMLHttpRequest) {
xmlreq = new XMLHttpRequest(); } else if (window.ActiveXObject) { try {
// Try to create XMLHttpRequest in later versions
// of Internet Explorer xmlreq = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e1) { // Failed to create required ActiveXObject try {
// Try version supported by older versions
// of Internet Explorer xmlreq = new ActiveXObject("Microsoft.XMLHTTP"); } catch (e2) { // Unable to create an XMLHttpRequest by any means
xmlreq = false;
}
}
} return xmlreq;
} /*
* Returns a function that waits for the specified XMLHttpRequest
* to complete, then passes it XML response to the given handler function.
* req - The XMLHttpRequest whose state is changing
* responseXmlHandler - Function to pass the XML response to
*/ /*getReadyStateHandler()像这样被调用:handlerFunction = getReadyStateHandler(req, updateCart)。在这个示例中,getReadyStateHandler()返回的函数将检查在 req变量中的 XMLHttpRequest是否已经完成,然后用响应的 XML 调用名为 updateCart的函数。*/
function getReadyStateHandler(req, responseXmlHandler) { // Return an anonymous function that listens to the XMLHttpRequest instance
return function () { // If the request's status is "complete"
if (req.readyState == 4) { // Check that we received a successful response from the server
if (req.status == 200) { // Pass the XML payload of the response to the handler function.
responseXmlHandler(req.responseXML); } else { // An HTTP problem has occurred
alert("HTTP error "+req.status+": "+req.statusText);
}
}
}
}

7.index.jsp

 <%@ page import="java.util.*" %>
<%@ page import="developerworks.ajax.store.*" %>
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" language="javascript" src="ajax1.js"></script>
<script type="text/javascript" language="javascript" src="cart.js"></script>
</head>
<body>
<div style="float: left; width: 500px">
<h2>Catalog</h2>
<table border="1">
<thead><th>Name</th><th>Description</th><th>Price</th><th></th></thead>
<tbody>
<%
for (Iterator<Item> I = new Catalog().getAllItems().iterator() ; I.hasNext() ; ) {
Item item = I.next();
%>
<tr><td><%= item.getName() %></td><td><%= item.getDescription() %></td><td><%= item.getFormattedPrice() %></td><td><button onclick="addToCart('<%= item.getCode() %>')">Add to Cart</button></td>
<td><button onclick="removeToCart('<%= item.getCode() %>')">Delete to Cart</button></td></tr>
<% } %>
</tbody>
</table>
<div style="position: absolute; top: 0px; right: 0px; width: 250px">
<h2>Cart Contents</h2>
<ul id="contents">
</ul>
Total cost: <span id="total">$0.00</span>
</div>
</body>
</html>

8.web.xml

 <?xml version="1.0" encoding="ISO-8859-1"?>
<web-app
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4"> <display-name>Ajax Shopping-Cart WebApp</display-name> <servlet>
<servlet-name>Cart</servlet-name>
<servlet-class>developerworks.ajax.servlet.CartServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet> <servlet-mapping>
<servlet-name>Cart</servlet-name>
<url-pattern>/cart.do</url-pattern>
</servlet-mapping>
</web-app>

三、运行结果

Ajax实例-购物车

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

上一篇:1、Dreamweaver+php开发网站第一步


下一篇:python基础--杂项