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
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实例-购物车的更多相关文章
- jQuery Ajax 实例 ($.ajax、$.post、$.get)
jQuery Ajax 实例 ($.ajax.$.post.$.get) 转 Jquery在异步提交方面封装的很好,直接用AJAX非常麻烦,Jquery大大简化了我们的操作,不用考虑浏览器的诧异了. ...
- JavaScript强化教程——jQuery AJAX 实例
什么是 AJAX?AJAX = 异步 JavaScript 和 XML(Asynchronous JavaScript and XML).简短地说,在不重载整个网页的情况下,AJAX 通过后台加载数据 ...
- jQuery AJAX实例
<html><head><title>jQuery Ajax 实例演示</title></head><script language= ...
- C#中jQuery Ajax实例(二)
上一篇写了一个简单的Ajax异步程序,这一次同样是简单的程序,只不过这次先把参数传到一般处理程序(后缀为ashx)中,再把结果传回到页面. 1.html代码: <html xmlns=" ...
- C#中jQuery Ajax实例(一)
目标:在aspx页面输入两参数,传到后台.cs代码,在无刷新显示到前台 下面是我的Ajax异步传值的第一个实例 1.前台html代码: <html xmlns="http://www. ...
- jQuery Ajax 实例 ($.ajax、$.post、$.get)【转载】
本文转载自:http://jun1986.iteye.com/blog/1399242 Jquery在异步提交方面封装的很好,直接用AJAX非常麻烦,Jquery大大简化了我们的操作,不用考虑浏览器的 ...
- jQuery Ajax 实例 ($.ajax、$.post、$.get)转
Jquery在异步提交方面封装的很好,直接用AJAX非常麻烦,Jquery大大简化了我们的操作,不用考虑浏览器的诧异了. 推荐一篇不错的jQuery Ajax 实例文章,忘记了可以去看看,地址为:ht ...
- jquery ajax实例教程和一些高级用法
jquery ajax的调用方式:jquery.ajax(url,[settings]),jquery ajax常用参数:红色标记参数几乎每个ajax请求都会用到这几个参数,本文将介绍更多jquery ...
- Ajax实例二:取得新内容
Ajax实例二:取得新内容 通过点击pre和next按钮,从服务器取得最新内容. HTML代码 <div id="slide">图片显示区</div> &l ...
随机推荐
- linux下搭建mysql主从
在master上创建repl账户,用于复制. grant replication slave on *.* to 'repl'@'%' identified by 'P@$$W0rd'; flush ...
- php7+apache的环境安装配置
因为刚开始接触php,所以要对php的开发环境进行搭建. 1.首先到Apache的官网下载最新版: http://httpd.apache.org/download.cgi: 参照该网址配置Apach ...
- 关于ASCII、GB231、GBK、UTF-8/UTF8、ANSI、unicode的学习笔记
继续上次的学习内容,写一些自己学习的笔记吧!总是觉得没有笔记的学习总是不那么踏实,我承认自己是个记忆力很差的人,特别羡慕那些可以把自己学过的东西记得很牢靠的人.哎!可惜我不是,那只能做出来点东西,就算 ...
- iframe 传值问题
当一个页面中插入了iframe或者由不同的框架组成(fieldset)时,这种情况下,需要处理的业务逻辑比较常见的就是数据进行交互了 1.页面中插入了iframe情况 由于页面中插入了iframe,那 ...
- 全球SEO行业调查报告
这是一份来自MOZ的调查报告,本报告是两年一次的SEO行业调查,主要围绕SEO从业人员的特征.工作内容时间分配比例.对未来市场的看法.使用的seo工具以及SEO知识扩充渠道等展开. 这份报告可以对从事 ...
- 可执行文件(ELF)格式之讲解
ELF(Executable and Linking Format)是一种对象文件的格式,用于定义不同类型的对象文件(Object files)中都放了什么东西.以及都以什么样的格式去放这些东西.它自 ...
- html之cellspacing && cellpadding讲解
单元格间距(表格间距)(cellspacing) -- 代表表格边框与单元格补白的距离,也是单元格补白之间的距离 单元格边距(表格填充)(cellpadding) -- 代表单元格外面的一个距离,用于 ...
- Struct2、Hibernate3、Spring3框架搭建实战(转)
采用目前最新的struts-2.3.1.2.hibernate3.6.10.Final.spring-framework-3.1.1.RELEASE开发包,以及eclipse-jee-indigo-S ...
- Git常用命令大全
查看.添加.提交.删除.找回,重置修改文件 git help <command> # 显示command的help git show # 显示某次提交的内容 git show $id gi ...
- TJU 4087. box
题目:Tuhao and his two small partners participated in the tournament.But in the end, they lost the cha ...