Fork me on GitHub

十二.宜立方商城——购物车实现

一.课程计划

  1. 购物车实现
  2. 订单确认页面展示

二.购物车的实现

2.1 功能分析

  1. 购物车是一个独立的表现层工程。
  2. 添加购物车不要求登录。可以指定购买商品的数量。
  3. 展示购物车列表页面
  4. 修改购物车商品数量
  5. 删除购物车商品

2.2 工程搭建

image

全部参考content项目

三.未登录状态下购物车的实现

3.1 添加购物车

3.1.1 功能分析

在不登陆的情况下也可以添加购物车。把购物车信息写入cookie。

优点:

  1. 不占用服务端存储空间
  2. 用户体验好。
  3. 代码实现简单。

缺点:

  1. cookie中保存的容量有限。最大4k
  2. 把购物车信息保存在cookie中,更换设备购物车信息不能同步。

改造商品详情页面
image

image

image

image

image

image

image

3.1.2 Controller

请求的url:/cart/add/{itemId}

参数:

  1. 商品id: Long itemId
  2. 商品数量: int num

业务逻辑:

  1. 从cookie中查询商品列表。
  2. 判断商品在商品列表中是否存在。
  3. 如果存在,商品数量相加。
  4. 不存在,根据商品id查询商品信息。
  5. 把商品添加到购车列表。
  6. 把购车商品列表写入cookie。

返回值:逻辑视图

Cookie保存购物车

  1. key:cart
  2. Value:购物车列表转换成json数据。需要对数据进行编码。
  3. Cookie的有效期:保存7天。

商品列表:

List,每个商品数据使用TbItem保存。当根据商品id查询商品信息后,取第一张图片保存到image属性中即可。

读写cookie可以使用CookieUtils工具类实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
/**
* @author RickYinPeng
* @ClassName CartController
* @Description 购物车处理Controller
* @date 2018/12/30/13:08
*/
@Controller
public class CartController {

@Autowired
private ItemService itemService;

@Value("${COOKIE_CART_EXPIRE}")
private Integer COOKIE_CART_EXPIRE;

@RequestMapping("/cart/add/{itemId}")
public String addCart(@PathVariable Long itemId, @RequestParam(defaultValue = "1") Integer num,
HttpServletRequest request, HttpServletResponse response){
//从cookie中取购物车列表
List<TbItem> cartList = getCartListFromCookie(request);
//判断商品在商品列表中是否存在
boolean flag = false;
for (TbItem tbItem : cartList) {
/**
* 这样比较是不行的,因为现在tbItem.getId()的返回值时Long
* itemId也是Long类型,两个对象使用==比较,比较的是地址而不是值
* 所以我们需要调用Long中一个方法longValue()来获取到long类型的值
*/
//如果存在数量相加
if(tbItem.getId()==itemId.longValue()){
flag = true;
//找到商品,数量相加
tbItem.setNum(tbItem.getNum()+num);
//跳出循环
break;
}
}
//如果不存在
if(!flag){

//根据商品id查询商品信息。得到一个TbItem对象
TbItem tbItem = itemService.getItemById(itemId);

//设置商品数量,因为现在这个数量是我们的库存,是从数据库中查出来的
tbItem.setNum(num);

//取一张图片
String image = tbItem.getImage();

if(StringUtils.isNotBlank(image)){
tbItem.setImage(image.split(",")[0]);
}

//把商品添加到商品列表
cartList.add(tbItem);
}

//写入cookie
CookieUtils.setCookie(request,response,"cart",JsonUtils.objectToJson(cartList),COOKIE_CART_EXPIRE,true);

//返回添加成功页面
return "cartSuccess";
}

/**
* 从cookie中取购物车列表的信息
* @param request
* @return
*/
private List<TbItem> getCartListFromCookie(HttpServletRequest request){
String json = CookieUtils.getCookieValue(request, "cart", true);
//判断json是否为空
if(StringUtils.isBlank(json)){
return new ArrayList<>();
}
//将json转换为List
List<TbItem> list = JsonUtils.jsonToList(json, TbItem.class);
return list;
}
}

image

3.2 展示购物车商品列表

image

image

请求的url:/cart/cart

参数:无

返回值:逻辑视图

业务逻辑:

  1. 从cookie中取商品列表。
  2. 把商品列表传递给页面

3.2.1 Controller

1
2
3
4
5
6
7
8
9
10
11
@RequestMapping("/cart/cart")
public String showCartList(HttpServletRequest request){
//从cookie中取购物车列表
List<TbItem> cartList = getCartListFromCookie(request);

//把列表传给页面
request.setAttribute("cartList",cartList);

//返回逻辑视图
return "cart";
}

image

image

3.3 修改购物车商品数量

3.3.1 功能分析

  1. 在页面中可以修改商品数量
  2. 重新计算小计和总计。
  3. 修改需要写入cookie。
    每次修改都需要向服务端发送一个ajax请求,在服务端修改cookie中的商品数量。

image

image

image

image

image

请求的url:/cart/update/num/{itemId}/{num}

参数:long itemId、int num

业务逻辑:

  1. 接收两个参数
  2. 从cookie中取商品列表
  3. 遍历商品列表找到对应商品
  4. 更新商品数量
  5. 把商品列表写入cookie。
  6. 响应e3Result。Json数据。
    返回值:

    e3Result。Json数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@RequestMapping("/cart/update/num/{itemId}/{num}")
@ResponseBody
public E3Result updateCartNum(@PathVariable Long itemId,@PathVariable Integer num,
HttpServletRequest request,HttpServletResponse response){
//从cookie中取购物车列表
List<TbItem> cartList = getCartListFromCookie(request);
//遍历商品列表找到对应商品
for (TbItem tbItem : cartList) {
if(tbItem.getId().longValue()==itemId){
//更新数量
tbItem.setNum(num);
break;
}
}

//把购物车列表写回cookie
CookieUtils.setCookie(request,response,"cart",JsonUtils.objectToJson(cartList),COOKIE_CART_EXPIRE,true);

//返回成功
return E3Result.ok();
}

image

image

406一般是缺少jackson的jar或者是以.html结尾的页面无法返回json

3.3.2 解决请求*.html后缀无法返回json数据的问题

在springmvc中请求*.html不可以返回json数据。

修改web.xml,添加url拦截格式。

1
2
3
4
5
6
7
8
9
10
11
12
<servlet-mapping>
<servlet-name>e3_cart_web</servlet-name>
<!--不过滤jsp页面(springmvc嘛)-->
<!--伪静态化-->
<url-pattern>*.html</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>e3_cart_web</servlet-name>
<!--不过滤jsp页面(springmvc嘛)-->
<!--伪静态化-->
<url-pattern>*.action</url-pattern>
</servlet-mapping>

再添加一个就行了,让它别以*.html请求了不就完事了吗

image

image

image

image

3.4 删除购物车商品

3.4.1 功能分析

请求的url:/cart/delete/{itemId}

参数:商品id

返回值:展示购物车列表页面。Url需要做redirect跳转。

业务逻辑:

  1. 从url中取商品id
  2. 从cookie中取购物车商品列表
  3. 遍历列表找到对应的商品
  4. 删除商品。
  5. 把商品列表写入cookie。

    返回逻辑视图:在逻辑视图中做redirect跳转
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@RequestMapping("/cart/delete/{itemId}")
public String deleteCartItem(@PathVariable Long itemId,HttpServletRequest request,
HttpServletResponse response){
//从cookie中取购物车列表
List<TbItem> cartList = getCartListFromCookie(request);
//遍历列表找到需要删除的商品
for (TbItem tbItem : cartList) {
if(tbItem.getId().longValue()==itemId){
//删除商品
cartList.remove(tbItem);
//跳出循环
break;
}
}
//把购物车列表写回cookie
CookieUtils.setCookie(request,response,"cart",JsonUtils.objectToJson(cartList),COOKIE_CART_EXPIRE,true);
//返回逻辑视图
return "redirect:/cart/cart.html";
}

3.4.2 Controller

image

image

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@RequestMapping("/cart/delete/{itemId}")
public String deleteCartItem(@PathVariable Long itemId,HttpServletRequest request,
HttpServletResponse response){
//从cookie中取购物车列表
List<TbItem> cartList = getCartListFromCookie(request);
//遍历列表找到需要删除的商品
for (TbItem tbItem : cartList) {
if(tbItem.getId().longValue()==itemId){
//删除商品
cartList.remove(tbItem);
//跳出循环
break;
}
}
//把购物车列表写回cookie
CookieUtils.setCookie(request,response,"cart",JsonUtils.objectToJson(cartList),COOKIE_CART_EXPIRE,true);
//返回逻辑视图
return "redirect:/cart/cart.html";
}

四.登录状态下购物车实现

4.1 功能分析

购物车数据保存位置

  1. 未登录状态下,将购物车数据保存到cookie中
  2. 登录状态下需要把购物车数据保存到服务端。需要永久保存,可以保存到数据库中。可以把购物车数据保存到redis中。

redis使用的数据类型

  1. 使用Hash数据类型
  2. Hash的key应该是用户id。Hash中的field是商品id,value可以把商品信息转换为json

添加购物车:

  1. 登录状态下直接将商品数据放在redis中
  2. 未登录状态下保存到cookie中

如何判断是否登录?:

  1. 从cookie中取token
  2. 取不到就是未登录
  3. 取到token,到redis中查询token是否过期
  4. 如果过期就是未登录状态
  5. 没过期就是登录状态

4.2 判断用户是否登录

4.2.1 功能分析

应该使用springmvc的拦截器

  1. 实现一个HandlerInterceptor接口
  2. 在执行handler方法之前做业务处理
  3. 从cookie中取token。使用CookieUtils工具类实现
  4. 没有取到token,用户未登录。放行
  5. 取到token,调用sso系统的服务,根据token查询用户信息
  6. 没有返回用户信息。登录已过期,未登录,放行。
  7. 返回用户信息。用户是否是登录状态。可以把用户对象保存到request中,在Controller中可以通过判断request中是否包含用户对象,确定是否为登录状态

4.2.2 LoginInterceptor

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/**
* @author RickYinPeng
* @ClassName LoginInterceptor
* @Description 用户登录拦截器
* @date 2018/12/30/20:43
*/
public class LoginInterceptor implements HandlerInterceptor{

@Autowired
private TokenService tokenService;

@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
//前处理,执行handler之前执行的方法
//返回true:放行
//返回false:拦截

//1.从cookie中取token
String token = CookieUtils.getCookieValue(httpServletRequest, "token");
//2.如果没有token,未登录状态,直接放行
if(StringUtils.isBlank(token)){
return true;
}
//3.取到token,需要调用SSO系统的服务,根据token取用户信息
E3Result e3Result = tokenService.getUserByToken(token);
//4.没有取到用户信息。登录过期,直接放行。
if(e3Result.getStatus()!=200){
return true;
}
//5.取到用户信息。登录状态。
TbUser tbUser = (TbUser) e3Result.getData();
//6.把用户信息放到request中。只需要在Controller中判断是否包含user信息。放行
httpServletRequest.setAttribute("user",tbUser);
return true;
}

@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
//handler执行之后,返回ModelAndView之前

}

@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
//完成处理,返回ModelAndView之后
//可以在此处理异常
}
}

image

4.3 修改原来的Controller

image

image

image

image

image

image

image

image

image

image

image

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
@RequestMapping("/cart/add/{itemId}")
public String addCart(@PathVariable Long itemId, @RequestParam(defaultValue = "1") Integer num,
HttpServletRequest request, HttpServletResponse response){
//判断用户是否为登录状态
TbUser tbUser = (TbUser) request.getAttribute("user");
//如果是登录状态,就把购物车写入redis
if(tbUser!=null){
//保存到服务端
cartService.addCart(tbUser.getId(),itemId,num);
//返回逻辑视图
return "cartSuccess";
}
//如果未登录使用cookie

//从cookie中取购物车列表
List<TbItem> cartList = getCartListFromCookie(request);
//判断商品在商品列表中是否存在
boolean flag = false;
for (TbItem tbItem : cartList) {
/**
* 这样比较是不行的,因为现在tbItem.getId()的返回值时Long
* itemId也是Long类型,两个对象使用==比较,比较的是地址而不是值
* 所以我们需要调用Long中一个方法longValue()来获取到long类型的值
*/
//如果存在数量相加
if(tbItem.getId()==itemId.longValue()){
flag = true;
//找到商品,数量相加
tbItem.setNum(tbItem.getNum()+num);
//跳出循环
break;
}
}
//如果不存在
if(!flag){

//根据商品id查询商品信息。得到一个TbItem对象
TbItem tbItem = itemService.getItemById(itemId);

//设置商品数量,因为现在这个数量是我们的库存,是从数据库中查出来的
tbItem.setNum(num);

//取一张图片
String image = tbItem.getImage();

if(StringUtils.isNotBlank(image)){
tbItem.setImage(image.split(",")[0]);
}

//把商品添加到商品列表
cartList.add(tbItem);
}

//写入cookie
CookieUtils.setCookie(request,response,"cart",JsonUtils.objectToJson(cartList),COOKIE_CART_EXPIRE,true);

//返回添加成功页面
return "cartSuccess";
}

4.4 登录状态下展示购物车列表

image

image

4.4.1 功能分析

  1. 判断用户是否为登录状态
  2. 如果是登录状态
  3. 从cookie中取购物车列表
  4. 如果不为空,把cookie中的购物车商品和服务端的购物车商品合并
  5. 把cookie中的购物车删除
  6. 从服务端取购物车列表
  7. 未登录状态
  8. 从cookie中取购物车列表

其中未登录状态下从cookie中取购物车列表我们已经做完了

image

image

4.4.2 完成Service服务

接口

image

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public interface CartService {

/**
* 往redis中添加购物车
* @param userId 用户id
* @param itemId 商品id
* @return
*/
E3Result addCart(Long userId,Long itemId,Integer num);

/**
* 合并服务端购物车列表和Cookie中购物车列表信息
* @param userId 用户id
* @param itemList Cookie中购物车信息
* @return
*/
E3Result mergeCart(Long userId, List<TbItem> itemList);

/**
* 取redis中购物车列表
* @param userId 用户id
* @return
*/
List<TbItem> getCartList(Long userId);
}
实现合并购物车

image

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Override
public E3Result mergeCart(Long userId, List<TbItem> itemList) {
//遍历商品列表
//把列表添加到购物车
//判断购物车中是否有此商品
//如果有,商品数量相加
//如果没有,添加新的商品
for (TbItem tbItem : itemList) {
/**
* 上面的这些逻辑我们可以直接调用商品的addCart方法,很简单
*/
addCart(userId,tbItem.getId(),tbItem.getNum());
}
//返回成功
return E3Result.ok();
}
从redis中取hash的值

image

image

image

image

从redis中取购物车列表

image

1
2
3
4
5
6
7
8
9
10
11
12
13
@Override
public List<TbItem> getCartList(Long userId) {
//根据用户id查询购物车列表
List<String> jsonList = jedisClient.hvals(REDIS_CART_PRE + ":" + userId);
List<TbItem> tbItemList = new ArrayList<>();
for (String s : jsonList) {
//将json转换成TbItem对象
TbItem tbItem = JsonUtils.jsonToPojo(s, TbItem.class);
//添加到列表
tbItemList.add(tbItem);
}
return tbItemList;
}
Controller
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/**
* 展示购物车列表
* @param request
* @return
*/
@RequestMapping("/cart/cart")
public String showCartList(HttpServletRequest request,HttpServletResponse response){
//从cookie中取购物车列表
List<TbItem> cartList = getCartListFromCookie(request);

//判断用户是否为登录状态
TbUser tbUser = (TbUser) request.getAttribute("user");
//如果是登录状态
if(tbUser!=null){
//从cookie中取购物车列表(已经在外面取出了)
//如果不为空,把cookie中的购物车商品和服务端的购物车商品合并
cartService.mergeCart(tbUser.getId(), cartList);

//把cookie中的购物车删除
CookieUtils.deleteCookie(request,response,"cart");
//从服务端取购物车列表
cartList = cartService.getCartList(tbUser.getId());
}
//未登录状态
//把列表传给页面
request.setAttribute("cartList",cartList);

//返回逻辑视图
return "cart";
}

image

测试成功

4.5 登录状态下修改、删除购物车(这个简单)

4.5.1 接口

image

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package yp.e3mall.cart.service;

import yp.e3mall.common.utils.E3Result;
import yp.e3mall.pojo.TbItem;

import java.util.List;

public interface CartService {

/**
* 往redis中添加购物车
* @param userId 用户id
* @param itemId 商品id
* @return
*/
E3Result addCart(Long userId,Long itemId,Integer num);

/**
* 合并服务端购物车列表和Cookie中购物车列表信息
* @param userId 用户id
* @param itemList Cookie中购物车信息
* @return
*/
E3Result mergeCart(Long userId, List<TbItem> itemList);

/**
* 取redis中购物车列表
* @param userId 用户id
* @return
*/
List<TbItem> getCartList(Long userId);

/**
* 更新redis中购物车中商品数量
* @param userId 用户id
* @param itemId 商品id
* @param num 商品数量
* @return
*/
E3Result updateCartNum(Long userId,Long itemId,int num);

/**
*
* @param userId 用户id
* @param itemId 商品id
* @return
*/
E3Result deleteCartItem(Long userId,Long itemId);
}

4.5.2 实现类

image

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
package yp.e3mall.cart.service.impl;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import yp.e3mall.cart.service.CartService;
import yp.e3mall.common.jedis.JedisClient;
import yp.e3mall.common.utils.E3Result;
import yp.e3mall.common.utils.JsonUtils;
import yp.e3mall.mapper.TbItemMapper;
import yp.e3mall.pojo.TbItem;

import java.util.ArrayList;
import java.util.List;

/**
* @author RickYinPeng
* @ClassName CartServiceImpl
* @Description 购物车处理服务
* @date 2018/12/30/22:14
*/
@Service
public class CartServiceImpl implements CartService{

@Autowired
private JedisClient jedisClient;

@Value("${REDIS_CART_PRE}")
private String REDIS_CART_PRE;

@Autowired
private TbItemMapper tbItemMapper;

@Override
public E3Result addCart(Long userId, Long itemId,Integer num) {
//向redis中添加购物车

//数据类型是hash key:用户id field:商品id value:商品信息

//判断商品是否存在
Boolean hexists = jedisClient.hexists(REDIS_CART_PRE + ":" + userId, itemId + "");

//如果存在,数量相加
if(hexists){
String json = jedisClient.hget(REDIS_CART_PRE + ":" + userId, itemId + "");
//把json转换成Tbitem
TbItem tbItem = JsonUtils.jsonToPojo(json, TbItem.class);
tbItem.setNum(tbItem.getNum()+num);
//写回redis
jedisClient.hset(REDIS_CART_PRE + ":" + userId, itemId + "",JsonUtils.objectToJson(tbItem));
return E3Result.ok();
}

//如果不存在,根据商品id取商品信息
TbItem tbItem = tbItemMapper.selectByPrimaryKey(itemId);

//设置购物车数量
tbItem.setNum(num);

String image = tbItem.getImage();
if(StringUtils.isNotBlank(image)){
tbItem.setImage(image.split(",")[0]);
}
//添加到购物车列表
jedisClient.hset(REDIS_CART_PRE + ":" + userId, itemId + "",JsonUtils.objectToJson(tbItem));

//返回成功
return E3Result.ok();
}

@Override
public E3Result mergeCart(Long userId, List<TbItem> itemList) {
//遍历商品列表
//把列表添加到购物车
//判断购物车中是否有此商品
//如果有,商品数量相加
//如果没有,添加新的商品
for (TbItem tbItem : itemList) {
/**
* 上面的这些逻辑我们可以直接调用商品的addCart方法,很简单
*/
addCart(userId,tbItem.getId(),tbItem.getNum());
}
//返回成功
return E3Result.ok();
}

@Override
public List<TbItem> getCartList(Long userId) {
//根据用户id查询购物车列表
List<String> jsonList = jedisClient.hvals(REDIS_CART_PRE + ":" + userId);
List<TbItem> tbItemList = new ArrayList<>();
for (String s : jsonList) {
//将json转换成TbItem对象
TbItem tbItem = JsonUtils.jsonToPojo(s, TbItem.class);
//添加到列表
tbItemList.add(tbItem);
}
return tbItemList;
}

@Override
public E3Result updateCartNum(Long userId, Long itemId, int num) {
//从redis中取出商品信息
String json = jedisClient.hget(REDIS_CART_PRE + ":" + userId, itemId + "");
TbItem tbItem = JsonUtils.jsonToPojo(json, TbItem.class);
tbItem.setNum(num);
//写回redis
jedisClient.hset(REDIS_CART_PRE + ":" + userId, itemId + "",JsonUtils.objectToJson(tbItem));

return E3Result.ok();
}

@Override
public E3Result deleteCartItem(Long userId, Long itemId) {
jedisClient.hdel(REDIS_CART_PRE + ":" + userId, itemId + "");
return E3Result.ok();
}
}

4.5.3 Controller(也很简单)

image

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/**
* 更新商品信息
* @param itemId 商品ID
* @param num 商品数量
* @param request
* @param response
* @return
*/
@RequestMapping("/cart/update/num/{itemId}/{num}")
@ResponseBody
public E3Result updateCartNum(@PathVariable Long itemId,@PathVariable Integer num,
HttpServletRequest request,HttpServletResponse response){
//判断用户是否登录
TbUser user = (TbUser) request.getAttribute("user");
if(user!=null){
cartService.updateCartNum(user.getId(),itemId,num);
return E3Result.ok();
}

//从cookie中取购物车列表
List<TbItem> cartList = getCartListFromCookie(request);
//遍历商品列表找到对应商品
for (TbItem tbItem : cartList) {
if(tbItem.getId().longValue()==itemId){
//更新数量
tbItem.setNum(num);
break;
}
}

//把购物车列表写回cookie
CookieUtils.setCookie(request,response,"cart",JsonUtils.objectToJson(cartList),COOKIE_CART_EXPIRE,true);

//返回成功
return E3Result.ok();
}

@RequestMapping("/cart/delete/{itemId}")
public String deleteCartItem(@PathVariable Long itemId,HttpServletRequest request,
HttpServletResponse response){
//判断用户是否登录
TbUser user = (TbUser) request.getAttribute("user");
if(user!=null){
cartService.deleteCartItem(user.getId(),itemId);
return "redirect:/cart/cart.html";
}


//从cookie中取购物车列表
List<TbItem> cartList = getCartListFromCookie(request);
//遍历列表找到需要删除的商品
for (TbItem tbItem : cartList) {
if(tbItem.getId().longValue()==itemId){
//删除商品
cartList.remove(tbItem);
//跳出循环
break;
}
}
//把购物车列表写回cookie
CookieUtils.setCookie(request,response,"cart",JsonUtils.objectToJson(cartList),COOKIE_CART_EXPIRE,true);
//返回逻辑视图
return "redirect:/cart/cart.html";
}