1. 程式人生 > >淘淘商城 專案(IDEA版)之——購物車功能實現:redis+cookies實現購物車功能

淘淘商城 專案(IDEA版)之——購物車功能實現:redis+cookies實現購物車功能

Redis+Cookie實現購物車功能

1、將淘淘商城原有cookie實現購物車方式修改為redis+cookie實現方式

2、新增登入之後自動同步cookie中未同步(就是未登入新增到購物車的商品)的購物車資訊到redis

業務流程邏輯-加入購物車:
這裡寫圖片描述
1、首先將jedis相關類和配置檔案拷貝過來(我這裡拷的是yougou-content-service目錄下)
這裡寫圖片描述
2、拷貝到yougou-cart-web中,並將applicationContext-jedis.xml 修改為springmvc-jedis.xml,裡邊的配置不用改,因為我的jedis檔案那個包還是那個名,看下圖:
這裡寫圖片描述


這裡寫圖片描述
3、resource.properties屬性檔案中如下,有註解我就不解釋了
這裡寫圖片描述
resource.properties

#購物車在cookie中儲存的key
CART_KEY=CART_KEY
#cookie購物車商品的有效期,預設為7天
CART_EXPIRE=604800
#登入系統的URL
SSO_BASE_URL=http://localhost:8089
#根據使用者資訊取url
SSO_USER_TOKEN=/user/token/
#購物車key
REDIS_CART_KEY=REDIS_CART_KEY
###cookie中儲存token的key
TOKEN_KEY=TOKEN_KEY
#redis購物車商品的有效期,預設為30天
REDIS_CART_EXPIRE=2592000

4、新增屬性檔案中新增屬性的注入
這裡寫圖片描述
5、新增 到購物車方法程式碼(不貼圖了,一個屏截不全)

/**
 * 新增 商品到購物車
 * @param itemId
 * @param num
 * @param request
 * @param response
 * @return
 */
@RequestMapping("/cart/add/{itemId}")
public String addItemCart(@PathVariable Long itemId,
                          @RequestParam
(defaultValue = "1") Integer num, HttpServletRequest request, HttpServletResponse response) { //跨域請求獲取使用者資訊(呼叫抽取方法一) YougouResult result = getUserInfoJsonp(request); //取購物車商品列表(呼叫抽取方法二) List<TbItem> cartItemList = this.getCartItemList(request, result); //判斷商品在購物車中是否存在 boolean flag = false; for (TbItem tbItem : cartItemList) { if (tbItem.getId() == itemId.longValue()) { //如果存在修改數量 tbItem.setNum(tbItem.getNum() + num); flag = true; break; } } //如果不存在,新增一個新的商品 if (!flag) { //需要呼叫服務獲取商品資訊 TbItem tbItem = itemService.getItemById(itemId); //設定購買的商品數量 tbItem.setNum(num); //取一張圖片 String image = tbItem.getImage(); if (StringUtils.isNotBlank(image)) { String[] images = image.split(","); tbItem.setImage(images[0]); } //把商品新增到購物車 cartItemList.add(tbItem); } //儲存購物車列表(呼叫抽取方法三) saveCartItemList(request, response, cartItemList, result); //返回新增成功頁面 return "cartSuccess"; }

抽取方法一 如下 :

/**
 * 跨域請求獲取使用者資訊
 * @param request
 * @return
 */
private YougouResult getUserInfoJsonp(HttpServletRequest request) {
    YougouResult result = null;
    //獲取cookies中token資訊
    String token = CookieUtils.getCookieValue(request, TOKEN_KEY);
    if (StringUtils.isBlank(token))
        return result;
    String userInfo = HttpClientUtil.doGet(SSO_BASE_URL + SSO_USER_TOKEN + token);
    if (StringUtils.isBlank(userInfo))
        return result;
    result = YougouResult.formatToPojo(userInfo, TbUser.class);
    return result;
}

抽取方法二 如下 :

 /**
 * 查詢購物車資訊
 * description:此方法本應該是service(服務層)的介面,
 * 因為沒有資料庫操作,這塊為了方便就定義到controller(控制層)了。
 * @param request
 * @return
 */
private List<TbItem> getCartItemList(HttpServletRequest request, YougouResult result) {
    String cartJson = "";
    //未登入去cookies中取購物車,已登入去redis中取購物車
    if (result == null || result.getStatus() != 200) {
        //從cookie中取購物車商品列表
        cartJson = CookieUtils.getCookieValue(request, CART_KEY, true);
    }else {
        //獲取使用者id
        TbUser tbUser = (TbUser) result.getData();
        //從redis中取購物車
        cartJson = jedisClient.get(REDIS_CART_KEY + ":" + tbUser.getId() + ":base");
    }
    if (StringUtils.isBlank(cartJson)) {
        //如果沒有內容,返回一個空的列表
        return new ArrayList<>();
    }
    List<TbItem> itemList = JsonUtils.jsonToList(cartJson, TbItem.class);
    return itemList;
}

抽取方法三 如下 :

/**
 * 將購物車寫入到cookie或redis
 * @param request
 * @param response
 * @param cartItemList
 * @param result
 */
private void saveCartItemList(HttpServletRequest request,
                              HttpServletResponse response,
                              List<TbItem> cartItemList,
                              YougouResult result) {
    //未登入寫入cookies,已登入寫入redis
    if (result == null || result.getStatus() != 200) {
        //把購物車列表寫入cookie
        CookieUtils.setCookie(request, response, CART_KEY,
                JsonUtils.objectToJson(cartItemList), CART_EXPIRE, true);
    }else {
        //獲取使用者id
        TbUser tbUser = (TbUser) result.getData();
        //把購物車列表寫入redis
        jedisClient.set(REDIS_CART_KEY + ":" + tbUser.getId() + ":base", JsonUtils.objectToJson(cartItemList));
        //設定key的過期時間
        jedisClient.expire(REDIS_CART_KEY + ":" + tbUser.getId() + ":base", REDIS_CART_EXPIRE);
    }
}

說明

1、查詢商品呼叫的還是yougou-manager-service的ItemService介面。
2、獲取使用者資訊時,使用HttpClient呼叫yougou-sso-web中UserController介面的getUserByToken方法,方法程式碼我貼到下邊。
3、寫入redis的key命名規則為REDIS_CART_KEY:登入使用者的id:base
以上就是淘淘商城redis+cookie方式實現購物車新增,刪除以及修改都是同理,這裡我就不貼程式碼了,感興趣的小夥伴可以下載整個專案程式碼,ps:完整專案完善了很多功能以及合理性哦!

附:yougou-sso-web中UserController介面的getUserByToken方法程式碼

//jsonp的第二種實現方法
@RequestMapping(value = "/user/token/{token}", method = RequestMethod.GET)
@ResponseBody
public Object getUserByToken(@PathVariable String token, String callback) {
    YougouResult result = userService.getUserByToken(token);
    //判斷是否為jsonp請求
    if ( StringUtils.isNotBlank(callback) ) {
        MappingJacksonValue mappingJacksonValue  = new MappingJacksonValue(result);
        mappingJacksonValue.setJsonpFunction(callback);
        return mappingJacksonValue;
    }
    return result;
}