CGB2009-京淘项目DAY18

1. 完成购物车删除操作

1.1 请求URL地址

在这里插入图片描述

1.2 编辑CartController

 /**
     * 删除购物车Controller
     * URL地址: http://www.jt.com/cart/delete/1474391990.html
     * 返回值:  重定向到购物车列表页面
     */
    @RequestMapping("/delete/{itemId}")
    public String deleteCarts(Cart cart){

        long userId = 7;
        cart.setUserId(userId);
        cartService.deleteCart(cart);
        return "redirect:/cart/show.html";
    }

1.2 编辑CartService

   @Override
    public void deleteCart(Cart cart) {

        cartMapper.delete(new QueryWrapper<>(cart));
    }

2. 用户权限控制

2.1 需求说明

如果用户没有登录,则不允许访问购物车/订单等敏感操作.应该重定向到用户登录页面
方法: 1.shiro安全框架 只适用于后端程序.
2.拦截器机制

2.2 拦截器定义

2.2.1 SpringMVC调用规则

在这里插入图片描述

2.2.2 编辑拦截器配置

package com.jt.config;

import com.jt.interceptor.UserInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class MvcConfigurer implements WebMvcConfigurer{

	@Autowired
	private UserInterceptor userInterceptor;

	//开启匹配后缀型配置
	@Override
	public void configurePathMatch(PathMatchConfigurer configurer) {
		
		configurer.setUseSuffixPatternMatch(true);
	}

	//完成拦截器的配置
	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		registry.addInterceptor(userInterceptor)
				.addPathPatterns("/cart/**","/order/**");
	}
}

2.2.3 ThreadLocal

名称: 本地线程变量
作用: 在同一个线程内,实现数据共享.

编辑工具API:

public class UserThreadLocal {

    private static ThreadLocal<User> userThreadLocal = new ThreadLocal<>();

    //存数据
    public static void set(User user){

        userThreadLocal.set(user);
    }

    //取数据
    public static User get(){

        return userThreadLocal.get();
    }

    //数据删除  防止内存泄露
    public static void remove(){

        userThreadLocal.remove();
    }
}

2.2.3 定义拦截器

package com.jt.interceptor;

import com.jt.pojo.User;
import com.jt.util.CookieUtils;
import com.jt.util.ObjectMapperUtil;
import com.jt.util.UserThreadLocal;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import redis.clients.jedis.JedisCluster;

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

@Component
public class UserInterceptor implements HandlerInterceptor {

    @Autowired
    private JedisCluster jedisCluster;

    //处理器执行之前  用户不登录拦截     登录放行
    //判断依据:     cookie  redis
    //返回值说明:   false  表示拦截     true 放行
    //实现用户数据动态获取
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        String ticket = CookieUtils.getCookieValue(request, "JT_TICKET");
        if(StringUtils.hasLength(ticket) && jedisCluster.exists(ticket)){

            //1.从redis中把数据进行获取
            String json = jedisCluster.get(ticket);
            User user = ObjectMapperUtil.toObj(json, User.class);
            //2.利用request对象实现数据的传递  使用最多的方式
            request.setAttribute("JT_USER",user);

            //3.利用ThreadLocal方式进行数据存储
            UserThreadLocal.set(user);
            return true;    //程序放行
        }

        //请求如果被拦截,一般都要配合重定向的方式使用
        response.sendRedirect("/user/login.html");
        return false;
    }

    //处理器执行之后
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    //业务调用结束前
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

        //1.清空request对象
        request.removeAttribute("JT_USER");
        //2.清空threadLocal数据
        UserThreadLocal.remove();
    }
}

2.3 关于JT业务说明

2.3.1 用户登录机制

1).用户登录
在这里插入图片描述
2).用户回显功能
如果用户登录成功之后,会在cookie中记录TICKET登录凭证.利用跨域机制(JSONP|CORS) 通过TICKET数据信息查询用户数据.之后返回.

3).用户退出操作
删除TICKET/REDIS中的数据.

2.3.2 前端权限机制

通过拦截器实现权限的控制.如果用户不登录,则不允许访问涉密数据.使用的接口HandlerInterceptor 其中有3个方法用来控制程序运行的轨迹. 在拦截器中如果需要实现数据的传递,可以使用ThreadLocal或者Request对象的方式获取.
但是需要注意:数据存储之后记得清空 防止内存泄露.
在这里插入图片描述

3 订单模块实现

3.1 创建项目

3.1.1 编辑项目名称

在这里插入图片描述

3.1.2 添加继承/依赖/插件

<?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>jt</artifactId>
        <groupId>com.jt</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>jt-order</artifactId>

    <!--添加依赖 jt-common-->
    <dependencies>
        <dependency>
            <groupId>com.jt</groupId>
            <artifactId>jt-common</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

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

</project>

3.1.3 表设计

在这里插入图片描述

3.1.4 添加POJO对象

在这里插入图片描述

3.1.5 导入配置文件

在这里插入图片描述

3.1.6 编辑YML配置文件

server:
  port: 8095
  servlet:
    context-path: /
spring:
  datasource:
    #如果需要项目发布,则数据库地址必须配置远程数据库
    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:
  config: classpath:logging-config.xml
  level: 
    com.jt.mapper: debug
    
dubbo:
  scan:
    basePackages: com.jt    #指定dubbo的包路径
  application:
    name: provider-order     #指定服务名称(必须指定)
  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: 20883 #每个服务都应该有自己特定的端口

3.2 订单确认页面跳转

3.2.1 编辑URL页面

在这里插入图片描述

3.2.2 编辑OrderController

package com.jt.controller;

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

import java.util.List;

@Controller
@RequestMapping("/order")
public class OrderController {

    @Reference(check = false)
    private DubboCartService cartService;

    /**
     * url:http://www.jt.com/order/create.html
     * 参数: 暂时没有
     * 返回值: order-cart.jsp
     * 页面取值: ${carts}
     */
    @RequestMapping("/create")
    public String orderCreate(Model model){

        long userId = UserThreadLocal.get().getId();
        List<Cart> cartList = cartService.findCartListByUserId(userId);
        model.addAttribute("carts",cartList);
        return "order-cart";
    }
}

3.3 SpringMVC参数传递说明

3.3.1 简单参数传递

1.编辑HTML代码

2.编辑Controller中的函数
public void addUser(String name){

}

3.3.2 对象方式接收

1.编辑HTML代码

2.编辑Controller中的函数
public void addUser(User user){

}

3.3.3 对象的引用接收

说明: 项目中如果出现了重名的属性 可以使用对象的引用的方式进行定义.
1.编辑HTML代码

2.Controller中的方法
public void addUser(User user,Dog dog){

}

3.对象引用定义
public class User{
private String name;
private Dog dog;
}

public class Dog{
private String name;
}

3.4 订单入库操作

3.4.1 页面HTML标识

<form id="orderForm" class="hide">
		<input type="hidden" name="paymentType" value="1"/>
		<c:forEach items="${carts}" var="cart" varStatus="status">
			<c:set var="totalPrice"  value="${ totalPrice + (cart.itemPrice * cart.num)}"/>
			<input type="hidden" name="orderItems[${status.index}].itemId" value="${cart.itemId}"/>
			<input type="hidden" name="orderItems[${status.index}].num" value="${cart.num }"/>
			<input type="hidden" name="orderItems[${status.index}].price" value="${cart.itemPrice}"/>
			<input type="hidden" name="orderItems[${status.index}].totalFee" value="${cart.itemPrice * cart.num}"/>
			<input type="hidden" name="orderItems[${status.index}].title" value="${cart.itemTitle}"/>
			<input type="hidden" name="orderItems[${status.index}].picPath" value="${cart.itemImage}"/>
		</c:forEach>
		<input type="hidden" name="payment" value="<fmt:formatNumber groupingUsed="false" maxFractionDigits="2" minFractionDigits="2" value="${totalPrice/100 }"/>"/>
		<input type="hidden" name="orderShipping.receiverName" value="陈晨"/>
		<input type="hidden" name="orderShipping.receiverMobile" value="13800807944"/>
		<input type="hidden" name="orderShipping.receiverState" value="北京"/>
		<input type="hidden" name="orderShipping.receiverCity" value="北京"/>
		<input type="hidden" name="orderShipping.receiverDistrict" value="海淀区"/>
		<input type="hidden" name="orderShipping.receiverAddress" value="清华大学"/>
	</form>

3.4.2 页面JS

在这里插入图片描述

3.4.2 编辑OrderController

 /**
     * URL地址:http://www.jt.com/order/submit
     * 请求参数: 整个order表单
     * 返回值结果: SysResult对象   返回orderId
     * @return
     */
    @RequestMapping("/submit")
    @ResponseBody
    public SysResult saveOrder(Order order){
        long userId = UserThreadLocal.get().getId();
        order.setUserId(userId);
        String orderId = orderService.saveOrder(order);
        return SysResult.success(orderId);
    }

3.4.3 编辑OrderService

@Override
	@Transactional	//控制事务
	public String saveOrder(Order order) {
		String orderId = ""+order.getUserId() + System.currentTimeMillis();

		//1.完成订单入库
		order.setOrderId(orderId).setStatus(1);
		orderMapper.insert(order);
		System.out.println("订单入库成功!!!");

		//2.完成订单物流信息
		OrderShipping orderShipping = order.getOrderShipping();
		orderShipping.setOrderId(orderId);
		orderShippingMapper.insert(orderShipping);
		System.out.println("完成订单物流入库操作");

		//3.完成订单商品入库
		List<OrderItem> orderItems = order.getOrderItems();
		for (OrderItem orderItem : orderItems){
			orderItem.setOrderId(orderId);
			orderItemMapper.insert(orderItem);
		}
		System.out.println("订单入库完成");
		return orderId;
	}

3.5 实现订单查询

3.5.1 页面URL标识

业务说明: 当用户通过id查询订单信息时 查询订单的三张表数据 之后返回给页面即可
在这里插入图片描述

3.5.2 编辑OrderController

   /**
     * 实现订单查询
     * 1.url地址: http://www.jt.com/order/success.html?id=71610696858906
     * 2.url参数: id=71610696858906
     * 3.返回值结果: 返回成功页面
     * 4.页面取值 ${order.orderId}
     */
    @RequestMapping("/success")
    public String success(String id,Model model){

        Order order = orderService.findOrderById(id);
        model.addAttribute("order",order);
        return "success";
    }

3.5.3 编辑OrderService

@Override
	public Order findOrderById(String id) {

		//1.根据orderId查询order对象
		Order order = orderMapper.selectById(id);
		//2.根据orderId查询订单物流对象
		OrderShipping orderShipping = orderShippingMapper.selectById(id);
		//3.根据orderId查询订单物流信息
		QueryWrapper<OrderItem> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("order_id", id);
		List<OrderItem> itemList = orderItemMapper.selectList(queryWrapper);
		order.setOrderShipping(orderShipping).setOrderItems(itemList);
		return order;
	}

3.5.4 订单效果实现

在这里插入图片描述

4 京淘项目总结

4.1 Maven工作原理

1).maven作用 一站式的项目管理工具 管理jar包 项目打包部署
2).maven 依赖传递性 A --B–C 如何实现的
3).Maven如何保证jar包文件不被篡改 sha1 消息摘要.

4.2 SpringBoot工作原理

1).开箱即用原则? 如何实现的??
2).为属性赋值用法 @Value(“${key}”)
3).动态导入pro配置文件 @propertySource
4).环境分割 — 环境命名 默认环境选择
5).LOMBOK插件 注解 @Data xxxx
6).SpringBoot整合Mybatis 理解配置文件 别名包/驼峰映射规则
7).SpringBoot整合MybatisPlus ORM思想 对象关系映射.
8).SpringBoot整合web动态资源 JSP 项目打包 war包

4.3 分布式架构设计方案

1).分布式架构设计 按照模块拆分 按照层级拆分
2).理解分布式/集群/高可用的概念
3).构建分布式系统的原则 如何统一管理jar包 如何统一管理工具API

4.4 京淘后端项目搭建

1).业务 商品CURD操作 /商品分类CURD操作
2).VO对象的编辑原则 调用别人的JS 必须按照要求返回JSON.
3).全局异常处理的设计.
4).如何定义系统返回值对象 SysResult对象
5).文件上传案例.

4.5 反向代理服务器

1).什么是反向代理
2).什么是正向代理
3).nginx相关配置 命令 配置
4).hosts文件作用 实现域名与IP地址的映射
5).nginx 负载均衡方式 1.轮询 2.权重 3.iphash
6).nginx 高级属性用法 1.down 2.backup 3.高可用设定.

4.6 Linux

1).命令: cd/cp/mv/mkdir/rm/vim/…
2).安装JDK vim /etc/profile java -version
3).mariadb数据库安装 考虑权限 导入数据库/表 防火墙命令
4).实现manage项目Linux部署.
5).Linux的nginx项目部署
6).实现数据库高可用 数据库主从同步命令 基于Mycat实现数据库高可用.

4.7 Redis相关学习

1).redis命令 支持1-5-8种数据类型
2).redis分片机制 实现内存扩容 一致性hash算法 2^32取值方式
3).redis哨兵机制 实现高可用 哨兵的工作原理 如何监控
4).redis集群配置 redis分区算法. crc16(key)%16384
5).redis持久化策略 RDB快照 /AOF 操作过程
6).redis内存优化策略 LRU/LFU/random/TTL
7).什么是缓存穿透 访问不存在的数据 布隆过滤器算法
8).什么是缓存击穿 访问某个热点数据失效了 多级缓存
9).什么是缓存雪崩 大量的数据同时失效 多级缓存
10).SpringBoot整合redis相关配置.

4.8 实现前端搭建

1).跨域思想 同源策略(协议://域名:端口)
2).跨域解决方案 1.JSONP方式(1.利用script标签 src实现跨域 2.自定义回调函数 3.特殊格式封装)
2.CORS(设定服务端数据共享 设定响应头信息)
3).httpClient 万能的远程过程调用的方法 一般多见于框架底层代码 例如SpringCloud
4).伪静态思想 以.html结尾的请求

4.9 微服务框架

1).SOA思想
2).RPC 远程过程调用 相对本地而言 代词
3).微服务调用思想
4).注册中心 zookeeper服务. 单台—> 集群搭建
5).微服务框架的调用的流程 ZK集群的选举机制/工作原理
6).Dubbo框架 1.中立的接口 2.服务生产者 3.服务器消费者
7).Dubbo负载均衡机制 1.一致性hash 2.最小访问 3.随机策略 4.轮询机制 客户端负载均衡

4.10 业务流程调用

1).基于dubbo 实现商品数据的获取
2).基于dubbo实现jt-sso单点登录 Cookie操作 登录/登出/数据回显
3).完成购物车功能 CRUD操作 购物车中的记录如果存在则更新数量/不存在新增购物车.
4).完成权限控制 基于拦截器
5).利用request对象/ThreadLocal方式动态取值.
6).订单业务逻辑 表3张 为对象的引用赋值. 多张表业务操作 注意事务控制.

主要学习SpringCloud机制… docker容器 MQ技术.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

闪耀太阳

感觉文章不错的记得打赏呀

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值