【业务功能篇97】微服务-springcloud-springboot-电商购物车模块-获取当前登录用户的购物车信息
购物车功能
一、购物车模块
1.创建cart服务
我们需要先创建一个cart的微服务,然后添加相关的依赖,设置配置,放开注解。
<dependencies><dependency><groupId>com.msb.mall</groupId><artifactId>mall-commons</artifactId><version>0.0.1-SNAPSHOT</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies>
然后属性文件中的配置
server.port=40000
spring.application.name=mall-cartspring.cloud.nacos.discovery.server-addr=192.168.56.100:8848
spring.thymeleaf.cache=false
然后再添加配置中心的配置:bootstrap.yml文件
spring.application.name=mall-cart
spring.cloud.nacos.config.server-addr=192.168.56.100:8848
放开注册中心的注解
2.Nginx配置
首先在windows中的host指定对应域名
拷贝对应的静态资源到Nginx的static/cart目录中
然后修改Nginx的配置文件
然后重启nginx服务
docker restart nginx
3.配置网关服务
Nginx接收了 cart.msb.com
这个域名的访问,那么会把服务反向代理给网关服务,这时网关服务就需要把该请求路由到购物车服务中。我们需要修改网关服务的配置
最后调整下模板页面中的静态资源的路径就可以了
然后启动服务访问即可
二、购物车功能
1.购物车模式处理
讨论购物车中数据的存储方式。我们在购物车中可以有多见商品
然后对应的数据我们可以选择存储在Redis中,对应的数据存储结构我们要慎重的考虑,因为有多条记录,如果用List来存储
[{skuId:1,subTile:'华为',price:666},{skuId:1,subTile:'华为',price:666},{skuId:1,subTile:'华为',price:666}]
那么我们后面要对商品做添加删除和修改商品数量的时候就会比较麻烦,我们需要取出List中的整个数据,然后找到我们要操作的数据,然后把所有数据回写到Redis中,这种方式显然不可取,这时我们可以考虑hash的方式来存储:
这样我们就可以一条一条来处理了,相比上面会更加的灵活。然后我们在后端服务中存储的结构为
Map<String,Map<String,CartItemVo>>
2.购物车VO
针对购物车的信息存储,我们创建两个对应的VO对象。
package com.msb.mall.vo;import java.math.BigDecimal;
import java.util.List;/*** 购物车中的商品信息*/
public class CartItem {// 商品的编号 SkuIdprivate Long skuId;// 商品的图片private String image;// 商品的标题private String title;// 是否选中private boolean check = true;// 商品的销售属性private List<String> skuAttr;// 商品的单价private BigDecimal price;// 购买的数量private Integer count;// 商品的总价private BigDecimal totalPrice;public Long getSkuId() {return skuId;}public void setSkuId(Long skuId) {this.skuId = skuId;}public String getImage() {return image;}public void setImage(String image) {this.image = image;}public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}public boolean isCheck() {return check;}public void setCheck(boolean check) {this.check = check;}public List<String> getSkuAttr() {return skuAttr;}public void setSkuAttr(List<String> skuAttr) {this.skuAttr = skuAttr;}public BigDecimal getPrice() {return price;}public void setPrice(BigDecimal price) {this.price = price;}public Integer getCount() {return count;}public void setCount(Integer count) {this.count = count;}public BigDecimal getTotalPrice() {// 商品的总价 price * countreturn price.multiply(new BigDecimal(count));}}
Cart
package com.msb.mall.vo;import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.List;/*** 购物车*/
public class Cart {// 购物车中的商品种类private Integer countType;// 选中的商品数量private Integer checkCountNum;// 选中商品的总价private BigDecimal totalAmount;// 购物中存储的商品信息private List<CartItem> items;public Integer getCountType() {return items.size();}public Integer getCheckCountNum() {Integer count = 0;for (CartItem item : items) {if (item.isCheck()){count += item.getCount();}}return count;}public BigDecimal getTotalAmount() {BigDecimal amount = new BigDecimal(0);for (CartItem item : items) {if (item.isCheck()){amount = amount.add(item.getTotalPrice());}}return amount;}public List<CartItem> getItems() {return items;}public void setItems(List<CartItem> items) {this.items = items;}
}
3.认证信息
我们需要在购物车服务中根据当前登录用的用户信息去Redis中查询对应的购物车信息。首先我们需要导入Redis的相关依赖,同时我们要借助于前面讲解的SpringSession来共享认证的Session信息。
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>org.springframework.session</groupId><artifactId>spring-session-data-redis</artifactId></dependency>
添加属性文件信息
server.port=40000
spring.application.name=mall-cartspring.cloud.nacos.discovery.server-addr=192.168.56.100:8848
spring.thymeleaf.cache=falsespring.redis.host=192.168.56.100
spring.redis.port=6379
spring.thymeleaf.enabled=falsespring.session.store-type=redis
server.servlet.session.timeout=30m
spring.session.redis.namespace=spring:session
添加Cookie的配置信息
@Configuration
public class MySessionConfig {/*** 自定义Cookie的配置* @return*/@Beanpublic CookieSerializer cookieSerializer(){DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();cookieSerializer.setDomainName("msb.com"); // 设置session对应的一级域名cookieSerializer.setCookieName("msbsession");return cookieSerializer;}/*** 对存储在Redis中的数据指定序列化的方式* @return*/@Beanpublic RedisSerializer<Object> redisSerializer(){return new GenericJackson2JsonRedisSerializer();}
}
添加自定义的拦截器
/*** 我们自定义的拦截器:帮助我们获取当前登录的用户信息* 通过Session共享获取的*/
public class AuthInterceptor implements HandlerInterceptor {// 本地线程对象 Map<thread,Object>public static ThreadLocal<MemberVO> threadLocal = new ThreadLocal();@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 通过HttpSession获取当前登录的用户信息HttpSession session = request.getSession();Object attribute = session.getAttribute(AuthConstant.AUTH_SESSION_REDIS);if(attribute != null){MemberVO memberVO = (MemberVO) attribute;threadLocal.set(memberVO);}return true;}
}
注册拦截器
@Configuration
public class MyWebInterceptorConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new AuthInterceptor()).addPathPatterns("/**");}
}
然后登录后访问controller服务测试
4.页面跳转
从商品详情页面点击添加购物车完成添加购物车的逻辑。
5.添加购物车逻辑
具体完成添加购物车的逻辑,也service中我们获取到商品的SKUId和商品数量后,我们要实现的逻辑
具体核心代码
/*** 把商品添加到购物车中* @param skuId* @param num* @return*/@Overridepublic CartItem addCart(Long skuId, Integer num) throws Exception {BoundHashOperations<String, Object, Object> hashOperations = getCartKeyOperation();// 如果Redis存储在商品的信息,那么我们只需要修改商品的数量就可以了Object o = hashOperations.get(skuId.toString());if(o != null){// 说明已经存在了这个商品那么修改商品的数量即可String json = (String) o;CartItem item = JSON.parseObject(json, CartItem.class);item.setCount(item.getCount()+num);hashOperations.put(skuId.toString(),JSON.toJSONString(item));return item;}CartItem item = new CartItem();CompletableFuture future1 = CompletableFuture.runAsync(()->{// 1.远程调用获取 商品信息R r = productFeignService.info(skuId);String skuInfoJSON = (String) r.get("skuInfoJSON");SkuInfoVo vo = JSON.parseObject(skuInfoJSON,SkuInfoVo.class);item.setCheck(true);item.setCount(num);item.setPrice(vo.getPrice());item.setImage(vo.getSkuDefaultImg());item.setSkuId(skuId);item.setTitle(vo.getSkuTitle());},executor);CompletableFuture future2 = CompletableFuture.runAsync(()->{// 2.获取商品的销售属性List<String> skuSaleAttrs = productFeignService.getSkuSaleAttrs(skuId);item.setSkuAttr(skuSaleAttrs);},executor);CompletableFuture.allOf(future1,future2).get();// 3.把数据存储在Redis中String json = JSON.toJSONString(item);hashOperations.put(skuId.toString(),json);return item;}private BoundHashOperations<String, Object, Object> getCartKeyOperation() {// hash key: cart:1 skuId:cartItemMemberVO memberVO = AuthInterceptor.threadLocal.get();String cartKey = CartConstant.CART_PERFIX + memberVO.getId();BoundHashOperations<String, Object, Object> hashOperations = redisTemplate.boundHashOps(cartKey);return hashOperations;}
6.购物车主页
添加商品进入购物车后,我们可以点击结算进入购物车页面,那么我们需要在后台查询出所有的当前登录用户的购物车商品信息,然后在页面中展示
然后在页面中处理数据
相关文章:
【业务功能篇97】微服务-springcloud-springboot-电商购物车模块-获取当前登录用户的购物车信息
购物车功能 一、购物车模块 1.创建cart服务 我们需要先创建一个cart的微服务,然后添加相关的依赖,设置配置,放开注解。 <dependencies><dependency><groupId>com.msb.mall</groupId><artifactId>mall-commo…...
Shell常用的几个正则表达式:[:alnum:], [:alpha:], [:upper:], [:lower:], [:digit:] 认知
一:通配符命令简介: 匹配符合相关条件的符号,匹配文件名查找。 通配符类型: *:匹配任意长度的任意字符 ?:匹配任意单个字符 []:匹配指定范围内的任意单个字符 [^]:匹配指…...
简单的爬虫代码 爬(豆瓣电影)
路漫漫其修远兮,吾将上下而求索 这次写一个最简单的python爬虫代码,也是大多教程第一次爬取的,代码里面有个别的简单介绍,希望能加深您对python爬虫的理解。 本次爬取两个网页数据 一 爬取的网站 豆瓣电影 爬取网页中的&#…...
微服务之架构演变
随着互联网的发展,网站应用规模不断扩大,网站架构随之不断演变,演变历史大致分为单体应用架构-垂直应用架构-分布式架构-SOA架构-微服务架构-云原生架构 架构演变 单体应用架构 以前网站流量小,只需要一个应用就可以把所有功能…...
面试问题记录一 --- C++(Qt方向)
以下是我于2023年6~7月间换工作时遇到的面试题目,有需要的小伙伴可以参考下。约100个题目。 1 C和C++的区别 1) 文件区别:C源文件后缀 .c;C++源文件后缀 .cpp 2) 返回值: C默认返回int型;C++ 若无返回值,必须指定为void 3) 参数列表:C默认接收多个…...
使用词袋模型(BoW)测试提取图像的特征点和聚类中心
文章目录 环境配置代码测试 环境配置 (1) 导入opencv,参考链接 https://blog.csdn.net/Aer_7z/article/details/132612369(2) 安装numpy 激活虚拟环境的前提下,输入: pip install numpy(3) 安装sklearn 激活虚拟环境的前提下,输…...
利用vba处理Excel表格数据实现键值转化,适用于将编码转化成对应的文本
最近遇到了一个甲方需要提供系统登录的用户名单和对应的角色权限内容。无奈直接从数据库导出的数据对应的都是编码,没有转成中文,想着偷个懒能不能直接用Excel直接转,网上看了一下有修改单元格格式的,但需要编码是2到3个。多的就用…...
IntelliJ IDEA(Windows 版)的所有快捷键
🪁🍁 希望本文能够给您带来一定的帮助🌸文章粗浅,敬请批评指正!🍁🐥 大家好 本文参考了 IntelliJ IDEA 的官网,列举了IntelliJ IDEA(Windows 版)的所有快捷…...
文件上传漏洞全面渗透姿势
0x00 文件上传场景 (本文档只做技术交流) 文件上传的场景真的随处可见,不加防范小心,容易造成漏洞,造成信息泄露,甚至更为严重的灾难。 比如某博客网站评论编辑模块,右上角就有支持上传图片的功能,提交带…...
GreenPlum的gpfdist使用与原理流程分析
一、简介 GreenPlum 的数据导入功能作为对数据源的一种扩充,数据导入的方式有: 1、insert 该方式通过 sql 语句,把数据一条一条插入至表中。这种方式,不仅读取数据慢(一条一条读取),且数据需要…...
Spring AOP与静态代理/动态代理
文章目录 一、代理模式静态代理动态代理代理模式与AOP 二、Spring AOPSping AOP用来处理什么场景jdk 动态代理cglib 动态代理面试题:讲讲Spring AOP的原理与执行流程 总结 一、代理模式 代理模式是一种结构型设计模式,它允许对象提供替代品或占位符&…...
【LeetCode算法系列题解】第51~55题
CONTENTS LeetCode 51. N 皇后(困难)LeetCode 52. N 皇后 II(困难)LeetCode 53. 最大子序和(中等)LeetCode 54. 螺旋矩阵(中等)LeetCode 55. 跳跃游戏(中等) …...
驱动开发错误汇编
本博文将会不定期更新。以便记录我的驱动开发生涯中的一些点点滴滴的技术细节和琐事。 1. link阶段找不到导出函数 比如"LNK2019 无法解析的外部符号 _FltCreateCommunicationPort32"。 出现这种情况的原因是,驱动的编译环境忽略了所有的默认库&#x…...
知识图谱项目实践
目录 步骤 SpaCy Textacy——Text Analysis for Cybersecurity Networkx Dateparser 导入库 写出页面的名称 编辑 自然语言处理 词性标注 可能标记的完整列表 依存句法分析(Dependency Parsing,DEP) 可能的标签完整列表 实例理…...
stable diffusion实践操作-提示词-人物属性
系列文章目录 stable diffusion实践操作-提示词 文章目录 系列文章目录前言一、提示词汇总1.1 人物属性11.2 人物属性2 前言 本文主要收纳总结了提示词-人物属性。 一、提示词汇总 1.1 人物属性1 角色类型人物身材胸部头发-发型头发-发色[女仆][霊烏路空][大腿][乳房][呆毛…...
RabbitMQ的安装和配置
将RabbitMQ文件夹传到linux根目录 开启管理界面及配置...
WebRTC 日志
WebRTC 日志 flyfish WebRTC支持的日志等级 // // The meanings of the levels are: // LS_VERBOSE: This level is for data which we do not want to appear in the // normal debug log, but should appear in diagnostic logs. // LS_INFO: Chatty level used in de…...
【python爬虫】16.爬虫知识点总结复习
文章目录 前言爬虫总复习工具解析与提取(一)解析与提取(二)更厉害的请求存储更多的爬虫更强大的爬虫——框架给爬虫加上翅膀 爬虫进阶路线指引解析与提取 存储数据分析与可视化更多的爬虫更强大的爬虫——框架项目训练 反爬虫应对…...
Windows系统中Apache Http服务器简单使用
1 简介 Apache HTTP服务器是一个开源的、跨平台的Web服务器软件。它由Apache软件基金会开发和维护。Apache HTTP服务器可以在多种操作系统上运行,如Windows、Linux、Unix等,并且支持多种编程语言和技术,如PHP、Perl、Python、Java等。…...
Django ORM 框架中的表关系,你真的弄懂了吗?
Django ORM 框架中的表关系 为了说清楚问题,我们设计一个 crm 系统,包含五张表: 1.tb_student 学生表 2.tb_student_detail 学生详情表 3.tb_salesman 课程顾问表 4.tb_course 课程表 5.tb_entry 报名表 表关系和字段如下图:…...
第五课:C++实现加密PDF文档解密
请注意,未经授权的加密PDF文件解密是非法的,本文仅为学术和研究目的提供参考。 打开加密的PDF文件并获取密钥 在C++中,可以使用pdfium库打开加密的PDF文件。使用pdfium库中的FPDF_LoadCustomDocument函数可以打开具有自定义访问权限的加密文件。该函数接受一个IFX_FileRead*…...
罗马数字转整数
罗马数字转整数 题目: 罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M …...
processflow流程图多人协作预热
前言 在线上办公如火如荼的今天,多人协作功能是每个应用绕不开的门槛。processflow在线流程图(前身基于drawio二次开发)沉寂两年之久,经过长时间设计开发,调整,最终完成了多人协作的核心模块设计。废话不多…...
PCL点云处理之快速计算多个点到同一直线的距离(二百零五)
PCL点云处理之快速计算多个点到同一直线的距离(二百零五) 一、算法简介二、具体实现1.代码2.结果一、算法简介 点到直线的距离计算,是一种常用的算法,在点云处理中,经常遇到需要计算多个点云到同一条直线的距离计算需求,此时若是逐点计算将耗费大量的时间,熟悉点到直线…...
xxl-job 任务调度搭建及简单使用
xxl-job是开源架构,可以通过它实现调度中心和执行器。 git地址和 官网中进行了详细的技术说明。 xxl-job支持单机部署和集群式部署,在集群式部署中又可以实现调度中心集群式部署和执行器集群式部署。本文主要针对调度中心和执行器分离单机部署方式进…...
mysql数据库使用技巧整理
查看当前数据库已建立的client连接 > SHOW VARIABLES LIKE max_connections; -- 查看数据库允许的最大连接数,不是实时正在使用的连接数 > SHOW STATUS LIKE Threads_connected; -- 查看当前数据库client的连接数 > SHOW PROCESSLIST; -- 查看具体的连接...
车规微控制器的ECC机制及EMU外设
车规微控制器的ECC机制及EMU外设 文章目录 车规微控制器的ECC机制及EMU外设引言ECC的基本原理ECC RAM的访问方式ECC RAM的初始化SRAM ECC错误注入及EMU外设Flash ECC校验参考文献 引言 ECC是微控制器系统中,用于保障信息安全的常用机制,主要是避免存储设…...
Less的强大变量用法
less中的变量应用十分强大,可以灵活的应用到各种不同需求的场景。 一,属性值变量 声明:sass声明变量是用$符号,而less声明变量是用符号 作用域:也区分为全局变量和局部变量,如果引用的变量有定义局部变量&…...
【相机标定】opencv python 标定相机内参时不计算 k3 畸变参数
文章目录 1. 背景2. 完整的 opencv python 标定相机内参过程3. 选择是否计算畸变参数 k3 1. 背景 畸变参数 k3 通常用于描述径向畸变的更高阶效应,即在需要高精度的应用中可以用到,一般的应用中 k1, k2 足矣。 常见的应用中, orbslam3 中是否…...
html 标签简介
概述 标签的效果不重要,重要的是标签的语义。 文本标签 文本标签用于包裹:词汇、短语等。排版标签,比如div,p,h1等。排版标签更宏观(大段的文字),文本标签更微观(词汇、短语)。文…...
什么网站做简历/电商运营多少钱一个月
题库来源:安全生产模拟考试一点通公众号小程序 2020建筑电工(建筑特殊工种)考试题库及建筑电工(建筑特殊工种)模拟考试,包含建筑电工(建筑特殊工种)考试题库答案解析及建筑电工(建筑特殊工种)模拟考试练习。由安全生产模拟考试一点通公众号结合国家建筑…...
怎样建立商贸网站/百度快照手机入口
A一我护灯近次感观片近次感观片近次感观片近JAX(async JavaScript and XML),指的是通过 JavaScript 的异步通信,从服务器获取 XML 文档从中提取数据,再更新当前网页的对应部分,而不用刷新整个网页。后来,AJAX 这个词就…...
河北中保建设集团网站首页/400个成品短视频
2019独角兽企业重金招聘Python工程师标准>>> Connector配置 Connector 属于 StandardService 里的一个组件,可以在 server.xml 中配置,指定协议、端口、超时时间等。 1 2 3 4 <Service name"Catalina"><Connector port&q…...
站长之家素材网/seo内部优化方案
“告警了!告警了!”。 "什么告警了?"正在睡梦中迷糊的小王突然被运维同事的一个电话叫醒,顿时一脸惊愕。 “慢查询!客户报障了!赶紧起来处理啊!” 小王赶紧打开便携,远程连…...
切图做网站/二次感染即将大爆发
传送门 题意:有个房间,房间的值用四面的门加起来的值表示,非常巧妙,西门用1表示,北门用2表示,东门用4表示,南门用8表示,最后判断是否连通的方法使用&,非常巧妙。 题…...
连云港网站建设制作/百度云手机登录入口
我的项目文件层次是:项目名称/include、output、src src/admin、stu、tch、common 最外层的Makefile: DEBUG yMYDEBUG DEBUGifeq ($(DEBUG),y)DEBFLAGS -O -g -D$(MYDEBUG)elseDEBFLAGS endif PRJ_HOME : $(shell pwd)SOURCES : $(wildcard *.c)OBJEC…...