黑马淘淘商城第十二天 购物车实现、订单确认页面展示

1. 课程计划

第十二天:

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

2. 购物车的实现

2.1. 功能分析

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

2.2. 工程搭建

Taotao-cart-web打包方式war
可以参考taotao-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>com.taotao</groupId>
		<artifactId>taotao-parent</artifactId>
		<version>0.0.1-SNAPSHOT</version>
	</parent>
	<groupId>com.taotao</groupId>
	<artifactId>taotao-cart-web</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>
	<dependencies>
		<dependency>
			<groupId>com.taotao</groupId>
			<artifactId>taotao-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</g roupId>
			<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>

2.2.2. 框架整合
在这里插入图片描述

2.3. 添加购物车

2.3.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保存。当根据商品id查询商品信息后,取第一张图片保存到image属性中即可。

读写cookie可以使用CookieUtils工具类实现。
2.3.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, Integer num,
			HttpServletRequest request, HttpServletResponse response) {
		// 1、从cookie中查询商品列表。
		List<TbItem> cartList = getCartList(request);
		// 2、判断商品在商品列表中是否存在。
		boolean hasItem = false;
		for (TbItem tbItem : cartList) {
			//对象比较的是地址,应该是值的比较
			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);
		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<>();
	}
	
}

2.4. 展示购物车商品列表

请求的url:/cart/cart
参数:无
返回值:逻辑视图
业务逻辑:
1、从cookie中取商品列表。
2、把商品列表传递给页面。
2.4.1. Controller

@RequestMapping("/cart/cart")
	public String showCartList(HttpServletRequest request, Model model) {
		//取购物车商品列表
		List<TbItem> cartList = getCartList(request);
		//传递给页面
		model.addAttribute("cartList", cartList);
		return "cart";
	}

2.5. 修改购物车商品数量

2.5.1. 功能分析
1、在页面中可以修改商品数量
2、重新计算小计和总计。
3、修改需要写入cookie。
4、每次修改都需要向服务端发送一个ajax请求,在服务端修改cookie中的商品数量。
在这里插入图片描述
请求的url:/cart/update/num/{itemId}/{num}
参数:long itemId、int num
业务逻辑:
1、接收两个参数
2、从cookie中取商品列表
3、遍历商品列表找到对应商品
4、更新商品数量
5、把商品列表写入cookie。
6、响应TaoTaoResult。Json数据。
返回值:
TaoTaoResult。Json数据
2.5.2. Controller

@RequestMapping("/cart/update/num/{itemId}/{num}")
	@ResponseBody
	public TaotaoResult 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);
			}
		}
		// 5、把商品列表写入cookie。
		CookieUtils.setCookie(request, response, TT_CART, JsonUtils.objectToJson(cartList), CART_EXPIRE, true);
		// 6、响应TaoTaoResult。Json数据。
		return TaotaoResult.ok();
	}

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

在这里插入图片描述

2.6. 删除购物车商品

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

2.6.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";
	}

淘淘静态页面

2.7. 小结

使用cookie实现购物车:
优点:
1、实现简单
2、不需要占用服务端存储空间。
缺点:
1、存储容量有限
2、更换设备购车信息不能同步。

实现购车商品数据同步:
1、要求用户登录。
2、把购物车商品列表保存到数据库中。推荐使用redis。
3、Key:用户id,value:购车商品列表。推荐使用hash,hash的field:商品id,value:商品信息。
4、在用户未登录情况下写cookie。当用户登录后,访问购物车列表时,
a) 把cookie中的数据同步到redis。
b) 把cookie中的数据删除
c) 展示购物车列表时以redis为准。
d) 如果redis中有数据cookie中也有数据,需要做数据合并。相同商品数量相加,不同商品添加一个新商品。
5、如果用户登录状态,展示购物车列表以redis为准。如果未登录,以cookie为准。

  1. 订单系统
    3.1. 功能分析
    1、在购物车页面点击“去结算”按钮跳转到订单确认页面。
    a) 展示商品列表
    b) 配送地址列表
    c) 选择支付方式
    2、展示订单确认页面之前,应该确认用户身份。
    a) 使用拦截器实现。
    b) Cookie中取token
    c) 取不到token跳转到登录页面
    d) 取到token,根据token查询用户信息。
    e) 如果没有用户信息,登录过期跳转到登录页面
    f) 取到用户信息,放行。
    3、提交订单
    a) 生成订单
    b) 展示订单提交成功页面。

订单系统系统:订单确认页面、订单提交成功页面。
订单服务系统

3.2. 工程搭建
在这里插入图片描述
创建一个订单服务系统:
Taotao-order
|–taotao-order-interface
|–taotao-order-Service
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
可以参考taotao-manager整合。

表现层工程:
Taotao-order-web打包方式war。
在这里插入图片描述
在这里插入图片描述

3.3. 展示订单确认页面

3.3.1. 功能分析
1、在购物车页面点击“去结算”按钮跳转到订单确认页面。
2、请求的url:
在这里插入图片描述
/order/order-cart
3、参数:没有参数。
4、购物车商品数据从cookie中取出来的。可以在订单系统中取到cookie中的购物车数据。
5、配送地址列表,需要用户登录。需要根据用户id查询收货地址列表。静态数据。
6、支付方式。静态数据。
7、返回值:逻辑视图String,展示订单确认页面。

3.3.2. Dao层、Service层(没有)
需要根据用户id查询收货地址列表。没有此功能。

3.3.3. 表现层
请求的url:/order/order-cart
参数:无
业务逻辑:
从cookie中取商品列表展示到页面。
返回值:逻辑视图。

@Controller
public class OrderController {
	
	@Value("${TT_CART}")
	private String TT_CART;

	/**
	 * 展示订单确认页面。
	 * <p>Title: showOrderCart</p>
	 * <p>Description: </p>
	 * @return
	 */
	@RequestMapping("/order/order-cart")
	public String showOrderCart(HttpServletRequest request) {
		//取用户id
		//从cookie中取token,然后根据token查询用户信息。需要调用sso系统的服务。
		//根据用户id查询收货地址列表
		//从cookie中取商品列表
		List<TbItem> cartList = getCartList(request);
		//传递给页面
		request.setAttribute("cartList", cartList);
		//返回逻辑视图
		return "order-cart";
	}
	
	/**
	 * 从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<>();
	}
}

3.4. 用户身份认证

在展示订单确认页面之前,需要对用户身份进行认证,要求用户必须登录。

3.4.1. 功能分析
1、使用springmvc的拦截器实现。需要实现一个接口HandlerInterceptor接口。
2、业务逻辑
a) 从cookie中取token。
b) 没有token,需要跳转到登录页面。
c) 有token。调用sso系统的服务,根据token查询用户信息。
d) 如果查不到用户信息。用户登录已经过期。需要跳转到登录页面。
e) 查询到用户信息。放行。
3、在springmvc.xml中配置拦截器。
3.4.2. 拦截器实现

public class LoginInterceptor implements HandlerInterceptor {
	
	@Value("${TT_TOKEN}")
	private String TT_TOKEN;
	@Value("${SSO_LOGIN_URL}")
	private String SSO_LOGIN_URL;
	
	@Autowired
	private UserService userService;

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		//执行Handler之前执行此方法
		// a)从cookie中取token。
		String token = CookieUtils.getCookieValue(request, TT_TOKEN);
		if (StringUtils.isBlank(token)) {
			//取当前请求的url
			String url = request.getRequestURL().toString();
			// b)没有token,需要跳转到登录页面。
			response.sendRedirect(SSO_LOGIN_URL + "?redirectUrl=" + url);
			//拦截
			return false;
		}
		// c)有token。调用sso系统的服务,根据token查询用户信息。
		TaotaoResult result = userService.getUserByToken(token);
		if (result.getStatus() != 200) {
			// d)如果查不到用户信息。用户登录已经过期。需要跳转到登录页面。
			//取当前请求的url
			String url = request.getRequestURL().toString();
			// b)没有token,需要跳转到登录页面。
			response.sendRedirect(SSO_LOGIN_URL + "?redirectUrl=" + url);
			//拦截
			return false;
		}
		// e)查询到用户信息。放行。
		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之后,执行。异常处理。

	}

}

3.4.3. 配置拦截器
在这里插入图片描述
3.4.4. 实现sso系统的回调
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值