当前位置: 首页 > news >正文

【电商项目实战】商品详情显示与Redis存储购物车信息

🎉🎉欢迎来到我的CSDN主页!🎉🎉

🏅我是Java方文山,一个在CSDN分享笔记的博主。📚📚

🌟推荐给大家我的专栏《电商项目实战》。🎯🎯

👉点击这里,就可以查看我的主页啦!👇👇

Java方文山的个人主页

🎁如果感觉还不错的话请给我点赞吧!🎁🎁

💖期待你的加入,一起学习,一起进步!💖💖

请添加图片描述

一、商品详情

当我们点击商品的时候需要展示对应的商品详情,首先在首页商品页写入后端的接口

controller代码

@Controller
@RequestMapping("/goods")
public class GoodsController {@Autowiredprivate IGoodsService goodsService;@RequestMapping("/ByIdSelect")public String ByIdSelect(GoodsVo vo, Model model){Goods g = goodsService.getById(vo.getGid());model.addAttribute("g",g);return "proDetail";}}

 在对应的页面显示相应的数据

<!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">${(g.goodsTitle)!}</a></div></div><!-----------------------Detail------------------------------><div class="detCon"><div class="proDet wrapper"><div class="proCon clearfix"><div class="proImg fl"><img class="det" src="${(g.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>${(g.goodsTitle)!}</h4><p>${(g.goodsName)!}</p><span>¥${(g.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>${(g.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="${(g.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>

效果展示 

二、加入购物车

1.前端方法编写

商品详情页面引入了一个cart.js,里面是有关该所有的点击事件方法

$(function(){/**************数量加减***************/$(".num .sub").click(function(){var num = parseInt($(this).siblings("span").text());if(num<=1){$(this).attr("disabled","disabled");}else{num--;$(this).siblings("span").text(num);//获取除了货币符号以外的数字var price = $(this).parents(".number").prev().text().substring(1);//单价和数量相乘并保留两位小数$(this).parents(".th").find(".sAll").text('¥'+(num*price).toFixed(2));jisuan();zg();}});$(".num .add").click(function(){var num = parseInt($(this).siblings("span").text());if(num>=5){confirm("限购5件");}else{num++;$(this).siblings("span").text(num);var price = $(this).parents(".number").prev().text().substring(1);$(this).parents(".th").find(".sAll").text('¥'+(num*price).toFixed(2));jisuan();zg();}});//计算总价function jisuan(){var all=0;var len =$(".th input[type='checkbox']:checked").length;if(len==0){$("#all").text('¥'+parseFloat(0).toFixed(2));}else{$(".th input[type='checkbox']:checked").each(function(){//获取小计里的数值var sAll = $(this).parents(".pro").siblings('.sAll').text().substring(1);//累加all+=parseFloat(sAll);//赋值$("#all").text('¥'+all.toFixed(2));})}}//计算总共几件商品function zg(){var zsl = 0;var index = $(".th input[type='checkbox']:checked").parents(".th").find(".num span");var len =index.length;if(len==0){$("#sl").text(0);}else{index.each(function(){zsl+=parseInt($(this).text());$("#sl").text(zsl);})}if($("#sl").text()>0){$(".count").css("background","#c10000");}else{$(".count").css("background","#8e8e8e");}}/*****************商品全选***********************/$("input[type='checkbox']").on('click',function(){var sf = $(this).is(":checked");var sc= $(this).hasClass("checkAll");if(sf){if(sc){$("input[type='checkbox']").each(function(){  this.checked=true;  }); zg();jisuan();}else{$(this).checked=true; var len = $("input[type='checkbox']:checked").length;var len1 = $("input").length-1;if(len==len1){$("input[type='checkbox']").each(function(){  this.checked=true;  }); }zg();jisuan();}}else{if(sc){$("input[type='checkbox']").each(function(){  this.checked=false;  }); zg();jisuan();}else{$(this).checked=false;var len = $(".th input[type='checkbox']:checked").length;var len1 = $("input").length-1;if(len<len1){$('.checkAll').attr("checked",false);}zg();jisuan();}}});/****************************proDetail 加入购物车*******************************/$(".btns .cart").click(function(){//获取购物车上的商品IDlet gid=this.dataset.gid;//获取商品数量let num=$("div span.fl").text;//发起请求$.post('/cart/add',{gid},resp=>{},"json")});//删除购物车商品$('.del').click(function(){//单个删除if($(this).parent().parent().hasClass("th")){$(".mask").show();$(".tipDel").show();index = $(this).parents(".th").index()-1;$('.cer').click(function(){$(".mask").hide();$(".tipDel").hide();$(".th").eq(index).remove();$('.cer').off('click');if($(".th").length==0){$(".table .goOn").show();}})}else{//选中多个一起删除if($(".th input[type='checkbox']:checked").length==0){$(".mask").show();$(".pleaseC").show();}else{$(".mask").show();$(".tipDel").show();$('.cer').click(function(){$(".th input[type='checkbox']:checked").each(function(j){index = $(this).parents('.th').index()-1;$(".th").eq(index).remove();if($(".th").length==0){$(".table .goOn").show();}})$(".mask").hide();$(".tipDel").hide();zg();jisuan();})}}})$('.cancel').click(function(){$(".mask").hide();$(".tipDel").hide();})//改变商品规格
//	$(".pro dd").hover(function(){
//		var html='';
//		html='<span class="edit">修改</span>';
//		$(this).addClass("on").append(html).parents(".th").siblings(".th").find(".pro dd").removeClass("on").find('.edit').remove();
//		$(".edit").each(function(i){
//			$(this).attr("id",'edit'+i);
//			$("#edit"+i).click(function(){
//				$(".proDets").show();
//				$(".mask").show();
//				$(".changeBtn .buy").attr("data-id",i);
//			})
//		})
//	},function(){
//		$(this).removeClass("on");
//	})
//	$(".changeBtn .buy").click(function(){
//		var index = $(this).attr("data-id");
//		var result = $(".smallImg .on").find("img").attr("alt");
//		$("#edit"+index).prev().text(result);
//		$(".proDets").hide();
//		$(".mask").hide();
//		$("#edit"+index).parent("dd").removeClass("on").find(".edit").remove();
//	});
//	$(".changeBtn .cart").click(function(){
//		$(".proDets").hide();
//		$(".mask").hide();
//	})
})

2.后端代码编写 

我们的用户购物车数据放在数据库太耗费数据库的资源了,我们可以将数据放入redis,进行一个时限判断,如果一周内没有进行数据访问就加入数据库并清除缓存。

我们需要编写新增和查询Redis中购物车数据方法

IRedisService

    // 保存用户购物车信息void saveCart(User user, GoodsVo vo);// 查询用户购物车信息List<GoodsVo> loadCart(User user);

 IRedisService实现类

    @Overridepublic  List<GoodsVo> loadCart(User user) {HashOperations<String,String,GoodsVo> operations=redisTemplate.opsForHash();String bigKey=Constants.REDIS_CART_PREFIX + user.getId();//根据用户Id查询所有的购物车信息List<GoodsVo> values = operations.values(bigKey);return values;}

controller 

    @RequestMapping("/getCart")public String getCart(GoodsVo vo, HttpServletRequest request, Model model) {//根据键获取tokenString token = CookieUtils.getCookieValue(request, "userToken");//根据token获取用户User user = redisService.loadUser(token);//获取用户购物车商品信息List<GoodsVo> goodsVos = redisService.loadCart(user);//根据商品Id查询对应商品List<Integer> ids = goodsVos.stream().map(GoodsVo::getGid).collect(Collectors.toList());List<Goods> goods = goodsService.listByIds(ids);
//        进行遍历筛选合适的数据for (Goods g : goods) {//找到对应属性的商品GoodsVo gv = goodsVos.stream().filter(v -> Objects.equals(v.getGid(), g.getGid())).findFirst().orElse(null);if (gv != null) {//将该商品g的属性赋值给GoodsVosBeanUtils.copyProperties(g, gv);}}System.out.println(goodsVos);model.addAttribute("item", goodsVos);return "cart";}

因为我们redis中只有商品的id所以需要将所有商品的id拿到数据库中查询,将该商品的图片信息标题等查询出来利用BeanUtils将属性加入到goodsVos中,方便前端页面显示

 

三、优化细节部分

1.购物车显示数据

<!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><#--有数据就显示--><#if item??><#list item as g><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="${(g.goodsImg)!}"></dt><dd class="fl"><p>${(g.goodsName)!}</p><p>颜色分类:</p><p>${(g.goodsType)!}</p></dd></dl></a></div><div class="price">¥${(g.goodsPrice)!}</div><div class="number"><p class="num clearfix"><img class="fl sub" src="img/temp/sub.jpg"><span class="fl">${(g.num)!}</span><img class="fl add" src="img/temp/add.jpg"></p></div><div class="price sAll">¥20.00</div><div class="price"><a class="del" href="#2">删除</a></div></div></#list><#else><div class="goOn">空空如也~<a href="${ctx}/">去逛逛</a></div></#if><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>

这里直接将我们后端所拿到的数据进行判断遍历展示即可

2.退出登录

首先我们不止需要清除浏览器上的cookie还需要清除redis中保存的用户信息,所以在Redis的service层定义一个删除的方法

  // 清除用户数据void logout(String token);

实现类编写相应代码

    @Overridepublic void logout(String token) {//根据token删除对应的键redisTemplate.delete(Constants.REDIS_USER_PREFIX +token);}

 这时候,我们就可以编写退出的controller代码了

   @RequestMapping("/logout")public String  login( HttpServletRequest request, HttpServletResponse response){//清除redis缓存String token = CookieUtils.getCookieValue(request, "userToken");redisService.logout(token);//清除cookieCookieUtils.deleteCookie(request,response,"userToken");CookieUtils.deleteCookie(request,response,"nickname");return "redirect:/";}

清除浏览器cookie的同时也清除redis中的数据避免资源浪费

3.参数解析器 

通过这几天的编写,不知道大家发现没有,我们很多方法中都有获取用户的token信息,可以说这段代码是重复的,我们可以将其优化掉

 UserArgumentResolver 

@Component
public class UserArgumentResolver implements HandlerMethodArgumentResolver {@Autowiredprivate IRedisService redisService;@Overridepublic boolean supportsParameter(MethodParameter parameter) {return parameter.getGenericParameterType()== User.class;}@Overridepublic Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {HttpServletRequest request = (HttpServletRequest) webRequest.getNativeRequest();//从请求中获取cookieString token = CookieUtils.getCookieValue(request, "userToken");User user = redisService.loadUser(token);return user;}
}

这个解析器的作用是判断控制器方法的参数是否为User类型,如果是,则会在处理请求之前执行resolveArgument方法。在resolveArgument方法中,它会通过HttpServletRequest获取请求中的cookie,然后调用redisServiceloadUser方法根据cookie中的token加载对应的用户信息。最后,返回解析得到的User对象作为控制器方法的参数。

这里还需要一个config配置类,用于加载自定义解析器

WebConfig

@Component
public class WebConfig implements WebMvcConfigurer {@Autowiredprivate UserArgumentResolver userArgumentResolver;@Overridepublic void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {resolvers.add(userArgumentResolver);}}

请添加图片描述

到这里我的分享就结束了,欢迎到评论区探讨交流!!

💖如果觉得有用的话还请点个赞吧 💖

相关文章:

【电商项目实战】商品详情显示与Redis存储购物车信息

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的专栏《电商项目实战》。&#x1f3af;&#x1f3af; &am…...

概率论基础

1.概率论 1.1 随机事件与概率 1.1.1 基本概念 ​ 样本点(sample point)&#xff1a; 称为试验 S S S的可能结果为样本点&#xff0c;用 ω \omega ω表示。 ​ 样本空间(sample space)&#xff1a;称试验 S S S的样本点构成的集合为样本空间&#xff0c;用 Ω \Omega Ω表示…...

Mac电脑CMake安装和配置

1.从CMake官网下载dmg文件并且安装 ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/a43f1462b5f743b4ba0bf5302ee76066.png)...

FormData传送复杂数据

FormData 是一个用于创建表单数据对象的 JavaScript 类。它通常用于通过 JavaScript 发送表单数据&#xff0c;尤其是用于发送 AJAX 请求时非常有用。 使用 FormData 可以方便地构建一个以 multipart/form-data 格式提交的表单数据&#xff0c;这允许你在发送 XMLHttpRequest …...

力扣回溯算法-电话号码的字母组合

力扣第17题&#xff0c;电话号码的字母组合 题目 给定一个仅包含数字 2-9 的字符串&#xff0c;返回所有它能表示的字母组合。 给出数字到字母的映射如下&#xff08;与电话按键相同&#xff09;。注意 1 不对应任何字母。 .电话号码的字母组合 示例: 输入&#xff1a;“2…...

运维面试笔试题

目录 shell脚本 nginx 数据库mysql k8s(kubernetes) 安全与防护 网络TCP/IP shell脚本 1 通过正则表达式匹配文本...

Oracle database 静默安装 oracle12c 一键安装 12.1.0.2

基于oracle安装包中应答文件实现一键安装 注意此安装脚本基于12.1.0.2 安装包 原始安装包结构为两个压缩包 此脚本使用安装包为原始压缩包解压后、 重新封装为一个.zip压缩包 建议在linux 环境下解压重新压缩后 使用该脚本 支持环境: Linux :centerOS 7 oracle :12.1.0.…...

【Java EE初阶三 】线程的状态与安全(上)

1. join方法与多线程 1.1 初识多线程 为了提高cpu得利用率&#xff0c;因此就引入了多个线程的概念&#xff1b;即每个线程负责完成整个程序的一部分工作即可。 写一个代码&#xff0c;让主线程&#xff0c;创建一个新的线程&#xff0c;由新线程负责完成运算&#xff08;12。…...

英飞凌TC3xx之一起认识GTM系列(五)如何实现GTM与DSADC关联的配置

英飞凌TC3xx之一起认识GTM系列(五)如何实现GTM与DSADC关联的配置 1 GTM与DSADC的连接1.1 EDSADC 到 GTM 的连接1.1.1 工作原理说明1.1.2 应用举例1.2 GTM 到 EDSADC 的连接1.2.1 工作原理说明1.2.2 应用举例2 总结编者按:笔者在从事这部分开发工作的时候,看着手册上的各种通…...

小兔鲜儿 uniapp - 购物车模块

目录 加入购物车​ 接口相关​ 购物车列表​ 静态结构​ 登录状态​ 列表渲染​ 删除购物车 接口相关​ 参考代码 修改商品信息​ 接口相关​ ​修改商品数量​ 修改商品选中/全选​ 底部结算信息​ 计算总钱数(总金额)​ 带返回按钮的购物车​ 完成加入购物车…...

Python使用PyMySql增删改查Mysql数据库

PyMysql简介 PyMysql是Python中用于连接MySQL数据库的一个第三方库&#xff0c;它实现了MySQL客户端/服务器协议&#xff0c;使得Python程序能够与MySQL服务器进行交互。由于Python 2的mysql-python&#xff08;又称mysqldb&#xff09;模块在Python 3上支持不够完善&#xff0…...

前端实现websocket类封装

随着Web应用程序的发展&#xff0c;越来越多的人开始利用Websocket技术来构建实时应用程序。Websocket是一种在客户端和服务器之间建立持久连接的协议。这种协议可以在一个单独的连接上实现双向通信。与HTTP请求-响应模型不同&#xff0c;Websocket允许服务器自主地向客户端发送…...

鸿蒙开发中的一些小问题

这是我在学习鸿蒙开发中遇见的小问题 Q1&#xff1a;This custom component must have a build function. <etsLint>Q2&#xff1a;page_title is not translated into en_US(American English)Q3&#xff1a;Module "../CustomComponent/CustomButton" declar…...

OpenCV-12绘制图像

OpenCV提供了许多绘制图像的API&#xff0c;可以在图像上绘制各种图形&#xff0c;例如直线&#xff0c;矩形&#xff0c;圆&#xff0c;椭圆等图形。 一、画直线 利用API line&#xff08;img, pt1, pt2, color, thickness, lineType, shift&#xff09;可以绘制直线。 其中…...

“2023年的技术发展与个人成长:回顾与展望“

文章目录 每日一句正能量前言工作生活未来展望后记 每日一句正能量 凡事顺其自然&#xff0c;遇事处于泰然&#xff0c;得意之时淡然&#xff0c;失意之时坦然&#xff0c;艰辛曲折必然&#xff0c;历尽沧桑悟然。 前言 在这快速发展的信息时代&#xff0c;技术的进步和创新不…...

算法逆袭之路(1)

11.29 开始跟进算法题进度! 每天刷4题左右 ,一周之内一定要是统一类型 而且一定稍作总结, 了解他们的内在思路究竟是怎样的!! 12.24 一定要每天早中晚都要复习一下 早中午每段一两道, 而且一定要是同一个类型, 不然刷起来都没有意义 12.26/27&#xff1a; 斐波那契数 爬…...

2023.12.31每日一题

LeetCode每日一题 2023年的最后一题 1154.一年中的第几天 1154. 一年中的第几天 - 力扣&#xff08;LeetCode&#xff09; 描述 给你一个字符串 date &#xff0c;按 YYYY-MM-DD 格式表示一个 现行公元纪年法 日期。返回该日期是当年的第几天。 示例 1&#xff1a; 输入&a…...

Flink实时电商数仓(八)

用户域登录各窗口汇总表 主要任务&#xff1a;从kafka页面日志主题读取数据&#xff0c;统计 七日回流用户&#xff1a;之前活跃的用户&#xff0c;有一段时间不活跃了&#xff0c;之后又开始活跃&#xff0c;称为回流用户当日独立用户数&#xff1a;同一个用户当天重复登录&a…...

Python Pymysql实现数据存储

什么是 PyMySQL&#xff1f; PyMySQL 是在 Python3.x 版本中用于连接 MySQL 服务器的一个库&#xff0c;Python2 中则使用mysqldb。 PyMySQL 遵循 Python 数据库 API v2.0 规范&#xff0c;并包含了 pure-Python MySQL 客户端库。 PyMySQL 安装 在使用 PyMySQL 之前&#xf…...

软件测试/测试开发丨Python 常用第三方库 pymysql

pymysql 概述 Python 的数据库接口标准是 Python DB-APIPyMySQL 是从 Python 连接到 MySQL 数据库服务器的接口PyMySQL 的目标是成为 MySQLdb 的替代品官方文档&#xff1a;pymysql.readthedocs.io/ pymysql 安装 使用 pip 安装使用 Pycharm 界面安装 pip install pymysqlp…...

SkyWalking 10.2.0 SWCK 配置过程

SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外&#xff0c;K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案&#xff0c;全安装在K8S群集中。 具体可参…...

C++初阶-list的底层

目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

JVM垃圾回收机制全解析

Java虚拟机&#xff08;JVM&#xff09;中的垃圾收集器&#xff08;Garbage Collector&#xff0c;简称GC&#xff09;是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象&#xff0c;从而释放内存空间&#xff0c;避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)

引言&#xff1a;为什么 Eureka 依然是存量系统的核心&#xff1f; 尽管 Nacos 等新注册中心崛起&#xff0c;但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制&#xff0c;是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...

css的定位(position)详解:相对定位 绝对定位 固定定位

在 CSS 中&#xff0c;元素的定位通过 position 属性控制&#xff0c;共有 5 种定位模式&#xff1a;static&#xff08;静态定位&#xff09;、relative&#xff08;相对定位&#xff09;、absolute&#xff08;绝对定位&#xff09;、fixed&#xff08;固定定位&#xff09;和…...

GitHub 趋势日报 (2025年06月08日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...

【python异步多线程】异步多线程爬虫代码示例

claude生成的python多线程、异步代码示例&#xff0c;模拟20个网页的爬取&#xff0c;每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程&#xff1a;允许程序同时执行多个任务&#xff0c;提高IO密集型任务&#xff08;如网络请求&#xff09;的效率…...

Java入门学习详细版(一)

大家好&#xff0c;Java 学习是一个系统学习的过程&#xff0c;核心原则就是“理论 实践 坚持”&#xff0c;并且需循序渐进&#xff0c;不可过于着急&#xff0c;本篇文章推出的这份详细入门学习资料将带大家从零基础开始&#xff0c;逐步掌握 Java 的核心概念和编程技能。 …...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码

目录 一、&#x1f468;‍&#x1f393;网站题目 二、✍️网站描述 三、&#x1f4da;网站介绍 四、&#x1f310;网站效果 五、&#x1fa93; 代码实现 &#x1f9f1;HTML 六、&#x1f947; 如何让学习不再盲目 七、&#x1f381;更多干货 一、&#x1f468;‍&#x1f…...

蓝桥杯 冶炼金属

原题目链接 &#x1f527; 冶炼金属转换率推测题解 &#x1f4dc; 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V&#xff0c;是一个正整数&#xff0c;表示每 V V V 个普通金属 O O O 可以冶炼出 …...