84分布式电商项目 - Redis存储购物车

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: 84分布式电商项目 - Redis存储购物车

判断当前用户是否登陆,如果未登录采用 Cookie 存储,如果登录则采用 Redis 存储。登录后要进行 Cookie 购物车与 Redis 购物车的合并操作,并清除 Cookie 购物车。

获取当前登录人账号

spring-security.xml 更改配置:

去掉

<http pattern="/cart/*.do" security="none"></http>

添加

<http use-expressions="false" entry-point-ref="casProcessingFilterEntryPoint">
   <intercept-url pattern="/cart/*.do" access="IS_AUTHENTICATED_ANONYMOUSLY"/><intercept-url pattern="/**" access="ROLE_USER"/>
   <custom-filter position="CAS_FILTER" ref="casAuthenticationFilter" /> 
   <custom-filter ref="requestSingleLogoutFilter" before="LOGOUT_FILTER"/>
   <custom-filter ref="singleLogoutFilter" before="CAS_FILTER"/> 
 </http>

access="IS_AUTHENTICATED_ANONYMOUSLY"用于设置资源可以在不登陆时可以访问。

此 配 置 与 security="none"的 区 别 在 于 当 用 户 未 登 陆 时 获 取 登 陆 人 账 号 的 值 为anonymousUser ,而 security="none"的话,无论是否登陆都不能获取登录人账号的值。

代码实现:

在 pinyougou-cart-web 的 findCartList 和addGoodsToCartList 方法中,获取用户名

//得到登陆人账号,判断当前是否有人登陆
String username = SecurityContextHolder.getContext().getAuthentication().getName();

测试:当用户未登陆时,username 的值为anonymousUser

远程购物车存取

服务层接口

pinyougou-cart-interface 中 CartService.java 定义方法

/**
   * 需求:查询redis购物车数据
   * @return
   */
  List<Cart> findRedisCartList(String username);
  /**
   * 把购物车列表保存到redis购物车
   * @param cartList
   * @param username
   */
  void saveCartListToRedisCart(List<Cart> cartList, String username);
服务层实现

pinyougou-cart-service 中 CartServiceImpl.java 实现方法

/**
   * 需求:查询redis购物车数据
   * 
   * @return
   */
  public List<Cart> findRedisCartList(String username) {
    // 查询redis服务购物车列表
    List<Cart> cartList = (List<Cart>) redisTemplate.boundHashOps(
        "cartList").get(username);
    // 判断查询购物车数据是否有值
    if (cartList == null) {
      return new ArrayList<Cart>();
    }
    return cartList;
  }
  /**
   * 把购物车列表保存到redis购物车
   *
   * @param cartList
   * @param username
   */
  public void saveCartListToRedisCart(List<Cart> cartList, String username) {
    // TODO Auto-generated method stub
    redisTemplate.boundHashOps("cartList").put(username, cartList);
  }
控制层

修改 CartController.java 的 findCartList 方法

/**
   * 需求:查询购物车列表
   * 
   * @return
   */
  @RequestMapping("/findCartList")
  public List<Cart> findCartList(HttpServletRequest request) {
    // 判断用户此时是否处于登录状态
    // 获取用户名
    String username = SecurityContextHolder.getContext()
        .getAuthentication().getName();
    //定义集合
    List<Cart> cartList = null;
    // 查询cookie购物车数据
    String cartListStr = CookieUtil.getCookieValue(request, "cartList", true);
    // 登录
    if (!username.equals("anonymousUser")) {
      //登录
       cartList = cartService.findRedisCartList(username);    
       return cartList;
    } 
    //未登录
    // 判断集合是否存在值
    if (StringUtils.isBlank(cartListStr)) {
      cartListStr = "[]";
    }
    // 把购物车字符串转换成对象
    cartList = JSON.parseArray(cartListStr, Cart.class);  
    return cartList;
  }

修改 addGoodsToCartList 方法

@RequestMapping("addGoodsToCartList")
  @CrossOrigin(origins="http://item.pinyougou.com",allowCredentials="true")
  public PygResult addGoodsToCartList(String itemId, Integer num,
      HttpServletRequest request, HttpServletResponse response) {
    try {
      itemId = itemId.replace(",", "");
      // 获取用户登录身份信息
      String username = SecurityContextHolder.getContext()
          .getAuthentication().getName();
      // 查询购物车列表
      List<Cart> cartList = this.findCartList(request);
      // 添加购物车
      cartList = cartService.addGoodsToCartList(cartList, Long.parseLong(itemId), num);
      // 判断用户是否处于登录状态
      if (username.equals("anonymousUser")) {
        // 未登录
        CookieUtil.setCookie(request, response, "cartList",
            JSON.toJSONString(cartList), 46800, true);
      } else {
        // 登录
        cartService.saveCartListToRedisCart(cartList, username);
      }
      return new PygResult(true, "购物车添加成功");
    } catch (Exception e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
      return new PygResult(false, "购物车添加失败");
    }
  }
跳板页

(1)创建跳板页:pinyougou-cart-web 工程新建 login.html ,页面添加脚本

<script type="text/javascript">
  location.href="cart.html";
</script>

(2)购物车页面链接到跳板页

请<a href="login.html">登录</a>

购物车合并

服务接口层

pinyougou-cart-interface 工程的 CartService.java 定义方法

/**
   * 需求:合并购物车数据
   * @param username
   * @param cartListStr
   */
  List<Cart> mergeCart(String username, String cartListStr);
服务实现层

pinyougou-cart-service 工程 CartServiceImpl.java 实现方法

/**
   * 需求:合并购物车数据
   * 
   * @param username
   * @param cartListStr
   */
  public List<Cart> mergeCart(String username, String cartListStr) {
    // 根据用户名查询所有购物车数据
    List<Cart> cartList1 = (List<Cart>) redisTemplate.boundHashOps("cartList").get(username);
    // 把cookie购物车数据转换集合
    List<Cart> cartList2 = JSON.parseArray(cartListStr, Cart.class);
    //循环redis购物车
    for (Cart cart : cartList2) {
      //获取当前商家列表
      List<TbOrderItem> orderItemList = cart.getOrderItemList();
      //循环
      for (TbOrderItem tbOrderItem : orderItemList) {
        //返回合并后redis购物车集合
        cartList1 = this.addGoodsToCartList(cartList1, tbOrderItem.getItemId(), tbOrderItem.getNum());
      }
    }
    return cartList1;
  }
控制层

修改 pinyougou-cart-web 工程 CartController 类的 findCartList 方法

/**
   * 需求:查询购物车列表
   * 
   * @return
   */
  @RequestMapping("/findCartList")
  public List<Cart> findCartList(HttpServletRequest request) {
    // 判断用户此时是否处于登录状态
    // 获取用户名
    String username = SecurityContextHolder.getContext()
        .getAuthentication().getName();
    //定义集合
    List<Cart> cartList = null;
    // 查询cookie购物车数据
    String cartListStr = CookieUtil.getCookieValue(request, "cartList", true);
    // 登录
    if (!username.equals("anonymousUser")) {
      //判断cookie购物车不为空,合并
      if(StringUtils.isNotBlank(cartListStr)){
        //合并购物车
        cartList =  cartService.mergeCart(username,cartListStr);
      }
      //登录
       cartList = cartService.findRedisCartList(username);    
       return cartList;
    } 
    //未登录
    // 判断集合是否存在值
    if (StringUtils.isBlank(cartListStr)) {
      cartListStr = "[]";
    }
    // 把购物车字符串转换成对象
    cartList = JSON.parseArray(cartListStr, Cart.class);  
    return cartList;
  }


相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
1月前
|
NoSQL 算法 安全
Redlock 算法-主从redis分布式锁主节点宕机锁丢失的问题
Redlock 算法-主从redis分布式锁主节点宕机锁丢失的问题
155 0
|
1月前
|
NoSQL 关系型数据库 MySQL
分布式锁(redis/mysql)
分布式锁(redis/mysql)
62 1
|
1月前
|
NoSQL Java Redis
如何通俗易懂的理解Redis分布式锁
在多线程并发的情况下,我们如何保证一个代码块在同一时间只能由一个线程访问呢?
39 2
|
1月前
|
SpringCloudAlibaba Java 持续交付
【构建一套Spring Cloud项目的大概步骤】&【Springcloud Alibaba微服务分布式架构学习资料】
【构建一套Spring Cloud项目的大概步骤】&【Springcloud Alibaba微服务分布式架构学习资料】
159 0
|
2天前
|
存储 NoSQL Java
基于Redis实现分布式锁
基于Redis实现分布式锁
9 0
|
1月前
|
缓存 NoSQL Java
Java项目:支持并发的秒杀项目(基于Redis)
Java项目:支持并发的秒杀项目(基于Redis)
26 0
|
1月前
|
缓存 NoSQL Java
spring cache整合redis实现springboot项目中的缓存功能
spring cache整合redis实现springboot项目中的缓存功能
46 1
|
1月前
|
存储 监控 容灾
TiDB存储层深入:分布式存储架构与数据一致性保障
【2月更文挑战第26天】本文将深入探讨TiDB的存储层,详细解析其分布式存储架构、数据复制机制以及数据一致性保障措施。通过了解存储层的核心组件和工作原理,我们可以更好地理解TiDB如何确保数据的可靠性、高可用性和可扩展性。本文将从存储层的架构、数据分布、容错机制等方面展开介绍,帮助读者全面掌握TiDB存储层的关键技术和优势。
|
1月前
|
人工智能 监控 NoSQL
【万字长文 一文搞定】Redis:从新手村到大师殿堂的奥德赛之旅 9种实现分布式锁的全技术指南
【万字长文 一文搞定】Redis:从新手村到大师殿堂的奥德赛之旅 9种实现分布式锁的全技术指南
83 4

热门文章

最新文章