当前位置: 首页 > 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…...

简易版抽奖活动的设计技术方案

1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...

STM32标准库-DMA直接存储器存取

文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA&#xff08;Direct Memory Access&#xff09;直接存储器存取 DMA可以提供外设…...

如何将联系人从 iPhone 转移到 Android

从 iPhone 换到 Android 手机时&#xff0c;你可能需要保留重要的数据&#xff0c;例如通讯录。好在&#xff0c;将通讯录从 iPhone 转移到 Android 手机非常简单&#xff0c;你可以从本文中学习 6 种可靠的方法&#xff0c;确保随时保持连接&#xff0c;不错过任何信息。 第 1…...

3403. 从盒子中找出字典序最大的字符串 I

3403. 从盒子中找出字典序最大的字符串 I 题目链接&#xff1a;3403. 从盒子中找出字典序最大的字符串 I 代码如下&#xff1a; class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...

MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)

macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 &#x1f37a; 最新版brew安装慢到怀疑人生&#xff1f;别怕&#xff0c;教你轻松起飞&#xff01; 最近Homebrew更新至最新版&#xff0c;每次执行 brew 命令时都会自动从官方地址 https://formulae.…...

人工智能--安全大模型训练计划:基于Fine-tuning + LLM Agent

安全大模型训练计划&#xff1a;基于Fine-tuning LLM Agent 1. 构建高质量安全数据集 目标&#xff1a;为安全大模型创建高质量、去偏、符合伦理的训练数据集&#xff0c;涵盖安全相关任务&#xff08;如有害内容检测、隐私保护、道德推理等&#xff09;。 1.1 数据收集 描…...

LangChain 中的文档加载器(Loader)与文本切分器(Splitter)详解《二》

&#x1f9e0; LangChain 中 TextSplitter 的使用详解&#xff1a;从基础到进阶&#xff08;附代码&#xff09; 一、前言 在处理大规模文本数据时&#xff0c;特别是在构建知识库或进行大模型训练与推理时&#xff0c;文本切分&#xff08;Text Splitting&#xff09; 是一个…...

大数据治理的常见方式

大数据治理的常见方式 大数据治理是确保数据质量、安全性和可用性的系统性方法&#xff0c;以下是几种常见的治理方式&#xff1a; 1. 数据质量管理 核心方法&#xff1a; 数据校验&#xff1a;建立数据校验规则&#xff08;格式、范围、一致性等&#xff09;数据清洗&…...

轻量级Docker管理工具Docker Switchboard

简介 什么是 Docker Switchboard &#xff1f; Docker Switchboard 是一个轻量级的 Web 应用程序&#xff0c;用于管理 Docker 容器。它提供了一个干净、用户友好的界面来启动、停止和监控主机上运行的容器&#xff0c;使其成为本地开发、家庭实验室或小型服务器设置的理想选择…...

MeshGPT 笔记

[2311.15475] MeshGPT: Generating Triangle Meshes with Decoder-Only Transformers https://library.scholarcy.com/try 真正意义上的AI生成三维模型MESHGPT来袭&#xff01;_哔哩哔哩_bilibili GitHub - lucidrains/meshgpt-pytorch: Implementation of MeshGPT, SOTA Me…...