目录
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中也更新了。