1. 程式人生 > >Cookie儲存購物車

Cookie儲存購物車

1.1 需求分析

  • 使用Cookie儲存購物車資料,服務層負責業務邏輯,控制器層負責讀寫cookie。
  • 說明:Cookie的value儲存List<Cart> 的json格式字串資料(中文需要Unicode編碼,因為cookie的值不能存在中文字元)
  • 總結:
    實現cookie儲存購物車控制器層程式碼:
    cookieName: pinyougou_cart
    cookieValue: List<Cart>集合轉化成json格式的字串,有中文需要轉碼。
  • 實現步驟:
  1. 定義CartController.java控制器,讀寫購物車。
    把商品新增到購物車,再把購物車儲存Cookie
    先從瀏覽器中獲取Cookie,從Cookie中獲取原來的購物車
  • 詳細步驟:(未登入的使用者,購物車儲存到Cookie)
  1.  獲取購物車
  2. 把商品新增到購物車
  3. 把新增後的購物車儲存到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);
}

 服務實現層:

  • 實現思路:(對照上圖結構去實現)
  1. 根據SKU商品ID查詢SKU商品物件。
  2. 獲取商家ID
  3. 根據商家ID判斷購物車集合中是否存在該商家的購物車
  4. 如果購物車集合中不存在該商家的購物車
    4.1 建立新的購物車物件
    4.2 將新的購物車物件新增到購物車集合
  5. 如果購物車集合中存在該商家的購物車
    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);
                    }
                  
 // 如果cartorderItems訂單明細為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