一、创建购物车前后端模块
二、cart购物车Web前端的properties文件:
#端口号
server.port=8085
#日志级别
logging.level.root=info
#dubbo协议
#dubbo中的服务名称
spring.dubbo.application=cart-web
#protocol协议的意思,即dubbo通讯协议
spring.dubbo.protocol.name=dubbo
#zookeeper注册中心地址,registry注册的意思
spring.dubbo.registry.address=172.25.0.11:2181
#protocol协议的意思,registry注册的意思,即zookeeeper注册协议
spring.dubbo.registry.protocol=zookeeper
#dubbo扫描包路径
spring.dubbo.base-package=com.atguigu.gmall
#设置超时10分钟,防止debug启动断点测试的时候超时
spring.dubbo.consumer.timeout=600000
#设置检测服务是否启动,服务启动了,消费者再去消费
spring.dubbo.consumer.check=false
# 关闭thymeleaf的缓存(热部署)
spring.thymeleaf.cache=false
# 松校验
spring.thymeleaf.mode=LEGACYHTML5
Resource资源文件中:
**static文件夹:**属于静态页面,可以通过浏览器直接访问
**templates文件夹:**都是渲染模块,属于java代码,在服务器属于隐藏路径!!!
三、购物车业务逻辑
1、未登陆的用户,可以使用购物车,需要引入浏览器cookie的操作。
2、登陆的用户,在使用购物车,则需要使用mysql和redis来存储数据,redis作为购物车的缓存
3、用户未登陆添加购物车cookie缓存,或者用户已经登陆添加购物车。
允许购物车中的数据和原始商品数据的不一致性(这个是典型的数据弱一致性)。
假设管理员从后台修改了某一个sku商品信息,或者某个sku商品下架了,用户的购物车不需要及时的更新,而且也更新不过来,上十亿的商品,如果使用强一致性,数据量就非常的庞大,对服务器就造成巨大的压力!!!
只需要保持用户的购物车所添加的商品不变即可!
4、购物车同步合并问题(未登陆的cookie购物车和登陆的购物车合并)
什么时候同步合并(结算、登陆的时候合并购物车)
同步合并购物车后,需要删除cookie购物车数据(因为防止下次登陆又重复同步;或者别人购买之后,退出账户,为了保护用户隐私)
5、用户在不同的客户端同时登陆,如何处理购物车的数据?
四、购物车的添加功能
1、传递参数(商品skuId、添加数量)
2、根据skuId调用skuService查询商品的详细信息
3、将商品的详细信息封装成购物车信息
4、判断用户是否登录
5、如果未登陆执行cookie操作,如果登录了则执行db操作
购物车数据进行写入:
Cookie:写入:response.addCookie(cookie),拿出来:request.getCookie()
Cookie跨域问题:二级域名相互之间的cookie是不共享的,如:item.jd.com和cart.jd.com两个网站保存的cookie不相互共享的。如果保存到jd.com的一级域名,则全部二级域名共享。
设置域的方法解决:
setDomain(),getDomain()保存一级域名的cookie
五、cookie技术比较常用,那么我们需要把它添加进spring容器里(和redis技术一样),这里在web-util模块创建cookie工具类,加入以下源码:
这样我们就可以在任何有加入web-util模块依赖的其他模块,直接使用cookie技术了!!!
public class CookieUtil {
/***
* 获得cookie中的值,默认为主ip:www.gmall.com
* @param request
* @param cookieName
* @param isDecoder
* @return
*/
public static String getCookieValue(HttpServletRequest request, String cookieName, boolean isDecoder) {
Cookie[] cookies = request.getCookies();
if (cookies == null || cookieName == null){
return null;
}
String retValue = null;
try {
for (int i = 0; i < cookies.length; i++) {
if (cookies[i].getName().equals(cookieName)) {
if (isDecoder) {//如果涉及中文
retValue = URLDecoder.decode(cookies[i].getValue(), "UTF-8");
} else {
retValue = cookies[i].getValue();
}
break;
}
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return retValue;
}
/***
* 设置cookie的值
* @param request
* @param response
* @param cookieName
* @param cookieValue
* @param cookieMaxage
* @param isEncode
*/
public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName, String cookieValue, int cookieMaxage, boolean isEncode) {
try {
if (cookieValue == null) {
cookieValue = "";
} else if (isEncode) {
cookieValue = URLEncoder.encode(cookieValue, "utf-8");
}
Cookie cookie = new Cookie(cookieName, cookieValue);
if (cookieMaxage >= 0)
cookie.setMaxAge(cookieMaxage);
if (null != request)// 设置域名的cookie
cookie.setDomain(getDomainName(request));
// 在域名的根路径下保存
cookie.setPath("/");
response.addCookie(cookie);
} catch (Exception e) {
e.printStackTrace();
}
}
/***
* 获得cookie的主域名,本系统为gmall.com,保存时使用
* @param request
* @return
*/
private static final String getDomainName(HttpServletRequest request) {
String domainName = null;
String serverName = request.getRequestURL().toString();
if (serverName == null || serverName.equals("")) {
domainName = "";
} else {
serverName = serverName.toLowerCase();
serverName = serverName.substring(7);
final int end = serverName.indexOf("/");
serverName = serverName.substring(0, end);
final String[] domains = serverName.split("\\.");
int len = domains.length;
if (len > 3) {
// www.xxx.com.cn
domainName = domains[len - 3] + "." + domains[len - 2] + "." + domains[len - 1];
} else if (len <= 3 && len > 1) {
// xxx.com or xxx.cn
domainName = domains[len - 2] + "." + domains[len - 1];
} else {
domainName = serverName;
}
}
if (domainName != null && domainName.indexOf(":") > 0) {
String[] ary = domainName.split("\\:");
domainName = ary[0];
}
System.out.println("domainName = " + domainName);
return domainName;
}
/***
* 将cookie中的内容按照key删除
* @param request
* @param response
* @param cookieName
*/
public static void deleteCookie(HttpServletRequest request, HttpServletResponse response, String cookieName) {
setCookie(request, response, cookieName, null, 0, false);
}
}