购物车实体
public class BuyerCart implements Serializable { private String sellerId;//商家ID private String sellerName;//商家名称 private List<OrderItem> orderItemList;//购物车明细 //..getset }购物项实体(在这里也是订单项)
public class OrderItem implements Serializable { private Long id; /** * 商品id */ private Long itemId; /** * SPU_ID */ private Long goodsId; /** * 订单id */ private Long orderId; /** * 商品标题 */ private String title; /** * 商品单价 */ private BigDecimal price; /** * 商品购买数量 */ private Integer num; /** * 商品总金额 */ private BigDecimal totalFee; /** * 商品图片地址 */ private String picPath; private String sellerId; //...getset }一、添加购物车 二、总体业务流程
当controller中的方法进行简单地完成之后,进行测试,发现点击加入购物车按钮没有反应 原因:跨域请求被阻止 什么是跨域请求: 浏览器厂商在开发浏览器时,设置了同源策略。 同源策略:要求发送请求的url地址和返回响应的url地址必须保证协议,ip地址,端口号不能够发生改变,只要有一个发生变化,浏览器就会认为这个响应不安全,会拒绝接收响应数据,这就是跨域请求访问。
注意:如果前端window.location.href进行跳转,跳转到不同服务器页面,不会触发跨域访问问题,只是页面跳转,不会有数据返回
解决方案
jsonp:jquery如果发生ajax请求,可以将数据类型设置为jsonp,原理是jquery在发送数据的同时,会在数据中生产一个令牌,controller接收到数据后,进行处理,返回响应时,将令牌原样返回,jquery会判断令牌是否是当初发送的,如果是,则接收响应;反之,拒绝接收。cors:是w3c支持的解决方法,原理是在响应体设置信息Access-Control-Allow-Origin,如果使用SpringMVC4.2以上版本,可以使用@Cross注解,就相当于设置了响应头信息使用cors解决跨域问题
/** * 添加商品到购物车 * @CrossOrigin注解,相当于设置了响应体信息,是w3c支持的一种跨域解决方案 * origins属性,设置的地址是返回响应给静态页面,静态页面所在服务器的地址 * @param itemId 商品库存id * @param num 购买数量 * @return */ @RequestMapping("/addGoodsToCartList") @CrossOrigin(origins = "http://localhost:8086", allowCredentials = "true") public Result addGoodsToCartList(Long itemId, Integer num){ return new Result(true,"添加成功!"); } //添加商品到购物车 $scope.addToCart=function(){ //alert('SKUID:'+$scope.sku.id ); $http.get('http://localhost:8080/cart/addGoodsToCartList.do?itemId=' +$scope.sku.id+'&num='+$scope.num ,{'withCredentials':true} ).success( function(response){ if(response.success){ location.href='http://localhost:8080/cart.html'; }else{ alert(response.message); } } ); }一、点击加入购物车按钮,将商品添加到购物车
二、返回给前端购物车列表
/** * 购物车业务 */ @RestController @RequestMapping("/cart") public class BuyerCartController { @Reference private CartService cartService; @Autowired private HttpServletRequest request; @Autowired private HttpServletResponse response; /** * 添加商品到购物车 * @CrossOrigin注解,相当于设置了响应体信息,是w3c支持的一种跨域解决方案 * origins属性,设置的地址是返回响应给静态页面,静态页面所在服务器的地址 * @param itemId 商品库存id * @param num 购买数量 * @return */ @RequestMapping("/addGoodsToCartList") @CrossOrigin(origins = "http://localhost:8086", allowCredentials = "true") public Result addGoodsToCartList(Long itemId, Integer num){ try { //1. 获取当前登录用户名称 String username = SecurityContextHolder.getContext().getAuthentication().getName(); //2. 获取购物车列表 List<BuyerCart> cartList = findCartList(); //3. 将当前商品加入到购物车列表 cartList = cartService.addItemToCartList(cartList,itemId,num); //4. 判断当前用户是否登录, 未登录用户名为"anonymousUser" if ("anonymousUser".equals(username)){ //4.a.如果未登录, 则将购物车列表存入cookie中 CookieUtil.setCookie(request, response, Constants.CART_LIST_COOKIE, JSON.toJSONString(cartList), 60 * 60 * 24 * 30, "utf-8"); //4.b.如果已登录, 则将购物车列表存入redis中 cartService.setCartListToRedis(username, cartList); } return new Result(true,"添加成功!"); } catch (Exception e) { e.printStackTrace(); return new Result(false, "添加失败!"); } } /** * 获取购物车列表数据 * @return */ @RequestMapping("/findCartList") public List<BuyerCart> findCartList(){ //1. 获取当前登录用户名称 String username = SecurityContextHolder.getContext().getAuthentication().getName(); //2. 从cookie中获取购物车列表json格式字符串 String cookieCartJson = CookieUtil.getCookieValue(request, Constants.CART_LIST_COOKIE, "utf-8"); //3. 如果购物车列表json串为空则返回"[]" if (cookieCartJson==null || "".equals(cookieCartJson)){ cookieCartJson = "[]"; } //4. 将购物车列表json转换为对象 List<BuyerCart> cookieCartList = JSON.parseArray(cookieCartJson, BuyerCart.class); //5. 判断用户是否登录, 未登录用户为"anonymousUser" if (!"anonymousUser".equals(username)){ //5.a. 未登录, 返回cookie中的购物车列表对象 return cookieCartList; }else { //5.b.1.已登录, 从redis中获取购物车列表对象 List<BuyerCart> redisCartList = cartService.getCartListToRedis(username); //5.b.2.判断cookie中是否存在购物车列表 if (cookieCartList.size()>0){ //如果cookie中存在购物车列表则和redis中的购物车列表合并成一个对象 cartService.mergeCookieCartListAndRedisCartList(cookieCartList,redisCartList); //删除cookie中购物车列表 CookieUtil.deleteCookie(request,response,Constants.CART_LIST_COOKIE); //将合并后的购物车列表存入redis中 cartService.setCartListToRedis(username,redisCartList); } //5.b.3.返回购物车列表对象 return redisCartList; } } }