1.1 需求分析
- 使用Cookie存储购物车数据,服务层负责业务逻辑,控制器层负责读写cookie。
- 说明:Cookie的value存储List<Cart> 的json格式字符串数据(中文需要Unicode编码,因为cookie的值不能存在中文字符)
- 总结:
实现cookie存储购物车控制器层代码:
cookieName: pinyougou_cart
cookieValue: List<Cart>集合转化成json格式的字符串,有中文需要转码。- 实现步骤:
- 定义CartController.java控制器,读写购物车。
把商品添加到购物车,再把购物车存储Cookie
先从浏览器中获取Cookie,从Cookie中获取原来的购物车
- 详细步骤:(未登录的用户,购物车存储到Cookie)
- 获取购物车
- 把商品添加到购物车
- 把添加后的购物车存储到Cookie
- Cookie工具类(放在common工程中)
public final class CookieUtils { /** 定义Cookie名称的静态内部类 */ public static class CookieName{ /** 定义存放在Cookie中购物车的名称 */ public static final String PINYOUGOU_CART = "pinyougou_cart"; } /** * 根据Cookie的名称获取指定的Cookie * @param request 请求对象 * @param cookieName cookie的名称 * @return Cookie */ public static Cookie getCookie(HttpServletRequest request, String cookieName){ /** 获取所有的Cookie */ Cookie[] cookies = request.getCookies(); if (cookies != null && cookies.length > 0){ for (Cookie cookie : cookies){ if (cookie.getName().equals(cookieName)){ return cookie; } } } return null; } /** * 根据CookieName获取指定的Cookie值 * @param request 请求对象 * @param cookieName cookie的名称 * @param encoded 是否编码 * @return Cookie的值 */ public static String getCookieValue(HttpServletRequest request, String cookieName, boolean encoded) { /** 获取指定的Cookie */ Cookie cookie = getCookie(request, cookieName); String cookieValue = null; try { if (cookie != null) { if (encoded){ cookieValue = URLDecoder.decode(cookie.getValue(), "UTF-8"); }else{ cookieValue = cookie.getValue(); } } } catch (Exception e) { e.printStackTrace(); } return cookieValue; } /** * 根据Cookie的名称删除指定的Cookie * @param request 请求对象 * @param response 响应对象 * @param cookieName cookie名称 */ public static void deleteCookie(HttpServletRequest request, HttpServletResponse response, String cookieName) { setCookie(request, response, cookieName, null, 0, false); } /** * 设置Cookie * @param request 请求对象 * @param response 响应对象 * @param cookieName cookie的名称 * @param cookieValue cookie的值 * @param maxAge 存放Cookie的最大存放时间(按秒计算) * @param encoded 是否编码 */ public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName, String cookieValue, int maxAge, boolean encoded) { try { /** 对Cookie的值进行判断 */ if (cookieValue == null) { cookieValue = ""; } if (encoded) { cookieValue = URLEncoder.encode(cookieValue, "UTF-8"); } Cookie cookie = getCookie(request, cookieName); if (cookie == null){ cookie = new Cookie(cookieName, cookieValue); } /** 设置Cookie的值 */ cookie.setValue(cookieValue); /** 设置最大存活时间 */ cookie.setMaxAge(maxAge); /** 设置访问路径 */ cookie.setPath("/"); /** 添加到用户浏览器 */ response.addCookie(cookie); } catch (Exception e) { e.printStackTrace(); } } }
CartController.java控制器:
/** 购物车控制器 */ @RestController @RequestMapping("/cart") public class CartController { @Reference(timeout = 30000) private CartService cartService; @Autowired private HttpServletRequest request; @Autowired private HttpServletResponse response;
/** 添加SKU商品到购物车 */ @GetMapping("/addCart") public boolean addCart(Long itemId, Integer num){ try{ // 获取购物车集合 List<Cart> carts = findCart(); // 调用服务层添加SKU商品到购物车 carts = cartService.addItemToCart(carts, itemId, num); // 将购物车重新存入Cookie中 CookieUtils.setCookie(request, response, CookieUtils.CookieName.PINYOUGOU_CART, JSON.toJSONString(carts), 3600 * 24, true); return true; }catch (Exception ex){ ex.printStackTrace(); } return false; }
/** 获取购物车集合 */
@GetMapping("/findCart")
public List<Cart> findCart() {
// 从Cookie中获取购物车集合json字符串
String cartStr = CookieUtils.getCookieValue(request,
CookieUtils.CookieName.PINYOUGOU_CART, true);
// 判断是否为空
if (StringUtils.isBlank(cartStr)){
cartStr = "[]";
}
List<Cart> carts = JSON.parseArray(cartStr, Cart.class);
return carts;
}
}
服务接口层:
CartService.java:
/** 购物车服务接口 */
public interface CartService {
/**
* 添加SKU商品到购物车
* @param carts 购物车(一个Cart对应一个商家)
* @param itemId SKU商品id
* @param num 购买数据
* @return 修改后的购物车
*/
List<Cart> addItemToCart(List<Cart> carts,
Long itemId, Integer num);
}
服务实现层:
- 实现思路:(对照上图结构去实现)
- 根据SKU商品ID查询SKU商品对象。
- 获取商家ID
- 根据商家ID判断购物车集合中是否存在该商家的购物车
- 如果购物车集合中不存在该商家的购物车
4.1 创建新的购物车对象
4.2 将新的购物车对象添加到购物车集合- 如果购物车集合中存在该商家的购物车
5.1 判断购物车订单明细集合中是否存在该商品
5.2 如果没有,新增购物车订单明细
5.3 如果有,在原购物车订单明细上添加数量,更改金额
创建服务接口实现类CartServiceImpl.java:
/** 购物车服务接口实现类 */
@Service(interfaceName = "com.pinyougou.cart.service.CartService")
@Transactional
public class CartServiceImpl implements CartService {
@Autowired
private ItemMapper itemMapper;
/**
* 添加SKU商品到购物车
* @param carts 购物车(一个Cart对应一个商家)
* @param itemId SKU商品id
* @param num 购买数据
* @return 修改后的购物车
*/
public List<Cart> addItemToCart(List<Cart> carts,
Long itemId, Integer num){
try{
// 根据SKU商品ID查询SKU商品对象
Item item = itemMapper.selectByPrimaryKey(itemId);
// 获取商家id
String sellerId = item.getSellerId();
// 根据商家id判断购物车集合中是否存在该商家的购物车
Cart cart = searchCartBySellerId(carts, sellerId);
if (cart == null){ // 购物车集合中不存在该商家购物车
// 创建新的购物车对象
cart = new Cart();
cart.setSellerId(sellerId);
cart.setSellerName(item.getSeller());
// 创建订单明细(购物中一个商品)
OrderItem orderItem = createOrderItem(item, num);
List<OrderItem> orderItems = new ArrayList<>(0);
orderItems.add(orderItem);
// 为购物车设置订单明细集合
cart.setOrderItems(orderItems);
// 将新的购物车对象添加到购物车集合
carts.add(cart);
}else{ // 购物车集合中存在该商家购物车
// 判断购物车订单明细集合中是否存在该商品
OrderItem orderItem = searchOrderItemByItemId(
cart.getOrderItems(), itemId);
if (orderItem == null){
// 如果没有,新增购物车订单明细
orderItem = createOrderItem(item, num);
cart.getOrderItems().add(orderItem);
}else{
// 如果有,在原购物车订单明细上添加数量,更改金额
orderItem.setNum(orderItem.getNum() + num);
orderItem.setTotalFee(new BigDecimal(
orderItem.getPrice().doubleValue()
* orderItem.getNum()));
// 如果订单明细的购买数小于等于0,则删除
if (orderItem.getNum() <= 0){
// 删除购物车中的订单明细(商品)
cart.getOrderItems().remove(orderItem);
}
// 如果cart的orderItems订单明细为0,则删除cart
if (cart.getOrderItems().size() == 0){
carts.remove(cart);
}
}
}
return carts;
}catch (Exception ex){
throw new RuntimeException(ex);
}
}
/** 从购物车集合中获取该商家的购物车 */
private Cart searchCartBySellerId(
List<Cart> carts, String sellerId) {
for (Cart cart : carts){
if (cart.getSellerId().equals(sellerId)){
return cart;
}
}
return null;
}
/** 创建订单明细 */
private OrderItem createOrderItem(Item item, Integer num) {
// 创建订单明细
OrderItem orderItem = new OrderItem();
orderItem.setSellerId(item.getSellerId());
orderItem.setGoodsId(item.getGoodsId());
orderItem.setItemId(item.getId());
orderItem.setNum(num);
orderItem.setPicPath(item.getImage());
orderItem.setPrice(item.getPrice());
orderItem.setTitle(item.getTitle());
// 小计
orderItem.setTotalFee(new BigDecimal(
item.getPrice().doubleValue() * num));
return orderItem;
}
/** 从订单明细集合中获取指定订单明细 */
private OrderItem searchOrderItemByItemId(
List<OrderItem> orderItems, Long itemId) {
for (OrderItem orderItem : orderItems){
if (orderItem.getItemId().equals(itemId)){
return orderItem;
}
}
return null;
}
}
添加购物车:http://cart.pinyougou.com/cart/addCart?itemId=1369458&num=100