购物车的实现以及原理

目前电商项目的购物车有俩种方案,

一种是类似于淘宝的登录之后才允许添加购物车,这个只需要判断一个用户的登录,如果用户登录直接添加购物车就可以,

另外一种就是今天要讲的这个类似于京东的购物车的实现,

京东的购物车是在你不登录的情况下也可以添加购物车,然后在用户登录之后会自动同步到登录用户的购物车,为什么呢?下面来说下原理:

京东的购物车,如果在用户不登录的情况下,用户添加的购物车信息默认是添加到cookie里面的,但是已经登录的用户数据是存放到redis里面的,这里就涉及到了一个cookie数据和redis数据合并的一个实现,代码如下:

package com.pinyougou.cart.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSON;
import com.pinyougou.cart.service.CartService;
import com.pinyougou.pojo.group.Cart;
import entity.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import util.CookieUtil;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

@RestController
@RequestMapping("/cart")
public class CartController {

    @Autowired
    private HttpServletRequest request;//引入request对象

    @Autowired
    private HttpServletResponse response;//引入response对象

    @Reference
    private CartService cartService;//调用购物车的service层(因为这里分布式框架使用的是dubbo,所以用到@Reference注解,正常的话可以直接使用@Autowired或者@Resource注解就可以)

    @RequestMapping("/findCartList")
    public List<Cart> findCartList() {//查找购物车的方法
       /**
        *这里的用户登录使用的是CAS的验证中心
        */
        String name = SecurityContextHolder.getContext().getAuthentication().getName();//获取登录用户的名称
        String cookieValue = CookieUtil.getCookieValue(request, "cartList", "UTF-8");//获取保存在cookie里的购物车
        if (cookieValue == null || cookieValue.equals("")) {
            cookieValue = "[]";
        }
        List<Cart> carts_cookie = JSON.parseArray(cookieValue, Cart.class);//把从cookie里获取到的数据转成一个购物车集合
        if (name.equals("anonymousUser")) {//anonymousUser是没有登录并且持有CAS票据的一个用户,如果用户是anonymousUser说明用户没有登录,则返回cookie里的购物车列表
            return carts_cookie;
        } else {//否则的话根据登录的用户去redis去查询这个用户已经存在的购物车
            List<Cart> carts_redis = cartService.findCartListFromRedis(name);
            if (carts_cookie.size() > 0) {//当cookie里有数据的时候,在进行一个cookie与redis数据的合并,合并完清除cookie里的购物车数据,这里为了保证代码的健壮性,所以进行一个判断,否则服务器的压力会很大
                List<Cart> carts = cartService.mergeCartList(carts_cookie, carts_redis);
                cartService.saveCartListToRedis(name, carts);
                util.CookieUtil.deleteCookie(request, response, "cartList");
                return carts;
            }

            return carts_redis;
        }
    }

    @RequestMapping("/addGoodsToCartList")//添加购物车的方法
    public Result addGoodsToCartList(Long itemId, Integer num) {
        String name = SecurityContextHolder.getContext().getAuthentication().getName();
        System.out.println(name);
        try {

            List<Cart> cartList = findCartList();
            cartList = cartService.addGoodsToCartList(cartList, itemId, num);
            if (name.equals("anonymousUser")) {//如果用户没有登录,把购物车信息添加到cookie里面
                String s = JSON.toJSONString(cartList);
                util.CookieUtil.setCookie(request, response, "cartList", s, 3600 * 24, "UTF-8");
            } else {//否则添加数据到redis
                cartService.saveCartListToRedis(name, cartList);
            }
            return new Result(true, "添加购物车成功");
        } catch (Exception e) {
            return new Result(false, "添加购物车失败");
        }
    }
}

猜你喜欢

转载自blog.csdn.net/King_1768/article/details/89252085