1.介绍
1.购物车在不登陆的情况下,也可以使用
需要引入浏览器cookie的操作
2.购物车在登陆情况下,需要使用Redis和MySQL来存储数据
Redis作为购物车缓存
3.在缓存情况下,或者用户添加购物车后,允许购物车中的数据和原始数据的不一致
4.购物车同步问题
什么时候同步(结算、登陆)
同步购物车后,是否删除cookie数据
5.用户在不同客户端同时登陆
如何处理购物车数据`在这里插入代码片
2购物车添加功能
1.传递参数(商品skuId,添加数量)
2.根据skuId调用skuService查询商品信息
3.将商品详细信息分装成购物车信息
4.判断用户是否登陆
5.根据用户登陆决定走cookie的分支还是db
购物车数据写入
Cookie:response.addCookie(cookie); request.getCookies();
Cookie的跨越问题setDomain(),getDomain()
Db
3.Cookie工具类
package com.atguigu.gmall.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;
/**
* @param
* @return
*/
public class CookieUtil {
/***
* 获得cookie中的值,默认为主ip:www.gmall.com
* @param request
* @param cookieName
* @param isDecoder
* @return
*/
public static String getCookieValue(HttpServletRequest request, String cookieName, boolean isDecoder) {
Cookie[] cookies = request.getCookies();
if (cookies == null || cookieName == null){
return null;
}
String retValue = null;
try {
for (int i = 0; i < cookies.length; i++) {
if (cookies[i].getName().equals(cookieName)) {
//如果涉及中文
if (isDecoder) {
retValue = URLDecoder.decode(cookies[i].getValue(), "UTF-8");
} else {
retValue = cookies[i].getValue();
}
break;
}
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return retValue;
}
/***
* 设置cookie的值
* @param request
* @param response
* @param cookieName
* @param cookieValue
* @param cookieMaxage
* @param isEncode
*/
public static void setCookie(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);
}
// 设置域名的cookie
if (null != request) {
cookie.setDomain(getDomainName(request));
}
// 在域名的根路径下保存
cookie.setPath("/");
response.addCookie(cookie);
} catch (Exception e) {
e.printStackTrace();
}
}
/***
* 获得cookie的主域名,本系统为gmall.com,保存时使用
* @param request
* @return
*/
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];
}
System.out.println("domainName = " + domainName);
return domainName;
}
/***
* 将cookie中的内容按照key删除
* @param request
* @param response
* @param cookieName
*/
public static void deleteCookie(HttpServletRequest request, HttpServletResponse response, String cookieName) {
setCookie(request, response, cookieName, null, 0, false);
}
}
3.数据库中购物车bean类OmsCartItem
package com.atguigu.gmall.bean;
import javax.persistence.Id;
import javax.persistence.Transient;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
public class OmsCartItem implements Serializable{
@Id
private String id;
private String productId;
private String productSkuId;
private String memberId;
private BigDecimal quantity;
private BigDecimal price;
private String sp1;
private String sp2;
private String sp3;
private String productPic;
private String productName;
private String productSubTitle;
private String productSkuCode;
private String memberNickname;
private Date createDate;
private Date modifyDate;
private int deleteStatus;
private String productCategoryId;
private String productBrand;
private String productSn;
private String productAttr;
private String isChecked;
@Transient
private BigDecimal totalPrice;
//神略
}
5.购物车通用Mapper类
package com.atguigu.gmall.cart.mapper;
import com.atguigu.gmall.bean.OmsCartItem;
import tk.mybatis.mapper.common.Mapper;
/**
* Created by Steven on 2020/1/29.
*/
public interface OmsCartItemMapper extends Mapper<OmsCartItem>{
}
5.购物车实现类CartServiceImpl
package com.atguigu.gmall.cart.service.impl;
import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.atguigu.gmall.bean.OmsCartItem;
import com.atguigu.gmall.cart.mapper.OmsCartItemMapper;
import com.atguigu.gmall.manager.util.RedisUtil;
import com.atguigu.gmall.service.CartService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import redis.clients.jedis.Jedis;
import tk.mybatis.mapper.entity.Example;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Created by Steven on 2020/1/29.
*/
@Service
public class CartServiceImpl implements CartService{
@Autowired
OmsCartItemMapper omsCartItemMapper;
@Autowired
RedisUtil redisUtil;
@Override
public OmsCartItem ifCartExistsByUser(String memberId, String skuId) {
OmsCartItem omsCartItem=new OmsCartItem();
omsCartItem.setMemberId(memberId);
omsCartItem.setProductSkuId(skuId);
OmsCartItem omsCartItem1 = omsCartItemMapper.selectOne(omsCartItem);
return omsCartItem1;
}
@Override
public void addCart(OmsCartItem omsCartItem) {
if(StringUtils.isNotBlank(omsCartItem.getMemberId())){
omsCartItemMapper.insertSelective(omsCartItem);
}
}
@Override
public void updateCart(OmsCartItem omsCartItemFromDb) {
Example example=new Example(OmsCartItem.class);
example.createCriteria().andEqualTo("id",omsCartItemFromDb.getId());
omsCartItemMapper.updateByExampleSelective(omsCartItemFromDb,example);
}
@Override
public void flushCartCache(String memberId) {
OmsCartItem omsCartItem = new OmsCartItem();
omsCartItem.setMemberId(memberId);
List<OmsCartItem> omsCartItems = omsCartItemMapper.select(omsCartItem);
//同步到Redis缓存中
Jedis jedis = redisUtil.getJedis();
Map<String,String> map=new HashMap<>();
for (OmsCartItem cartItem : omsCartItems) {
map.put(cartItem.getProductId(), JSON.toJSONString(cartItem));
}
jedis.del("member:"+memberId+":cart");
jedis.hmset("member:"+memberId+":cart",map);
jedis.close();
}
@Override
public List<OmsCartItem> cartList(String memberId) {
Jedis jedis=null;
List<OmsCartItem> omsCartItems=new ArrayList<>();
try {
jedis = redisUtil.getJedis();
List<String> hvals = jedis.hvals("member:" + memberId + ":cart");
for (String hval : hvals) {
OmsCartItem omsCartItem = JSON.parseObject(hval, OmsCartItem.class);
omsCartItems.add(omsCartItem);
}
}catch (Exception e){
e.printStackTrace();
return null;
}finally {
jedis.close();
}
return omsCartItems;
}
@Override
public void checkCart(OmsCartItem omsCartItem) {
Example e=new Example(OmsCartItem.class);
e.createCriteria().andEqualTo("memberId",omsCartItem.getMemberId()).andEqualTo("productSkuId",omsCartItem.getProductSkuId());
omsCartItemMapper.updateByExampleSelective(omsCartItem,e);
//同步缓存
flushCartCache(omsCartItem.getMemberId());
}
}
5.购物车实现类CartController
package com.atguigu.gmall.cart.controller;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSON;
import com.atguigu.gmall.bean.OmsCartItem;
import com.atguigu.gmall.bean.PmsSkuInfo;
import com.atguigu.gmall.service.CartService;
import com.atguigu.gmall.service.SkuService;
import com.atguigu.gmall.util.CookieUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* Created by Steven on 2020/1/28.
*/
@Controller
public class CartController {
@Reference
SkuService skuService;
@Reference
CartService cartService;
@RequestMapping("checkCart")
public String checkCart(String isChecked,String skuId,HttpServletRequest request, HttpServletResponse response, ModelMap modelMap){
String memberId="1";
//调用服务,修改状态
OmsCartItem omsCartItem=new OmsCartItem();
omsCartItem.setProductSkuId(skuId);
omsCartItem.setMemberId(memberId);
omsCartItem.setIsChecked(isChecked);
cartService.checkCart(omsCartItem);
//将最新数据查出,渲染给内嵌页
List<OmsCartItem> omsCartItems = cartService.cartList(memberId);
modelMap.put("cartList",omsCartItems);
//被勾选商品的总额
BigDecimal totalAmount=getTotalAmount(omsCartItems);
modelMap.put("totalAmount",totalAmount);
return "cartListInner";
}
@RequestMapping("cartList")
public String cartList(HttpServletRequest request, HttpServletResponse response, ModelMap modelMap){
List<OmsCartItem> omsCartItems=new ArrayList<>();
String memberId="1";
if (StringUtils.isNotBlank(memberId)){
omsCartItems=cartService.cartList(memberId);
}else {
//没有登陆查询cookie
String cartListCookie = CookieUtil.getCookieValue(request, "cartListCookie", true);
if(StringUtils.isNotBlank(cartListCookie)){
omsCartItems=JSON.parseArray(cartListCookie,OmsCartItem.class);
}
}
for (OmsCartItem omsCartItem : omsCartItems) {
omsCartItem.setTotalPrice(omsCartItem.getPrice().multiply(omsCartItem.getQuantity()));
}
modelMap.put("cartList",omsCartItems);
//被勾选商品的总额
BigDecimal totalAmount=getTotalAmount(omsCartItems);
modelMap.put("totalAmount",totalAmount);
return "cartList";
}
private BigDecimal getTotalAmount(List<OmsCartItem> omsCartItems) {
BigDecimal totalAmount=new BigDecimal("0");
for (OmsCartItem omsCartItem : omsCartItems) {
BigDecimal totalPrice = omsCartItem.getTotalPrice();
if(omsCartItem.getIsChecked().equals("1")){
totalAmount.add(totalPrice);
}
}
return totalAmount;
}
@RequestMapping("addToCart")
public String addToCart(String skuId, int quantity, HttpServletRequest request, HttpServletResponse response) {
List<OmsCartItem> omsCartItems = new ArrayList<>();
//调用商品服务查询商品信息
PmsSkuInfo skuInfo = skuService.getSkuById(skuId, "");
//将商品信息封装成购物车信息
OmsCartItem omsCartItem=new OmsCartItem();
omsCartItem.setCreateDate(new Date());
omsCartItem.setDeleteStatus(0);
omsCartItem.setModifyDate(new Date());
omsCartItem.setPrice(skuInfo.getPrice());
omsCartItem.setProductAttr("");
omsCartItem.setProductBrand("");
omsCartItem.setProductCategoryId(skuInfo.getCatalog3Id());
omsCartItem.setProductId(skuInfo.getProductId());
omsCartItem.setProductName(skuInfo.getSkuName());
omsCartItem.setProductPic(skuInfo.getSkuDefaultImg());
omsCartItem.setProductSkuCode("123456");
omsCartItem.setProductSkuId(skuInfo.getId());
omsCartItem.setQuantity(new BigDecimal(quantity));
//判断用户是否登陆
String memberId = "1";
if(StringUtils.isBlank(memberId)) {
//用户没有登陆
//cookie原有的购物车数据
String cartListCookie = CookieUtil.getCookieValue(request, "cartListCookie", true);
if (StringUtils.isBlank(cartListCookie)) {
//cookie为空
omsCartItems.add(omsCartItem);
} else {
//cookie不为空
omsCartItems = JSON.parseArray(cartListCookie, OmsCartItem.class);
//判断添加的数据在购物车中是否存在
boolean exist = if_cart_exist(omsCartItems, omsCartItem);
if (exist) {
//前添加过,更新购物车添加数量
for (OmsCartItem cartItem : omsCartItems) {
if(cartItem.getProductSkuId().equals(omsCartItem.getProductSkuId())){
cartItem.setQuantity(cartItem.getQuantity().add(omsCartItem.getQuantity()));
}
}
} else {
//之前没添加过,新增当前的购物车
omsCartItems.add(omsCartItem);
}
}
//更新cookie
CookieUtil.setCookie(request, response, "cartListCookie", JSON.toJSONString(omsCartItems), 60 * 60 * 73, true);
}else{
//用户已经登陆
//从db中查出购物车数据
OmsCartItem omsCartItemFromDb=cartService.ifCartExistsByUser(memberId,skuId);
if(omsCartItemFromDb==null){
//该用户没有添加过购物车商品
omsCartItem.setMemberId(memberId);
omsCartItem.setMemberNickname("Steven");
omsCartItem.setQuantity(new BigDecimal(quantity));
cartService.addCart(omsCartItem);
}else{
//该用户添加过购物车商品
omsCartItemFromDb.setQuantity(omsCartItem.getQuantity().add(omsCartItemFromDb.getQuantity()));
cartService.updateCart(omsCartItemFromDb);
}
//同步缓存
cartService.flushCartCache(memberId);
}
return "redirect:/success.html";
}
private boolean if_cart_exist(List<OmsCartItem> omsCartItems, OmsCartItem omsCartItem) {
boolean flag=false;
for (OmsCartItem cartItem : omsCartItems) {
String productSkuId = cartItem.getProductSkuId();
if(productSkuId.equals(omsCartItem.getProductSkuId())){
flag=true;
}
}
return flag;
}
}
版权声明:本文为SuperstarSteven原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。