淘淘商城 專案(IDEA版)之——購物車功能實現:redis+cookies實現購物車功能
阿新 • • 發佈:2019-02-18
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;
}