乐趣区

关于cookie:第三阶段-Day19-用户回显-封装Cookie-商品远程调用-购物车模块-CRUD操作

1. 用户模块实现

1.1 用户信息回显

1.1.1 页面 URL 剖析

1.1.2 查看页面 JS

1.1.3 编辑 JT-SSO 的 Controller

`/**
     * 业务实现:
     *  1. 用户通过 cookie 信息查问用户数据.    通过 ticket 获取 redis 中的业务数据.
     *  2.url 申请: http://sso.jt.com/user/query/+ _ticket
     *  3. 参数:    参数在 url 中. 利用 restFul 获取
     *  4. 返回值要求: SysResult 对象 (userJSON)
     */
    @RequestMapping("/query/{ticket}")
    public JSONPObject findUserByTicket(@PathVariable String ticket,
                                        HttpServletResponse response,
                                        String callback){String userJSON = jedisCluster.get(ticket);
        //1.lru 算法清空数据   2. 有可能 cookie 信息有误
        if(StringUtils.isEmpty(userJSON)){
            //2. 应该删除 cookie 信息.
            Cookie cookie = new Cookie("JT_TICKET", "");
            cookie.setMaxAge(0);
            cookie.setDomain("jt.com");
            cookie.setPath("/");
            response.addCookie(cookie);
            return new JSONPObject(callback,SysResult.fail());
        }
        return new JSONPObject(callback,SysResult.success(userJSON));
    }` 

1.2 编辑 Cookie 工具 API

`package com.jt.util;

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

public class CookieUtil {

    //1. 新增 cookie
    public static void addCookie(HttpServletResponse response,String cookieName, String cookieValue, int seconds, String domain){Cookie cookie = new Cookie(cookieName,cookieValue);
        cookie.setMaxAge(seconds);
        cookie.setDomain(domain);
        cookie.setPath("/");
        response.addCookie(cookie);
    }

    //2. 依据 name 查问 value 的值
    public static String getCookieValue(HttpServletRequest request,String cookieName){Cookie[] cookies = request.getCookies();
        if(cookies !=null && cookies.length >0){for (Cookie cookie : cookies){if(cookieName.equals(cookie.getName())){return cookie.getValue();
                }
            }
        }
        return null;
    }

    //3. 删除 cookie
    public static void deleteCookie(HttpServletResponse response,String cookieName,String domain){addCookie(response,cookieName,"",0, domain);
    }
}` 


1.3 用户退出操作

1.3.1 业务阐明

如果用户点击退出操作, 首先应该删除 Redis 中的数据 其次删除 Cookie 中的数据 之后重定向到零碎首页.

1.3.2 URL 剖析

1.3.3 编辑 UserController

 `/**
     * 实现用户的退出操作. 重定向到零碎首页
     * url: http://www.jt.com/user/logout.html
     * 业务:
     *      1. 删除 Redis 中的数据  key
     *      2. 删除 Cookie 记录
     */
    @RequestMapping("logout")
    public String logout(HttpServletRequest request,HttpServletResponse response){
        //1. 依据 JT_TICKET 获取指定的 ticket
        String ticket = CookieUtil.getCookieValue(request,"JT_TICKET");

        //2. 判断 ticket 是否为 null
        if(!StringUtils.isEmpty(ticket)){jedisCluster.del(ticket);
            CookieUtil.deleteCookie(response,"JT_TICKET","jt.com");
        }

        return "redirect:/";
    }` 


2 实现商品详情展示

2.1 业务阐明

阐明: 当用户点击商品时, 须要跳转到商品的展示页面中 页面名称 item.jsp

2.2 重构 JT-MANAGE

2.2.1 创立接口

阐明: 在 jt-common 中创立接口

2.2.2 编辑 Dubbo 实现类

`package com.jt.service;

import com.alibaba.dubbo.config.annotation.Service;
import com.jt.mapper.ItemDescMapper;
import com.jt.mapper.ItemMapper;
import com.jt.pojo.Item;
import com.jt.pojo.ItemDesc;
import org.springframework.beans.factory.annotation.Autowired;

@Service(timeout = 3000)
public class DubboItemServiceImpl implements DubboItemService{

    @Autowired
    private ItemMapper itemMapper;
    @Autowired
    private ItemDescMapper itemDescMapper;

    @Override
    public Item findItemById(Long itemId) {return itemMapper.selectById(itemId);
    }

    @Override
    public ItemDesc findItemDescById(Long itemId) {return itemDescMapper.selectById(itemId);
    }
}` 

2.2.3 编辑 YML 配置文件

`server:
  port: 8091
  servlet:
    context-path: /
spring:
  datasource:
    #引入 druid 数据源
    #type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/jtdb?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
    username: root
    password: root

  mvc:
    view:
      prefix: /WEB-INF/views/
      suffix: .jsp
#mybatis-plush 配置
mybatis-plus:
  type-aliases-package: com.jt.pojo
  mapper-locations: classpath:/mybatis/mappers/*.xml
  configuration:
    map-underscore-to-camel-case: true

logging:
  level: 
    com.jt.mapper: debug

#对于 Dubbo 配置
dubbo:
  scan:
    basePackages: com.jt    #指定 dubbo 的包门路 扫描 dubbo 注解
  application:              #利用名称
    name: provider-manage     #一个接口对应一个服务名称   一个接口能够有多个实现
  registry:  #注册核心 用户获取数据从机中获取 主机只负责监控整个集群 实现数据同步
    address: zookeeper://192.168.126.129:2181?backup=192.168.126.129:2182,192.168.126.129:2183
  protocol:  #指定协定
    name: dubbo  #应用 dubbo 协定 (tcp-ip)  web-controller 间接调用 sso-Service
    port: 20881  #每一个服务都有本人特定的端口 不能反复.` 

2.2.4 编辑 ItemController

`package com.jt.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.jt.pojo.Item;
import com.jt.pojo.ItemDesc;
import com.jt.service.DubboItemService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/items")
public class ItemController {@Reference(timeout = 3000)
    private DubboItemService itemService;

    /**
     * 实现商品详情页面跳转
     * url: http://www.jt.com/items/562379.html
     * 参数: 562379 itemId
     * 返回值:  item.jsp 页面
     * 页面取值阐明:
     *      ${item.title}   item 对象
     *      ${itemDesc.itemDesc}  itemDesc 对象
     *
     * 思路:
     *      1. 重构 jt-manage 我的项目
     *      2. 创立中立接口 DubboItemService
     *      3. 实现业务调用获取 item/itemDesc 对象
     */
    @RequestMapping("/{itemId}")
    public String findItemById(@PathVariable Long itemId, Model model){Item item = itemService.findItemById(itemId);
        ItemDesc itemDesc = itemService.findItemDescById(itemId);
        // 将数据保留到 request 域中
        model.addAttribute("item",item);
        model.addAttribute("itemDesc",itemDesc);
        return "item";
    }
}` 

2.2.5 页面成果展示

3 购物车模块实现

3.1 创立服务提供者

3.1.1 创立我的项目 JT-CART

3.1.2 增加继承 / 依赖 / 插件

 `<!--2. 增加依赖信息 -->
    <dependencies>
        <!-- 依赖本质依赖的是 jar 包文件 -->
        <dependency>
            <groupId>com.jt</groupId>
            <artifactId>jt-common</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

    <!--3. 增加插件 -->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>` 


3.1.3 编辑 POJO 对象

`@TableName("tb_cart")
@Data
@Accessors(chain = true)
public class Cart extends BasePojo{  // 应用包装类型

    @TableId(type = IdType.AUTO)
    private Long id;
    private Long uesrId;        // 用户 ID 号
    private Long itemId;        // 商品 ID 号
    private String itemTitle;   // 商品题目
    private String itemImage;   // 图片
    private Long itemPrice;     // 商品价格
    private Integer num;        // 商品数量

}` 


3.1.4 编辑 CartService 接口

3.1.5 jt-cart 代码构造

3.2 购物车列表页面展示

3.2.1 页面 url 剖析

阐明: 当用户点击购物车按钮时, 须要跳转到购物车展示页面. cart.jsp
页面取值: ${cartList}
要求: 只查问 userId= 7 的购物车列表信息. 之后进行页面展示

3.2.2 编辑 CartController

`package com.jt.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.jt.pojo.Cart;
import com.jt.service.DubboCartService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.List;

@Controller
@RequestMapping("/cart")
public class CartController {@Reference(timeout = 3000,check = false)
    private DubboCartService cartService;

    /**
     * 业务需要: 依据 userId 查问购物车数据
     * url 地址: http://www.jt.com/cart/show.html
     * 申请参数: 动静获取 userId
     * 返回值后果:  cart.jsp 页面
     * 页面取值形式: ${cartList}
     */
    @RequestMapping("/show")
    public String findCartListByUserId(Model model){
        Long userId = 7L;
        List<Cart> cartList = cartService.findCartListByUserId(userId);
        model.addAttribute("cartList",cartList);
        return "cart";
    }
}` 

3.2.3 编辑 CartService

`package com.jt.service;

import com.alibaba.dubbo.config.annotation.Service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jt.mapper.CartMapper;
import com.jt.pojo.Cart;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

@Service
public class DubboCartServiceImpl implements DubboCartService{

    @Autowired
    private CartMapper cartMapper;

    @Override
    public List<Cart> findCartListByUserId(Long userId) {QueryWrapper<Cart> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        return cartMapper.selectList(queryWrapper);
    }
}` 


3.2.4 页面成果展示

3.3 购物车数量的批改

3.3.1 业务阐明

3.3.2 页面 JS 剖析


3.3.3 编辑 CartController

 `/**
     * 业务: 实现购物车数量的更新
     * url: http://www.jt.com/cart/update/num/562379/12
     * 参数: itemId/num
     * 返回值: void
     */
    @RequestMapping("/update/num/{itemId}/{num}")
    @ResponseBody  //1. 返回值转化为 json 2.ajax 完结标识
    public void updateCartNum(Cart cart){ //key 名称必须与属性的名称统一.

        Long userId = 7L;
        cart.setUserId(userId);
        cartService.updateCartNum(cart);
    }` 

3.3.4 编辑 CartService

 `@Override
    public void updateCartNum(Cart cart) {//cartMapper.updateCartNum(cart);
        //1. 筹备批改的数据  依据对象中不为 null 的元素当做 set 条件
        Cart cartTemp = new Cart();
        cartTemp.setNum(cart.getNum());

        //2. 依据对象中不为 null 的元素当做 where 条件
        UpdateWrapper<Cart> updateWrapper =
                        new UpdateWrapper<>(cart.setNum(null));
        /*updateWrapper.eq("user_id", cart.getUserId())
                     .eq("item_id", cart.getItemId());*/
        cartMapper.update(cartTemp,updateWrapper);

    }` 

3.3.5 编辑 CartMapper

`public interface CartMapper extends BaseMapper<Cart> {@Update("update tb_cart set num = #{num},updated=now() where user_id=#{userId} and item_id=#{itemId}")
    void updateCartNum(Cart cart);
}` 

*   1
*   2
*   3
*   4

3.4 购物车新增

3.4.1 购物车新增业务

当用户点击购物车按钮时实现购物车入库操作. 如果用户反复加购则应该批改购物车商品的数量.
加购胜利之后, 应该重定向到购物车列表页面.

3.4.2 页面剖析

3.4.3 页面表单提交

`<form id="cartForm" method="post">
                                    <input class="text" id="buy-num" name="num" value="1" onkeyup="setAmount.modify('#buy-num');"/>
                                    <input type="hidden" class="text"  name="itemTitle" value="${item.title}"/>
                                    <input type="hidden" class="text" name="itemImage" value="${item.images[0]}"/>
                                    <input type="hidden" class="text" name="itemPrice" value="${item.price}"/>
                                </form>` 

3.4.4 页面 JS 解析

`<a class="btn-append" id="InitCartUrl" onclick="addCart();" clstag="shangpin|keycount|product|initcarturl"> 退出购物车 <b></b></a>
// 利用 post 传值
        function addCart(){var url = "http://www.jt.com/cart/add/${item.id}.html";
            document.forms[0].action = url;        //js 设置提交链接
            document.forms[0].submit();            //js 表单提交}` 

3.4.5 编辑 CartController

 `/**
     * 实现购物车新增
     * url: http://www.jt.com/cart/add/562379.html
     * 参数: form 表单提交  对象接管
     * 返回值: 重定向到购物车列表页面中
     */
    @RequestMapping("/add/{itemId}")
    public String saveCart(Cart cart){

        Long userId = 7L;
        cart.setUserId(userId);
        cartService.saveCart(cart);
        return "redirect:/cart/show.html";
    }` 



3.4.6 编辑 CartService

`/**
     *  如果反复加购则更新数量
     * 1. 查问是否曾经有改数据 user_id/item_id
     */
    @Override
    public void saveCart(Cart cart) {QueryWrapper<Cart> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", cart.getUserId())
                    .eq("item_id", cart.getItemId());
        Cart cartDB = cartMapper.selectOne(queryWrapper);
        if(cartDB == null){
            // 用户第一次加购
            cartMapper.insert(cart);
        }else {
            // 用户须要批改数量
            int num = cart.getNum() + cartDB.getNum();
            cart.setNum(num);
            cartMapper.updateCartNum(cart);
        }
    }` 

3.4.6 页面成果

退出移动版