【电商项目实战】商品详情显示与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);}}

请添加图片描述

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

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

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

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

相关文章

合伙企业有哪些分类

合伙企业分为&#xff1a;普通合伙企业和有限合伙企业。其中&#xff0c;普通合伙企业又包含特殊的普通合伙企业。 1、普通合伙企业由2人以上普通合伙人(没有上限规定)组成。 普通合伙企业中&#xff0c;合伙人对合伙企业债务承担无限连带责任。 特殊的普通合伙企业中&#xf…

软件测试/测试开发丨Python 封装 学习笔记

封装的概念 封装&#xff08;Encapsulation&#xff09; 隐藏&#xff1a;属性和实现细节&#xff0c;不允许外部直接访问暴露&#xff1a;公开方法&#xff0c;实现对内部信息的操作和访问 封装的作用 限制安全的访问和操作&#xff0c;提高数据安全性可进行数据检查&#x…

『番外篇九』SwiftUI 实战:打造一款“五脏俱全”的网络图片显示 App(上)

概览 俗话说得好:“读书破万卷,下笔如有神”。不过如果把这句话放到编程的学习上可就不那么贴切了。 要想熟练掌握一门编程语言,光看书是绝对不够的。我们还需尽可能的多撸码、早撸码,撸到无路可退、海枯石烂才有可能一窥门径。 在本篇和续篇博文中,我们将和小伙伴们一起…

c++_09_继承

1 继承 C的继承是弱继承 继承的语法&#xff1a; class 子类 : 继承方式1 基类1, 继承方式2 基类2, ... { ... }; 继承方式&#xff1a; 共有继承 public 保护继承 protected 私有继承 private 2 继承的基本属性&#xff08;3种继承方式均有&#xff09; 继承所…

Javaweb之JDBC的详细解析

2. JDBC介绍(了解) 2.1 介绍 通过Mybatis的快速入门&#xff0c;我们明白了&#xff0c;通过Mybatis可以很方便的进行数据库的访问操作。但是大家要明白&#xff0c;其实java语言操作数据库呢&#xff0c;只能通过一种方式&#xff1a;使用sun公司提供的 JDBC 规范。 Mybatis…

从 MySQL 的事务 到 锁机制 再到 MVCC

其他系列文章导航 Java基础合集数据结构与算法合集 设计模式合集 多线程合集 分布式合集 ES合集 文章目录 其他系列文章导航 文章目录 前言 一、事务 1.1 含义 1.2 ACID 二、锁机制 2.1 锁分类 2.2 隔离级别 三、MVCC 3.1 介绍 3.2 隔离级别 3.3 原理 四、总结 前…

【2023年度总结】 何其有幸 年岁并进 一元复始 万象更新

&#x1f319; 新年将至&#xff0c;万物更新&#xff0c;旧疾当愈。 今年极度焦虑。发生太多事情&#xff0c;做出很多改变。 自律。早起、拍照、运动、读书、学习、认识了很多厉害的朋友&#xff0c;尝试影响周围的人。这是我生活正向能量的来源。 学习。今年依然是把大量…

C#上位机与欧姆龙PLC的通信06---- HostLink协议(FINS版)

1、介绍 对于上位机开发来说&#xff0c;欧姆龙PLC支持的主要的协议有Hostlink协议&#xff0c;FinsTcp/Udp协议&#xff0c;EtherNetIP协议&#xff0c;本项目使用Hostlink协议。 Hostlink协议是欧姆龙PLC与上位机链接的公开协议。上位机通过发送Hostlink命令&#xff0c;可…

python实现Ethernet/IP协议的客户端(二)

Ethernet/IP是一种工业自动化领域中常用的网络通信协议&#xff0c;它是基于标准以太网技术的应用层协议。作为工业领域的通信协议之一&#xff0c;Ethernet/IP 提供了一种在工业自动化设备之间实现通信和数据交换的标准化方法。python要实现Ethernet/IP的客户端&#xff0c;可…

【Linux】socket基础API

目录 1. 创建socket&#xff08;TCP/UDP&#xff0c;客户端服务器&#xff09; 1.1 第一个参数——domain 1.2 第二个参数——type 1.3 第三个参数——protocol 2. 绑定socket地址&#xff08;TCP/UDP&#xff0c;服务器&#xff09; 2.1 字节序及转换函数 2.2 IP地址及…

消融实验(ablation study)——全网最全解读

消融实验&#xff08;ablation study&#xff09; 是什么优势与劣势案例总结 是什么 消融实验是一种科学研究方法&#xff0c;用于确定一个条件或参数对结果的影响程度。当研究者提出了一个新的方案或方法时&#xff0c;消融实验通过逐一控制一个条件或参数&#xff0c;来观察…

6个火爆全网的AI开源项目,用上月10万+

标题月10万可能说的有点夸张和含糊&#xff0c;10万具体指的是你可以利用这些开源项目实现&#xff1a; 访问量10万 收入10万 用户10万 …… 开源项目只是免费的工具&#xff0c;具体怎么实现还需要你根据自己需求去深入运营。这里只是给你推荐一些比较热门的开源项目&…

基于QT开发的温室气体数据记录软件

1、概述 温室气体分析仪数据记录软件用于实现温室气体分析仪数据的获取与存储&#xff0c;阀箱数据的获取与存储、冷阱数据的获取与存储、采样单元数据的获取与存储、阀箱和采样单元的远程操作以及系统功能的管理。其主操作界面如下&#xff1a; 上述软件界面分为2各区域&…

用html,js和layui写一个简单的点击打怪小游戏

介绍&#xff1a; 一个简单的打怪小游戏&#xff0c;点击开始游戏后&#xff0c;出现攻击按钮&#xff0c;击败怪物后可以选择继续下一关和结束游戏。 继续下一个怪兽的血量会增加5点&#xff0c;攻击按钮会随机变色。 效果图&#xff1a; html代码&#xff1a; <!DOCTYPE…

QDialog

属性方法 样式表 background-color: qlineargradient(spread:reflect, x1:0.999896, y1:0.494136, x2:1, y2:1, stop:0 rgba(0, 0, 0, 255), stop:1 rgba(255, 255, 255, 255));border: 1px groove rgb(232, 232, 232);border-radius: 20px; QDialog 的常用方法&#xff1a; e…

前端 js 基础(1)

js 结果输出 &#xff08;点击按钮修改文字 &#xff09; <!DOCTYPE html> <html> <head></head><body><h2>Head 中的 JavaScript</h2><p id"demo">一个段落。</p><button type"button" onclic…

基于PHP的校园代购商城系统

有需要请加文章底部Q哦 可远程调试 基于PHP的校园代购商城系统 一 介绍 此校园代购商城系统基于原生PHP开发&#xff0c;数据库mysql&#xff0c;前端bootstrap。系统角色分为用户和管理员。(附带参考设计文档) 技术栈&#xff1a;phpmysqlbootstrapphpstudyvscode 二 功能 …

2023/12/30 c++ work

定义一个Person类&#xff0c;私有成员int age&#xff0c;string &name&#xff0c;定义一个Stu类&#xff0c;包含私有成员double *score&#xff0c;写出两个类的构造函数、析构函数、拷贝构造和拷贝赋值函数&#xff0c;完成对Person的运算符重载(算术运算符、条件运算…

03 团队研究进一步详细介绍

一、印第安纳大学邢璐祎课题组 【团队网站】 https://www.xing-luyi.com/ 【团队介绍】 研究以形式化方法为特色&#xff0c;并保证系统中的安全性和隐私合规性&#xff0c;特别是物联网、云、移动和软件供应链。 【团队成果汇总】 物联网系统&#xff1a;[Oakland24][Se…

骑砍战团MOD开发(30)-游戏大地图map.txt

骑砍1战团mod开发-大地图制作方法_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1rz4y1c7wH/ 一.骑砍游戏大地图 骑砍RTS视角游戏大地图 大地图静态模型(map.txt) 军团/城镇图标(module_parties.py). 骑砍大地图的战争迷雾和天气通过API进行管理和控制: # Weather-h…