JavaWeb-仿小米商场(6):商品添加到购物车
1 功能描述
接上篇 JavaWeb - 仿小米商城(5):商品详情展示 本篇博客将分析和实现小米商城商品添加到购物车 和展示。如以下H5页面所示:
2 功能分析
2.1 功能逻辑抽象
商品购物车功能在逻辑上并不复杂:在商品界面每当点击商品 <img>标签或商品名称时,都会向后端提 交一个 GET 请求来将本商品数据内容添加到Session。后端在收到请求后查询数据库并以Map形式储存 内容到session。
商品购物车是面向数据库中的 tb_cart表,在购物车列表页面点击结算将数据添加到数据表。在开发时基 于三层架构体系建立对应的 CartServlet 类、CartService 接口和实现类、CartDao 接口和实现类。
备注:vo,dto,domain,entity,pojo的含义
POJO(Plain Ordinary Java Object)简单的Java对象,实际就是普通JavaBeans(规范),pojo是业 务称呼.
entity:实体类,一个类,属性严格对应一个表格的行数据
domain:封装数据库的javabean对象,一个对象可以封装多个表格数据.(domain的范围大于 entity)
DTO:专门负责接收前端表格数据的对应结构的javabean.
vo:view object,视图对象,ajax要什么,就封装什么
POJO与JavaBean的比较:
pojo:用于数据的临时传递,它只能装载数据,作为数据存储的载体,不具有业务逻辑的处理能 力。 javaBean:与pojo相比,它里面可以有其他方法。 JavaBean是可重用组件,需要符合以下条 件:
这个类必须有一个公共的缺省构造函数 这个类的属性使用getter和setter来访问设置数据,其他方 法遵从标准命名规范 这个类可以序列化 3 代码实现
3 代码实现
3.1 前端
3.1.1 修改商品详情a链接地址
3.1.2 编写cart.html代码
前端在加载html内容时便向后端提交异步请求。在购物车详情页查询CartServlet里的showCart方法数 据,发出请求向CartServlet获取session中添加的购物项的json数据
cart.html 的js代码如下
//加一
function pNum(pid, p, no) {
var nums = $("#num_count" + no).val();
if (Number(nums) >= 5) {
alert("每人限购五件")
} else {
nums=parseInt(nums)+1;//购买数量不能超过总库存或者限制购买数量
}
$.ajax({
url: "cart.do?action=updateCartNum&pid=" + pid + "&num=" + nums + "&price=" + p,
method: "get",
success: function () {
location.href = "cart.html";
},
error: function () {
alert("服务器异常");
}
})
}
//减一
function mNum(pid, p, no) {
var nums = $("#num_count" + no).val();
nums=parseInt(nums)-1
if (Number(nums) < 1) {
if (confirm("确认要删除吗?")) {
nums = 1;
alert("最少不能少于一件")
}
}
$.ajax({
url: "cart.do?action=updateCartNum&pid=" + pid + "&num=" + nums + "&price=" + p,
method: "get",
success: function () {
location.href = "cart.html";
},
error: function () {
alert("服务器异常");
}
})
}
function deleteCartItem(pid) {
if (confirm("确认要删除吗")) {
location.href = "cart.do?action=updateCartNum&pid=" + pid + "&num=0";
}
}
function clearCart(pid) {
if (confirm("确认要删除吗")) {
location.href = "cart.do?action=clearCart&pid=" + pid;
}
}
$(document).ready(function () {
//获取session数据显示到页面
$.get("cart.do?action=showCart", "", function (result) {
if (result.flag === true) {//登录
var sum = 0;//计算总金额变量
var index = 1;
for (var i in result.data) {
var money = result.data[i].quantity * result.data[i].price;
var temp = ' <tr> ' +
' <th>' + index + '</th> ' +
' <th>' + result.data[i].goodName + '</th> ' +
' <th>' + result.data[i].price + '</th> ' +
' <th width="100px"> ' +
' <div class="input-group"> ' +
' <span class="input-group-btn"> ' +
' <button class="btn btn-default" type="button" ' +
' οnclick="mNum(' + result.data[i].goodsId + ',' + result.data[i].price + ',' + index + ')">-</button> ' +
' </span> ' +
' <input type="text" class="form-control" id="num_count' + index + '" value="' + result.data[i].quantity + '" ' +
' readonly="readonly" style="width:40px"> ' +
' <span class="input-group-btn"> ' +
' <button class="btn btn-default" type="button" ' +
' οnclick="pNum(' + result.data[i].goodsId + ',' + result.data[i].price + ',' + index + ')">+</button> ' +
' </span> ' +
' </div> ' +
' </th> ' +
' <th>¥  ' + result.data[i].subtotal + '</th> ' +
' <th> ' +
' <button type="button" class="btn btn-default" οnclick="deleteCartItem(' + result.data[i].goodsId + ')">删除</button> ' +
' </th> ' +
' </tr>';
index++;
sum += result.data[i].subtotal;
$("#cartBody").append(temp)
}
$("#total").html("<b>¥  : " + sum + "</b>")
}
});
});
3.2 后端
3.2 后端
在 CartServlet 类中定义查询所有商品分类内容的主体逻辑
@WebServlet("/cart.do")
public class CartServlet extends BaseServlet {
private ResultData resultData = new ResultData();
//添加商品到购物车
public String addCart(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//接收get传递过来的参数,
String goodsId = req.getParameter("goodsId");
String goodsname = req.getParameter("goodsname");
String price = req.getParameter("price");
Map<String, CartItem> cartItemMap = null;
//先从session中取出
cartItemMap = (Map<String, CartItem>) req.getSession().getAttribute(Constants.CART);
if (cartItemMap == null) {
cartItemMap = new HashMap<>();
}
//之前是有该商品
if (cartItemMap.containsKey(goodsId)) {
CartItem cartItem = cartItemMap.get(goodsId);
//原有数据加1
cartItem.setQuantity(cartItem.getQuantity() + 1);
Double total = cartItem.getQuantity() * cartItem.getPrice();
cartItem.setSubtotal(total);
} else { //没有相同商品
Double v = Double.parseDouble(price);
CartItem newItem = new CartItem(goodsname, v, goodsId, 1, v);
cartItemMap.put(goodsId, newItem);
}
System.err.println(cartItemMap);
System.err.println(cartItemMap.get("1"));
req.getSession().setAttribute(Constants.CART, cartItemMap);
return Constants.REDIRECT + "/cartSuccess.html";
}
//显示商品购物车数到html页面
public String showCart(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//接收get传递过来的参数,
Map<String, CartItem> cartItemMap = (Map<String, CartItem>) req.getSession().getAttribute(Constants.CART);
if (cartItemMap != null) {
resultData.setFlag(true);
resultData.setData(cartItemMap);
} else {
resultData.setFlag(false);
resultData.setErrorMsg("购物车没有数据");
}
String json = JSON.toJSONString(resultData);
System.out.println(json);
resp.setContentType("application/json;charset=utf-8");
return json;
}
//修改购物车商品数量
public String updateCartNum(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//接收get传递过来的参数,
String goodsId = req.getParameter("pid");
String numStr = req.getParameter("num");
Map<String, CartItem> cartItemMap = null;
//先从session中取出
cartItemMap = (Map<String, CartItem>) req.getSession().getAttribute(Constants.CART);
if (cartItemMap != null) {
//之前是有该商品
if (cartItemMap.containsKey(goodsId)) {
CartItem cartItem = cartItemMap.get(goodsId);
//原有数据加1
int num = Integer.parseInt(numStr);
if (num==0){
cartItemMap.remove(goodsId);
}else{
cartItem.setQuantity(num);
Double total = cartItem.getQuantity() * cartItem.getPrice();
cartItem.setSubtotal(total);
resultData.setFlag(true);
}
} else {
resultData.setFlag(false);
}
} else {
resultData.setFlag(false);
}
return null;
}
//清除购物车数据
public String clearCart(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//情况session
req.getSession().removeAttribute(Constants.CART);
return Constants.REDIRECT + "/index.html";
}
}
后端程序执行顺利的话,返回的响应结果可以使用 chrome浏览器的自动 json 解析功能观察到以下效 果。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-22KOXaFd-1652699011549)(D:\鲲鹏培训\项目\仿小米商城\项目编写过程截图\购物车json数据展示.png)]
{
//情况session
req.getSession().removeAttribute(Constants.CART);
return Constants.REDIRECT + “/index.html”;
}
}
后端程序执行顺利的话,返回的响应结果可以使用 chrome浏览器的自动 json 解析功能观察到以下效 果。
![在这里插入图片描述](https://img-blog.csdnimg.cn/54556e492c2b40a58721d79214fea82e.png#pic_center)