Closed AugustTuan closed 2 years ago
老师讲了什么?
用户在未登录状态可以使用离线购物车,添加商品
当用户登录以后,离线购物车的商品会合并到在线购物车并清空离线购物车。
购物车还需要增删改查功能。
购物的下单功能,优惠券提醒功能。
在线购物车(特性:购物项是文档型数据,需要持久化存在、读多写多。)
离线购物车
老师首先分析了购物车有哪些数据要保存:
学习策略:
掌握程度
课程难度
时间花费
遗留问题
接口文档
老师讲了什么?
这一集老师根据前端可能会传给后端的数据,封装了两个VO
CartVo——购物车总信息:购物项数组,购物车的总数,总类型数,总价,优惠后的价格
CartItemVo——每一个购物项内容:skuId,check,title,image,skuAttr,count,price,totalPrice
然后老师重写了这些属性的get方法,比如总数量就是遍历每一个购物项,将count进行累加。
学习策略:
掌握程度
课程难度
时间花费
遗留问题
接口文档
老师讲了什么?
这一集老师实现了让后台服务器识别用户是否已经登录,如果没有登录可以给用户注册一个临时用户。
由于老师选择用redis
保存购物车的信息,所以老师引入了redis
依赖,配置了redis
地址。
老师创建了cartService
接口以及其实现类,注入了redisTemplate
来操作redis
。
之后老师在cart
服务引入了SpringSession
的依赖,添加了配置,最后注解开启了SPringSession
。
老师创建了一个CartController
,针对两种获取购物车数据的方式,创建了两个接口请求(一个是跳转到购物车页面,一个是使用ajax请求悬浮显示)
针对跳转到购物车页面的功能,老师创建了一个cartListPage(HttpSession session)
该方法的逻辑:如果能够从浏览器对应的session
中拿到login-user
信息,则说明用户已经登录;如果没有,则为用户创建一个user-key
的cookie
,相当于一个临时用户。浏览器下次访问购物车就可以带上这个cookie
。
针对这个逻辑,老师创建了一个拦截器,用于在执行Controller
方法之前,判断用户是否登录,并封装好给到Controller目标请求。
拦截器继承HandlerInterceptor
接口,重写preHandle
方法(在执行目标Controller
以前),该方法主要分为两部分
Cart
中的Controller
,所以专门抽取了一个UserInfoVo
,包含user-id
(登录了)和user-key
(没登录)cookie-id
来获取session
信息。服务器拿着浏览器cookie的id,从session
中获取数据,封装成MemberRespVo
,拦截器从MemberRespVo
中获取user-id
,set到UserInfoVo中。session
中获取不到user-key
,就使用request.getCookies()
,获取Cookie[]
,遍历Cokkie数组,检查是否有cookie
的name=“user-key”
,如果有说明已经分配了临时数据,将user-key
的值封装进UserInfoVo
传递给目标Controller
WevMVCConfigurer
接口,指定拦截的请求路径,老师这里使用“/**”
表示拦截所有请求。userInfoTo
放进threadLocal
中,同一个线程(一次请求过程中)的controller
就可以拿到userInfoTo
。如果用户既没有user-id
也没有user-key
,那么就拦截器就随机生成一个user-key
,封装进userInfoTo
。 并且实现postHandle
方法(Controller
方法执行完毕),命令浏览器创建一个user-key
的cookie
保存。(设置作用域和过期时间)
学习策略:
掌握程度
课程难度
时间花费
遗留问题
00:30 应该用一个专门的redis用来存放购物车? 那是不是实际项目,每个大的功能都专门用一个redis服务器?
00:40 老师提到了面向接口编程
1:30 Sl4j是干啥来着?
跟日志有关
11:13 讲到了拦截器,拦截器是啥?
没有登录的情况下,有session吗?
13:20 可以从request里面获取session?
19:15 讲到了thread local,在同一个现成共享数据
25:30/**
是指所有请求的意思吗?
我把SpringSession和单点登录真有点学混乱了。
SpringSession通过统一redis存储,扩大子域范围,分布式服务不共享session,子域名之间cookie不共享的问题。(跟单点登录无关,没有中心认证服务器,单点登录靠的是认证服务器命令浏览器创建cookie。
Controller里面的接收请求的是类吗?还是方法
凡是固定的内容,老师都抽取成常量。凡是要和前后端,服务间传输的内容,老师都抽取成Vo/To
为什么到了拦截器这里就需要用threadlocal来共享数据了呢?以前的Controller和service和dao之间不都是直接注入,传参吗?难道不要threadLocal,拦截器的数据就到不了Controller吗?
接口文档
老师讲了什么?
学习策略:
掌握程度
课程难度
时间花费
遗留问题
接口文档
老师讲了什么?
这一集老师完成了购物车的添加功能(临时购物车和登录购物车),添加购物车的流程如下:
老师在CasrtService
中增加了一个请求处理 addToCart
,其接收商品的skuId和添加的数量。
threadLocal
中拿到拦截器的UserInfoTo
,如果用户登录了获取user_id
,否则获取user-key
。将这个视为存入redis
的key
,来区分临时购物车和登录购物车。redisTemplate
,使用BoundHashOperations
,创建一个专门操作对应key
的operations
对象。 将上述两个流程抽取成getCartOps
方法。 专门根据用户的登录状态,来决定操作redis
中哪一个key
对应的value
。想要向redis
中保存商品信息,首先要调用远程的product
服务,获取skuInfo
信息,并添加到cartItem
中。
至于sku
的组合信息,需要自定义SQL,查询sku_sale_attr_value
表,最后set
到cartItem
中去
最后使用cartops.put(skuId.toString(),cartItem.toJsonString)
,将cartItem信息保存进redis。
由于这个方法涉及了两处远程查询,老师为了提高系统的性能,采用了多线程的方式
CompletableFuture.runAsync(()→{ })
中去Completable.allOf.get();
让主线程阻塞等待两个远程查询都结束,再将数据存入redis
(否则会出现redis
中没有数据的问题)学习策略:
掌握程度
课程难度
时间花费
遗留问题
TypeReference
了sql
了接口文档
老师讲了什么?
这一集老师细化了添加购物车,即如果购物车中已经有了对应的商品,只需要修改商品的数量即可)
老师在添加商品之前,先查询是否商品已经存在String res=(String)cartOps.get(skuId.toString());
如果没有这个商品就继续执行添加商品的方法,如果没有,则进行数量累加。
String res=(String) cartOps.get(skuId.toString());//将redis对应skuId的商品信息拿到转换成字符串
if(StringUtils.isNotEmpty(res)){ //如果商品信息不为空,说明已经存在对应的商品
cartItem cartItem =JSON.parseObject(res,CartItem.calss); //将商品信息字符串转成购物车列表项对象
cartItem.setCount(cartItem.getCount()+num);//对对象的num字段进行累加
cartOps.put(skuId,toString(),JSON.tojSONString(cartItem));//再将购物车列表项对象转成JSON字符串存回redis。
return cartItem;
学习策略:
掌握程度
课程难度
时间花费
遗留问题
接口文档
老师讲了什么?
这一集老师使用重定向解决了购物车刷新“添加成功”页面,后台重复提交的问题。
原有的逻辑:刷新页面,就会发送addToCart
请求,后台就会执行addToCart
方法,向redis
中保存数据,返回最近的cartItem
并展示success
页面。
优化逻辑:当添加成功后,重定向到success页面(相当于跳转到了新的页面),刷新页面后不会再重复发送添加请求。
基于这个优化逻辑,老师又增加了一个Controller addToCartSuccessPage()
,当请求aadToCart请求执行完毕以后,会将skuId添加在重定向路径的后面,访问Controller addToCartSuccessPage()
,其负责查询redis中的购物项并展示success页面
最后老师对比了两种重定向携带数据的方式
redirectAttributes.addFlashAttribute();
将数据保存到session里面,并在重定向的页面取出,但是只能取一次。再次刷新就丢失
redirectAttributes.addAttribute();
将数据放在url后面(重定向的页面可以取出url,进行查询,再将数据放在model里面。)
学习策略:
掌握程度
课程难度
时间花费
遗留问题
Controller
的请求参数就是一个页面?redirectAttribute
和model
的区别是啥?session
里面,只能用一次?session
不是会话级别的吗?接口文档
老师讲了什么?
这一集老师实现了购物车列表的展示,并且登录后的购物车可以合并临时购物车
老师创建了一个cartListPage的controller
,其中cartService.cart()
可以获取整个购物车对象,并返回给前端页面。
getCart的逻辑是:
通过UserInfoTo userInfoTo=CartInterceptor.threadLocal.get();
获取用户的登录信息,来判断用户的登陆状态。
对于没有登录的用户,返回临时购物车
if(userInFoTo.getUserId==null) //如果用户没有登录
{
String cartKey=CART)PREFIIX+userInfoTo.getUserKey(); //将用户的user-key+前缀就是redis中的key值
BoundHashOperations<String,Object,Object> hashOps=redisTemplate.boundHashOps(cartKey)封装一个专门操作这个key值得对象
list<Object> values=hashOps.values(); //获取redis中对应得value值
if(values!=null&&values.size()>0{ //如果value有值
List<CartItem> collect=values.stream().map((obj)→{ //将value的值进行遍历
String str=(String) obj;
CartItem cartItem =JSON.parseObject(str,CartItem.class); //将redis中的value值都转换成cartItem对象
}).collect(Collectors.toList());//最后收集成一个cartItem对象的list集合
cart.setItems(collect);} //将集合中的cartItem加到临时购物车cart中去
return cart; //将cart返回给前端页面
如果用户已经登陆了,那么就先获取临时购物车的数据,将cartItem addTocart()
,再获取登录购物车的数据,返回给前端。至于临时购物车的数据,就做一次删除(把临时购物车的cartKey直接一删就没了)
学习策略:
掌握程度
课程难度
时间花费
遗留问题
object
?接口文档
老师讲了什么?
skuId
和check
获取cartItem
,修改其是否选中信息。再重定向cart.html
,查询最新的购物车数据并展示。学习策略:
掌握程度
课程难度
时间花费
遗留问题
接口文档
老师讲了什么?
这一集老师实现了修改购物项数量的功能,思路和上一集类似。 创建一个controller,接收数量和skuId,更新redis,重定向到购物车页面,展示最新数据。
public void changeItemCount(Long skuId,Integer num){
cartItem cartItem=getCartItem(skuId); 根据前端传来的skuId,获取购物项
cartItem.setCount(num); //更新购物项的数量
BoundHashOperations<String,Object,Object> cartOps=getCartOps(); //创建一个专门操作购物车的对象
cartOps.put(skuId.toString(),JSON.toJSONString(cartItem)); //向购物车中保存购物项
} //
学习策略:
掌握程度
课程难度
时间花费
遗留问题
接口文档
老师讲了什么?
这一集老师实现了修改购物项数量的功能,思路和上一集类似。 创建一个controller,接收skuId,直接删除这个skuId对应的键值,重定向到购物车页面,展示最新数据。
public void deleteItem(Long skuId){
BoundHashOperations<String,Object,Object> cartOps=getCartOps(); //创建一个专门操作购物车的对象
cartOps.delete(skuId.toString()); //删除购物项
} //
学习策略:
掌握程度
课程难度
时间花费
遗留问题
接口文档
P236 商城业务- 购物车-环境搭建
老师讲了什么?
学习策略:
掌握程度
课程难度
时间花费
遗留问题
接口文档
148