淘淘商城69-商城購物車系統實現之登入與未登入狀態下更新購物車的商品數量
目錄
1.更新購物車的商品數量的js分析
在taotao-cart-web的cart.js中有更新商品時js事件處理。
商品數量加一、減一時會觸發對應的事件,修改dom,從而修改前端展示的價格
然後會非同步請求url:/cart/update/num/"+_thisInput.attr("itemId")+"/"+_thisInput.val()
也就是url:/cart/update/num/itemId/num,修改服務端的資料。
refreshTotalPrice函式用於重新計算總價。
2.登入狀態下更新購物車的商品數量
2.1服務層
2.1.1dao層
直接通過jedisClient操作redis資料庫
2.1.2service層
在taotao-cart-interface建立對應介面
/**
* 根據使用者id與商品id更新購物項
* @param userId
* @param itemId
* @param num
* @return
*/
TaotaoResult updateItemCartByItemId(Long userId,Long itemId,Integer num);
在taotao-cart-service建立實現類
業務邏輯:
從redis中獲取到對應的商品的物件,設定物件的商品數量,轉成JSON,存入redis中。
/**根據使用者id與商品id更新購物項*/ @Override public TaotaoResult updateItemCartByItemId(Long userId, Long itemId, Integer num) { TbItem tbItem = queryItemByItemAndUserId(itemId, userId); if(tbItem!=null) { tbItem.setNum(num); jedisClient.hset(TT_CART_REDIS_PRE_KEY+":"+userId, itemId+"", JsonUtils.objectToJson(tbItem)); } return TaotaoResult.ok(); } /** * 根據key:itemId,filed:userId,從redis獲取itemJson * @param itemId * @param userId * @return */ private TbItem queryItemByItemAndUserId(Long itemId,Long userId) { String itemJson = jedisClient.hget(TT_CART_REDIS_PRE_KEY+":"+userId,itemId+""); if(StringUtils.isNoneBlank(itemJson)) { TbItem tbItem = JsonUtils.jsonToPojo(itemJson, TbItem.class); return tbItem; } return null; }
2.2表現層
2.2.1controller
url:/cart/update/num/{itemId}/{num}
引數:itemId、num
從cookie中獲取token,根據token查詢redis,判斷使用者是否登入,已登入更新購物車到redis中,未登入更新到cookie中。
/**
* 更新redis或cookie購物車
*
* @param itemId
* @param num
* @param request
* @param response
* @return
*/
@RequestMapping("/cart/update/num/{itemId}/{num}")
@ResponseBody
public TaotaoResult updateItemCartByItemId(@PathVariable Long itemId, @PathVariable Integer num,
HttpServletRequest request, HttpServletResponse response) {
// 1.從cookie中獲取token
String token = CookieUtils.getCookieValue(request, COOKIE_TOKEN_KEY);
// 2.根據token呼叫SSO的服務,獲取使用者的資訊
TaotaoResult result = loginService.getUserByToken(token);
// 判斷 使用者是否登入
if (result.getStatus() == 200) {
// 3.如果使用者已經登入,更新到redis中
TbUser tbUser = (TbUser) result.getData();
cartService.updateItemCartByItemId(tbUser.getId(), itemId, num);
} else {
// 4.如果使用者沒登入,更新到cookie
//updateCookieItemCart(itemId, num, request, response);
}
return TaotaoResult.ok();
}
2.2.2*.html無法返回json
我們在web.xml中配置的url攔截的形式為"*.html",而我們在controller返回的是一個java物件。瀏覽器發起請求比如
http://localhost:8089/cart/update/num/13216546416/5.html時,服務端應該響應一堆包含html、css等的字串,但是我們響應一個java物件,這時瀏覽器就會報406的錯誤,所以需要在web.xml中配置攔截*.action。
2.3測試訪問
安裝taotao-cart。
由於要呼叫taotao-sso與taotao-manager查詢使用者與商品資訊,所以需要啟動taotao-sso、taotao-manager。
需要登入在cookie中寫入toekn,所以要啟動taotao-sso-web。
需要搜尋商品,所以要啟動taotao-search、taotao-search-web。----如果手動輸入url進入商品詳情頁,可以不啟動
需要在商品詳情頁加入購物車,所以需要啟動taotao-item-web。
最後購物車這裡的taotao-cart、taotao-cart-web也要啟動。
在登入狀態下
增加一個商品
可以發現更新已同步到redis
3.未登入狀態下更新購物車的商品數量
在未登入狀態都是對cookie的操作
3.1服務層
服務層不變,存入cookie,需要要使用servlet原生response物件,跟service沒什麼關係,所以放在controller中。
3.2表現層
3.2.1controller
更新cookie中的購物車思路比較簡單:從cookie中獲取所有購物車,遍歷購物車找到對應商品更新數量,重新存入cookie即可
這裡將更新cookie中購物車的程式碼,單獨抽出來一個方法
/** 更新cookie中的購物車 */
private void updateCookieItemCart(Long itemId, Integer num, HttpServletRequest request,
HttpServletResponse response) {
List<TbItem> cartList = getCookieCartList(request);
boolean flag = false;
// 1.判斷如果購物車中是否包含要新增的商品
for (TbItem tbItem : cartList) {
// 2.包含商品 更新數量
if (tbItem.getId() == itemId.longValue()) {
tbItem.setNum(num);
flag = true;
break;
}
}
// 3.如果數量更新了,就cookie中的購物車
if (flag) {
CookieUtils.setCookie(request, response, COOKIE_CART_KEY, JsonUtils.objectToJson(cartList), 7 * 24 * 3600,
true);
}
}
3.3測試訪問
安裝taotao-cart。
由於要呼叫taotao-sso與taotao-manager查詢使用者與商品資訊,所以需要啟動taotao-sso、taotao-manager。
需要登入在cookie中寫入toekn,所以要啟動taotao-sso-web。
需要搜尋商品,所以要啟動taotao-search、taotao-search-web。----如果手動輸入url進入商品詳情頁,可以不啟動
需要在商品詳情頁加入購物車,所以需要啟動taotao-item-web。
最後購物車這裡的taotao-cart、taotao-cart-web也要啟動。
首先退出登入
原本cookie中商品數量為2,增加一個
現在數量變為3
重新整理一下看看是否在cookie中也更新了,很明顯cookie中也更新了。