目前电商项目的购物车有俩种方案,
一种是类似于淘宝的登录之后才允许添加购物车,这个只需要判断一个用户的登录,如果用户登录直接添加购物车就可以,
另外一种就是今天要讲的这个类似于京东的购物车的实现,
京东的购物车是在你不登录的情况下也可以添加购物车,然后在用户登录之后会自动同步到登录用户的购物车,为什么呢?下面来说下原理:
京东的购物车,如果在用户不登录的情况下,用户添加的购物车信息默认是添加到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, "添加购物车失败"); } } }