购物车实现














2.2.	工程搭建
e3-cart-web打包方式war
可以参考e3-portal-web

2.2.1.	Pom文件
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>cn.e3mall</groupId>
		<artifactId>e3-parent</artifactId>
		<version>0.0.1-SNAPSHOT</version>
	</parent>
	<groupId>cn.e3mall</groupId>
	<artifactId>e3-cart-web</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>
	<dependencies>
		<dependency>
			<groupId>cn.e3mall</groupId>
			<artifactId>e3-manager-interface</artifactId>
			<version>0.0.1-SNAPSHOT</version>
		</dependency>
		<!-- Spring -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-beans</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aspects</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jms</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context-support</artifactId>
		</dependency>
		<!-- JSP相关 -->
		<dependency>
			<groupId>jstl</groupId>
			<artifactId>jstl</artifactId>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jsp-api</artifactId>
			<scope>provided</scope>
		</dependency>
		<!-- dubbo相关 -->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>dubbo</artifactId>
			<!-- 排除依赖 -->
			<exclusions>
				<exclusion>
					<groupId>org.springframework</groupId>
					<artifactId>spring</artifactId>
				</exclusion>
				<exclusion>
					<groupId>org.jboss.netty</groupId>
					<artifactId>netty</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>org.apache.zookeeper</groupId>
			<artifactId>zookeeper</artifactId>
		</dependency>
		<dependency>
			<groupId>com.github.sgroschupf</groupId>
			<artifactId>zkclient</artifactId>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
		</dependency>
	</dependencies>
	<!-- 配置tomcat插件 -->
	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.tomcat.maven</groupId>
				<artifactId>tomcat7-maven-plugin</artifactId>
				<configuration>
					<port>8089</port>
					<path>/</path>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

3.	未登录状态下使用购物车
3.1.	添加购物车
3.1.1.	功能分析
在不登陆的情况下也可以添加购物车。把购物车信息写入cookie。
优点:
1、不占用服务端存储空间
2、用户体验好。
3、代码实现简单。
缺点:
1、cookie中保存的容量有限。最大4k
2、把购物车信息保存在cookie中,更换设备购物车信息不能同步。





改造商品详情页面
 
 


请求的url:/cart/add/{itemId}
参数:
1)商品id: Long itemId
2)商品数量: int num
业务逻辑:
1、从cookie中查询商品列表。
2、判断商品在商品列表中是否存在。
3、如果存在,商品数量相加。
4、不存在,根据商品id查询商品信息。
5、把商品添加到购车列表。
6、把购车商品列表写入cookie。

返回值:逻辑视图

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

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

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

3.1.2.	Controller商品添加到购物车

@Controller
public class CartController {
	
	@Value("${TT_CART}")
	private String TT_CART;
	@Value("${CART_EXPIRE}")
	private Integer CART_EXPIRE;

	@Autowired
	private ItemService itemService;
	
	@RequestMapping("/cart/add/{itemId}")
	public String addCartItem(@PathVariable Long itemId, @RequestParam(defaultValue=”1”)Integer num,
			HttpServletRequest request, HttpServletResponse response) {
		// 1、从cookie中查询商品列表。
		List<TbItem> cartList = getCartList(request);
		// 2、判断商品在商品列表中是否存在。
		boolean hasItem = false;
		for (TbItem tbItem : cartList) {
			//对象比较的是内存地址,应该是值的比较,Long是一个对象,属于包装数据类型
			if (tbItem.getId() == itemId.longValue()) {
				// 3、如果存在,商品数量相加。
				tbItem.setNum(tbItem.getNum() + num);
				hasItem = true;//加入一个标志位判断商品是否存在
                       // 跳出循环
				break;
			}
		}
		if (!hasItem) {
			// 4、不存在,根据商品id查询商品信息。
			TbItem tbItem = itemService.getItemById(itemId);
			//取一张图片
			String image = tbItem.getImage();
			if (StringUtils.isNoneBlank(image)) {
				String[] images = image.split(",");
				tbItem.setImage(images[0]);
			}
			//设置购买商品数量
			tbItem.setNum(num);
			// 5、把商品添加到购车列表。
			cartList.add(tbItem);
		}
		// 6、把购车商品列表写入cookie。
		CookieUtils.setCookie(request, response, TT_CART, JsonUtils.objectToJson(cartList), CART_EXPIRE, true); // CART_EXPIRE定义了cookie的保存时间
		return "cartSuccess";
	}
	


	/**
	 * 从cookie中取购物车列表,
	 * <p>Title: getCartList</p>
	 * <p>Description: </p>
	 * @param request
	 * @return
	 */
	private List<TbItem> getCartList(HttpServletRequest request) {
		//取购物车列表
		String json = CookieUtils.getCookieValue(request, TT_CART, true);
		//判断json是否为null
		if (StringUtils.isNotBlank(json)) {
			//把json转换成商品列表返回
			List<TbItem> list = JsonUtils.jsonToList(json, TbItem.class);
			return list;
		}
		return new ArrayList<>(); //这里不为null,防止空指针异常
	}
	
}
调试中查看cookie
 
3.2.	展示购物车商品列表
 加入购物车后点击进购物车结算
请求的url:/cart/cart
参数:无
返回值:逻辑视图
业务逻辑:
1、从cookie中取商品列表。
2、把商品列表传递给页面。
3.2.1.	Controller
@requestmapping("/cart/cart")
	public string showcartlist(httpservletrequest request, model model) {
		//从cookie中取购物车商品列表
		list<tbitem> cartlist = getcartlist(request);
		//购物车商品列表传递给页面
		model.addattribute("cartlist", cartlist);
		return "cart";
	}

3.3.	修改购物车商品数量
 
3.3.1.	功能分析
1、在页面中可以修改商品数量
2、重新计算小计和总计。
3、修改需要写入cookie。
4、每次修改都需要向服务端发送一个ajax请求,在服务端修改cookie中的商品数量。
 
+与-没有绑定ID,所以根据class 中的incremen绑定
 
请求的url:/cart/update/num/{itemId}/{num}
"/cart/update/num/"+_thisInput.attr("itemId")+"/"+_thisInput.val() + ".html"
参数:long itemId、int num
业务逻辑:
1、接收两个参数
2、从cookie中取商品列表
3、遍历商品列表找到对应商品
4、更新商品数量
5、把商品列表写入cookie。
6、响应e3Result。Json数据。
返回值:
 e3Result。Json数据
3.3.2.	Controller更新购物车商品数量
@RequestMapping("/cart/update/num/{itemId}/{num}")
	@ResponseBody
	public e3Result updateNum(@PathVariable Long itemId, @PathVariable Integer num,
			HttpServletRequest request, HttpServletResponse response) {
		// 1、接收两个参数
		// 2、从cookie中取商品列表
		List<TbItem> cartList = getCartList(request);
		// 3、遍历商品列表找到对应商品
		for (TbItem tbItem : cartList) {
			if (tbItem.getId() == itemId.longValue()) {
				// 4、更新商品数量
				tbItem.setNum(num);
                       break;’//找到后就跳出循环
			}
		}
		// 5、把商品列表写入cookie。
		CookieUtils.setCookie(request, response, TT_CART, JsonUtils.objectToJson(cartList), CART_EXPIRE, true);
		// 6、响应e3Result。Json数据。
		return e3Result.ok();
	}
Springmvc中返回406错误可能是jackson包没加 ,另一个原因是*.html后缀无法返回json数据

3.3.3.	解决请求*.html后缀无法返回json数据的问题
在springmvc中请求*.html不可以返回json数据。
修改web.xml,添加url拦截格式。

 


3.4.	删除购物车商品
 
3.4.1.	功能分析
请求的url:/cart/delete/{itemId}
参数:商品id
返回值:展示购物车列表页面。Url需要做redirect跳转。
业务逻辑:
1、从url中取商品id
2、从cookie中取购物车商品列表
3、遍历列表找到对应的商品
4、删除商品。
5、把商品列表写入cookie。
6、返回逻辑视图:在逻辑视图中做redirect跳转。

3.4.2.	Controller
@RequestMapping("/cart/delete/{itemId}")
	public String deleteCartItem(@PathVariable Long itemId, HttpServletRequest request,
			HttpServletResponse response) {
		// 1、从url中取商品id
		// 2、从cookie中取购物车商品列表
		List<TbItem> cartList = getCartList(request);
		// 3、遍历列表找到对应的商品
		for (TbItem tbItem : cartList) {
			if (tbItem.getId() == itemId.longValue()) {
				// 4、删除商品。
				cartList.remove(tbItem);
				break;
			}
		}
		// 5、把商品列表写入cookie。
		CookieUtils.setCookie(request, response, TT_CART, JsonUtils.objectToJson(cartList), CART_EXPIRE, true);
		// 6、返回逻辑视图:在逻辑视图中做redirect跳转。
		return "redirect:/cart/cart.html";
	}

4.	登录状态下的购物车处理
4.1.	功能分析
1、购物车数据保存的位置:
未登录状态下,把购物车数据保存到cookie中。
登录状态下,需要把购物车数据保存到服务端。需要永久保存,可以保存到数据库中。可以把购物车数据保存到redis中。
2、redis使用的数据类型
a)	使用hash数据类型
b)	Hash的key应该是用户id。Hash中的field是商品id,value可以把商品信息转换成json
c)	Redis是单线程,要求redis读取的数据量要小,读取多的数据,如果是string型,当一个gett/setter方法数据量大时,其余的数据需要等待。
3、添加购物车
登录状态下直接把商品数据保存到redis中。
未登录状态保存到cookie中。
4、如何判断是否登录?
a)	从cookie中取token
b)	取不到未登录
c)	取到token,到redis中查询token是否过期。
d)	如果过期,未登录状态
e)	没过期登录状态。
调用sso服务得到用户信息,拿到用户id后,
4.2.	判断用户是否登录
4.2.1.	功能分析
应该使用拦截器实现,将用户信息放到request中,在controller用request是否有用户信息来判断是否登录。
1、实现一个HandlerInterceptor接口。
2、在执行handler方法之前做业务处理
3、从cookie中取token。使用CookieUtils工具类实现。
4、没有取到token,用户未登录。放行
5、取到token,调用sso系统的服务,根据token查询用户信息。
6、没有返回用户信息。登录已经过期,未登录,放行。
7、返回用户信息。用户是登录状态。可以把用户对象保存到request中,在Controller中可以通过判断request中是否包含用户对象,确定是否为登录状态。

4.2.2.	LoginInterceptor
/**
 * 判断用户是否登录的拦截器
 * <p>Title: LoginInterceptor</p>
 * <p>Description: </p>
 * <p>Company: www.itcast.cn</p> 
 * @version 1.0
 */
public class LoginInterceptor implements HandlerInterceptor {
	
	@Value("${COOKIE_TOKEN_KEY}")
	private String COOKIE_TOKEN_KEY;
	@Autowired
	private UserService userService;
	
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		// 执行handler方法之前执行此方法
		// 1、实现一个HandlerInterceptor接口。
		// 2、在执行handler方法之前做业务处理
		// 3、从cookie中取token。使用CookieUtils工具类实现。
		String token = CookieUtils.getCookieValue(request, COOKIE_TOKEN_KEY);
		// 4、没有取到token,用户未登录。放行
		if (StringUtils.isBlank(token)) {
			return true;
		}
		// 5、取到token,调用sso系统的服务,根据token查询用户信息。
		E3Result e3Result = userService.getUserByToken(token);
		// 6、没有返回用户信息。登录已经过期,未登录,放行。
		if (e3Result.getStatus() != 200) {
			return true;
		}
		// 7、返回用户信息。用户是登录状态。可以把用户对象保存到request中,在Controller中可以通过判断request中是否包含用户对象,确定是否为登录状态。
		TbUser user = (TbUser) e3Result.getData();
		request.setAttribute("user", user);
		//返回true放行 登录与不登录都需要用购物车 
		//返回false拦截
		return true;
	}
	
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
			throws Exception {
		// 执行handler方法之后,并且是返回ModelAndView对象之前

	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		// 返回ModelAndView之后。可以捕获异常。

	}

}

4.2.3.	Springmvc.xml配置拦截器
<!-- 拦截器配置 -->
	<mvc:interceptors>
		<mvc:interceptor>
			<mvc:mapping path="/**"/>
			<bean class="cn.e3mall.cart.interceptor.LoginInterceptor"/>
		</mvc:interceptor>
	</mvc:interceptors>

4.3.	添加购物车
4.3.1.	功能分析
登录状态下添加购物车,直接把数据保存到redis中。需要调用购物车服务,使用redis的hash来保存数据。
Key:用户id
Field:商品id
Value:商品对象转换成json

参数:
1、用户id
2、商品id
3、商品数量

业务逻辑:
1、根据商品id查询商品信息
2、把商品信息保存到redis
a)	判断购物车中是否有此商品
b)	如果有,数量相加
c)	如果没有,根据商品id查询商品信息。
d)	把商品信息添加到购物车
3、返回值。E3Result
4.3.2.	dao层
根据商品id查询商品信息,单表查询。可以使用逆向工程。

4.3.3.	Service层
@Service
public class CartServiceImpl implements CartService {
	
	@Value("${CART_REDIS_KEY}")
	private String CART_REDIS_KEY;

	@Autowired
	private TbItemMapper itemMapper;
	@Autowired
	private JedisClient jedisClient;
	
	@Override
	public E3Result addCart(long userId, long itemId, int num) {
		// a)判断购物车中是否有此商品
		Boolean flag = jedisClient.hexists(CART_REDIS_KEY + ":" + userId, itemId + "");
		// b)如果有,数量相加
		if (flag) {
			//从hash中取商品数据
			String json = jedisClient.hget(CART_REDIS_KEY + ":" + userId, itemId + "");
			//转换成java对象
			TbItem tbItem = JsonUtils.jsonToPojo(json, TbItem.class);
			//数量相加
			tbItem.setNum(tbItem.getNum() + num);
			//写入hash
			jedisClient.hset(CART_REDIS_KEY + ":" + userId, itemId + "", JsonUtils.objectToJson(tbItem));
			//返回添加成功
			return E3Result.ok();
		}
		// c)如果没有,根据商品id查询商品信息。
		TbItem tbItem = itemMapper.selectByPrimaryKey(itemId);
		//设置商品数量
		tbItem.setNum(num);
		String image = tbItem.getImage();
		//取一张图片
		if (StringUtils.isNotBlank(image)) {
			tbItem.setImage(image.split(",")[0]);
		}
		// d)把商品信息添加到购物车
		jedisClient.hset(CART_REDIS_KEY + ":" + userId, itemId + "", JsonUtils.objectToJson(tbItem));
		return E3Result.ok();
	}

}

发布服务:
 
4.3.4.	Controller
@RequestMapping("/cart/add/{itemId}")
	public String addCart(@PathVariable Long itemId, Integer num,
			HttpServletRequest request, HttpServletResponse response) {
		//判断用户是否为登录状态
		Object object = request.getAttribute("user");
		if (object != null) {
			TbUser user = (TbUser) object;
			//取用户id
			Long userId = user.getId();
			//添加到服务端
			E3Result e3Result = cartService.addCart(userId, itemId, num);
			return "cartSuccess";
		}
		//如果登录直接把购物车信息添加到服务端
		//如果未登录保存到cookie中
		// 1、从cookie中取购物车列表。
		List<TbItem> cartList = getItemListFromCookie(request);
		// 2、判断商品列表是否存在此商品。
		boolean falg = false;
		for (TbItem tbItem : cartList) {
			if (tbItem.getId() == itemId.longValue()) {
				//数量相加
				// 4、如果存在,数量相加。
				tbItem.setNum(tbItem.getNum() + num);
				falg = true;
				break;
			}
		}
		// 3、如果不存在添加到列表
		if (!falg) {
			//根据商品id取商品信息
			TbItem tbItem = itemService.getItemById(itemId);
			//设置数量
			tbItem.setNum(num);
			String image = tbItem.getImage();
			//取一张图片
			if (StringUtils.isNotBlank(image)) {
				tbItem.setImage(image.split(",")[0]);
			}
			//添加到列表
			cartList.add(tbItem);
		}
		// 5、把购车列表写入cookie
		CookieUtils.setCookie(request, response, COOKIE_CART_KEY, JsonUtils.objectToJson(cartList), COOKIE_CART_EXPIRE, true);
		// 6、返回逻辑视图,提示添加成功
		return "cartSuccess";
	}
  
4.4.	登录状态下访问购物车列表
4.4.1.	功能分析
1、未登录状态下购物车列表是从cookie中取。
2、登录状态下购物车应该是从服务端取。
3、如果cookie中有购物车数据,应该吧cookie中的购物车和服务端合并,合并后删除cookie中的购物车数据。
4、合并购物车时,如果商品存在,数量相加,如果不存在,添加一个新的商品。
5、从服务端取购物车列表展示

4.4.2.	Dao层
不需要访问数据库,只需要访问redis。

4.4.3.	Service层
1、合并购物车
参数:用户id
      List<TbItem>
返回值:E3Result
业务逻辑:
1)遍历商品列表
2)如果服务端有相同商品,数量相加
3)如果没有相同商品,添加一个新的商品

2、取购物车列表
参数:用户id
返回值:List<TbItem>
业务逻辑:
1)从hash中取所有商品数据
2)返回

/**
	 * 合并购物车
	 * <p>Title: mergeCart</p>
	 * <p>Description: </p>
	 * @param userId
	 * @param itemList
	 * @return
	 * @see cn.e3mall.cart.service.CartService#mergeCart(long, java.util.List)
	 */
	@Override
	public E3Result mergeCart(long userId, List<TbItem> itemList) {
		//遍历商品列表
		for (TbItem tbItem : itemList) {
			addCart(userId, tbItem.getId(), tbItem.getNum());
		}
		return E3Result.ok();
	}

	/**
	 * 取购物车列表
	 * <p>Title: getCartList</p>
	 * <p>Description: </p>
	 * @param userId
	 * @return
	 * @see cn.e3mall.cart.service.CartService#getCartList(long)
	 */
	@Override
	public List<TbItem> getCartList(long userId) {
		//从redis中根据用户id查询商品列表
		List<String> strList = jedisClient.hvals(CART_REDIS_KEY + ":" + userId);
		List<TbItem> resultList = new ArrayList<>();
		//把json列表转换成TbItem列表
		for (String string : strList) {
			TbItem tbItem = JsonUtils.jsonToPojo(string, TbItem.class);
			//添加到列表
			resultList.add(tbItem);
		}
		return resultList;
	}

4.4.4.	表现层
1、判断用户是否登录。
2、如果已经登录,判断cookie中是否有购物车信息
3、如果有合并购物车,并删除cookie中的购物车。
4、如果是登录状态,应从服务端取购物车列表。
5、如果是未登录状态,从cookie中取购物车列表
@RequestMapping("/cart/cart")
	public String showCartList(HttpServletRequest request, HttpServletResponse response) {
		//从cookie中取购物车列表
		List<TbItem> cartList = getItemListFromCookie(request);
		//判断用户是否登录
		Object object = request.getAttribute("user");
		if (object != null) {
			TbUser user = (TbUser) object; 
			//用户已经登录
			System.out.println("用户已经登录,用户名为:" + user.getUsername());
			//判断购物车列表是否为空
			if (!cartList.isEmpty()) {
				//合并购物车
				cartService.mergeCart(user.getId(), cartList);
				//删除cookie中的购物车
				CookieUtils.setCookie(request, response, COOKIE_CART_KEY, "");
			}
			//从服务端取购物车列表
			List<TbItem> list = cartService.getCartList(user.getId());
			request.setAttribute("cartList", list);
			return "cart";
		} else {
			System.out.println("用户未登录");
		}
		//传递给页面
		request.setAttribute("cartList", cartList);
		return "cart";
	}

4.5.	修改购物车数量
只需要更新hash中商品的数量即可。
不需要对数据库进行操作,只需要对redis操作即可。

4.5.1.	Server
参数:
1、用户id
2、商品id
3、数量
返回值:
E3Result
业务逻辑:
1、根据商品id从hash中取商品信息。
2、把json转换成java对象
3、更新商品数量
4、把商品数据写回hash

@Override
	public E3Result updateCartItemNum(long userId, long itemId, int num) {
		//从hash中取商品信息
		String json = jedisClient.hget(CART_REDIS_KEY + ":" + userId, itemId + "");
		//转换成java对象
		TbItem tbItem = JsonUtils.jsonToPojo(json, TbItem.class);
		//更新数量
		tbItem.setNum(num);
		//写入hash
		jedisClient.hset(CART_REDIS_KEY + ":" + userId, itemId + "", JsonUtils.objectToJson(tbItem));
		return E3Result.ok();
	}

4.5.2.	Controller
1、判断是否为登录状态
2、如果是登录状态,更新服务端商品数量
3、如果未登录,更新cookie中是商品数量
/**
	 * 更新商品数量
	 * <p>Title: updateCartItemNum</p>
	 * <p>Description: </p>
	 * @param itemId
	 * @param num
	 * @return
	 */
	@RequestMapping("/cart/update/num/{itemId}/{num}")
	@ResponseBody
	public E3Result updateCartItemNum(@PathVariable Long itemId, @PathVariable Integer num,
			HttpServletRequest request, HttpServletResponse response) {
		//判断是否为登录状态
		Object object = request.getAttribute("user");
		if (object != null) {
			TbUser user = (TbUser) object;
			//更新服务端的购物车
			cartService.updateCartItemNum(user.getId(), itemId, num);
			return E3Result.ok();
		}
		// 1、从cookie中取购物车列表
		List<TbItem> cartList = getItemListFromCookie(request);
		// 2、遍历列表找到对应的商品
		for (TbItem tbItem : cartList) {
			if (tbItem.getId() == itemId.longValue()) {
				// 3、更新商品数量
				tbItem.setNum(num);
				break;
			}
		}
		// 4、把购物车列表写入cookie
		CookieUtils.setCookie(request, response, COOKIE_CART_KEY, JsonUtils.objectToJson(cartList), COOKIE_CART_EXPIRE, true);
		//返回OK
		return E3Result.ok();
	}
4.6.	删除购物车商品
4.6.1.	业务逻辑
1、判断是否为登录状态
2、如果是登录状态,直接删除hash中的商品。
3、如果不是登录状态,对cookie中的购物车进行操作

4.6.2.	Service
参数:用户id
      商品id
返回值:E3Result
业务逻辑:
根据商品id删除hash中对应的商品数据。
@Override
	public E3Result deleteCartItem(long userId, long itemId) {
		// 根据商品id删除hash中对应的商品数据。
		jedisClient.hdel(CART_REDIS_KEY + ":" + userId, itemId + "");
		return E3Result.ok();
	}

4.6.3.	Controller
1、判断用户登录状态
2、如果登录删除服务端
3、如果未登录删除cookie中的购物车商品
/**
	 * 删除购物车商品
	 * <p>Title: deleteCartItem</p>
	 * <p>Description: </p>
	 * @param itemId
	 * @return
	 */
	@RequestMapping("/cart/delete/{itemId}")
	public String deleteCartItem(@PathVariable Long itemId, 
			HttpServletRequest request, HttpServletResponse response) {
		//判断用户登录状态
		Object object = request.getAttribute("user");
		if (object != null) {
			TbUser user = (TbUser) object;
			//删除服务端的购物车商品
			cartService.deleteCartItem(user.getId(), itemId);
			return "redirect:/cart/cart.html";
		}
		// 1、从url 中取商品id
		// 2、从cookie 中取购物车列表
		List<TbItem> cartList = getItemListFromCookie(request);
		// 3、遍历列表找到商品
		for (TbItem tbItem : cartList) {
			if (tbItem.getId() == itemId.longValue()) {
				// 4、删除商品
				cartList.remove(tbItem);
				//退出循环
				break;
			}
		}
		// 5、把购物车列表写入cookie
		CookieUtils.setCookie(request, response, COOKIE_CART_KEY, JsonUtils.objectToJson(cartList), COOKIE_CART_EXPIRE, true);
		// 6、返回逻辑视图。做redirect跳转到购物车列表页面。
		return "redirect:/cart/cart.html";
	}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值