课程目标
- 说出京东购物车的实现思路
- 运用Cookie储存购物车
- 编写购物车前端代码
- 运用Redis存储购物车
购物车需求分析与解决方案
-
需求分析:
- 用户在商品详细页点击加入购物车,提交商品SKU编号和购买数量,添加到购物车;
-
架构图分析:

-
存储方案:
- 当用户没有登录:采用cookie存储 [本地购物车]
- 当用户登录后,采用redis存储,并且要将cookie中的购物车合并到redis中,cookie中的购物车清空; [远程购物车]
-
cookie购物车存储逻辑:

-
注意:
- 不是所有的逻辑层必须写在service层,但是写在service一方面是解耦合分工明确,一方面方便共用,前端的controller.js和service.js也是如此;
购物车解决方案思路:
1. 建好相关包,导入相关依赖和配置文件;
2. interface:
1. 分析:
* 在电商项目中,购物车是一个必须要做的东西;首先从购物车的角度来讲,我们有商品,那么就有购物车,购物车里面包含很多个商品,每个商品又有各自的属性,同时整个购物车也应该包含商家信息;所以应该架构为:
1. 购物车列表:[商家信息]与[商品明细]
2. 商品明细:[商品的标题,价格,数量等]
* 所以在建interface时创建方法应该有:添加单个商品到购物车,[删除的操作可以在前端实现]
* 同时应该要考虑到一些用户没有登录的时候,应该也能使用购物车功能,所以应该有两种购物车方式:一种是本地购物车[cookie],一种是远程购物车[redis]
* 如此,在Interface中应该再添加两个方法,一个是存储购物车到cookie,一个是存储购物车到redis;
* 如果用户一开始没有登录,但是已经添加了部分商品,后来又登录了,应该将以前的远程购物车中的商品与cookie中的商品同时存储起来,并将本地购物车中的商品删除;
2. 方法:
1. 添加购物车到商品列表
2. 从redis中提取购物车列表
3. 将购物车列表存入redis
4. 合并购物车
2. service:
1. 分析:
* 首先应该有查询方法: 根据SKU id查询商品明细的SKU对象,如果对象不存在抛出异常,如果存在,则先由商品的id值找到商家对象,判断商家对象是否为null,如果购物车中不存在商家的购物车,说明这是在这家店买的第一件商品,应该新建立一个购物车对象,存入商家的信息和商品明细信息,并添加到总购物车中;
* 如果该商家对象存在,说明在总购物车中已经添加了一些该商家的商品了,这时候应该要考虑该商品是否跟已经添加的商品一样,如果是一样的,应该更新数量和金额,因为重复添加,金额应该增加,商品数量也应该增加;如果不是一样的,应该建立一个新的明细对象,然后将这个商品明细添加到用户的购物车中的这个商家购物车中;
* 考虑到商品增加要更新金额和数量,如果商品数量为0,说明用户不想买了,此时应该将商品删除,如果最终该商家在该购物车列表中没有商品,那么就应该将该商家的购物车删除掉;
* 同时应该提供从redis中提取购物车列表的方法,从redis中存入购物车列表的方法,合并购物车的方法;
* 应该将查询的部分功能拆分,既可以复用又避免代码臃肿,所以应该提取出一个方法:根据商家id在购物车列表中查询购物车对象
2. 方法:
1. 添加购物车方法
2. 根据商家id查询购物车方法
3. 向redis中存入购物车列表
4. 从redis中提取购物车列表
5. 合并购物车方法
3. web:
1. 分析:
* 注入service的方法的时候,使用@Reference方法,可以加个timeout=6000防止超时;
* 查询购物车的时候,可以通过获取当前登录人名字判断,因为使用绿卡政策[anonymousUser匿名登录]:anonymousUser[未登录],账户名[已登录]进行判断,如果是未登录则从cookie中提取购物车,如果是已登录则从redis中获取购物车列表;
* 从redis中获取购物车列表的时候,应该判断本地是否存在数据以提高性能[不判断的时候每次调用此方法都会合并操作],如果第一次从redis中提取的话,应该将本地的购物车合并并将本地购物车的数据进行删除;
* 添加购物车列表,应该也获取登录名以判断是否登录,如果未登录应该存入cookie,如果已经登录,存入redis;
实战代码:[电商项目] :
代码结构图:

Interface:
1. pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<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">
<parent>
<artifactId>pinyougou-parent</artifactId>
<groupId>com.pinyougou</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
<artifactId>pinyougou-cart-interface</artifactId>
<dependencies>
<dependency>
<groupId>com.pinyougou</groupId>
<artifactId>pinyougou-pojo</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
2. CartService.java:
package com.pinyougou.cart.service;
import com.pinyougou.pojogroup.Cart;
import java.util.List;
public interface CartService {
/*
*
* 添加购物车到商品列表
* */
//接收一个购物车列表然后处理过后返回一个购物车列表,接收的数据首先要有购物车列表,还有主表id,数量等;
public List<Cart> addGoodsToCartList(List<Cart>list,Long itemId,Integer num);
/*
*
* 从redis中提取购物车列表
* */
public List<Cart> findCartListFromRedis(String username);
/*
*
* 将购物车列表存入redis
* */
public void saveCartListToRedis(String username,List<Cart> cartList);
/*
*
* 合并购物车
* */
public List<Cart> mergeCartList(List<Cart> cartList1,List<Cart> cartList2);
}
service:
1. pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<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">
<parent>
<artifactId>pinyougou-parent</artifactId>
<groupId>com.pinyougou</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>war</packaging>
<artifactId>pinyougou-cart-service</artifactId>
<dependencies>
<!-- 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>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
</dependency>
<!-- dubbo相关 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
</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>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<dependency>
<groupId>javassist</groupId>
<artifactId>javassist</artifactId>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.pinyougou</groupId>
<artifactId>pinyougou-cart-interface</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.pinyougou</groupId>
<artifactId>pinyougou-dao</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--缓存技术放在common中,所以需要使用-->
<dependency>
<groupId>com.pinyougou</groupId>
<artifactId>pinyougou-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<!-- 指定端口 -->
<port>9007</port>
<!-- 请求路径 -->
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
</project>
2. webapp/WEB-INF/web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<!-- 加载spring容器 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:spring/applicationContext*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
3. resources/applicationContext-service.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<dubbo:protocol name="dubbo" port="20887"></dubbo:protocol>
<dubbo:application name="pinyougou-cart-service"/>
<dubbo:registry address="zookeeper://192.168.25.128:2181"/>
<dubbo:annotation package="com.pinyougou.cart.service.impl" />
</beans>
4. spring/application-tx.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 开启事务控制的注解支持 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
5. impl/CartServiceImpl.java:
package com.pinyougou.cart.service.impl;
import com.alibaba.dubbo.config.annotation.Service;
import com.pinyougou.cart.service.CartService;
import com.pinyougou.mapper.TbItemMapper;
import com.pinyougou.pojo.TbItem;
import com.pinyougou.pojo.TbOrderItem;
import com.pinyougou.pojogroup.Cart;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
@Service
public class CartServiceImpl implements CartService {
@Autowired
private TbItemMapper itemMapper;
@Override
public List<Cart> addGoodsToCartList(List<Cart> cartList, Long itemId, Integer num) {
//1. 根据SKU ID 查询商品明细SKU的对象
TbItem item=itemMapper.selectByPrimaryKey(itemId);
//进行健壮性判断
if (item == null) {
throw new RuntimeException("商品不存在");
}
if (!item.getStatus().equals("1")) {
throw new RuntimeException("商品状态不合法");
}
//2. 根据SKU对象得到商家ID
String sellerId=item.getSellerId();
//3. 根据商家ID在购物车列表中查询购物车对象
Cart cart=searchCartBySellerId(cartList, sellerId);
//4. 如果购物车列表中不存在该商家的购物车
if (cart == null) {
//4.1 创建一个新的购物车对象
cart=new Cart();
cart.setSellerId(sellerId); //存入商家id
cart.setSellerName(item.getSeller()); //商家名称
List<TbOrderItem> orderItemList=new ArrayList<>(); //创建购物车的明细列表
TbOrderItem orderItem=createOrderItem(item, num);
orderItemList.add(orderItem);
cart.setOrderItemList(orderItemList);
//4.2 将新的购物车对象添加到购物车列表中
cartList.add(cart);
} else {
//5. 如果购物车列表中存在该商家的购物车
TbOrderItem orderItem=searchOrderItemByItemId(cart.getOrderItemList(), itemId);
//判断该商品是否该购物车的明细列表中存在
if (orderItem == null) {
//5.1 如果不存在,创建新的购物车明细对象,并添加到该购物车的明细列表中
orderItem=createOrderItem(item,num);
cart.getOrderItemList().add(orderItem);
} else {
//5.2 如果存在,在原有的数量上添加数量,并且更新金额
orderItem.setNum(orderItem.getNum()+num); //更新数量
//金额
orderItem.setTotalFee(new BigDecimal(orderItem.getPrice().doubleValue()*orderItem.getNum()));
//当明细的数量小于=0的时候,移除此明细
if (orderItem.getNum()<=0){
cart.getOrderItemList().remove(orderItem);
}
//当购物车的明细数量为0,在购物车列表中移除此购物车
if (cart.getOrderItemList().size()==0){
cartList.remove(cart);
}
}
}
return cartList;
}
@Autowired
private RedisTemplate redisTemplate;
@Override
public List<Cart> findCartListFromRedis(String username) {
System.out.println("从redis中提取购物车列表:"+username);
List<Cart> cartList=(List<Cart>) redisTemplate.boundHashOps("cartList").get(username);
if (cartList==null){
cartList=new ArrayList<>();
}
return cartList;
}
@Override
public void saveCartListToRedis(String username, List<Cart> cartList) {
System.out.println("向redis中存入购物车列表:"+username);
redisTemplate.boundHashOps("cartList").put(username,cartList);
}
@Override
public List<Cart> mergeCartList(List<Cart> cartList1, List<Cart> cartList2) {
// cartList1.addAll(cartList2);不能简单合并
for (Cart cart:cartList2){
for (TbOrderItem orderItem : cart.getOrderItemList()) {
cartList1=addGoodsToCartList(cartList1,orderItem.getItemId(),orderItem.getNum());
}
}
return cartList1;
}
/*
*
* 根据商家id 在购物车列表中查询购物车对象
* */
private Cart searchCartBySellerId(List<Cart> cartList, String sellerId) {
for (Cart cart : cartList) {
if (cart.getSellerId().equals(sellerId)) {
return cart;
}
}
return null;
}
/*
*
*
* 根据SKU id在购物车明细列表中查询购物车明细对象
*
* */
private TbOrderItem searchOrderItemByItemId(List<TbOrderItem> orderItemList, Long itemId) {
for (TbOrderItem orderItem : orderItemList) {
//将字符串id值转为long值进行比较
if (orderItem.getItemId().longValue() == itemId.longValue()) {
return orderItem;
}
}
return null;
}
/*
*
* 创建购物车明细对象
* */
private TbOrderItem createOrderItem(TbItem item, Integer num) {
//创建新的购物车明细对象
TbOrderItem orderItem=new TbOrderItem();
orderItem.setGoodsId(item.getGoodsId());
orderItem.setItemId(item.getId());
orderItem.setNum(num);
orderItem.setPicPath(item.getImage());
orderItem.setPrice(item.getPrice());
orderItem.setSellerId(item.getSellerId());
orderItem.setTitle(item.getTitle());
orderItem.setTotalFee(new BigDecimal(item.getPrice().doubleValue() * num));
return orderItem;
}
}
web:
1. pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<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">
<parent>
<artifactId>pinyougou-parent</artifactId>
<groupId>com.pinyougou</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>war</packaging>
<artifactId>pinyougou-cart-web</artifactId>
<dependencies>
<!-- 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>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
</dependency>
<!-- dubbo相关 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
</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>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<dependency>
<groupId>javassist</groupId>
<artifactId>javassist</artifactId>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>4.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>4.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-cas</artifactId>
<version>4.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.jasig.cas.client</groupId>
<artifactId>cas-client-core</artifactId>
<version>3.3.3</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.pinyougou</groupId>
<artifactId>pinyougou-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.pinyougou</groupId>
<artifactId>pinyougou-cart-interface</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<!-- 指定端口 -->
<port>9107</port>
<!-- 请求路径 -->
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
</project>
2. controller/CartController.java:
package com.pinyougou.cart.controller;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSON;
import com.pinyougou.cart.service.CartService;
import com.pinyougou.pojogroup.Cart;
import entity.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.security.Security;
import java.util.List;
@RestController
@RequestMapping("/cart")
public class CartController {
@Reference(timeout = 6000)
private CartService cartService;
@Autowired
private HttpServletRequest request;
@Autowired
private HttpServletResponse response;
//因为cookie是只能读取值,不能读取对象等所以需要将里面的数据读取并转换为我们可以操作的对象或集合;
@RequestMapping("/findCartList")
public List<Cart> findCartList() {
//当前登录人账号
String username=SecurityContextHolder.getContext().getAuthentication().getName();
System.out.println("当前登录人:" + username);
String cartListString=util.CookieUtil.getCookieValue(request, "cartList", "UTF-8");
if (cartListString == null || cartListString.equals("")) {
cartListString="[]";
}
List<Cart> cartList_cookie=JSON.parseArray(cartListString, Cart.class);
if (username.equals("anonymousUser")) {
//如果未登录
//从cookie中提取购物车
System.out.println("从cookie中提取购物车");
return cartList_cookie;
} else {
//如果已登录
//获得redis购物车
List<Cart> cartList_redis=cartService.findCartListFromRedis(username);
if (cartList_cookie.size()>0){
//判断当本地购物车中存在数据
//得到合并后的购物车
List<Cart> cartList=cartService.mergeCartList(cartList_cookie,cartList_redis);
//将合并后的购物车存入reids
cartService.saveCartListToRedis(username,cartList);
//本地购物车清除
util.CookieUtil.deleteCookie(request,response,"cartList");
System.out.println("zhixinglehebinggouwuchedeluoji");
return cartList;
}
return cartList_redis;
}
}
@RequestMapping("/addGoodsToCartList")
public Result addGoodsToCartList(Long itemId, Integer num) {
String name=SecurityContextHolder.getContext().getAuthentication().getName();
System.out.println("当前登录人:" + name);
try {
//从cookie中提取购物车
List<Cart> cartList=findCartList();
//调用服务方法操作购物车
cartList=cartService.addGoodsToCartList(cartList, itemId, num);
if (name.equals("anonymousUser")) {
//如果未登录
//将新的购物车存入cookie
String cartListString=JSON.toJSONString(cartList);
util.CookieUtil.setCookie(request, response, "cartList", cartListString, 3600 * 24, "UTF-8");
System.out.println("向cookie存储购物车");
} else {
//如果登录
cartService.saveCartListToRedis(name,cartList);
}
return new Result(true, "存入购物车成功");
} catch (Exception e) {
e.printStackTrace();
return new Result(false, "存入购物车失败");
}
}
}
3. user/service/UserDetailServiceImpl.java: [这是一个认证类,需要有它程序才能运行;]
package com.pinyougou.user.service;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import java.util.ArrayList;
import java.util.List;
public class UserDetailServiceImpl implements UserDetailsService{
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
System.out.println("经过了认证类:"+username);
List<GrantedAuthority> authorities=new ArrayList<>();
authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
return new User(username,"",authorities);
}
}
4. spring/spring-security.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans" 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.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">
<http pattern="/css/**" security="none"></http>
<http pattern="/img/**" security="none"></http>
<http pattern="/js/**" security="none"></http>
<http pattern="/plugins/**" security="none"></http>
<http pattern="/cart.html" security="none"></http>
<!-- entry-point-ref 入口点引用 -->
<!--登录不在自己本身的系统中进行登录,所以需要设置入口点-->
<http use-expressions="false" entry-point-ref="casProcessingFilterEntryPoint">
<!--匿名角色IS_AUTHENTICATED_ANONYMOUSLY-->
<!--如果用户登录了,则显示登录名,如果未登录则登录名:anonymousUser,必须要放在ROLE_USER前面-->
<intercept-url pattern="/cart/*.do" access="IS_AUTHENTICATED_ANONYMOUSLY"></intercept-url>
<intercept-url pattern="/**" access="ROLE_USER"/>
<csrf disabled="true"/>
<!-- custom-filter为过滤器, position 表示将过滤器放在指定的位置上,before表示放在指定位置之前 ,after表示放在指定的位置之后 -->
<custom-filter ref="casAuthenticationFilter" position="CAS_FILTER" />
<custom-filter ref="requestSingleLogoutFilter" before="LOGOUT_FILTER"/>
<custom-filter ref="singleLogoutFilter" before="CAS_FILTER"/>
</http>
<!--CAS只是单点登录的一种解决方案,所以这里不一定一定要接入CAS,也可以接入其他的;-->
<!-- CAS入口点 开始 -->
<beans:bean id="casProcessingFilterEntryPoint" class="org.springframework.security.cas.web.CasAuthenticationEntryPoint">
<!-- 单点登录服务器登录URL -->
<beans:property name="loginUrl" value="http://localhost:9100/cas/login"/>
<beans:property name="serviceProperties" ref="serviceProperties"/>
</beans:bean>
<beans:bean id="serviceProperties" class="org.springframework.security.cas.ServiceProperties">
<!--service 配置自身工程的根地址+/login/cas -->
<beans:property name="service" value="http://localhost:9107/login/cas"/>
</beans:bean>
<!-- CAS入口点 结束 -->
<!-- 认证过滤器 开始 -->
<beans:bean id="casAuthenticationFilter" class="org.springframework.security.cas.web.CasAuthenticationFilter">
<beans:property name="authenticationManager" ref="authenticationManager"/>
</beans:bean>
<!-- 认证管理器 -->
<authentication-manager alias="authenticationManager">
<authentication-provider ref="casAuthenticationProvider">
</authentication-provider>
</authentication-manager>
<!-- 认证提供者 -->
<beans:bean id="casAuthenticationProvider" class="org.springframework.security.cas.authentication.CasAuthenticationProvider">
<beans:property name="authenticationUserDetailsService">
<beans:bean class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
<beans:constructor-arg ref="userDetailsService" />
</beans:bean>
</beans:property>
<beans:property name="serviceProperties" ref="serviceProperties"/>
<!-- ticketValidator 为票据验证器 -->
<beans:property name="ticketValidator">
<beans:bean class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator">
<beans:constructor-arg index="0" value="http://localhost:9100/cas"/>
</beans:bean>
</beans:property>
<beans:property name="key" value="an_id_for_this_auth_provider_only"/>
</beans:bean>
<!-- 认证类 -->
<beans:bean id="userDetailsService" class="com.pinyougou.user.service.UserDetailServiceImpl"/>
<!-- 认证过滤器 结束 -->
<!-- 单点登出 开始 -->
<beans:bean id="singleLogoutFilter" class="org.jasig.cas.client.session.SingleSignOutFilter"/>
<!-- 经过此配置,当用户在地址栏输入本地工程 /logout/cas -->
<beans:bean id="requestSingleLogoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
<beans:constructor-arg value="http://localhost:9100/cas/logout?service=http://localhost:9103"/>
<beans:constructor-arg>
<beans:bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"/>
</beans:constructor-arg>
<beans:property name="filterProcessesUrl" value="/logout/cas"/>
</beans:bean>
<!-- 单点登出 结束 -->
</beans:beans>
5. spring/springmvc.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:property-placeholder location="classpath:config/application.properties" />
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
<property name="supportedMediaTypes" value="application/json"/>
<property name="features">
<array>
<value>WriteMapNullValue</value>
<value>WriteDateUseDateFormat</value>
</array>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<!-- 引用dubbo 服务 -->
<dubbo:application name="pinyougou-cart-web" />
<dubbo:registry address="zookeeper://192.168.25.128:2181"/>
<dubbo:annotation package="com.pinyougou.cart.controller" />
</beans>
6. webapp
1. webapp/js/controller.js:
//购物车控制层
app.controller('cartController',function ($scope,cartService) {
//查询购物车列表
$scope.findCartList=function () {
cartService.findCartList().success(
function (response) {
$scope.cartList=response;
$scope.totalValue=cartService.sum($scope.cartList);
})
};
//数量加减
$scope.addGoodsToCartList=function (itemId,num) {
cartService.addGoodsToCartList(itemId,num).success(
function (response) {
if (response.success){
//如果成功刷新列表
$scope.findCartList();
}else {
//如果失败弹出错误信息
alert(response.message);
}
}
)
};
/* //订单金额
sum=function () {
$scope.totalNum=0; //总数量
$scope.totalMoney=0; //总金额
for (var i=0;i<$scope.cartList.length;i++){
var cart=$scope.cartList[i]; //购物车对象
for (var j=0; j<cart.orderItemList.length;j++){
var orderItem=cart.orderItemList[j]; //购物车明细
$scope.totalNum+=orderItem.num; //累加数量
$scope.totalMoney+=orderItem.totalFee; //累加金额
}
}
}*/
});
2. js/service/cartService.js:
//购物车服务层
app.service('cartService',function ($http) {
//购物车列表
this.findCartList=function(){
return $http.get('cart/findCartList.do');
};
//添加商品到购物车
this.addGoodsToCartList=function (itemId,num) {
return $http.get('cart/addGoodsToCartList.do?itemId='+itemId+'&num='+num);
}
//将总金额和总数量在这里进行计算
this.sum=function(cartList){
//初始化总金数量和总金额数,并将其封装到一个数组中;
var totalValue={totalNum:0,totalMoney:0};
//遍历购物车对象集合
for (var i=0;i<cartList.length;i++){
var cart=cartList[i]; //购物车对象
//遍历购物车对象中的订单明细
for (var j=0;j<cart.orderItemList.length;j++){
var orderItem=cart.orderItemList[j]; //购物车明细
totalValue.totalNum+=orderItem.num; //累加数量
totalValue.totalMoney+=orderItem.totalFee; //累加金额
}
}
return totalValue;
}
});
3. js/base.js:
var app=angular.module('pinyougou',[]);
4. WEB-INF/web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<!-- 解决post乱码 -->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/spring-security.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 指定加载的配置文件 ,通过参数contextConfigLocation加载-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/springmvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>cart.html</welcome-file>
</welcome-file-list>
</web-app>
5. cart.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=9; IE=8; IE=7; IE=EDGE">
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
<title>我的购物车</title>
<link rel="stylesheet" type="text/css" href="css/webbase.css" />
<link rel="stylesheet" type="text/css" href="css/pages-cart.css" />
<script type="text/javascript" src="plugins/angularjs/angular.min.js"></script>
<script type="text/javascript" src="js/base.js"></script>
<script type="text/javascript" src="js/service/cartService.js"></script>
<script type="text/javascript" src="js/controller/cartController.js"></script>
</head>
<body ng-app="pinyougou" ng-controller="cartController" ng-init="findCartList()">
<!--head-->
<div class="top">
<div class="py-container">
<div class="shortcut">
<ul class="fl">
<li class="f-item">品优购欢迎您!</li>
<li class="f-item">请 <a href="login.html">登录</a> <span><a href="#">免费注册</a></span></li>
</ul>
<ul class="fr">
<li class="f-item">我的订单</li>
<li class="f-item space"></li>
<li class="f-item">我的品优购</li>
<li class="f-item space"></li>
<li class="f-item">品优购会员</li>
<li class="f-item space"></li>
<li class="f-item">企业采购</li>
<li class="f-item space"></li>
<li class="f-item">关注品优购</li>
<li class="f-item space"></li>
<li class="f-item">客户服务</li>
<li class="f-item space"></li>
<li class="f-item">网站导航</li>
</ul>
</div>
</div>
</div>
<div class="cart py-container">
<!--logoArea-->
<div class="logoArea">
<div class="fl logo"><span class="title">购物车</span></div>
<div class="fr search">
<form class="sui-form form-inline">
<div class="input-append">
<input type="text" type="text" class="input-error input-xxlarge" placeholder="品优购自营" />
<button class="sui-btn btn-xlarge btn-danger" type="button">搜索</button>
</div>
</form>
</div>
</div>
<!--All goods-->
<div class="allgoods">
<h4>全部商品<span>11</span></h4>
<div class="cart-main">
<div class="yui3-g cart-th">
<div class="yui3-u-1-4"><input type="checkbox" name="" id="" value="" /> 全部</div>
<div class="yui3-u-1-4">商品</div>
<div class="yui3-u-1-8">单价(元)</div>
<div class="yui3-u-1-8">数量</div>
<div class="yui3-u-1-8">小计(元)</div>
<div class="yui3-u-1-8">操作</div>
</div>
<div class="cart-item-list" ng-repeat="cart in cartList">
<div class="cart-shop">
<input type="checkbox" name="" id="" value="" />
<span class="shopname self">{{cart.sellerName}} 【商家ID:{{cart.sellerId}}】</span>
</div>
<div class="cart-body">
<div class="cart-list" ng-repeat="item in cart.orderItemList">
<ul class="goods-list yui3-g">
<li class="yui3-u-1-24">
<input type="checkbox" name="" id="" value="" />
</li>
<li class="yui3-u-11-24">
<div class="good-item">
<div class="item-img"><img src="{{item.picPath}}" /></div>
<div class="item-msg">{{item.title}}</div>
</div>
</li>
<li class="yui3-u-1-8"><span class="price">{{item.price}}</span></li>
<li class="yui3-u-1-8">
<a href="javascript:void(0)" class="increment mins" ng-click="addGoodsToCartList(item.itemId,-1)">-</a>
<input autocomplete="off" type="text" value="1" minnum="1" class="itxt" ng-model="item.num"/>
<a href="javascript:void(0)" class="increment plus" ng-click="addGoodsToCartList(item.itemId,1)">+</a>
</li>
<li class="yui3-u-1-8"><span class="sum">{{item.totalFee}}</span></li>
<li class="yui3-u-1-8">
<a href="#none">删除</a><br />
<a href="#none">移到我的关注</a>
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="cart-tool">
<div class="select-all">
<input type="checkbox" name="" id="" value="" />
<span>全选</span>
</div>
<div class="option">
<a href="#none">删除选中的商品</a>
<a href="#none">移到我的关注</a>
<a href="#none">清除下柜商品</a>
</div>
<div class="toolbar">
<div class="chosed">已选择<span>{{totalValue.totalNum}}</span>件商品</div>
<div class="sumprice">
<span><em>总价(不含运费) :</em><i class="summoney">¥{{totalValue.totalMoney.toFixed(2)}}</i></span>
<span><em>已节省:</em><i>-¥20.00</i></span>
</div>
<div class="sumbtn">
<a class="sum-btn" href="getOrderInfo.html" target="_blank">结算</a>
</div>
</div>
</div>
<div class="clearfix"></div>
<div class="deled">
<span>已删除商品,您可以重新购买或加关注:</span>
<div class="cart-list del">
<ul class="goods-list yui3-g">
<li class="yui3-u-1-2">
<div class="good-item">
<div class="item-msg">Apple Macbook Air 13.3英寸笔记本电脑 银色(Corei5)处理器/8GB内存</div>
</div>
</li>
<li class="yui3-u-1-6"><span class="price">8848.00</span></li>
<li class="yui3-u-1-6">
<span class="number">1</span>
</li>
<li class="yui3-u-1-8">
<a href="#none">重新购买</a>
<a href="#none">移到我的关注</a>
</li>
</ul>
</div>
</div>
<div class="liked">
<ul class="sui-nav nav-tabs">
<li class="active">
<a href="#index" data-toggle="tab">猜你喜欢</a>
</li>
<li>
<a href="#profile" data-toggle="tab">特惠换购</a>
</li>
</ul>
<div class="clearfix"></div>
<div class="tab-content">
<div id="index" class="tab-pane active">
<div id="myCarousel" data-ride="carousel" data-interval="4000" class="sui-carousel slide">
<div class="carousel-inner">
<div class="active item">
<ul>
<li>
<img src="img/like1.png" />
<div class="intro">
<i>Apple苹果iPhone 6s (A1699)</i>
</div>
<div class="money">
<span>$29.00</span>
</div>
<div class="incar">
<a href="#" class="sui-btn btn-bordered btn-xlarge btn-default"><i class="car"></i><span class="cartxt">加入购物车</span></a>
</div>
</li>
<li>
<img src="img/like2.png" />
<div class="intro">
<i>Apple苹果iPhone 6s (A1699)</i>
</div>
<div class="money">
<span>$29.00</span>
</div>
<div class="incar">
<a href="#" class="sui-btn btn-bordered btn-xlarge btn-default"><i class="car"></i><span class="cartxt">加入购物车</span></a>
</div>
</li>
<li>
<img src="img/like3.png" />
<div class="intro">
<i>Apple苹果iPhone 6s (A1699)</i>
</div>
<div class="money">
<span>$29.00</span>
</div>
<div class="incar">
<a href="#" class="sui-btn btn-bordered btn-xlarge btn-default"><i class="car"></i><span class="cartxt">加入购物车</span></a>
</div>
</li>
<li>
<img src="img/like4.png" />
<div class="intro">
<i>Apple苹果iPhone 6s (A1699)</i>
</div>
<div class="money">
<span>$29.00</span>
</div>
<div class="incar">
<a href="#" class="sui-btn btn-bordered btn-xlarge btn-default"><i class="car"></i><span class="cartxt">加入购物车</span></a>
</div>
</li>
</ul>
</div>
<div class="item">
<ul>
<li>
<img src="img/like1.png" />
<div class="intro">
<i>Apple苹果iPhone 6s (A1699)</i>
</div>
<div class="money">
<span>$29.00</span>
</div>
<div class="incar">
<a href="#" class="sui-btn btn-bordered btn-xlarge btn-default"><i class="car"></i><span class="cartxt">加入购物车</span></a>
</div>
</li>
<li>
<img src="img/like2.png" />
<div class="intro">
<i>Apple苹果iPhone 6s (A1699)</i>
</div>
<div class="money">
<span>$29.00</span>
</div>
<div class="incar">
<a href="#" class="sui-btn btn-bordered btn-xlarge btn-default"><i class="car"></i><span class="cartxt">加入购物车</span></a>
</div>
</li>
<li>
<img src="img/like3.png" />
<div class="intro">
<i>Apple苹果iPhone 6s (A1699)</i>
</div>
<div class="money">
<span>$29.00</span>
</div>
<div class="incar">
<a href="#" class="sui-btn btn-bordered btn-xlarge btn-default"><i class="car"></i><span class="cartxt">加入购物车</span></a>
</div>
</li>
<li>
<img src="img/like4.png" />
<div class="intro">
<i>Apple苹果iPhone 6s (A1699)</i>
</div>
<div class="money">
<span>$29.00</span>
</div>
<div class="incar">
<a href="#" class="sui-btn btn-bordered btn-xlarge btn-default"><i class="car"></i><span class="cartxt">加入购物车</span></a>
</div>
</li>
</ul>
</div>
</div>
<a href="#myCarousel" data-slide="prev" class="carousel-control left">‹</a>
<a href="#myCarousel" data-slide="next" class="carousel-control right">›</a>
</div>
</div>
<div id="profile" class="tab-pane">
<p>特惠选购</p>
</div>
</div>
</div>
</div>
</div>
<!-- 底部栏位 -->
<!--页面底部-->
<div class="clearfix footer">
<div class="py-container">
<div class="footlink">
<div class="Mod-service">
<ul class="Mod-Service-list">
<li class="grid-service-item intro intro1">
<i class="serivce-item fl"></i>
<div class="service-text">
<h4>正品保障</h4>
<p>正品保障,提供发票</p>
</div>
</li>
<li class="grid-service-item intro intro2">
<i class="serivce-item fl"></i>
<div class="service-text">
<h4>正品保障</h4>
<p>正品保障,提供发票</p>
</div>
</li>
<li class="grid-service-item intro intro3">
<i class="serivce-item fl"></i>
<div class="service-text">
<h4>正品保障</h4>
<p>正品保障,提供发票</p>
</div>
</li>
<li class="grid-service-item intro intro4">
<i class="serivce-item fl"></i>
<div class="service-text">
<h4>正品保障</h4>
<p>正品保障,提供发票</p>
</div>
</li>
<li class="grid-service-item intro intro5">
<i class="serivce-item fl"></i>
<div class="service-text">
<h4>正品保障</h4>
<p>正品保障,提供发票</p>
</div>
</li>
</ul>
</div>
<div class="clearfix Mod-list">
<div class="yui3-g">
<div class="yui3-u-1-6">
<h4>购物指南</h4>
<ul class="unstyled">
<li>购物流程</li>
<li>会员介绍</li>
<li>生活旅行/团购</li>
<li>常见问题</li>
<li>购物指南</li>
</ul>
</div>
<div class="yui3-u-1-6">
<h4>配送方式</h4>
<ul class="unstyled">
<li>上门自提</li>
<li>211限时达</li>
<li>配送服务查询</li>
<li>配送费收取标准</li>
<li>海外配送</li>
</ul>
</div>
<div class="yui3-u-1-6">
<h4>支付方式</h4>
<ul class="unstyled">
<li>货到付款</li>
<li>在线支付</li>
<li>分期付款</li>
<li>邮局汇款</li>
<li>公司转账</li>
</ul>
</div>
<div class="yui3-u-1-6">
<h4>售后服务</h4>
<ul class="unstyled">
<li>售后政策</li>
<li>价格保护</li>
<li>退款说明</li>
<li>返修/退换货</li>
<li>取消订单</li>
</ul>
</div>
<div class="yui3-u-1-6">
<h4>特色服务</h4>
<ul class="unstyled">
<li>夺宝岛</li>
<li>DIY装机</li>
<li>延保服务</li>
<li>品优购E卡</li>
<li>品优购通信</li>
</ul>
</div>
<div class="yui3-u-1-6">
<h4>帮助中心</h4>
<img src="img/wx_cz.jpg">
</div>
</div>
</div>
<div class="Mod-copyright">
<ul class="helpLink">
<li>关于我们<span class="space"></span></li>
<li>联系我们<span class="space"></span></li>
<li>关于我们<span class="space"></span></li>
<li>商家入驻<span class="space"></span></li>
<li>营销中心<span class="space"></span></li>
<li>友情链接<span class="space"></span></li>
<li>关于我们<span class="space"></span></li>
<li>营销中心<span class="space"></span></li>
<li>友情链接<span class="space"></span></li>
<li>关于我们</li>
</ul>
<p>地址:北京市昌平区建材城西路金燕龙办公楼一层 邮编:100096 电话:400-618-4000 传真:010-82935100</p>
<p>京ICP备08001421号京公网安备110108007702</p>
</div>
</div>
</div>
</div>
<!--页面底部END-->
<script type="text/javascript" src="js/plugins/jquery/jquery.min.js"></script>
<script type="text/javascript" src="js/plugins/jquery.easing/jquery.easing.min.js"></script>
<script type="text/javascript" src="js/plugins/sui/sui.min.js"></script>
<script type="text/javascript" src="js/widget/nav.js"></script>
</body>
</html>
6. login.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<script type="text/javascript">
location.href='cart.html';
</script>
</body>
</html>
CookieUtil 工具类
package util;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
*
* Cookie 工具类
*
*/
public final class CookieUtil {
/**
* 得到Cookie的值, 不编码
*
* @param request
* @param cookieName
* @return
*/
public static String getCookieValue(HttpServletRequest request, String cookieName) {
return getCookieValue(request, cookieName, false);
}
/**
* 得到Cookie的值,
*
* @param request
* @param cookieName
* @return
*/
public static String getCookieValue(HttpServletRequest request, String cookieName, boolean isDecoder) {
Cookie[] cookieList = request.getCookies();
if (cookieList == null || cookieName == null) {
return null;
}
String retValue = null;
try {
for (int i = 0; i < cookieList.length; i++) {
if (cookieList[i].getName().equals(cookieName)) {
if (isDecoder) {
retValue = URLDecoder.decode(cookieList[i].getValue(), "UTF-8");
} else {
retValue = cookieList[i].getValue();
}
break;
}
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return retValue;
}
/**
* 得到Cookie的值,
*
* @param request
* @param cookieName
* @return
*/
public static String getCookieValue(HttpServletRequest request, String cookieName, String encodeString) {
Cookie[] cookieList = request.getCookies();
if (cookieList == null || cookieName == null) {
return null;
}
String retValue = null;
try {
for (int i = 0; i < cookieList.length; i++) {
if (cookieList[i].getName().equals(cookieName)) {
retValue = URLDecoder.decode(cookieList[i].getValue(), encodeString);
break;
}
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return retValue;
}
/**
* 设置Cookie的值 不设置生效时间默认浏览器关闭即失效,也不编码
*/
public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
String cookieValue) {
setCookie(request, response, cookieName, cookieValue, -1);
}
/**
* 设置Cookie的值 在指定时间内生效,但不编码
*/
public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
String cookieValue, int cookieMaxage) {
setCookie(request, response, cookieName, cookieValue, cookieMaxage, false);
}
/**
* 设置Cookie的值 不设置生效时间,但编码
*/
public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
String cookieValue, boolean isEncode) {
setCookie(request, response, cookieName, cookieValue, -1, isEncode);
}
/**
* 设置Cookie的值 在指定时间内生效, 编码参数
*/
public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
String cookieValue, int cookieMaxage, boolean isEncode) {
doSetCookie(request, response, cookieName, cookieValue, cookieMaxage, isEncode);
}
/**
* 设置Cookie的值 在指定时间内生效, 编码参数(指定编码)
*/
public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
String cookieValue, int cookieMaxage, String encodeString) {
doSetCookie(request, response, cookieName, cookieValue, cookieMaxage, encodeString);
}
/**
* 删除Cookie带cookie域名
*/
public static void deleteCookie(HttpServletRequest request, HttpServletResponse response,
String cookieName) {
doSetCookie(request, response, cookieName, "", -1, false);
}
/**
* 设置Cookie的值,并使其在指定时间内生效
*
* @param cookieMaxage cookie生效的最大秒数
*/
private static final void doSetCookie(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
String domainName = getDomainName(request);
System.out.println(domainName);
if (!"localhost".equals(domainName)) {
cookie.setDomain(domainName);
}
}
cookie.setPath("/");
response.addCookie(cookie);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 设置Cookie的值,并使其在指定时间内生效
*
* @param cookieMaxage cookie生效的最大秒数
*/
private static final void doSetCookie(HttpServletRequest request, HttpServletResponse response,
String cookieName, String cookieValue, int cookieMaxage, String encodeString) {
try {
if (cookieValue == null) {
cookieValue = "";
} else {
cookieValue = URLEncoder.encode(cookieValue, encodeString);
}
Cookie cookie = new Cookie(cookieName, cookieValue);
if (cookieMaxage > 0)
cookie.setMaxAge(cookieMaxage);
if (null != request) {// 设置域名的cookie
String domainName = getDomainName(request);
System.out.println(domainName);
if (!"localhost".equals(domainName)) {
cookie.setDomain(domainName);
}
}
cookie.setPath("/");
response.addCookie(cookie);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 得到cookie的域名
*/
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];
}
return domainName;
}
}
本文深入解析了京东购物车的实现思路,涵盖Cookie与Redis存储方案、前后端代码编写及需求分析。阐述了本地购物车与远程购物车的融合机制,以及如何在不同登录状态下处理购物车数据。





