淘淘商城67-商城購物車系統實現之登錄與未登錄狀態下添加商品到購物車

目錄

1.導入靜態資源

2.修改商品詳情頁

3.登錄狀態下添加購物車

3.1服務層

3.1.1dao層

3.1.2service層

3.2表現層

3.2.1properties文件

3.2.2controller

3.2.3配置springmvc.xml

3.3測試訪問

4.未登錄狀態下添加購物車

4.1服務層

4.2表現層

4.3訪問測試


1.導入靜態資源

將參考資料中的購物車靜態頁面下js、css、images導入webapp下,將jsp導入WEB-INF下

2.修改商品詳情頁

商品詳情在taotao-item-web系統的item.jsp中

加入購物車添加一個事件javascript:addCartItem();

function addCartItem(){
		//購買商品數量
		var num=$("#buy-num").val();
		window.location.href="http://localhost:8089/cart/add/${item.id}.html?num="+num;
	}

在前端點擊添加購物車,就會觸發addCartItem函數,跳轉url:cart/add/itemId.html?num=123,我們需要接收itemId與num,同步到redis或者cookie

3.登錄狀態下添加購物車

3.1服務層

3.1.1dao層

直接通過jedisClient操作redis數據庫

3.1.2service層

業務邏輯:

  1. 根據商品的id與用戶id從redis查詢商品的信息
  2. 判斷要添加的商品是否存在與redis中
  3. 如果存在,將添加商品的數量與redis已存在的商品數量相加後,存入redis
  4. 如果不存在,直接設置商品數量爲添加的商品數量,並設置image屬性爲第一張圖片,然後存入redis

首先在taotao-cart-interface下創建接口包com.taotao.cart.service,在接口包下創建接口CartService.java

使用hash類型,可以給key設置一個前綴用於分類。在taotao-cart-service的src/main/resources下創建resource.properties文件

#購物車的前綴
TT_CART_REDIS_PRE_KEY=TT_CART_REDIS_PRE_KEY

在taotao-cart-service下創建實現類包com.taotao.cart.service.impl,在實現類包下創建CartServiceImpl實現CartService

這裏封裝了一個根據key:itemId,filed:userId,從redis獲取itemJson的方法queryItemByItemAndUserId(Long itemId,Long userId)

後面還很常用

package com.taotao.cart.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

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 com.taotao.cart.jedis.JedisClient;
import com.taotao.cart.service.CartService;
import com.taotao.common.pojo.TaotaoResult;
import com.taotao.common.utils.JsonUtils;
import com.taotao.pojo.TbItem;
@Service
public class CartServiceImpl implements CartService {
	/**發佈服務*/
	/**注入依賴*/
	
	@Autowired
	private JedisClient jedisClient;
	/**redis緩存購物車的前綴*/
	@Value("${TT_CART_REDIS_PRE_KEY}")
	private String TT_CART_REDIS_PRE_KEY;
	
	/**登錄狀態下添加購物車*/
	@Override
	public TaotaoResult addItemCart(TbItem tbItem, Integer num, Long userId) {
		//1.根據 key和field查詢某一個商品
		TbItem tbItem2 = queryItemByItemAndUserId(tbItem.getId(), userId);
		//2.判斷要添加的商品是否存在於列表中
		if(tbItem2 != null) {
			//3.如果存在,直接數量相加
			tbItem2.setNum(tbItem2.getNum()+num);
			//存入redis中
			jedisClient.hset(TT_CART_REDIS_PRE_KEY+":"+userId, tbItem2.getId()+"", JsonUtils.objectToJson(tbItem2));
		}else {
			//4.如果不存在,設置商品數量,設置圖片
			tbItem.setNum(num);
			if(tbItem.getImage()!=null) {
				tbItem.setImage(tbItem.getImage().split(",")[0]);
			}
			//存入redis中
			jedisClient.hset(TT_CART_REDIS_PRE_KEY+":"+userId, tbItem.getId()+"", JsonUtils.objectToJson(tbItem));
		}
		return TaotaoResult.ok();
	}
   /**
	 * key:itemId,filed:userId,獲取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;
	}
}

 配置springmvc.xml文件

要注意圖中標註的地方

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
	http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd
	http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.2.xsd">
	<!-- 加載properties文件 -->
	<context:property-placeholder location="classpath:resource/*.properties" />
	<!-- 註解掃描 -->
	<context:component-scan base-package="com.taotao.cart.service"/>
	<!-- 使用dubbo發佈服務 -->
	<!-- 提供方應用信息,用於計算依賴關係 -->
	<dubbo:application name="taotao-cat" />
	<dubbo:registry protocol="zookeeper" address="192.168.25.133:2181" />
	<!-- 用dubbo協議在20884端口暴露服務 -->
	<dubbo:protocol name="dubbo" port="20884" />
	<!-- 聲明需要暴露的服務接口 -->
	<dubbo:service interface="com.taotao.cart.service.CartService" ref="cartServiceImpl" timeout="300000"/>
 
</beans>

3.2表現層

3.2.1properties文件

由於要將購物車存入cookie中,所以需要給購物車存入cookie時設置一個name,獲取token時正好也需要一個name,可以將這兩個name放在properties文件中

resource.properties

#COOKIE中存放token的key
COOKIE_TOKEN_KEY=COOKIE_TOKEN_KEY
#COOKIE中存放購物車的key
COOKIE_CART_KEY=COOKIE_CART_KEY

3.2.2controller

url: /cart/add/{itemId}

參數:itemId,num

返回值:添加購物車成功頁面。

 

處理的邏輯:

  1. 調用sso的服務,獲取用戶相關的信息
  2. 調用manager的服務,獲取商品的相關的信息
  3. 判斷如果是登錄的狀態,調用登錄的添加購物車的service
  4. 如果是未登錄的狀態,調用的是未登錄的添加購物車的方法。

由於要調用taotao-sso與taotao-manager的服務

需要在pom.xml中添加依賴

<dependency>
	<groupId>com.taotao</groupId>
	<artifactId>taotao-manager-interface</artifactId>
	<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
	<groupId>com.taotao</groupId>
	<artifactId>taotao-cart-interface</artifactId>
	<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
	<groupId>com.taotao</groupId>
	<artifactId>taotao-sso-interface</artifactId>
	<version>0.0.1-SNAPSHOT</version>
</dependency>

在taotao-cart-web下創建controller包com.taotao.cart.controller,在controller中創建CartController

package com.taotao.cart.controller;

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

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.taotao.cart.service.CartService;
import com.taotao.common.pojo.TaotaoResult;
import com.taotao.common.utils.CookieUtils;
import com.taotao.common.utils.JsonUtils;
import com.taotao.pojo.TbItem;
import com.taotao.pojo.TbUser;
import com.taotao.service.ItemService;
import com.taotao.sso.service.UserLoginService;

@Controller
public class CartController {
	/** 引入服務 */
	/** 注入依賴 */
	@Autowired
	private CartService cartService;
	@Autowired
	private ItemService itemService;
	@Autowired
	private UserLoginService loginService;
	/** COOKIE中存放token的key */
	@Value("${COOKIE_TOKEN_KEY}")
	private String COOKIE_TOKEN_KEY;
	/** COOKIE中存放購物車的key */
	@Value("${COOKIE_CART_KEY}")
	private String COOKIE_CART_KEY;

	/**
	 * 添加商品到redis或cookie購物車
	 * 
	 * @param itemId
	 * @param num
	 * @param request
	 * @param response
	 * @return
	 */
	// /cart/add/149204693130763.html?num=4
	@RequestMapping("/cart/add/{itemId}")
	public String addItemCart(@PathVariable Long itemId, 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);
		// 3.判斷,如果用戶存在,說明已經登錄
		// 3.1首先調用商品服務的方法,獲取商品的數據tbitem
		TbItem tbItem = itemService.getItemById(itemId);
		if (result.getStatus() == 200) {
			// 3.2獲取用戶信息中的userId
			TbUser tbUser = (TbUser) result.getData();
			// 3.3調用添加購物車的方法 將商品數據添加到redis中
			cartService.addItemCart(tbItem, num, tbUser.getId());
		} else {
			// 4.判斷,如果用戶不存在,說明未登錄,將商品數據添加到cookie中
			// 4.1先根據cookie獲取購物車的列表
		}
		return "cartSuccess";
	}

 

3.2.3配置springmvc.xml

加載properties文件與引入服務

<context:property-placeholder location="classpath:resource/resource.properties" />
<dubbo:reference interface="com.taotao.cart.service.CartService" id="cartService" timeout="300000" />

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也要啓動。

下面測試

首先登錄

登錄成功會跳轉首頁,因爲我們沒有啓動taotao-portal-web不用管,回退到商品搜索頁,會發現已經登錄了,說明cookie中寫入了token。點擊小米6x

點擊加入購物車

提示成功加入購物車

查看redis是否已經加入購物車,商品已經成功存入。

4.未登錄狀態下添加購物車

4.1服務層

服務層不變,存入cookie,需要要使用servlet原生response對象,跟service沒什麼關係,所以放在controller中。

4.2表現層

在addItemCart判斷用戶沒登錄中添加如下,需要判斷cookie中是否已存在該商品,存在的話商品數量需要相加,不存在的話直接設置商品數量,還需要設置圖片爲第一張圖片,最後設置cookie存放時間爲一個星期(7*24*3600)

由於從cookie中獲取購物車方法經常使用單獨抽成一個私有方法

完整代碼:

package com.taotao.cart.controller;

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

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.taotao.cart.service.CartService;
import com.taotao.common.pojo.TaotaoResult;
import com.taotao.common.utils.CookieUtils;
import com.taotao.common.utils.JsonUtils;
import com.taotao.pojo.TbItem;
import com.taotao.pojo.TbUser;
import com.taotao.service.ItemService;
import com.taotao.sso.service.UserLoginService;

@Controller
public class CartController {
	/** 引入服務 */
	/** 注入依賴 */
	@Autowired
	private CartService cartService;
	@Autowired
	private ItemService itemService;
	@Autowired
	private UserLoginService loginService;
	/** COOKIE中存放token的key */
	@Value("${COOKIE_TOKEN_KEY}")
	private String COOKIE_TOKEN_KEY;
	/** COOKIE中存放購物車的key */
	@Value("${COOKIE_CART_KEY}")
	private String COOKIE_CART_KEY;

	/**
	 * 添加商品到redis或cookie購物車
	 * 
	 * @param itemId
	 * @param num
	 * @param request
	 * @param response
	 * @return
	 */
	// /cart/add/149204693130763.html?num=4
	@RequestMapping("/cart/add/{itemId}")
	public String addItemCart(@PathVariable Long itemId, 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);
		// 3.判斷,如果用戶存在,說明已經登錄
		// 3.1首先調用商品服務的方法,獲取商品的數據tbitem
		TbItem tbItem = itemService.getItemById(itemId);
		if (result.getStatus() == 200) {
			// 3.2獲取用戶信息中的userId
			TbUser tbUser = (TbUser) result.getData();
			// 3.3調用添加購物車的方法 將商品數據添加到redis中
			cartService.addItemCart(tbItem, num, tbUser.getId());
		} else {
			// 4.判斷,如果用戶不存在,說明未登錄,將商品數據添加到cookie中
			// 4.1先根據cookie獲取購物車的列表
			List<TbItem> cartList = getCookieCartList(request);
			boolean flag = false;
			// 4.2判斷如果購物車中有包含要添加的商品 商品數量相加
			for (TbItem tbItem2 : cartList) {
				// 4.3 找到列表中的商品 更新數量
				if (tbItem2.getId() == itemId.longValue()) {
					tbItem2.setNum(tbItem2.getNum() + num);
					flag = true;
					break;
				}
			}
			if (!flag) {
				// 4.4如果沒有就直接添加到購物車
				// 4.5設置數量與圖片
				tbItem.setNum(num);
				if (tbItem.getImage() != null) {
					tbItem.setImage(tbItem.getImage().split(",")[0]);
				}

				cartList.add(tbItem);
			}
			// 4.6存到cookie中
			CookieUtils.setCookie(request, response, COOKIE_CART_KEY, JsonUtils.objectToJson(cartList), 7 * 24 * 3600,
					true);
		}
		return "cartSuccess";
	}

    /** 獲取購物車列表 */
	private List<TbItem> getCookieCartList(HttpServletRequest request) {
		// 1.從cookie中獲取購物車列表
		String cartJson = CookieUtils.getCookieValue(request, COOKIE_CART_KEY, true);
		// 2.將cartJson轉爲List<TbItem>
		if (StringUtils.isNotBlank(cartJson)) {
			List<TbItem> list = JsonUtils.jsonToList(cartJson, TbItem.class);
			return list;
		}
		return new ArrayList<>();
	}
}

4.3訪問測試

首先退出用戶

添加商品到購物車

 

提示添加成功

使用我已經做好的查看購物車列表的功能,查看cookie中是否存入了購物車

可以看到未登錄的情況下,添加購物車成功

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章