SpingBoot的项目实战--模拟电商【3.购物车模块】

news2024/7/4 23:58:22

🥳🥳Welcome Huihui's Code World ! !🥳🥳

接下来看看由辉辉所写的关于SpringBoot电商项目的相关操作吧 

目录

🥳🥳Welcome Huihui's Code World ! !🥳🥳

一.功能需求

二.代码编写

1.商品详情的显示

2.加入购物车

3.参数解析器

4.购物车的前端优化

5.购物车的删除【单个&批量】


一.功能需求

①商品详情的显示(根据id查询单个商品)

②加入购物车(redis+cookie+数据库)

③需要通过用户信息来获取购物车【参数解析器】

④前端的显示【商品数量,小计】

⑤购物车的删除【全选与全不选,单个删除与批量删除】

二.代码编写

1.商品详情的显示

首页的商品点击跳转到商品详情页

<a href="${ctx}/goods/selectOne?gid=${g.gid}">
<!DOCTYPE html>
<html>
<head lang="en">
	<#include "common/head.html">
	<link rel="stylesheet" type="text/css" href="css/public.css"/>
	<link rel="stylesheet" type="text/css" href="css/index.css" />
</head>
<body>
<!------------------------------head------------------------------>
<#include "common/top.html">

<!-------------------------banner--------------------------->
<div class="block_home_slider">
	<div id="home_slider" class="flexslider">
		<ul class="slides">
			<li>
				<div class="slide">
					<img src="img/banner2.jpg"/>
				</div>
			</li>
			<li>
				<div class="slide">
					<img src="img/banner1.jpg"/>
				</div>
			</li>
		</ul>
	</div>
</div>

<!------------------------------thImg------------------------------>
<div class="thImg">
	<div class="clearfix">
		<a href="${ctx}/page/vase_proList.html"><img src="img/i1.jpg"/></a>
		<a href="${ctx}/page/proList.html"><img src="img/i2.jpg"/></a>
		<a href="#2"><img src="img/i3.jpg"/></a>
	</div>
</div>

<!------------------------------news------------------------------>
<div class="news">
	<div class="wrapper">
		<h2><img src="img/ih1.jpg"/></h2>
		<div class="top clearfix">
			<a href="${ctx}/page/proDetail.html"><img src="img/n1.jpg"/><p></p></a>
			<a href="${ctx}/page/proDetail.html"><img src="img/n2.jpg"/><p></p></a>
			<a href="${ctx}/page/proDetail.html"><img src="img/n3.jpg"/><p></p></a>
		</div>
		<div class="bott clearfix">
			<a href="${ctx}/page/proDetail.html"><img src="img/n4.jpg"/><p></p></a>
			<a href="${ctx}/page/proDetail.html"><img src="img/n5.jpg"/><p></p></a>
			<a href="${ctx}/page/proDetail.html"><img src="img/n6.jpg"/><p></p></a>
		</div>
		<h2><img src="img/ih2.jpg"/></h2>
	<#list p1 as p>
		<div class="flower clearfix tran">
			<#list p as g>
			<a href="${ctx}/goods/selectOne?gid=${g.gid}"  class="clearfix">
				<dl>
					<dt>
						<span class="abl"></span>
						<img src="${g.goodsImg}"/>
						<span class="abr"></span>
					</dt>
					<dd>${g.goodsTitle}</dd>
					<dd><span>¥${g.goodsPrice}</span></dd>
				</dl>
			</a>
		</#list>
		</div>
		</#list>

	</div>
</div>

<!------------------------------ad------------------------------>
<a href="#" class="ad"><img src="img/ib1.jpg"/></a>

<!------------------------------people------------------------------>
<div class="people">
	<div class="wrapper">
		<h2><img src="img/ih3.jpg"/></h2>
		<#list p2 as p>
		<div class="pList clearfix tran">
				<#list p as g>
			<a href="${ctx}/goods/selectOne?gid=${g.gid}">
					<dl>
						<dt>
							<span class="abl"></span>
							<img src="${g.goodsImg}"/>
							<span class="abr"></span>
						</dt>
						<dd>${g.goodsTitle}</dd>
						<dd><span>¥${g.goodsPrice}</span></dd>
					</dl>
				</a>
			</#list>
		</div>
	</#list>
		</div>

	</div>
</div>

<#include "common/footer.html"/>

<script src="js/public.js" type="text/javascript" charset="utf-8"></script>
<script src="js/nav.js" type="text/javascript" charset="utf-8"></script>
<script src="js/jquery.flexslider-min.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
	$(function() {
		$('#home_slider').flexslider({
			animation: 'slide',
			controlNav: true,
			directionNav: true,
			animationLoop: true,
			slideshow: true,
			slideshowSpeed:2000,
			useCSS: false
		});

	});
</script>
</body>
</html>

效果预览

2.加入购物车

前端

<a href="javascript:void(0);"><p class="cart fr" data-gid="${(good.gid)!}">加入购物车</p></a>

完整代码

<!DOCTYPE html>
<html>
	<head>
		<#include "common/head.html">
		<link rel="stylesheet" type="text/css" href="css/public.css"/>
		<link rel="stylesheet" type="text/css" href="css/proList.css"/>
	</head>
	<body>
		<!------------------------------head------------------------------>
		<#include "common/top.html">
		<!-----------------address------------------------------->
		<div class="address">
			<div class="wrapper clearfix">
				<a href="${ctx}/">首页</a>
				<span>/</span>
				<a href="${ctx}/page/flowerDer.html">装饰摆件</a>
				<span>/</span>
				<a href="${ctx}/page/proList.html">干花花艺</a>
				<span>/</span>
				<#--
				注意:
				1)${goods.goodsTitle!}:只能判断goodsTitle属性是否为空,不能判断goods对象是否为空
				2)${(goods.goodsTitle)!}:既可以判断goods对象是否为空,也可以判断goodsTitle属性是否为空
				-->
				<a href="#" class="on">${(good.goodsTitle)!}</a>
			</div>
		</div>
		<!-----------------------Detail------------------------------>
		<div class="detCon">
			<div class="proDet wrapper">
				<div class="proCon clearfix">
					<div class="proImg fl">
						<img class="det" src="${(good.goodsImg)!}" />
						<#--<div class="smallImg clearfix">]
							<img src="img/temp/proDet01.jpg" data-src="img/temp/proDet01_big.jpg">
							<img src="img/temp/proDet02.jpg" data-src="img/temp/proDet02_big.jpg">
							<img src="img/temp/proDet03.jpg" data-src="img/temp/proDet03_big.jpg">
							<img src="img/temp/proDet04.jpg" data-src="img/temp/proDet04_big.jpg">
						</div>-->
					</div>
					<div class="fr intro">
						<div class="title">
							<h4>${(good.goodsName)!}</h4>
							<p>${(good.goodsDetail)!}</p>
							<span>¥${(good.goodsPrice)!}</span>
						</div>
						<div class="proIntro">
							<p>颜色分类</p>
							<div class="smallImg clearfix categ">
								<p class="fl"><img src="img/temp/prosmall01.jpg" alt="白瓷花瓶+20支快乐花" data-src="img/temp/proBig01.jpg"></p>
								<p class="fl"><img src="img/temp/prosmall02.jpg" alt="白瓷花瓶+20支兔尾巴草" data-src="img/temp/proBig02.jpg"></p>
								<p class="fl"><img src="img/temp/prosmall03.jpg" alt="20支快乐花" data-src="img/temp/proBig03.jpg"></p>
								<p class="fl"><img src="img/temp/prosmall04.jpg" alt="20支兔尾巴草" data-src="img/temp/proBig04.jpg"></p>
							</div>
							<p>数量&nbsp;&nbsp;库存<span>${(good.goodsStock)!}</span>件</p>
							<div class="num clearfix">
								<img class="fl sub" src="img/temp/sub.jpg">
								<span class="fl" contentEditable="true">1</span>
								<img class="fl add" src="img/temp/add.jpg">
								<p class="please fl">请选择商品属性!</p>
							</div>
						</div>
						<div class="btns clearfix">
							<a href="#2"><p class="buy fl">立即购买</p></a>
							<a href="javascript:void(0);"><p class="cart fr" data-gid="${(good.gid)!}">加入购物车</p></a>
						</div>
					</div>
				</div>
			</div>
		</div>
		<div class="introMsg wrapper clearfix">
			<div class="msgL fl">
				<div class="msgTit clearfix">
					<a class="on">商品详情</a>
					<a>所有评价</a>
				</div>
				<div class="msgAll">
					<div class="msgImgs">
						<img src="img/temp/det01.jpg">
						<img src="img/temp/det02.jpg">
						<img src="img/temp/det03.jpg">
						<img src="img/temp/det04.jpg">
						<img src="img/temp/det05.jpg">
						<img src="img/temp/det06.jpg">
						<img src="img/temp/det07.jpg">
					</div>
					<div class="eva">
						<div class="per clearfix">
							<img class="fl" src="img/temp/per01.jpg">
							<div class="perR fl">
								<p>馨***呀</p>
								<p>不好意思评价晚了,产品很好,价格比玻璃品便宜,没有我担心的杂色,发货快,包装好,全5分</p>
								<div class="clearfix">
									<p><img src="img/temp/eva01.jpg"></p>
									<p><img src="img/temp/eva02.jpg"></p>
									<p><img src="img/temp/eva03.jpg"></p>
									<p><img src="img/temp/eva04.jpg"></p>
									<p><img src="img/temp/eva05.jpg"></p>
								</div>
								<p><span>2016年12月27日08:31</span><span>颜色分类:大中小三件套(不含花)</span></p>
							</div>
						</div>
						<div class="per clearfix">
							<img class="fl" src="img/temp/per02.jpg">
							<div class="perR fl">
								<p>么***周</p>
								<p>花瓶超级棒,我看图以为是光面的,收货发现是磨砂,但感觉也超有质感,很喜欢。磨砂上面还有点纹路,不过觉得挺自然的,不影响美观。包装也很好,绝对不会磕碎碰坏,好评!</p>
								<p><span>2016年12月27日08:31</span><span>颜色分类:大中小三件套(不含花)</span></p>
							</div>
						</div>
						<div class="per clearfix">
							<img class="fl" src="img/temp/per01.jpg">
							<div class="perR fl">
								<p>馨***呀</p>
								<p>不好意思评价晚了,产品很好,价格比玻璃品便宜,没有我担心的杂色,发货快,包装好,全5分</p>
								<div class="clearfix">
									<p><img src="img/temp/eva01.jpg"></p>
									<p><img src="img/temp/eva02.jpg"></p>
									<p><img src="img/temp/eva03.jpg"></p>
									<p><img src="img/temp/eva04.jpg"></p>
									<p><img src="img/temp/eva05.jpg"></p>
								</div>
								<p><span>2016年12月27日08:31</span><span>颜色分类:大中小三件套(不含花)</span></p>
							</div>
						</div>
						<div class="per clearfix">
							<img class="fl" src="img/temp/per02.jpg">
							<div class="perR fl">
								<p>么***周</p>
								<p>花瓶超级棒,我看图以为是光面的,收货发现是磨砂,但感觉也超有质感,很喜欢。磨砂上面还有点纹路,不过觉得挺自然的,不影响美观。包装也很好,绝对不会磕碎碰坏,好评!</p>
								<p><span>2016年12月27日08:31</span><span>颜色分类:大中小三件套(不含花)</span></p>
							</div>
						</div>
						<div class="per clearfix">
							<img class="fl" src="img/temp/per01.jpg">
							<div class="perR fl">
								<p>馨***呀</p>
								<p>不好意思评价晚了,产品很好,价格比玻璃品便宜,没有我担心的杂色,发货快,包装好,全5分</p>
								<div class="clearfix">
									<p><img src="img/temp/eva01.jpg"></p>
									<p><img src="img/temp/eva02.jpg"></p>
									<p><img src="img/temp/eva03.jpg"></p>
									<p><img src="img/temp/eva04.jpg"></p>
									<p><img src="img/temp/eva05.jpg"></p>
								</div>
								<p><span>2016年12月27日08:31</span><span>颜色分类:大中小三件套(不含花)</span></p>
							</div>
						</div>
						<div class="per clearfix">
							<img class="fl" src="img/temp/per02.jpg">
							<div class="perR fl">
								<p>么***周</p>
								<p>花瓶超级棒,我看图以为是光面的,收货发现是磨砂,但感觉也超有质感,很喜欢。磨砂上面还有点纹路,不过觉得挺自然的,不影响美观。包装也很好,绝对不会磕碎碰坏,好评!</p>
								<p><span>2016年12月27日08:31</span><span>颜色分类:大中小三件套(不含花)</span></p>
							</div>
						</div>
						<div class="per clearfix">
							<img class="fl" src="img/temp/per01.jpg">
							<div class="perR fl">
								<p>馨***呀</p>
								<p>不好意思评价晚了,产品很好,价格比玻璃品便宜,没有我担心的杂色,发货快,包装好,全5分</p>
								<div class="clearfix">
									<p><img src="img/temp/eva01.jpg"></p>
									<p><img src="img/temp/eva02.jpg"></p>
									<p><img src="img/temp/eva03.jpg"></p>
									<p><img src="img/temp/eva04.jpg"></p>
									<p><img src="img/temp/eva05.jpg"></p>
								</div>
								<p><span>2016年12月27日08:31</span><span>颜色分类:大中小三件套(不含花)</span></p>
							</div>
						</div>
						<div class="per clearfix">
							<img class="fl" src="img/temp/per02.jpg">
							<div class="perR fl">
								<p>么***周</p>
								<p>花瓶超级棒,我看图以为是光面的,收货发现是磨砂,但感觉也超有质感,很喜欢。磨砂上面还有点纹路,不过觉得挺自然的,不影响美观。包装也很好,绝对不会磕碎碰坏,好评!</p>
								<p><span>2016年12月27日08:31</span><span>颜色分类:大中小三件套(不含花)</span></p>
							</div>
						</div>
						<div class="per clearfix">
							<img class="fl" src="img/temp/per01.jpg">
							<div class="perR fl">
								<p>馨***呀</p>
								<p>不好意思评价晚了,产品很好,价格比玻璃品便宜,没有我担心的杂色,发货快,包装好,全5分</p>
								<div class="clearfix">
									<p><img src="img/temp/eva01.jpg"></p>
									<p><img src="img/temp/eva02.jpg"></p>
									<p><img src="img/temp/eva03.jpg"></p>
									<p><img src="img/temp/eva04.jpg"></p>
									<p><img src="img/temp/eva05.jpg"></p>
								</div>
								<p><span>2016年12月27日08:31</span><span>颜色分类:大中小三件套(不含花)</span></p>
							</div>
						</div>
						<div class="per clearfix">
							<img class="fl" src="img/temp/per02.jpg">
							<div class="perR fl">
								<p>么***周</p>
								<p>花瓶超级棒,我看图以为是光面的,收货发现是磨砂,但感觉也超有质感,很喜欢。磨砂上面还有点纹路,不过觉得挺自然的,不影响美观。包装也很好,绝对不会磕碎碰坏,好评!</p>
								<p><span>2016年12月27日08:31</span><span>颜色分类:大中小三件套(不含花)</span></p>
							</div>
						</div>
					</div>
				</div>
			</div>
			<div class="msgR fr">
				<h4>为你推荐</h4>
				<div class="seeList">
					<a href="#">
						<dl>
							<dt><img src="img/temp/see01.jpg"></dt>
							<dd>【最家】复古文艺风玻璃花瓶</dd>
							<dd>¥193.20</dd>
						</dl>
					</a>
					<a href="#">
						<dl>
							<dt><img src="img/temp/see02.jpg"></dt>
							<dd>【最家】复古文艺风玻璃花瓶</dd>
							<dd>¥193.20</dd>
						</dl>
					</a>
					<a href="#">
						<dl>
							<dt><img src="img/temp/see03.jpg"></dt>
							<dd>【最家】复古文艺风玻璃花瓶</dd>
							<dd>¥193.20</dd>
						</dl>
					</a>
					<a href="#">
						<dl>
							<dt><img src="img/temp/see04.jpg"></dt>
							<dd>【最家】复古文艺风玻璃花瓶</dd>
							<dd>¥193.20</dd>
						</dl>
					</a>
				</div>
				
			</div>
		</div>
		<div class="like">
			<h4>猜你喜欢</h4>
			<div class="bottom">
				<div class="hd">
					<span class="prev"><img src="img/temp/prev.png"></span>
					<span class="next"><img src="img/temp/next.png"></span>
				</div>
				<div class="imgCon bd">
					<div class="likeList clearfix">
						<div>
							<a href="${ctx}/page/proDetail.html">
								<dl>
									<dt><img src="img/temp/like01.jpg"></dt>
									<dd>【最家】复古文艺风玻璃花瓶</dd>
									<dd>¥193.20</dd>
								</dl>
							</a>
							<a href="${ctx}/page/proDetail.html">
								<dl>
									<dt><img src="img/temp/like02.jpg"></dt>
									<dd>【最家】复古文艺风玻璃花瓶</dd>
									<dd>¥193.20</dd>
								</dl>
							</a>
							<a href="${ctx}/page/proDetail.html">
								<dl>
									<dt><img src="img/temp/like03.jpg"></dt>
									<dd>【最家】复古文艺风玻璃花瓶</dd>
									<dd>¥193.20</dd>
								</dl>
							</a>
							<a href="${ctx}/page/proDetail.html">
								<dl>
									<dt><img src="img/temp/like04.jpg"></dt>
									<dd>【最家】复古文艺风玻璃花瓶</dd>
									<dd>¥193.20</dd>
								</dl>
							</a>
							<a href="${ctx}/page/proDetail.html" class="last">
								<dl>
									<dt><img src="img/temp/like05.jpg"></dt>
									<dd>【最家】复古文艺风玻璃花瓶</dd>
									<dd>¥193.20</dd>
								</dl>
							</a>
						</div>
						<div>
							<a href="${ctx}/page/proDetail.html">
								<dl>
									<dt><img src="img/temp/like01.jpg"></dt>
									<dd>【最家】复古文艺风玻璃花瓶</dd>
									<dd>¥193.20</dd>
								</dl>
							</a>
							<a href="${ctx}/page/proDetail.html">
								<dl>
									<dt><img src="img/temp/like02.jpg"></dt>
									<dd>【最家】复古文艺风玻璃花瓶</dd>
									<dd>¥193.20</dd>
								</dl>
							</a>
							<a href="${ctx}/page/proDetail.html">
								<dl>
									<dt><img src="img/temp/like03.jpg"></dt>
									<dd>【最家】复古文艺风玻璃花瓶</dd>
									<dd>¥193.20</dd>
								</dl>
							</a>
							<a href="${ctx}/page/proDetail.html">
								<dl>
									<dt><img src="img/temp/like04.jpg"></dt>
									<dd>【最家】复古文艺风玻璃花瓶</dd>
									<dd>¥193.20</dd>
								</dl>
							</a>
							<a href="${ctx}/page/proDetail.html" class="last">
								<dl>
									<dt><img src="img/temp/like05.jpg"></dt>
									<dd>【最家】复古文艺风玻璃花瓶</dd>
									<dd>¥193.20</dd>
								</dl>
							</a>
						</div>
					</div>
				</div>
			</div>
		</div>
		<!--返回顶部-->
		<#include "common/footer.html">
		<script src="js/jquery.SuperSlide.2.1.1.js" type="text/javascript" charset="utf-8"></script>
		<script src="js/public.js" type="text/javascript" charset="utf-8"></script>
		<script src="js/nav.js" type="text/javascript" charset="utf-8"></script>
		<script src="js/pro.js" type="text/javascript" charset="utf-8"></script>
		<script src="js/cart.js" type="text/javascript" charset="utf-8"></script>
		<script type="text/javascript">
			jQuery(".bottom").slide({titCell:".hd ul",mainCell:".bd .likeList",autoPage:true,autoPlay:false,effect:"leftLoop",autoPlay:true,vis:1});
		</script>
	</body>
</html>

效果预览

js

/****************************proDetail 加入购物车*******************************/
	$(".btns .cart").click(function(){
		//获得需要添加到购物车中的商品id
		let gid=this.dataset.gid
		//获得添加的商品的数量
		let num=$("div.num span.fl").text()
		//ajax请求
		$.post('/cart/add',{gid,num},resp=>{
		if(resp.code===200){
			alert("添加成功")
		}
		},'json')
	});

service

package com.wh.easyshop.service;


import com.wh.easyshop.model.User;
import com.wh.easyshop.vo.CartVo;

import java.util.List;

public interface IRedisService {

    /**
     * 将购物车对象保存到Redis中
     */
    void saveCart(User user, CartVo cartVo);

}

将购物车数据加到redis时,需要注意使用的类型,我把购物车的数据放到redis中的使用的是hash的数据类型,

因为购物车的数据是来自于多个用户的,这样的话肯定需要用一个标识去标识出特定的用户的数据

,其次用户的购物车数据肯定也是多条的,这样也需要用一个特殊的字段去拿到特定的购物车信息

【键:{键:值}】➡【用户标识:{商品id:商品信息}】,hash的数据类型就很符合这样的存储格式,【特别适合于存储具有多个成员的结构体或对象

serviceimpl

package com.wh.easyshop.service;

import com.wh.easyshop.model.User;
import com.wh.easyshop.util.Constants;
import com.wh.easyshop.vo.CartVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
public class RedisServiceImpl implements IRedisService {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 将购物车数据存入缓存中
     * @param user
     * @param cartVo
     */
    @Override
    public void saveCart(User user, CartVo cartVo) {
        //获取操Redi中hash类型数据对象--通过其将购物车存入到缓存中
        HashOperations<String, String , CartVo> rediscart = redisTemplate.opsForHash();
        //大键【hash的键】
        String hashKey=Constants.REDIS_CART_PREFIX + user.getId();
        //小键【hash中键值对的键】--存入的商品id
        String ValueKey=cartVo.getGid().toString();
        //判断购物车中是否有这个【大键+小键】--去拿到键对应的购物车中的商品
        Boolean hascart = rediscart.hasKey(hashKey, ValueKey);
        if(hascart){
            //edit【购物车中有这个商品】
            //拿到键对应的购物车中的商品
            CartVo cart= rediscart.get(hashKey, ValueKey);
            cart.setNum(cart.getNum()+cartVo.getNum());
        }
        //add【购物车中没有这个商品】
        //往缓存中加入数据
        rediscart.put(hashKey,ValueKey,cartVo);
    }

}

controller

package com.wh.easyshop.controller;

import com.wh.easyshop.model.Goods;
import com.wh.easyshop.model.User;
import com.wh.easyshop.resp.JsonResponseBody;
import com.wh.easyshop.service.IGoodsService;
import com.wh.easyshop.service.IRedisService;
import com.wh.easyshop.util.CookieUtils;
import com.wh.easyshop.vo.CartVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.jws.WebParam;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 购物车 前端控制器
 * </p>
 *
 * @author wh
 * @since 2024-1-2
 */
@Controller
@RequestMapping("/cart")
public class CartController {
    @Autowired
    IRedisService redisService;
    @Autowired
    IGoodsService goodsService;

    @RequestMapping("/add")
    @ResponseBody
    public JsonResponseBody<?> addCart(CartVo cartVo, HttpServletRequest request) {
        //拿到cookie中的用户令牌
        String userToken = CookieUtils.getCookieValue(request, "UserToken");
        //通过令牌拿到用户对象
        User userByToken = redisService.getUserByToken(userToken);
        //将当前登录用户的购物车信息保存到redis中
        redisService.saveCart(userByToken,cartVo);
        return JsonResponseBody.success() ;
    }


}

把购物车的数据加到redis中时,我只加了商品的id以及商品的数量,又因为goods这个实体类中没有商品数量的这个字段,所以建了一个vo类

vo

package com.wh.easyshop.vo;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;

import java.io.Serializable;
import java.math.BigDecimal;

/**
 * @author是辉辉啦
 * @create 2024-01-02-15:14
 */
@Data
public class CartVo  implements Serializable {
    /**
     * 商品ID
     */
    private Long gid;

    /**
     * 商品数量
     */
    private  Integer num;
}

如果把其他的数据字段都加入到redis中的话,会降低效率,所以后面还需要从数据库中拿一次数据显示到购物车的页面。

service

package com.wh.easyshop.service;


import com.wh.easyshop.model.User;
import com.wh.easyshop.vo.CartVo;

import java.util.List;

public interface IRedisService {


    /**
     * 根据大键【user:用户的id】拿出redis中的购物车对象
     * @param user
     * @return
     */
    List<CartVo> loadCart(User user);

}

serviceimpl

package com.wh.easyshop.controller;

import com.wh.easyshop.model.Goods;
import com.wh.easyshop.model.User;
import com.wh.easyshop.resp.JsonResponseBody;
import com.wh.easyshop.service.IGoodsService;
import com.wh.easyshop.service.IRedisService;
import com.wh.easyshop.util.CookieUtils;
import com.wh.easyshop.vo.CartVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.jws.WebParam;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 购物车 前端控制器
 * </p>
 *
 * @author wh
 * @since 2024-1-2
 */
@Controller
@RequestMapping("/cart")
public class CartController {
    @Autowired
    IRedisService redisService;
    @Autowired
    IGoodsService goodsService;

    @RequestMapping("/toCart")
    public String index (HttpServletRequest request, Model model) {
        //拿到cookie中的用户令牌
        String userToken = CookieUtils.getCookieValue(request, "UserToken");
        //通过令牌拿到用户对象
        User userByToken = redisService.getUserByToken(userToken);
        //拿出对应用户的购物车中的所有的商品
        List<CartVo> cartVos = redisService.loadCart(userByToken);
        //拿出所有的购物车中的商id--集合
        List<Long> ids = cartVos.stream().map(CartVo::getGid).collect(Collectors.toList());
        //根据这个id集合查询所有对应的商品
        List<Goods> goods = goodsService.listByIds(ids);
        //遍历集合 赋值给对应的对象
        for (Goods g : goods) {
            //找到对应id相同的元素
            CartVo vo = cartVos.stream()
                    .filter(v -> Objects.equals(v.getGid(), g.getGid()))
                    .findFirst()
                    .get();
            //将商品g的属性赋值给vo【这样vo中的属性就有数据了】
            BeanUtils.copyProperties(g,vo);
        }
        model.addAttribute("cart",cartVos);
        return "cart";
    }


}

controller

package com.wh.easyshop.controller;

import com.wh.easyshop.model.Goods;
import com.wh.easyshop.model.User;
import com.wh.easyshop.resp.JsonResponseBody;
import com.wh.easyshop.service.IGoodsService;
import com.wh.easyshop.service.IRedisService;
import com.wh.easyshop.util.CookieUtils;
import com.wh.easyshop.vo.CartVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.jws.WebParam;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 购物车 前端控制器
 * </p>
 *
 * @author wh
 * @since 2024-1-2
 */
@Controller
@RequestMapping("/cart")
public class CartController {
    @Autowired
    IRedisService redisService;
    @Autowired
    IGoodsService goodsService;

    @RequestMapping("/toCart")
    public String index (HttpServletRequest request, Model model) {
        //拿到cookie中的用户令牌
        String userToken = CookieUtils.getCookieValue(request, "UserToken");
        //通过令牌拿到用户对象
        User userByToken = redisService.getUserByToken(userToken);
        //拿出对应用户的购物车中的所有的商品
        List<CartVo> cartVos = redisService.loadCart(userByToken);
        //拿出所有的购物车中的商id--集合
        List<Long> ids = cartVos.stream().map(CartVo::getGid).collect(Collectors.toList());
        //根据这个id集合查询所有对应的商品
        List<Goods> goods = goodsService.listByIds(ids);
        //遍历集合 赋值给对应的对象
        for (Goods g : goods) {
            //找到对应id相同的元素
            CartVo vo = cartVos.stream()
                    .filter(v -> Objects.equals(v.getGid(), g.getGid()))
                    .findFirst()
                    .get();
            //将商品g的属性赋值给vo【这样vo中的属性就有数据了】
            BeanUtils.copyProperties(g,vo);
        }
        model.addAttribute("cart",cartVos);
        return "cart";
    }


}

在购物车页面显示相应数据

这里还需要在首页的地方将跳转购物车页面的路径连接写好

 <a href="${ctx}/cart/toCart"><img src="img/gwc.png"/></a>
<script type="text/javascript" src="js/jquery-1.12.4.min.js"></script>
<script>
    $(function(){
        let nickname=getCookie("nickname");
        if(null!=nickname&&''!=nickname&&undefined!=nickname) {
            //设置昵称
            $('#nickname').text("您好,"+nickname);
            //隐藏登录注册按钮
            $('p.fl>span:eq(1)').css("display","none");
            //显示昵称和退出按钮
            $('p.fl>span:eq(0)').css("display","block");
        }else{
            //隐藏昵称
            $('#nickname').text("");
            //显示登录注册按钮
            $('p.fl>span:eq(1)').css("display","block");
            //隐藏昵称和退出按钮
            $('p.fl>span:eq(0)').css("display","none");
        }
    });

    function getCookie(cname) {
        var name = cname + "=";
        var decodedCookie = decodeURIComponent(document.cookie);
        var ca = decodedCookie.split(';');
        for(var i = 0; i <ca.length; i++) {
            var c = ca[i];
            while (c.charAt(0) == ' ') {
                c = c.substring(1);
            }
            if (c.indexOf(name) == 0) {
                return c.substring(name.length, c.length);
            }
        }
        return "";
    }
</script>
<div class="head">
    <div class="wrapper clearfix">
        <div class="clearfix" id="top">
            <h1 class="fl"><a href="${ctx}/"><img src="img/logo.png"/></a></h1>
            <div class="fr clearfix" id="top1">
                <p class="fl">
                    <span>
                        <span id="nickname"></span>
                        <a href="${ctx}/user/userLogout">退出</a>
                    </span>
                    <span style="display: none">
                        <a href="${ctx}/page/login.html" id="login">登录</a>
                        <a href="${ctx}/page/reg.html" id="reg">注册</a>
                    </span>
                </p>
                <form action="#" method="get" class="fl">
                    <input type="text" placeholder="热门搜索:干花花瓶" />
                    <input type="button" />
                </form>
                <div class="btn fl clearfix">
                    <a href="${ctx}/page/mygxin.html"><img src="img/grzx.png"/></a>
                    <a href="#" class="er1"><img src="img/ewm.png"/></a>
                    <a href="${ctx}/cart/toCart"><img src="img/gwc.png"/></a>
                    <p><a href="#"><img src="img/smewm.png"/></a></p>
                </div>
            </div>
        </div>
        <ul class="clearfix" id="bott">
            <li><a href="${ctx}/">首页</a></li>
            <li>
                <a href="#">所有商品</a>
                <div class="sList">
                    <div class="wrapper  clearfix">
                        <a href="${ctx}/page/paint.html">
                            <dl>
                                <dt><img src="img/nav1.jpg"/></dt>
                                <dd>浓情欧式</dd>
                            </dl>
                        </a>
                        <a href="${ctx}/page/paint.html">
                            <dl>
                                <dt><img src="img/nav2.jpg"/></dt>
                                <dd>浪漫美式</dd>
                            </dl>
                        </a>
                        <a href="${ctx}/page/paint.html">
                            <dl>
                                <dt><img src="img/nav3.jpg"/></dt>
                                <dd>雅致中式</dd>
                            </dl>
                        </a>
                        <a href="${ctx}/page/paint.html">
                            <dl>
                                <dt><img src="img/nav6.jpg"/></dt>
                                <dd>简约现代</dd>
                            </dl>
                        </a>
                        <a href="${ctx}/page/paint.html">
                            <dl>
                                <dt><img src="img/nav7.jpg"/></dt>
                                <dd>创意装饰</dd>
                            </dl>
                        </a>
                    </div>
                </div>
            </li>
            <li>
                <a href="${ctx}/page/flowerDer.html">装饰摆件</a>
                <div class="sList2">
                    <div class="clearfix">
                        <a href="${ctx}/page/proList.html">干花花艺</a>
                        <a href="${ctx}/page/vase_proList.html">花瓶花器</a>
                    </div>
                </div>
            </li>
            <li>
                <a href="${ctx}/page/decoration.html">布艺软饰</a>
                <div class="sList2">
                    <div class="clearfix">
                        <a href="${ctx}/page/zbproList.html">桌布罩件</a>
                        <a href="${ctx}/page/bzproList.html">抱枕靠垫</a>
                    </div>
                </div>
            </li>
            <li><a href="${ctx}/page/paint.html">墙式壁挂</a></li>
            <li><a href="${ctx}/page/perfume.html">蜡艺香薰</a></li>
            <li><a href="${ctx}/page/idea.html">创意家居</a></li>
        </ul>
    </div>
</div>

然后就是显示购物车的内容

<!DOCTYPE html>
<html>
	<head lang="en">
		<#include "common/head.html">
		<link rel="stylesheet" type="text/css" href="css/public.css"/>
		<link rel="stylesheet" type="text/css" href="css/proList.css" />
	</head>
	<body>
		<!--------------------------------------cart--------------------->
		<div class="head ding">
			<div class="wrapper clearfix">
				<div class="clearfix" id="top">
					<h1 class="fl"><a href="${ctx}/"><img src="img/logo.png"/></a></h1>
					<div class="fr clearfix" id="top1">
						<form action="#" method="get" class="fl">
							<input type="text" placeholder="搜索" />
							<input type="button" />
						</form>
					</div>
				</div>
			</div>
		</div>
		<div class="cart mt">
			<!-----------------logo------------------->
			<!--<div class="logo">
				<h1 class="wrapper clearfix">
					<a href="${ctx}/"><img class="fl" src="img/temp/logo.png"></a>
					<img class="top" src="img/temp/cartTop01.png">
				</h1>
			</div>-->
			<!-----------------site------------------->
			<div class="site">
				<p class=" wrapper clearfix">
					<span class="fl">购物车</span>
					<img class="top" src="img/temp/cartTop01.png">
					<a href="${ctx}/" class="fr">继续购物&gt;</a>
				</p>
			</div>
			<!-----------------table------------------->
			<div class="table wrapper">
				<div class="tr">
					<div>商品</div>
					<div>单价</div>
					<div>数量</div>
					<div>小计</div>
					<div>操作</div>
				</div>
				<#list cart as c >
				<div class="th">
					<div class="pro clearfix">
						<label class="fl">
							<input type="checkbox"/>
							<span></span>
						</label>
						<a class="fl" href="#">
							<dl class="clearfix">
								<dt class="fl"><img src="${(c.goodsImg)!}" style="width: 120px; height: 120px;"></dt>
								<dd class="fl">
									<p >${(c.goodsTitle)!}</p>
								</dd>
							</dl>
						</a>
					</div>
					<div class="price" style="margin-left:100px;">${(c.goodsPrice)!}</div>
					<div class="number">
						<p class="num clearfix">
							<img class="fl sub" src="img/temp/sub.jpg">
							<span class="fl">1</span>
							<img class="fl add" src="img/temp/add.jpg">
						</p>
					</div>
					<div class="price sAll" style="margin-left:80px;">¥20.00</div>
					<div class="price"><a class="del" href="#2"  style="margin-left:40px;">删除</a></div>
				</div>
				</#list>
				<div class="goOn">空空如也~<a href="${ctx}/">去逛逛</a></div>
				<div class="tr clearfix">
					<label class="fl">
						<input class="checkAll" type="checkbox"/>
						<span></span>
					</label>
					<p class="fl">
						<a href="javascript:void(0);">全选</a>
						<a href="javascript:void(0);" class="del">删除</a>
					</p>
					<p class="fr">
						<span>共<small id="sl">0</small>件商品</span>
						<span>合计:&nbsp;<small id="all">¥0.00</small></span>
						<a class="count">结算</a>
					</p>
				</div>
			</div>
		</div>
		<div class="mask"></div>
		<div class="tipDel">
			<p>确定要删除该商品吗?</p>
			<p class="clearfix">
				<a class="fl cer" href="javascript:void(0);">确定</a>
				<a class="fr cancel" href="javascript:void(0);">取消</a>
			</p>
		</div>
		<!--返回顶部-->
		<#include "common/footer.html">
		<!----------------mask------------------->
		<div class="mask"></div>
		<!-------------------mask内容------------------->
		<div class="proDets">
			<img class="off" src="img/temp/off.jpg" />
			<div class="proCon clearfix">
				<div class="proImg fr">
					<img class="list" src="img/temp/proDet.jpg"  />
					<div class="smallImg clearfix">
						<img src="img/temp/proDet01.jpg" data-src="img/temp/proDet01_big.jpg">
						<img src="img/temp/proDet02.jpg" data-src="img/temp/proDet02_big.jpg">
						<img src="img/temp/proDet03.jpg" data-src="img/temp/proDet03_big.jpg">
						<img src="img/temp/proDet04.jpg" data-src="img/temp/proDet04_big.jpg">
					</div>
				</div>
				<div class="fl">
					<div class="proIntro change">
						<p>颜色分类</p>
						<div class="smallImg clearfix">
							<p class="fl on"><img src="img/temp/prosmall01.jpg" alt="白瓷花瓶+20支快乐花" data-src="img/temp/proBig01.jpg"></p>
							<p class="fl"><img src="img/temp/prosmall02.jpg" alt="白瓷花瓶+20支兔尾巴草" data-src="img/temp/proBig02.jpg"></p>
							<p class="fl"><img src="img/temp/prosmall03.jpg" alt="20支快乐花" data-src="img/temp/proBig03.jpg"></p>
							<p class="fl"><img src="img/temp/prosmall04.jpg" alt="20支兔尾巴草" data-src="img/temp/proBig04.jpg"></p>
						</div>
					</div>
					<div class="changeBtn clearfix">
						<a href="#2" class="fl"><p class="buy">确认</p></a>
						<a href="#2" class="fr"><p class="cart">取消</p></a>
					</div>
				</div>
			</div>
		</div>
		<div class="pleaseC">
			<p>请选择宝贝</p>
			<img class="off" src="img/temp/off.jpg" />
		</div>
		<script src="js/public.js" type="text/javascript" charset="utf-8"></script>
		<script src="js/pro.js" type="text/javascript" charset="utf-8"></script>
		<script src="js/cart.js" type="text/javascript" charset="utf-8"></script>
	</body>
</html>

3.参数解析器

先说明一下参数解析器说发挥的作用

参数解析器:它的主要作用是处理请求中的参数,无论是获取Cookie中的值,Header中的值,JSON参数解析器的主要作用是处理请求中的参数,无论是获取Cookie中的值,Header中的值,JSON格式的数据,URI中的值,还是请求体中的数据,都可以通过相应的参数解析器来提取。

其中我们的代码中,是将用户的数据放到了redis以及cookie中,用户的数据又需要再很多的地方获取到【购物车,订单...】,所以我们可以专门写一个user的参数解析器

package com.wh.easyshop.util;

import com.wh.easyshop.model.User;
import com.wh.easyshop.service.IRedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import javax.servlet.http.HttpServletRequest;

/**
 * 用户参数解析器,用于从请求中获取User对象
 */
@Component
public class UserArgumentResolver implements HandlerMethodArgumentResolver {

    @Autowired
    private IRedisService redisService;

    /**
     * 判断是否支持该类型的参数解析
     * @param parameter 方法参数
     * @return 如果支持返回true,否则返回false
     */
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.getParameterType() == User.class;
    }

    /**
     * 解析请求中的参数,并返回User对象
     * @param parameter 方法参数
     * @param mavContainer ModelAndView容器
     * @param webRequest NativeWebRequest对象
     * @param binderFactory WebDataBinderFactory对象
     * @return User对象
     * @throws Exception 解析过程中可能出现的异常
     */
    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        HttpServletRequest request = (HttpServletRequest) webRequest.getNativeRequest();
        // 从cookie中获得userToken
        String token = CookieUtils.getCookieValue(request, "UserToken");
        // 使用Redis服务加载User对象
        User user = redisService.getUserByToken(token);
        return user;
    }
}

为了让参数解析器生效,我们还需要一个配置类

package com.wh.easyshop.util;
import com.wh.easyshop.util.UserArgumentResolver;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.List;

/**
 * WebConfig类,用于配置Spring MVC的参数解析器
 */
@Component
public class WebConfig implements WebMvcConfigurer {

    // 注入UserArgumentResolver实例
    @Autowired
    private UserArgumentResolver userArgumentResolver;

    /**
     * 重写addArgumentResolvers方法,将UserArgumentResolver添加到参数解析器列表中
     * @param resolvers 参数解析器列表
     */
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
        resolvers.add(userArgumentResolver);
    }

}

现在就可以使用参数解析器了

package com.wh.easyshop.controller;

import com.wh.easyshop.model.Goods;
import com.wh.easyshop.model.User;
import com.wh.easyshop.resp.JsonResponseBody;
import com.wh.easyshop.service.IGoodsService;
import com.wh.easyshop.service.IRedisService;
import com.wh.easyshop.util.CookieUtils;
import com.wh.easyshop.vo.CartVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.jws.WebParam;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 购物车 前端控制器
 * </p>
 *
 * @author wh
 * @since 2024-1-2
 */
@Controller
@RequestMapping("/cart")
public class CartController {
    @Autowired
    IRedisService redisService;
    @Autowired
    IGoodsService goodsService;

    @RequestMapping("/toCart")
    public String index (User user,HttpServletRequest request, Model model) {
        List<CartVo> cartVos = redisService.loadCart(user);//使用参数解析器
        //拿出所有的购物车中的商id--集合
        List<Long> ids = cartVos.stream().map(CartVo::getGid).collect(Collectors.toList());
        //根据这个id集合查询所有对应的商品
        List<Goods> goods = goodsService.listByIds(ids);
        //遍历集合 赋值给对应的对象
        for (Goods g : goods) {
            //找到对应id相同的元素
            CartVo vo = cartVos.stream()
                    .filter(v -> Objects.equals(v.getGid(), g.getGid()))
                    .findFirst()
                    .get();
            //将商品g的属性赋值给vo【这样vo中的属性就有数据了】
            BeanUtils.copyProperties(g,vo);
        }
        model.addAttribute("cart",cartVos);
        return "cart";
    }


}

4.购物车的前端优化

其中的小计和总计都还没有计算显示出来以及商品数量的加减,这里就把它优化一下

html

<!DOCTYPE html>
<html>
	<head lang="en">
		<#include "common/head.html">
		<link rel="stylesheet" type="text/css" href="css/public.css"/>
		<link rel="stylesheet" type="text/css" href="css/proList.css" />
	</head>
	<body>
		<!--------------------------------------cart--------------------->
		<div class="head ding">
			<div class="wrapper clearfix">
				<div class="clearfix" id="top">
					<h1 class="fl"><a href="${ctx}/"><img src="img/logo.png"/></a></h1>
					<div class="fr clearfix" id="top1">
						<form action="#" method="get" class="fl">
							<input type="text" placeholder="搜索" />
							<input type="button" />
						</form>
					</div>
				</div>
			</div>
		</div>
		<div class="cart mt">
			<!-----------------logo------------------->
			<!--<div class="logo">
				<h1 class="wrapper clearfix">
					<a href="${ctx}/"><img class="fl" src="img/temp/logo.png"></a>
					<img class="top" src="img/temp/cartTop01.png">
				</h1>
			</div>-->
			<!-----------------site------------------->
			<div class="site">
				<p class=" wrapper clearfix">
					<span class="fl">购物车</span>
					<img class="top" src="img/temp/cartTop01.png">
					<a href="${ctx}/" class="fr">继续购物&gt;</a>
				</p>
			</div>
			<!-----------------table------------------->
			<div class="table wrapper">
				<div class="tr">
					<div>商品</div>
					<div>单价</div>
					<div>数量</div>
					<div>小计</div>
					<div>操作</div>
				</div>
				<#list cart as c >
				<div class="th">
					<div class="pro clearfix">
						<label class="fl">
							<input type="checkbox" class="cartCheckBox"/>
							<span></span>
						</label>
						<a class="fl" href="#">
							<dl class="clearfix">
								<dt class="fl"><img src="${(c.goodsImg)!}" style="width: 100px; height: 100px;"></dt>
								<dd class="fl">
									<p >${(c.goodsTitle)!}</p>
								</dd>
							</dl>
						</a>
					</div>
					<div class="price myprice" style="">${(c.goodsPrice)!}</div>
					<div class="number">
						<p class="num clearfix">
							<img class="fl sub"  src="img/temp/sub.jpg">
							<span class="fl mynum" data-gid="${c.gid}">${c.num}</span>
							<img class="fl add"  src="img/temp/add.jpg">
						</p>
					</div>
					<div class="price sAll" >¥${(c.xj())!}</div>
					<div class="price"><a class="del"  data-gid="${c.gid}" >删除</a></div>
				</div>
				</#list>
				<div class="goOn">空空如也~<a href="${ctx}/">去逛逛</a></div>
				<div class="tr clearfix">
					<label class="fl">
						<input class="checkAll" type="checkbox"/>
						<span></span>
					</label>
					<p class="fl">
						<a href="javascript:void(0);">全选</a>
						<a  class="del" >删除</a>
					</p>
					<p class="fr">
						<span>共<small id="sl">0</small>件商品</span>
						<span>合计:&nbsp;<small id="all">¥0.00</small></span>
						<a class="count">结算</a>
					</p>
				</div>
			</div>
		</div>
		<div class="mask"></div>
		<div class="tipDel">
			<p>确定要删除该商品吗?</p>
			<p class="clearfix">
				<a class="fl cer" href="javascript:void(0);">确定</a>
				<a class="fr cancel" href="javascript:void(0);">取消</a>
			</p>
		</div>
		<!--返回顶部-->
		<#include "common/footer.html">
		<!----------------mask------------------->
		<div class="mask"></div>
		<!-------------------mask内容------------------->
		<div class="proDets">
			<img class="off" src="img/temp/off.jpg" />
			<div class="proCon clearfix">
				<div class="proImg fr">
					<img class="list" src="img/temp/proDet.jpg"  />
					<div class="smallImg clearfix">
						<img src="img/temp/proDet01.jpg" data-src="img/temp/proDet01_big.jpg">
						<img src="img/temp/proDet02.jpg" data-src="img/temp/proDet02_big.jpg">
						<img src="img/temp/proDet03.jpg" data-src="img/temp/proDet03_big.jpg">
						<img src="img/temp/proDet04.jpg" data-src="img/temp/proDet04_big.jpg">
					</div>
				</div>
				<div class="fl">
					<div class="proIntro change">
						<p>颜色分类</p>
						<div class="smallImg clearfix">
							<p class="fl on"><img src="img/temp/prosmall01.jpg" alt="白瓷花瓶+20支快乐花" data-src="img/temp/proBig01.jpg"></p>
							<p class="fl"><img src="img/temp/prosmall02.jpg" alt="白瓷花瓶+20支兔尾巴草" data-src="img/temp/proBig02.jpg"></p>
							<p class="fl"><img src="img/temp/prosmall03.jpg" alt="20支快乐花" data-src="img/temp/proBig03.jpg"></p>
							<p class="fl"><img src="img/temp/prosmall04.jpg" alt="20支兔尾巴草" data-src="img/temp/proBig04.jpg"></p>
						</div>
					</div>
					<div class="changeBtn clearfix">
						<a href="#2" class="fl"><p class="buy">确认</p></a>
						<a href="#2" class="fr"><p class="cart">取消</p></a>
					</div>
				</div>
			</div>
		</div>
		<div class="pleaseC">
			<p>请选择宝贝</p>
			<img class="off" src="img/temp/off.jpg" />
		</div>
		<script src="js/public.js" type="text/javascript" charset="utf-8"></script>
		<script src="js/pro.js" type="text/javascript" charset="utf-8"></script>
		<script src="js/cart.js" type="text/javascript" charset="utf-8"></script>
	</body>
</html>

js

$(function(){


	//计算总价&计算小计
	function jisuan(){
		//小计和总价他们都放在一个大的盒子(th)
		//所以去拿到这个大和盒子,遍历得到每个的价格和数量=>小计和总价
		let total=0;//计算总价
		$(".th").each((i,el)=>{
			//获得价格
			let price=$(el).find(".myprice").text().replace("¥","")
			//获得价格
			let count=$(el).find(".mynum").text()*1
			//计算小计
			$(el).find(".sAll").text("¥"+price*count)
			//子复选框--选中状态
			let flag =$(el).find('input[type=checkbox]').prop('checked')
			//如果元素被选择了
			if(flag){
				total+=price*count
			}
		})
		//把计算出来的总价给到相应的元素
		$("#all").text("¥"+total);
	}
	
	/**************数量加减***************/
	$(".num .sub").click(function () {
		update(this,-1)
	});

	$(".num .add").click(function () {
		update(this,1)
	});

	/**
	 * 更新购物车中指定商品的数量
	 * @param ele
	 * @param count
	 */
	function update(ele,count){
		//存放数量的元素【mynum是自己定义的】
		let el = $(ele).parent().find(".mynum")
		//拿到原来的内容
		let num = el.text()*1
		//加上变化的数量
		num+=count;
		//判断是否是正确数量
		if(num<=0) return
		//将数量改变到页面上去
		el.text(num)
		//获得数量
		let gid = el.attr('data-gid')
		//访问后端
		$.post('/cart/edit',{gid,num},resp=>{
			if(resp.code===200)
			jisuan()
		})
	}
})

更新数量的control后端处理

service

package com.wh.easyshop.service;


import com.wh.easyshop.model.User;
import com.wh.easyshop.vo.CartVo;

import java.util.List;

public interface IRedisService {

   

    /**
     * 修改购物车
     * @param user
     * @param cartVo
     */
    void editCart(CartVo cartVo,User user);


    void delCart(List<String> ids, User user);
}
package com.wh.easyshop.service;

import com.wh.easyshop.model.User;
import com.wh.easyshop.util.Constants;
import com.wh.easyshop.vo.CartVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
public class RedisServiceImpl implements IRedisService {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;


    @Override
    public void editCart(CartVo cartVo,User user) {

        //获取操Redi中hash类型数据对象--通过其将购物车存入到缓存中
        HashOperations<String, String , CartVo> rediscart = redisTemplate.opsForHash();
        //大键【hash的键】
        String hashKey=Constants.REDIS_CART_PREFIX + user.getId();
        //小键【hash中键值对的键】--存入的商品id
        String ValueKey=cartVo.getGid().toString();
        //往缓存中加入数据(覆盖原来的数据)
        rediscart.put(hashKey,ValueKey,cartVo);
    }

   

}

controller

package com.wh.easyshop.controller;

import com.wh.easyshop.model.Goods;
import com.wh.easyshop.model.User;
import com.wh.easyshop.resp.JsonResponseBody;
import com.wh.easyshop.service.IGoodsService;
import com.wh.easyshop.service.IRedisService;
import com.wh.easyshop.util.CookieUtils;
import com.wh.easyshop.vo.CartVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.jws.WebParam;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 购物车 前端控制器
 * </p>
 *
 * @author wh
 * @since 2024-1-2
 */
@Controller
@RequestMapping("/cart")
public class CartController {
    @Autowired
    IRedisService redisService;
    @Autowired
    IGoodsService goodsService;


    @RequestMapping("/edit")
    @ResponseBody
    public JsonResponseBody<?> editCart(CartVo cartVo,User user) {
        //修改用户的购物车信息
        redisService.editCart(cartVo,user);
        return JsonResponseBody.success() ;
    }

}

以上代码中都写有注释,而且逻辑也比较清晰,在这里就没有做过多的解析了

5.购物车的删除【单个&批量】

html

<!DOCTYPE html>
<html>
	<head lang="en">
		<#include "common/head.html">
		<link rel="stylesheet" type="text/css" href="css/public.css"/>
		<link rel="stylesheet" type="text/css" href="css/proList.css" />
	</head>
	<body>
		<!--------------------------------------cart--------------------->
		<div class="head ding">
			<div class="wrapper clearfix">
				<div class="clearfix" id="top">
					<h1 class="fl"><a href="${ctx}/"><img src="img/logo.png"/></a></h1>
					<div class="fr clearfix" id="top1">
						<form action="#" method="get" class="fl">
							<input type="text" placeholder="搜索" />
							<input type="button" />
						</form>
					</div>
				</div>
			</div>
		</div>
		<div class="cart mt">
			<!-----------------logo------------------->
			<!--<div class="logo">
				<h1 class="wrapper clearfix">
					<a href="${ctx}/"><img class="fl" src="img/temp/logo.png"></a>
					<img class="top" src="img/temp/cartTop01.png">
				</h1>
			</div>-->
			<!-----------------site------------------->
			<div class="site">
				<p class=" wrapper clearfix">
					<span class="fl">购物车</span>
					<img class="top" src="img/temp/cartTop01.png">
					<a href="${ctx}/" class="fr">继续购物&gt;</a>
				</p>
			</div>
			<!-----------------table------------------->
			<div class="table wrapper">
				<div class="tr">
					<div>商品</div>
					<div>单价</div>
					<div>数量</div>
					<div>小计</div>
					<div>操作</div>
				</div>
				<#list cart as c >
				<div class="th">
					<div class="pro clearfix">
						<label class="fl">
							<input type="checkbox" class="cartCheckBox"/>
							<span></span>
						</label>
						<a class="fl" href="#">
							<dl class="clearfix">
								<dt class="fl"><img src="${(c.goodsImg)!}" style="width: 100px; height: 100px;"></dt>
								<dd class="fl">
									<p >${(c.goodsTitle)!}</p>
								</dd>
							</dl>
						</a>
					</div>
					<div class="price myprice" style="">${(c.goodsPrice)!}</div>
					<div class="number">
						<p class="num clearfix">
							<img class="fl sub"  src="img/temp/sub.jpg">
							<span class="fl mynum" data-gid="${c.gid}">${c.num}</span>
							<img class="fl add"  src="img/temp/add.jpg">
						</p>
					</div>
					<div class="price sAll" >¥${(c.xj())!}</div>
					<div class="price"><a class="del"  data-gid="${c.gid}" >删除</a></div>
				</div>
				</#list>
				<div class="goOn">空空如也~<a href="${ctx}/">去逛逛</a></div>
				<div class="tr clearfix">
					<label class="fl">
						<input class="checkAll" type="checkbox"/>
						<span></span>
					</label>
					<p class="fl">
						<a href="javascript:void(0);">全选</a>
						<a  class="del" >删除</a>
					</p>
					<p class="fr">
						<span>共<small id="sl">0</small>件商品</span>
						<span>合计:&nbsp;<small id="all">¥0.00</small></span>
						<a class="count">结算</a>
					</p>
				</div>
			</div>
		</div>
		<div class="mask"></div>
		<div class="tipDel">
			<p>确定要删除该商品吗?</p>
			<p class="clearfix">
				<a class="fl cer" href="javascript:void(0);">确定</a>
				<a class="fr cancel" href="javascript:void(0);">取消</a>
			</p>
		</div>
		<!--返回顶部-->
		<#include "common/footer.html">
		<!----------------mask------------------->
		<div class="mask"></div>
		<!-------------------mask内容------------------->
		<div class="proDets">
			<img class="off" src="img/temp/off.jpg" />
			<div class="proCon clearfix">
				<div class="proImg fr">
					<img class="list" src="img/temp/proDet.jpg"  />
					<div class="smallImg clearfix">
						<img src="img/temp/proDet01.jpg" data-src="img/temp/proDet01_big.jpg">
						<img src="img/temp/proDet02.jpg" data-src="img/temp/proDet02_big.jpg">
						<img src="img/temp/proDet03.jpg" data-src="img/temp/proDet03_big.jpg">
						<img src="img/temp/proDet04.jpg" data-src="img/temp/proDet04_big.jpg">
					</div>
				</div>
				<div class="fl">
					<div class="proIntro change">
						<p>颜色分类</p>
						<div class="smallImg clearfix">
							<p class="fl on"><img src="img/temp/prosmall01.jpg" alt="白瓷花瓶+20支快乐花" data-src="img/temp/proBig01.jpg"></p>
							<p class="fl"><img src="img/temp/prosmall02.jpg" alt="白瓷花瓶+20支兔尾巴草" data-src="img/temp/proBig02.jpg"></p>
							<p class="fl"><img src="img/temp/prosmall03.jpg" alt="20支快乐花" data-src="img/temp/proBig03.jpg"></p>
							<p class="fl"><img src="img/temp/prosmall04.jpg" alt="20支兔尾巴草" data-src="img/temp/proBig04.jpg"></p>
						</div>
					</div>
					<div class="changeBtn clearfix">
						<a href="#2" class="fl"><p class="buy">确认</p></a>
						<a href="#2" class="fr"><p class="cart">取消</p></a>
					</div>
				</div>
			</div>
		</div>
		<div class="pleaseC">
			<p>请选择宝贝</p>
			<img class="off" src="img/temp/off.jpg" />
		</div>
		<script src="js/public.js" type="text/javascript" charset="utf-8"></script>
		<script src="js/pro.js" type="text/javascript" charset="utf-8"></script>
		<script src="js/cart.js" type="text/javascript" charset="utf-8"></script>
	</body>
</html>

js

$(function(){


	
	/*****************商品全选--全选框***********************/
	$(".checkAll").on('click',function(){
			//当全选框被选中时,其他的子复选框也要被选中
			$(".cartCheckBox").prop("checked", $(".checkAll").prop("checked"));
		jisuan()
		});
	/*****************商品全选--子复选框***********************/
			//给子复选框添加点击事件
		$(".cartCheckBox").on('click',function() {
			// console.log($(".other").length)
			//如果被选中的子复选框的长度等于所有的已有的子复选框的长度
			if ($(".cartCheckBox:checked").length === $(".cartCheckBox").length) {
				//就把全选框设置为选中状态
				$(".checkAll").prop("checked", true);
			} else {
				//否则就把全选框设置为未选中状态
				$(".checkAll").prop("checked", false);
			}
			jisuan()
		})




	//删除购物车商品
	$('.del').click(function() {

		//获取id
		let gid=$(this).attr('data-gid')
		//用一个容器来存放所有的商品id
		let ids=[]
		//如果带了id过来就是删除单个,没有带的话就是批量删除
		if(gid){
		ids.push(gid)
		}else{
			$(".th").each((i,el)=>{
				//子复选框--选中状态
				let flag =$(el).find('input[type=checkbox]').prop('checked')
				//如果元素被选择了
				if(flag){
					let id=$(el).find('.mynum').attr('data-gid')
					ids.push(id)
				}
			})
		}
		if(ids.length>0){
			$.post('/cart/del',{ids},resp=>{
				if(resp.code===200){
					alert("删除成功")
				}
			},'json')
		}

	})
	
	
})

service

package com.wh.easyshop.service;


import com.wh.easyshop.model.User;
import com.wh.easyshop.vo.CartVo;

import java.util.List;

public interface IRedisService {

 

    void delCart(List<String> ids, User user);
}
package com.wh.easyshop.service;

import com.wh.easyshop.model.User;
import com.wh.easyshop.util.Constants;
import com.wh.easyshop.vo.CartVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
public class RedisServiceImpl implements IRedisService {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

  

    /**
     * 删除购物车
     * @param ids
     * @param user
     */
    @Override
    public void delCart(List<String> ids, User user) {
        //获取操Redi中hash类型数据对象--通过其将购物车存入到缓存中
        HashOperations<String, String , CartVo> rediscart = redisTemplate.opsForHash();
        //大键【hash的键】
        String hashKey=Constants.REDIS_CART_PREFIX + user.getId();
        for (String id : ids) {
            rediscart.delete(hashKey,id);
        }
    }

}

controller

package com.wh.easyshop.controller;

import com.wh.easyshop.model.Goods;
import com.wh.easyshop.model.User;
import com.wh.easyshop.resp.JsonResponseBody;
import com.wh.easyshop.service.IGoodsService;
import com.wh.easyshop.service.IRedisService;
import com.wh.easyshop.util.CookieUtils;
import com.wh.easyshop.vo.CartVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.jws.WebParam;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 购物车 前端控制器
 * </p>
 *
 * @author wh
 * @since 2024-1-2
 */
@Controller
@RequestMapping("/cart")
public class CartController {
    @Autowired
    IRedisService redisService;
    @Autowired
    IGoodsService goodsService;



    @RequestMapping("/del")
    @ResponseBody
    public JsonResponseBody<?> delCart(@RequestParam("ids[]") List<String> ids, User user) {
        //删除用户的购物车信息
        redisService.delCart(ids,user);
        return JsonResponseBody.success() ;
    }


}

其中删除的时候,从前端带过来的数据格式是作用的👇

但是后端接受的数据是这样的,数据之间不一致,就会出现错误

为了成功的接受的前端的数据,我们可以使用一个注解

@RequestParam("ids[]")

@RequestParam("ids[]")

        是一个Java注解,用于将请求参数绑定到方法的参数上。在这个例子中,它指示控制器方法需要从请求参数中获取名为"ids[]"的值并将其绑定到一个List类型的方法参数上。

        具体来说,当你在URL或表单中发送一个请求时,你可以通过在请求中包含名为"ids[]"的参数来传递一个ID列表。@RequestParam("ids[]")告诉Spring框架去查找这个参数,并将其值绑定到方法参数上。这样,在方法内部,你就可以像使用普通的Java List一样使用这个参数了。

        需要注意的是,注解中的参数名称应该和请求参数的名称一致,这样Spring才能正确地将参数值绑定到方法参数上

好啦,今天的分享就到这了,希望能够帮到你呢!😊😊  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1352476.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

国内的数据安全与隐私保护现状如何?

在过去的几年中&#xff0c;中国已经采取了一系列的措施来应对数据安全和隐私保护的挑战。 法律法规 中国已经出台了一系列的法律法规来保护数据安全和隐私。例如&#xff0c;《中华人民共和国数据安全法》和《中华人民共和国个人信息保护法》等法律已经在2021年颁布施行。此外…

在pbootcms中制作静态化的TAG标签列表

如果你使用pbootcms来管理你的网站&#xff0c;你可能会遇到这样的需求&#xff1a;将TAG标签列表改成静态化的类似于栏目结构的需求。下面是实现这个需求的步骤。 步骤1 修改PHP文件 打开 apps/home/controller/ParserController.php 并找到大约在1852行左右的代码段&#x…

数据库02-06 形式化

01. 03. 04. 05. 06. 07. 08. 09.

网页爬虫对于网络安全有哪些影响?

在当今信息爆炸的时代&#xff0c;网络已经成为人们获取信息、交流思想和开展业务的重要平台。然而&#xff0c;随着网络的普及和技术的不断发展&#xff0c;网络安全问题也日益凸显&#xff0c;其中网页爬虫对网络安全的影响不容忽视。本文将就网页爬虫对网络安全的影响进行深…

odoo模型钩子函数,启动odoo执行自定义代码

在odoo的models模型基类中定义了这样一个方法_register_hook, 从方法的备注(表单注册以后执行的代码)可以看出这个方法的作用, 所以当我们想在odoo启动以后执行一些代码 比如队列监听等等事情的时候,就可以利用这个方法执行我们的代码 示例: class ModelName(models.Model):…

《动手学深度学习》学习笔记 第7章 现代卷积神经网络

本系列为《动手学深度学习》学习笔记 书籍链接&#xff1a;动手学深度学习 笔记是从第四章开始&#xff0c;前面三章为基础知识&#xff0c;有需要的可以自己去看看 关于本系列笔记&#xff1a; 书里为了让读者更好的理解&#xff0c;有大篇幅的描述性的文字&#xff0c;内容很…

用PHP搭建一个绘画API

【腾讯云AI绘画】用PHP搭建一个绘画API 大家好&#xff01;今天我要给大家推荐的是如何用PHP搭建一个绘画API&#xff0c;让你的网站或应用瞬间拥有强大的绘画能力&#xff01;无论你是想要让用户在网页上绘制自己的创意&#xff0c;还是想要实现自动绘画生成特效&#xff0c;这…

关于简单的数据可视化

1. 安装数据可视化必要的openpyxl、pandas&#xff0c;matplotlib等软件包 使用清华源&#xff0c;命令如下&#xff1a; pip install -i https://pypi.tuna.tsinghua.edu.cn/simple --trusted-host pypi.tuna.tsinghua.edu.cn pandaspip install -i https://pypi.tuna.tsingh…

【ROS2】MOMO的鱼香ROS2(五)ROS2入门篇——ROS2接口与自定义

ROS2接口与自定义 引言1 ROS2自带接口1.1 ROS2通用标准消息包1.2 ROS2传感器消息包1.3 ROS2几何相关消息包 2 ROS2接口介绍2.1 常用CLI命令2.2 原始数据类型与包装类型 3 自定义接口示例3.1 接口定义3.2 自定义接口RCLPY 引言 笔者跟着鱼香ROS的ROS2学习之旅 学习参考&#xf…

微同城生活源码系统:专业搭建本地生活服务平台 附带完整的安装部署教程

随着移动互联网的普及&#xff0c;人们越来越依赖手机进行日常生活中的各种活动&#xff0c;包括购物、餐饮、娱乐等。而传统的本地生活服务平台往往存在着功能单一、用户体验差等问题&#xff0c;无法满足用户日益增长的需求。因此&#xff0c;开发一款功能强大、易用性强的本…

CDGA,CDGP,CDMP有啥区别?考哪个好?

&#x1f3af;CDMP数据管理专业认证是由DAMA国际于2004推出&#xff0c;是一项涵盖学历教育、工作经验和专业知识考试在内的综合资格认证&#xff0c;也是目前全球为一数据管理方面权威性认证。 ✅CDGA&#xff1a;数据治理工程师&#xff0c;“DAMA中国”组织的数据治理方面的…

利用Ubuntu 20.04(WSL2)+ DevEco Device Tools搭建鸿蒙设备开发环境

小白一个&#xff0c;因为项目原因需要用到小熊派BearPi Nano做开发&#xff0c;决定使用WSL2上的Ubuntu 20.04进行开发环境的搭建&#xff0c;记录一下搭建的流程&#xff0c;过程难免有疏漏&#xff0c;望谅解。 过程中参考了随遇而安的dandelion 大佬的这一篇文章&#xff1…

【MPC学习笔记】01:MPC简介(Lecture 1_1 Unconstrained MPC)

本笔记来自北航诸兵老师的课程 课程地址&#xff1a;模型预测控制&#xff08;2022春&#xff09;lecture 1-1 Unconstrained MPC 文章目录 0 MPC 简介0.1 案例引入0.2 系统模型0.3 MPC的优点0.4 MPC的缺点0.5 MPC的未来 1 详细介绍 0 MPC 简介 0.1 案例引入 MPC&#xff08;…

MySQL--安装与配置与向日葵的基本操作使用

一.MySQL介绍 1.1 MySQL简介 MySQL是一个开源的关系型数据库管理系统&#xff0c;最早由瑞典MySQL AB公司开发。这个数据库系统有着高可靠性、高性能和易用性的特点&#xff0c;在互联网上得到了广泛的应用。MySQL支持SQL语言&#xff0c;可以运行在多种操作系统上&#xff0c…

数据结构【图篇】

数据结构【图篇】 文章目录 数据结构【图篇】前言为什么突然想学算法了&#xff1f;为什么选择码蹄集作为刷题软件&#xff1f; 目录一、图(一)、图的存储(二)、图的基本操作(三)、最短路径问题 二、拓扑排序三、结语 前言 为什么突然想学算法了&#xff1f; > 用较为“官方…

Java中100==100为true,而1000==1000为false?

前言 今天跟大家聊一个有趣的话题&#xff0c;在Java中两个Integer对象做比较时&#xff0c;会产生意想不到的结果。 例如&#xff1a; Integer a 100; Integer b 100; System.out.println(ab);其运行结果是&#xff1a;true。 而如果改成下面这样&#xff1a; Integer …

八大算法排序@堆排序(C语言版本)

目录 堆排序大堆排序概念算法思想建堆建堆核心算法建堆的代码 排序代码实现 小堆排序代码实现时间复杂度空间复杂度 堆排序 堆排序借用的是堆的特性来实现排序功能的。大堆需要满足父节点大于子节点&#xff0c;因此堆顶是整个数组中的最大元素。小堆则相反&#xff0c;要求父节…

在Android设备上设置和使用隧道代理HTTP

随着互联网的深入发展&#xff0c;网络信息的传递已经成为人们日常生活中不可或缺的一部分。对于我们中国人来说&#xff0c;由于某些特殊的原因&#xff0c;访问国外网站时常常会遇到限制。为了解决这个问题&#xff0c;使用代理服务器成为了许多人的选择。而在Android设备上设…

WPD小波包理解

WPD是分析信号特性和提供具有时频局部化函数的正交小波基的有效工具&#xff0c;同时也是一种小波分解&#xff0c;它可以将原始信号分解成若干子层。小波分解实现了单侧分解&#xff0c;但它只分离频率的低通分量。相比之下&#xff0c;WPD提供了更精确的信号分析&#xff0c;…

40道java集合面试题含答案(很全)

1. 什么是集合 集合就是一个放数据的容器&#xff0c;准确的说是放数据对象引用的容器集合类存放的都是对象的引用&#xff0c;而不是对象的本身集合类型主要有3种&#xff1a;set(集&#xff09;、list(列表&#xff09;和map(映射)。 2. 集合的特点 集合的特点主要有如下两…