一、概述

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

 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>

三、运行结果

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

Ajax实例-购物车的更多相关文章

  1. jQuery Ajax 实例 ($.ajax、$.post、$.get)

    jQuery Ajax 实例 ($.ajax.$.post.$.get) 转 Jquery在异步提交方面封装的很好,直接用AJAX非常麻烦,Jquery大大简化了我们的操作,不用考虑浏览器的诧异了. ...

  2. JavaScript强化教程——jQuery AJAX 实例

    什么是 AJAX?AJAX = 异步 JavaScript 和 XML(Asynchronous JavaScript and XML).简短地说,在不重载整个网页的情况下,AJAX 通过后台加载数据 ...

  3. jQuery AJAX实例

    <html><head><title>jQuery Ajax 实例演示</title></head><script language= ...

  4. C#中jQuery Ajax实例(二)

    上一篇写了一个简单的Ajax异步程序,这一次同样是简单的程序,只不过这次先把参数传到一般处理程序(后缀为ashx)中,再把结果传回到页面. 1.html代码: <html xmlns=" ...

  5. C#中jQuery Ajax实例(一)

    目标:在aspx页面输入两参数,传到后台.cs代码,在无刷新显示到前台 下面是我的Ajax异步传值的第一个实例 1.前台html代码: <html xmlns="http://www. ...

  6. jQuery Ajax 实例 ($.ajax、$.post、$.get)【转载】

    本文转载自:http://jun1986.iteye.com/blog/1399242 Jquery在异步提交方面封装的很好,直接用AJAX非常麻烦,Jquery大大简化了我们的操作,不用考虑浏览器的 ...

  7. jQuery Ajax 实例 ($.ajax、$.post、$.get)转

    Jquery在异步提交方面封装的很好,直接用AJAX非常麻烦,Jquery大大简化了我们的操作,不用考虑浏览器的诧异了. 推荐一篇不错的jQuery Ajax 实例文章,忘记了可以去看看,地址为:ht ...

  8. jquery ajax实例教程和一些高级用法

    jquery ajax的调用方式:jquery.ajax(url,[settings]),jquery ajax常用参数:红色标记参数几乎每个ajax请求都会用到这几个参数,本文将介绍更多jquery ...

  9. Ajax实例二:取得新内容

    Ajax实例二:取得新内容 通过点击pre和next按钮,从服务器取得最新内容. HTML代码 <div id="slide">图片显示区</div> &l ...

随机推荐

  1. oracle增加表空间的四种方法,查询表空间使用情况

    增加表空间大小的四种方法Meathod1:给表空间增加数据文件ALTER TABLESPACE app_data ADD DATAFILE'D:\ORACLE\PRODUCT\10.2.0\ORADA ...

  2. ubuntu添加自定义vga输出分辨率

    Ubuntu有点折腾人....但是在折腾之后发现它更加方便,而且懂得更多的东西 最近在调试一个视频采集芯片的驱动,主要是接收vga输入和hdmi输入,在实验的过程中遇到了一个恼火的问题,就是同一台电脑 ...

  3. log4j打印参数

    %m   输出代码中指定的消息 %p   输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL  %r   输出自应用启动到输出该log信息耗费的毫秒数  %c   输出所属的类目,通 ...

  4. shell基本语法备忘

    1.第一行要写明shell种类 #!/bin/bash   2.打印输出 #!/bin/bashecho "Hello World !~"   3.变量定义 变量=前后不能有空格, ...

  5. DataGridView控件

    DataGridView控件 DataGridView是用于Windows Froms 2.0的新网格控件.它可以取代先前版本中DataGrid控件,它易于使用并高度可定制,支持很多我们的用户需要的特 ...

  6. CSS3 filter10种特效整理

    -webkit-filter是css3的一个属性,Webkit率先支持了这几个功能,感觉效果很不错.一共有10种最基本的特效,下来这个DEMO很好的展示了这些效果: <!DOCTYPE html ...

  7. mysql 存储过程 -- 游标的使用(备忘)

    BEGIN ; DECLARE f_ratio FLOAT DEFAULT 0.8; ); ); DECLARE i_statDate DATE; DECLARE i_accumulateCount ...

  8. 手把手教你自动生成Makefile

    概述:autoconf/automake工具用于自动创建功能完善的Makefile文件,接下来简单介绍一下,如何使用上述工具 自动生成Makefile 前提:安装autoconf工具(ubuntu:s ...

  9. WebServices中使用Session

    默认情况下,Asp.net使用cookie来管理会话状态.因此,Asp.net假设客户端存储了会话cookie并将它与每一个请求一并发回给客户端. /// <summary> /// Su ...

  10. 【BZOJ】【3850】ZCC Loves Codefires

    贪心 就跟NOIP2012国王游戏差不多,考虑交换相邻两题的位置,对其他题是毫无影响的,然后看两题顺序先后哪个更优.sort即可. WA了一次的原因:虽然ans开的是long long,但是在这一句: ...