Java Web 网络商城案例演示十三(抽取购物车模块)
一、抽取购物车模型
购物项:(图片路径,商品名称,商品价格,这类商品购买的数量,这类商品的总价小计)
class Cartitem{
private Product product;//携带图片的路径,商品的名称,以及商品的价格
private int num;//当前类别的商品的数量
priavte double subTotal;// 小计,当前这类商品的总共的价格 经过计算获取到
}
购物车(个数不确定的购物项):
class Cart{
//List list = new ArrayList(); 个数不确定的购物项
//Map map = new HashMap(); 个数不确定的购物项
double total;//总计 积分 可以经过计算获取到
//方法:清空购物车
//方法:移除购物车上的购物项
//方法:添加商品到购物车
}
红色小框抽取为一类事务,购物项(类别)
抽取商品项的类
package cn.itzheng.store.domain;
public class CartItem {
private Product product;// 目的就是携带购物项3种参数的(图片的路径,商品的名称,商品的价格)
private int num;// 当前类别商品数量
private double subTotal;// 小计
//小计是经过计算可以获取到的
public Product getProduct() {
return product;
}
public void setProduct(Product product) {
this.product = product;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public double getSubTotal() {
return product.getShop_price() * num;
}
public void setSubTotal(double subTotal) {
this.subTotal = subTotal;
}
public CartItem() {
// TODO Auto-generated constructor stub
}
public CartItem(Product product, int num, double subTotal) {
super();
this.product = product;
this.num = num;
this.subTotal = subTotal;
}
@Override
public String toString() {
return "CartItem [product=" + product + ", num=" + num + ", subTotal=" + subTotal + "]";
}
}
抽取购物车Cart
Cart (map类型)
package cn.itzheng.store.domain;
//2个属性3个方法
public class Cart {
// 总计/积分
private double total = 0;
// 个数不确定的购物项 键商品的pid《=====》cartItem
Map<String, CartItem> map = new HashMap<String, CartItem>();
// 添加购物项到购物车
// 当用户点击加入购物车按钮,可以将当前要购买的商品和商品的id和商品的数量发送到服务端,服务端根据商品的id查询到商品的信息
// 有了商品的信息Product对象,有了要购买商品的数量,当前的购物项也就可以获取到了
public void addCartItemToCar(CartItem cartItem) {
// 获取到从前端购物车传入的cartIte对象当中的的Product对象当中Pid对象
String pid = cartItem.getProduct().getPid();
// 将当前购物项加入购物车之前,判断之前是否买过这类商品
// 如果没有买过 list.add();
// 如果买过:获取到原先的数量,获取到本次的数量,相加之后设置到原先购物项上
if (map.containsKey(pid)) {// 查看当前map集合当中有没有和传递进来的pid相同的key
// 获取到原先的购物项
CartItem oldItem = map.get(pid);
oldItem.setNum(oldItem.getNum() + cartItem.getNum());
} else {
// 如果没有对应的key对应pid的话说明之前没有商品
map.put(pid, cartItem);// 将该商品放入到map对象集合当中
}
}
// 移除购物项
public void removeCartItem(String pid) {
map.remove(pid);
}
// 用户点击移除购物项的链接的时候,可以将当前的的购物类别的商品的id发送到服务端
// 清空购物车
public void clearCart() {
map.clear();
}
// 总计是可以经过计算获取到
public double getTotal() {
//向让总计清零
total=0;
// 获取到Map集合中所有的购物项
Collection<CartItem> values = map.values();
// 遍历所有的购物项,将购物项上的小计相加
for (CartItem cartItem : values) {
total += cartItem.getSubTotal();
}
return total;// 返回的是所有价格的总和
}
public void setTotal(double total) {
this.total = total;
}
public Map<String, CartItem> getMap() {
return map;
}
public void setMap(Map<String, CartItem> map) {
this.map = map;
}
}
Cart (list类型)
//2个属性3个方法
public class Cart02 {
// 总计/积分
private double total;
//个数不确定的购物项
private List<CartItem> list = new ArrayList();
// 添加购物项到购物车
// 当用户点击加入购物车按钮,可以将当前要购买的商品和商品的id和商品的数量发送到服务端,服务端根据商品的id查询到商品的信息
// 有了商品的信息Product对象,有了要购买商品的数量,当前的购物项也就可以获取到了
public void addCartItemToCart(CartItem cartItem) {
// 将当前的购物项加入购物车之前,判断之前是否买过这一类商品
// 如果没有买过 list.add(cartItem);//将相应商品对应的类放入到集合当中
// 如果买过:获取到原先的数量,获取到本次的要购买的数量,相加之后再设置到原先的购物项上
// 设置变量,默认为false,没有购买过商品
boolean flag = false;
//存储原先购物项
CartItem old = null;
//遍历的是已经存在的商品的list集合
for (CartItem cartItem2 : list) {// 遍历list集合当中的CartItem对象
//判断传入的CartItem的product当中pid和之前list当中CartItem的product当中的pid是否相同
if (cartItem2.getProduct().getPid().equals(cartItem.getProduct().getPid())) {
flag=true;
//如果相等说明之前有这个旧商品赋值给对应的商品赋值给CartItem old
old=cartItem2;
}
}
//如果flag是false的话,说明没有与之前list集合当中对象的pid重复的就直接将传入进来的商品项传入到
if(flag == false) {//之前没有这个商品
list.add(cartItem);//将新的商品添加到旧商品的list集合当中
}else {//之前有这个商品
//获取到原先的数量和现在的数量
old.setNum(old.getNum()+cartItem.getNum());//获取到原先该商品的数量加上
}
}
// 移除购物项
// 用户点击移除购物项的链接的时候,可以将当前的的购物类别的商品的id发送到服务端
public void removeCartItem(String pid) {
// 遍历List,看每个CartItem上的product对象上的id是否和服务端获取到的pid相等,如果相等,删除当前的购物项
for (CartItem cartItem : list) {
if (cartItem.getProduct().getPid().equals(pid)) {
// 删除当前的cartItem
// 直接调用list.remove(cartItem); 无法删除当前的cartItem,需要通过迭代器来删除当前的购物项
}
}
}
// 清空购物车
public void clearCart() {
list.clear();// 将list集合当中的数据全部清空
}
}
二、将商品添加到购物车
1、购物车内存分析
2、添加购物项到购物车的原理分析
3、步骤实现
1、准备工作
/jsp/product_list.jsp 修改链接
<a href="${pageContext.request.contextPath}/ProductServlet?method=findProductByPid&pid=${p.pid}">
/jsp/product_info.jsp
创建一个from表单,设置from method,action的各自属性
<form id="myForm" action="${pageContext.request.contextPath}/CartServlet?method=addCartItemToCart" method="post">
设置隐藏域,通过隐藏域向服务器端传递商品的pid
<input type="hidden" name="pid" value="${product.pid} ">
通过js的方式提交表单(如果一个表单当中有多个按钮可以实现不同的按钮向不同的地方提交信息)
javascript:void(0)取消链接默认行为
<a href="javascript:void(0)">
<input id="btnId" style="background: url('${pageContext.request.contextPath}/img/product.gif') no-repeat scroll 0 -600px rgba(0, 0, 0, 0);height:36px;width:127px;" value="加入购物车" type="button">
</a>
加入购物车的功能
<script type="text/javascript">
/* 当页面加载完成之后 */
$(function(){
$("#btnId").click(function(){
//获取到from表单对象
var formObj = document.getElementById("myForm");
/* 通过javascript的方式提交 以下两行代码可以实现按钮向不同的地方提交表单 */
//formObj.action="/store_v5/CartServlet";
//formObj.method="get";
formObj.submit();
});
});
</script>
三、功能实现
1、添加商品到购物车
1、创建CartServlet
public class CartServlet extends BaseServlet {
// 添加购物项到购物车
public String addCartItemToCart(HttpServletRequest request, HttpServletResponse response) throws Exception {
// 从session当中获取购物车
Cart cart = (Cart) request.getSession().getAttribute("cart");
if (cart == null) {
// 如果获取不到,创建购物车对象,放置到session当中
cart = new Cart();
request.getSession().setAttribute("cart", cart);
}
// 如果从session当中获取到cart,使用即可
// 获取到页面点击加入购物车按钮商品的id,数量
String pid = request.getParameter("pid");// 获取表单提交的pid
int num = Integer.parseInt(request.getParameter("quantity"));// 获取表单提交的商品数量
// 通过商品id查询商品对象
ProductService productService = new ProductServiceImpl();
Product product = productService.findProductByPid(pid);
// 获取到待购买的购物项
CartItem cartItem = new CartItem();
cartItem.setNum(num);
cartItem.setProduct(product);
//调用购物车上的方法 ,将查询到商品对象放入到购物车当中
cart.addCartItemToCar(cartItem);
//重定向到购物车界面
response.sendRedirect("/store_v5/jsp/cart.jsp");
return null;
}
}
2、/jsp/cart.jsp 获取购物车上的商品信息
cart.cartItems获取对应方法返回的map集合的内容
//判断map集合当中是否有对应的值,现在是判断没有的话
<c:if test="${empty cart.cartItems }">
//判断map有对应的值的情况
<c:if test="${not empty cart.cartItems }">
<!-- 遍历map集合当中所有的值 -->
<c:forEach items="${cart.cartItems }" var="item">
代码详情如下
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>购物车</title>
<link rel="stylesheet"
href="${pageContext.request.contextPath}/css/bootstrap.min.css"
type="text/css" />
<script src="${pageContext.request.contextPath}/js/jquery-1.11.3.min.js"
type="text/javascript"></script>
<script src="${pageContext.request.contextPath}/js/bootstrap.min.js"
type="text/javascript"></script>
<!-- 引入自定义css文件 style.css -->
<link rel="stylesheet"
href="${pageContext.request.contextPath}/css/style.css" type="text/css" />
<style>
body {
margin-top: 20px;
margin: 0 auto;
}
.carousel-inner .item img {
width: 100%;
height: 300px;
}
.container .row div {
/* position:relative;
float:left; */
}
font {
color: #3164af;
font-size: 18px;
font-weight: normal;
padding: 0 10px;
}
</style>
</head>
<body>
<!-- 描述:菜单栏 -->
<%@ include file="/jsp/header.jsp"%>
<div class="container">
<!-- ${empty cart.cartItems }调用cart对象当中 -->
<c:if test="${empty cart.cartItems }">
<div class="row">
<div class="col-md-12">
<h1>开启剁手模式</h1>
</div>
</div>
</c:if>
<c:if test="${not empty cart.cartItems }">
<div class="row">
<div style="margin: 0 auto; margin-top: 10px; width: 950px;">
<strong style="font-size: 16px; margin: 5px 0;">订单详情</strong>
<table class="table table-bordered">
<tbody>
<tr class="warning">
<th>图片</th>
<th>商品</th>
<th>价格</th>
<th>数量</th>
<th>小计</th>
<th>操作</th>
</tr>
<!-- 遍历map集合当中所有的值 -->
<c:forEach items="${cart.cartItems }" var="item">
<tr class="active">
<!-- 获取购物车上购物项上的图片 -->
<td width="60" width="40%"><input type="hidden" name="id"
value="22"> <img
src="${pageContext.request.contextPath}/${item.product.pimage}"
width="70" height="60"></td>
<td width="30%"><a target="_blank">${item.product.pname}</a></td>
<td width="20%">${item.product.shop_price}</td>
<td width="10%"><input type="text" name="quantity"
value="${item.num}" maxlength="4" size="10"></td>
<td width="15%"><span class="subtotal">¥${item.subTotal }</span></td>
<td><a href="javascript:;" class="delete">删除</a></td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
</div>
<div style="margin-right: 130px;">
<div style="text-align: right;">
<em style="color: #ff6600;"> 登录后确认是否享有优惠 </em> 赠送积分: <em
style="color: #ff6600;">${cart.total }</em> 商品金额: <strong
style="color: #ff6600;">¥${cart.total }元</strong>
</div>
<div
style="text-align: right; margin-top: 10px; margin-bottom: 10px;">
<a href="${pageContext.request.contextPath}/jsp/order_info.jsp"
id="clear" class="clear">清空购物车</a> <a
href="${pageContext.request.contextPath}/jsp/order_info.jsp">
<%--提交表单 --%> <input type="submit" width="100" value="提交订单"
name="submit" border="0"
style="background: url('${pageContext.request.contextPath}/img/register.gif') no-repeat scroll 0 0 rgba(0, 0, 0, 0);
height:35px;width:100px;color:white;">
</a>
</div>
</div>
</c:if>
</div>
<div style="margin-top: 50px;">
<img src="${pageContext.request.contextPath}/img/footer.jpg"
width="100%" height="78" alt="我们的优势" title="我们的优势" />
</div>
<div style="text-align: center; margin-top: 5px;">
<ul class="list-inline">
<li><a href="${pageContext.request.contextPath}/jsp/info.jsp">关于我们</a></li>
<li><a>联系我们</a></li>
<li><a>招贤纳士</a></li>
<li><a>法律声明</a></li>
<li><a>友情链接</a></li>
<li><a target="_blank">支付方式</a></li>
<li><a target="_blank">配送方式</a></li>
<li><a>服务声明</a></li>
<li><a>广告声明</a></li>
</ul>
</div>
</body>
</html>
知识拓展:
重定向/转发
区别是:
1、一次还是两次请求响应request域数据丢失
2、路径显示的问题
3、第二次访问的位置
4、
3、向服务端发送要删除对象的pid(删除功能)
2、删除商品
原理分析:
准备工作:
1、为购物车上的删除链接绑定了点击事件,点击事件
<td><a href="javascript:;" id="${item.product.pid }" class="delete">删除</a></td>
<script type="text/javascript">
$(function(){
//页面加载完毕之后获取到class的值为delete元素标签,为其绑定点击事件
$(".delete").click(function(){
if(confirm("确认删除吗?")){
//获取到要删除商品的pid
var pid = this.id;
window.location.href="/store_v5/CartServlet?method=removeCartItem&id="+pid;
}
});
})
</script>
2、CartServlet—>removeCartItem
获取待删除的商品
获取 到购物车
调用购物车删除购物项方法
重定向到/jsp/cart.jsp
3、清空购物车
1、原理分析:
2、步骤实现
1、准备工作:在清空购物车的链接上调用CartServlet当中的clearCart方法
<a href="${pageContext.request.contextPath}/CartServlet?method=clearCart" id="clear" class="clear">清空购物车</a>
// clearCart
public String clearCart(HttpServletRequest request, HttpServletResponse response) throws Exception {
// 从session当中获取到购物车
Cart cart = (Cart) request.getSession().getAttribute("cart");
// 调用购物车上的情况购物车的方法
cart.clearCart();//清空session当中cart对象map集合的所有内容
// 重新定向到/jsp/cart.jsp
response.sendRedirect("/store_v5/jsp/cart.jsp");
return null;
}
获取到session当中的所有的cart对象当中方法清空map集合当中的所有内容
重定向到/jsp/cart.jsp页面