Cookie儲存購物車
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
檢視購物車:http://cart.pinyougou.com/cart/findCart