购物车逻辑分析及代码
一定要看懂了图再写 看懂了图再写 看懂了图再写
//4.a.如果未登录, 则将购物车列表存入cookie中 只能存字符串 要转义
String carListJsonStr = JSON.toJSONString(cartList);
CookieUtil.setCookie(request, response, Constants.COOKIE_CARTLIST, carListJsonStr, 3600 * 24 * 30, "utf-8");
Constants
package cn.itcast.core.util; /** * 常量 */ public interface Constants { public final static String REDIS_CONTENT_LIST = "contentList"; public final static String REDIS_CATEGORYLIST = "categoryList"; public final static String REDIS_BRANDLIST = "brandList"; public final static String REDIS_SPECLIST = "specList"; public final static String COOKIE_CARTLIST = "pyg_cartList"; public final static String REDIS_CARTLIST = "pyg_cartList"; }
CookieUtil
package cn.itcast.core.util; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.net.URLEncoder; /** * * Cookie 工具类 * */ public final class CookieUtil { /** * 得到Cookie的值, 不编码 * * @param request * @param cookieName * @return */ public static String getCookieValue(HttpServletRequest request, String cookieName) { return getCookieValue(request, cookieName, false); } /** * 得到Cookie的值, * * @param request * @param cookieName * @return */ public static String getCookieValue(HttpServletRequest request, String cookieName, boolean isDecoder) { Cookie[] cookieList = request.getCookies(); if (cookieList == null || cookieName == null) { return null; } String retValue = null; try { for (int i = 0; i < cookieList.length; i++) { if (cookieList[i].getName().equals(cookieName)) { if (isDecoder) { retValue = URLDecoder.decode(cookieList[i].getValue(), "UTF-8"); } else { retValue = cookieList[i].getValue(); } break; } } } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return retValue; } /** * 得到Cookie的值, * * @param request * @param cookieName * @return */ public static String getCookieValue(HttpServletRequest request, String cookieName, String encodeString) { Cookie[] cookieList = request.getCookies(); if (cookieList == null || cookieName == null) { return null; } String retValue = null; try { for (int i = 0; i < cookieList.length; i++) { if (cookieList[i].getName().equals(cookieName)) { retValue = URLDecoder.decode(cookieList[i].getValue(), encodeString); break; } } } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return retValue; } /** * 设置Cookie的值 不设置生效时间默认浏览器关闭即失效,也不编码 */ public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName, String cookieValue) { setCookie(request, response, cookieName, cookieValue, -1); } /** * 设置Cookie的值 在指定时间内生效,但不编码 */ public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName, String cookieValue, int cookieMaxage) { setCookie(request, response, cookieName, cookieValue, cookieMaxage, false); } /** * 设置Cookie的值 不设置生效时间,但编码 */ public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName, String cookieValue, boolean isEncode) { setCookie(request, response, cookieName, cookieValue, -1, isEncode); } /** * 设置Cookie的值 在指定时间内生效, 编码参数 */ public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName, String cookieValue, int cookieMaxage, boolean isEncode) { doSetCookie(request, response, cookieName, cookieValue, cookieMaxage, isEncode); } /** * 设置Cookie的值 在指定时间内生效, 编码参数(指定编码) */ public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName, String cookieValue, int cookieMaxage, String encodeString) { doSetCookie(request, response, cookieName, cookieValue, cookieMaxage, encodeString); } /** * 删除Cookie带cookie域名 */ public static void deleteCookie(HttpServletRequest request, HttpServletResponse response, String cookieName) { doSetCookie(request, response, cookieName, "", -1, false); } /** * 设置Cookie的值,并使其在指定时间内生效 * * @param cookieMaxage cookie生效的最大秒数 */ private static final void doSetCookie(HttpServletRequest request, HttpServletResponse response, String cookieName, String cookieValue, int cookieMaxage, boolean isEncode) { try { if (cookieValue == null) { cookieValue = ""; } else if (isEncode) { cookieValue = URLEncoder.encode(cookieValue, "utf-8"); } Cookie cookie = new Cookie(cookieName, cookieValue); if (cookieMaxage > 0) cookie.setMaxAge(cookieMaxage); if (null != request) {// 设置域名的cookie String domainName = getDomainName(request); System.out.println(domainName); if (!"localhost".equals(domainName)) { cookie.setDomain(domainName); } } cookie.setPath("/"); response.addCookie(cookie); } catch (Exception e) { e.printStackTrace(); } } /** * 设置Cookie的值,并使其在指定时间内生效 * * @param cookieMaxage cookie生效的最大秒数 */ private static final void doSetCookie(HttpServletRequest request, HttpServletResponse response, String cookieName, String cookieValue, int cookieMaxage, String encodeString) { try { if (cookieValue == null) { cookieValue = ""; } else { cookieValue = URLEncoder.encode(cookieValue, encodeString); } Cookie cookie = new Cookie(cookieName, cookieValue); if (cookieMaxage > 0) cookie.setMaxAge(cookieMaxage); if (null != request) {// 设置域名的cookie String domainName = getDomainName(request); System.out.println(domainName); if (!"localhost".equals(domainName)) { cookie.setDomain(domainName); } } cookie.setPath("/"); response.addCookie(cookie); } catch (Exception e) { e.printStackTrace(); } } /** * 得到cookie的域名 */ private static final String getDomainName(HttpServletRequest request) { String domainName = null; String serverName = request.getRequestURL().toString(); if (serverName == null || serverName.equals("")) { domainName = ""; } else { serverName = serverName.toLowerCase(); serverName = serverName.substring(7); final int end = serverName.indexOf("/"); serverName = serverName.substring(0, end); final String[] domains = serverName.split("\\."); int len = domains.length; if (len > 3) { // www.xxx.com.cn domainName = "." + domains[len - 3] + "." + domains[len - 2] + "." + domains[len - 1]; } else if (len <= 3 && len > 1) { // xxx.com or xxx.cn domainName = "." + domains[len - 2] + "." + domains[len - 1]; } else { domainName = serverName; } } if (domainName != null && domainName.indexOf(":") > 0) { String[] ary = domainName.split("\\:"); domainName = ary[0]; } return domainName; } }
CartController
package cn.itcast.core.controller; import cn.itcast.core.pojo.entity.BuyerCart; import cn.itcast.core.pojo.entity.Result; import cn.itcast.core.service.BuyerCartService; import cn.itcast.core.util.Constants; import cn.itcast.core.util.CookieUtil; import com.alibaba.dubbo.config.annotation.Reference; import com.alibaba.fastjson.JSON; 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 javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.List; /** * 购物车业务 */ @RestController @RequestMapping("/cart") public class CartController { @Reference private BuyerCartService buyerCartService; @Autowired private HttpServletRequest request; @Autowired private HttpServletResponse response; /** * 添加商品到购物车中 * @param itemId 购买商品的库存id * @param num 购买数量 * @return */ @RequestMapping("/addGoodsToCartList") //解决跨域访问, origins="http://localhost:8086"指定响应返回到哪台服务器 @CrossOrigin(origins="http://localhost:8086",allowCredentials="true") public Result addGoodsToCartList(Long itemId, Integer num) { //1. 获取当前登录用户名称 String userName = SecurityContextHolder.getContext().getAuthentication().getName(); //2. 获取购物车列表 List<BuyerCart> cartList = findCartList(); //3. 将当前商品加入到购物车列表 cartList = buyerCartService.addItemToCartList(cartList, itemId, num); //4. 判断当前用户是否登录, 未登录用户名为"anonymousUser" if ("anonymousUser".equals(userName)) { //4.a.如果未登录, 则将购物车列表存入cookie中 String carListJsonStr = JSON.toJSONString(cartList); CookieUtil.setCookie(request, response, Constants.COOKIE_CARTLIST, carListJsonStr, 3600 * 24 * 30, "utf-8"); } else { //4.b.如果已登录, 则将购物车列表存入redis中 buyerCartService.setCartListToRedis(userName, cartList); } return new Result(true, "添加成功!"); } /** * 查询当前用户的购物车列表数据并返回 * @return */ @RequestMapping("/findCartList") public List<BuyerCart> findCartList() { //1. 获取当前登录用户名称 String userName = SecurityContextHolder.getContext().getAuthentication().getName(); //2. 从cookie中获取购物车列表json格式字符串 String cookieCartListJsonStr = CookieUtil.getCookieValue(request, Constants.COOKIE_CARTLIST, "utf-8"); //3. 如果购物车列表json串为空则返回"[]" if (cookieCartListJsonStr == null || "".equals(cookieCartListJsonStr)) { cookieCartListJsonStr = "[]"; } //4. 将购物车列表json转换为对象 List<BuyerCart> cookieCartList = JSON.parseArray(cookieCartListJsonStr, BuyerCart.class); //5. 判断用户是否登录, 未登录用户为"anonymousUser" if ("anonymousUser".equals(userName)) { //5.a. 未登录, 返回cookie中的购物车列表对象 return cookieCartList; } else { //5.b.1.已登录, 从redis中获取购物车列表对象 List<BuyerCart> redisCartList = buyerCartService.getCartListFromRedis(userName); //5.b.2.判断cookie中是否存在购物车列表 if (cookieCartList != null && cookieCartList.size() > 0) { //如果cookie中存在购物车列表则和redis中的购物车列表合并成一个对象 redisCartList = buyerCartService.mergeCookieCartListToRedisCartList(cookieCartList, redisCartList); //删除cookie中购物车列表 CookieUtil.deleteCookie(request, response, Constants.COOKIE_CARTLIST); //将合并后的购物车列表存入redis中 buyerCartService.setCartListToRedis(userName, redisCartList); } //5.b.3.返回购物车列表对象 return redisCartList; } } }
BuyerCartService
package cn.itcast.core.service; import cn.itcast.core.pojo.entity.BuyerCart; import java.util.List; public interface BuyerCartService { //添加商品到购物车列表Service方法业务如下: List<BuyerCart> addItemToCartList(List<BuyerCart> cartList, Long itemId, Integer num); //将购物车列表添加到redis中 void setCartListToRedis(String userName, List<BuyerCart> cartList); //将购物车列表从redis中取出 List<BuyerCart> getCartListFromRedis(String userName); //将cookie中的购物车集合 合并到redis的购物车集合中返回 List<BuyerCart> mergeCookieCartListToRedisCartList(List<BuyerCart> cookieCartList, List<BuyerCart> redisCartList); }
BuyerCartServiceImpl
package cn.itcast.core.service; import cn.itcast.core.dao.item.ItemDao; import cn.itcast.core.pojo.entity.BuyerCart; import cn.itcast.core.pojo.item.Item; import cn.itcast.core.pojo.order.OrderItem; import cn.itcast.core.util.Constants; import com.alibaba.dubbo.config.annotation.Service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; @Service public class BuyerCartServiceImpl implements BuyerCartService { @Autowired private RedisTemplate redisTemplate; @Autowired private ItemDao itemDao; /** * 将购物车列表添加到redis中 * * @param userName 登录用户的用户名 * @param cartList 购物车列表 */ @Override public void setCartListToRedis(String userName, List<BuyerCart> cartList) { redisTemplate.boundHashOps(Constants.REDIS_CARTLIST).put(userName, cartList); } /** * 将购物车列表从redis中取出 * @param userName 登录用户的用户名 */ @Override public List<BuyerCart> getCartListFromRedis(String userName) { List<BuyerCart> cartList = (List<BuyerCart>) redisTemplate.boundHashOps(Constants.REDIS_CARTLIST).get(userName); if (cartList == null) { cartList = new ArrayList<BuyerCart>(); } return cartList; } /** * 将cookie中的购物车集合 合并到redis的购物车集合中返回 * * @param cookieCartList cookie中的购物车集合 * @param redisCartList redis的购物车集合 * @return */ @Override public List<BuyerCart> mergeCookieCartListToRedisCartList(List<BuyerCart> cookieCartList, List<BuyerCart> redisCartList) { if (cookieCartList != null) { //遍历ookie中的购物车集合 for (BuyerCart Cart : cookieCartList) { List<OrderItem> orderItemList = Cart.getOrderItemList(); if (orderItemList != null) { //遍历cookie中的购物项集合 for (OrderItem orderItem : orderItemList) { //把cookie中的购物项添加到redis的购物项集合中 redisCartList = addItemToCartList(redisCartList, orderItem.getItemId(), orderItem.getNum()); } } } } return redisCartList; } /** * 添加商品到这个人拥有的购物购物车列表中 * * @param cartList 现在所拥有的购物车列表 * @param itemId 库存id * @param num 购买数量 * @return 返回添加完后的购物车列表 */ @Override public List<BuyerCart> addItemToCartList(List<BuyerCart> cartList, Long itemId, Integer num) { //1. 根据商品SKU ID查询SKU商品信息 Item item = itemDao.selectByPrimaryKey(itemId); //2. 判断商品是否存在不存在, 抛异常 if (item == null) { throw new RuntimeException("您购买的商品不存在"); } //3. 判断商品状态是否为1已审核, 状态不对抛异常 if (!"1".equals(item.getStatus())) { throw new RuntimeException("您购买的商品非法"); } //4.获取商家ID sellerId String sellerId = item.getSellerId(); //5.根据商家ID查询购物车列表中是否存在该商家的购物车 BuyerCart buyerCart = findCartBySellerId(sellerId, cartList); //6.判断如果购物车列表中不存在该商家的购物车 if (buyerCart == null) { //6.a.1 新建购物车对象 buyerCart = new BuyerCart(); //向购物车加入卖家id buyerCart.setSellerId(sellerId); //向购物车加入卖家名字Seller() buyerCart.setSellerName(item.getSeller()); //创建购物车中需要的购物项集合 List<OrderItem> orderItemList = new ArrayList<>(); //创建购物项对象 OrderItem orderItem = creatOrderItem(item, num); //将购物项数据一个个加入 //将购物项加入到购物项集合中 orderItemList.add(orderItem); //向购物车加入购物项集合 buyerCart.setOrderItemList(orderItemList); //6.a.2 将新建的购物车对象添加到购物车列表 cartList.add(buyerCart); } else { //6.b.1如果购物车列表中存在该商家的购物车 (查询购物车明细列表中是否存在该商品) List<OrderItem> orderItemList = buyerCart.getOrderItemList(); OrderItem orderItem = findOrderItemByItemId(orderItemList, itemId); //6.b.2判断购物车明细是否为空 if (orderItem == null) { //6.b.3为空,新增购物车明细 orderItem = creatOrderItem(item, num); //将新建的购物项对象放到购物项集合中 orderItemList.add(orderItem); } else { //6.b.4不为空,在原购物车明细上添加数量,更改金额 orderItem.setNum(orderItem.getNum() + num); orderItem.setTotalFee(orderItem.getPrice().multiply(new BigDecimal(orderItem.getNum()))); } //6.b.5如果购物车明细中数量操作后小于等于0,则移除 if (orderItem.getNum() <= 0) { orderItemList.remove(orderItem); } //6.b.6如果购物车中购物车明细列表为空,则移除 if (orderItemList.size() == 0) { cartList.remove(buyerCart); } } //7. 返回购物车列表对象 return cartList; } /** * 从购物项集合中找符合itemId的同款购物项 * @param orderItemList 购物项集合 * @param itemId 库存id * @return */ private OrderItem findOrderItemByItemId(List<OrderItem> orderItemList, Long itemId) { if (orderItemList != null) { for (OrderItem orderItem : orderItemList) { if (itemId.equals(orderItem.getItemId())) { return orderItem; } } } return null; } /** * 从购物车列表中获取这个卖家的购物车 * * @param sellerId * @param cartList * @return */ private BuyerCart findCartBySellerId(String sellerId, List<BuyerCart> cartList) { //5.根据商家ID查询购物车列表中是否存在该商家的购物车 if (cartList != null) { for (BuyerCart Cart : cartList) { if (sellerId.equals(Cart.getSellerId())) { return Cart; } } } return null; } /** * 创建购物项对象 * @param item 库存对象 * @param num 购买数量 * @return */ private OrderItem creatOrderItem(Item item, Integer num) { if (num == null || num <= 0) { throw new RuntimeException("购买数量非法"); } OrderItem orderItem = new OrderItem(); //库存标题 orderItem.setTitle(item.getTitle()); //购买数量 orderItem.setNum(num); //商品id orderItem.setGoodsId(item.getGoodsId()); //库存id orderItem.setItemId(item.getId()); //卖家id orderItem.setSellerId(item.getSellerId()); //示例图片地址 orderItem.setPicPath(item.getImage()); //商品单价 orderItem.setPrice(item.getPrice()); //总价 = 单价 * 购买数量 orderItem.setTotalFee(orderItem.getPrice().multiply(new BigDecimal(orderItem.getNum()))); return orderItem; } }
版权声明:本文为lei0913原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。