欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

淘淘商城 项目(IDEA版)之——购物车功能实现:redis+cookies实现购物车功能

程序员文章站 2022-03-10 16:45:25
...

Redis+Cookie实现购物车功能

1、将淘淘商城原有cookie实现购物车方式修改为redis+cookie实现方式

2、新增登录之后自动同步cookie中未同步(就是未登录添加到购物车的商品)的购物车信息到redis

业务流程逻辑-加入购物车:
淘淘商城 项目(IDEA版)之——购物车功能实现:redis+cookies实现购物车功能
1、首先将jedis相关类和配置文件拷贝过来(我这里拷的是yougou-content-service目录下)
淘淘商城 项目(IDEA版)之——购物车功能实现:redis+cookies实现购物车功能
2、拷贝到yougou-cart-web中,并将applicationContext-jedis.xml 修改为springmvc-jedis.xml,里边的配置不用改,因为我的jedis文件那个包还是那个名,看下图:
淘淘商城 项目(IDEA版)之——购物车功能实现:redis+cookies实现购物车功能
淘淘商城 项目(IDEA版)之——购物车功能实现:redis+cookies实现购物车功能
3、resource.properties属性文件中如下,有注解我就不解释了
淘淘商城 项目(IDEA版)之——购物车功能实现:redis+cookies实现购物车功能
resource.properties

#购物车在cookie中保存的key
CART_KEY=CART_KEY
#cookie购物车商品的有效期,默认为7天
CART_EXPIRE=604800
#登录系统的URL
SSO_BASE_URL=http://localhost:8089
#根据用户信息取url
SSO_USER_TOKEN=/user/token/
#购物车key
REDIS_CART_KEY=REDIS_CART_KEY
###cookie中保存token的key
TOKEN_KEY=TOKEN_KEY
#redis购物车商品的有效期,默认为30天
REDIS_CART_EXPIRE=2592000

4、添加属性文件中新增属性的注入
淘淘商城 项目(IDEA版)之——购物车功能实现:redis+cookies实现购物车功能
5、添加 到购物车方法代码(不贴图了,一个屏截不全)

/**
 * 添加 商品到购物车
 * @param itemId
 * @param num
 * @param request
 * @param response
 * @return
 */
@RequestMapping("/cart/add/{itemId}")
public String addItemCart(@PathVariable Long itemId,
                          @RequestParam(defaultValue = "1") Integer num,
                          HttpServletRequest request,
                          HttpServletResponse response) {
    //跨域请求获取用户信息(调用抽取方法一)
    YougouResult result = getUserInfoJsonp(request);
    //取购物车商品列表(调用抽取方法二)
    List<TbItem> cartItemList = this.getCartItemList(request, result);
    //判断商品在购物车中是否存在
    boolean flag = false;
    for (TbItem tbItem : cartItemList) {
        if (tbItem.getId() == itemId.longValue()) {
            //如果存在修改数量
            tbItem.setNum(tbItem.getNum() + num);
            flag = true;
            break;
        }
    }
    //如果不存在,添加一个新的商品
    if (!flag) {
        //需要调用服务获取商品信息
        TbItem tbItem = itemService.getItemById(itemId);
        //设置购买的商品数量
        tbItem.setNum(num);
        //取一张图片
        String image = tbItem.getImage();
        if (StringUtils.isNotBlank(image)) {
            String[] images = image.split(",");
            tbItem.setImage(images[0]);
        }
        //把商品添加到购物车
        cartItemList.add(tbItem);
    }
    //保存购物车列表(调用抽取方法三)
    saveCartItemList(request, response, cartItemList, result);
    //返回添加成功页面
    return "cartSuccess";
}

抽取方法一 如下 :

/**
 * 跨域请求获取用户信息
 * @param request
 * @return
 */
private YougouResult getUserInfoJsonp(HttpServletRequest request) {
    YougouResult result = null;
    //获取cookies中token信息
    String token = CookieUtils.getCookieValue(request, TOKEN_KEY);
    if (StringUtils.isBlank(token))
        return result;
    String userInfo = HttpClientUtil.doGet(SSO_BASE_URL + SSO_USER_TOKEN + token);
    if (StringUtils.isBlank(userInfo))
        return result;
    result = YougouResult.formatToPojo(userInfo, TbUser.class);
    return result;
}

抽取方法二 如下 :

 /**
 * 查询购物车信息
 * description:此方法本应该是service(服务层)的接口,
 * 因为没有数据库操作,这块为了方便就定义到controller(控制层)了。
 * @param request
 * @return
 */
private List<TbItem> getCartItemList(HttpServletRequest request, YougouResult result) {
    String cartJson = "";
    //未登录去cookies中取购物车,已登录去redis中取购物车
    if (result == null || result.getStatus() != 200) {
        //从cookie中取购物车商品列表
        cartJson = CookieUtils.getCookieValue(request, CART_KEY, true);
    }else {
        //获取用户id
        TbUser tbUser = (TbUser) result.getData();
        //从redis中取购物车
        cartJson = jedisClient.get(REDIS_CART_KEY + ":" + tbUser.getId() + ":base");
    }
    if (StringUtils.isBlank(cartJson)) {
        //如果没有内容,返回一个空的列表
        return new ArrayList<>();
    }
    List<TbItem> itemList = JsonUtils.jsonToList(cartJson, TbItem.class);
    return itemList;
}

抽取方法三 如下 :

/**
 * 将购物车写入到cookie或redis
 * @param request
 * @param response
 * @param cartItemList
 * @param result
 */
private void saveCartItemList(HttpServletRequest request,
                              HttpServletResponse response,
                              List<TbItem> cartItemList,
                              YougouResult result) {
    //未登录写入cookies,已登录写入redis
    if (result == null || result.getStatus() != 200) {
        //把购物车列表写入cookie
        CookieUtils.setCookie(request, response, CART_KEY,
                JsonUtils.objectToJson(cartItemList), CART_EXPIRE, true);
    }else {
        //获取用户id
        TbUser tbUser = (TbUser) result.getData();
        //把购物车列表写入redis
        jedisClient.set(REDIS_CART_KEY + ":" + tbUser.getId() + ":base", JsonUtils.objectToJson(cartItemList));
        //设置key的过期时间
        jedisClient.expire(REDIS_CART_KEY + ":" + tbUser.getId() + ":base", REDIS_CART_EXPIRE);
    }
}

说明

1、查询商品调用的还是yougou-manager-service的ItemService接口。
2、获取用户信息时,使用HttpClient调用yougou-sso-web中UserController接口的getUserByToken方法,方法代码我贴到下边。
3、写入redis的key命名规则为REDIS_CART_KEY:登录用户的id:base
以上就是淘淘商城redis+cookie方式实现购物车添加,删除以及修改都是同理,这里我就不贴代码了,感兴趣的小伙伴可以下载整个项目代码,ps:完整项目完善了很多功能以及合理性哦!

完整项目下载地址:https://download.csdn.net/download/halen001/10383616


附:yougou-sso-web中UserController接口的getUserByToken方法代码

//jsonp的第二种实现方法
@RequestMapping(value = "/user/token/{token}", method = RequestMethod.GET)
@ResponseBody
public Object getUserByToken(@PathVariable String token, String callback) {
    YougouResult result = userService.getUserByToken(token);
    //判断是否为jsonp请求
    if ( StringUtils.isNotBlank(callback) ) {
        MappingJacksonValue mappingJacksonValue  = new MappingJacksonValue(result);
        mappingJacksonValue.setJsonpFunction(callback);
        return mappingJacksonValue;
    }
    return result;
}