商城:订单服务-订单确认页confirm

页面搭建

等待付款-订单详情页-静态文件:order/detail   首页:detail.html

订单页-订单列表-静态问价:order/list   首页:list.html

结算页-订单确认-静态问价:order/confirm  首页:comfirm.html

收银页-订单支付-静态文件:order/pay   首页:pay.html

整合SpringSession

1.引入Redis依赖

        <!--引入redis-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>io.lettuce</groupId>
                    <artifactId>lettuce-core</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
        </dependency>

2.配置文件.

spring:
  cache:
    #指定缓存类型为redis
    type: redis
    redis:
      # 指定redis中的过期时间为1h
      time-to-live: 3600000
      #      如果指定了前缀就用我们指定的 如果没有就用缓存的名字作为前缀
      #      key-prefix: CACHE_
      #      是否缓存空值
      cache-null-values: true

MyRedissonConfig        ProSessionConfig    MyThreadConfig

订单登录拦截

使没有登录的用户再支付之前先去登录

创建一个拦截器

@Component
public class LoginUserInterceptor implements HandlerInterceptor {

    private static ThreadLocal<MemberRespVo> loginUser = new ThreadLocal<>();
    @Override
    public boolean preHandle (HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
        MemberRespVo attribute = (MemberRespVo) request.getSession().getAttribute(AuthServerCostant.LOGIN_USER);
        if(attribute != null){
            loginUser.set(attribute);
            return true;
        }else {
            //没登录就去登录
            request.getSession().setAttribute("msg","请先进行登录");
            response.sendRedirect("http://auth.mall.com/long.html");
            return false;
        }
    }
}

拦截器配置文件

@Configuration
public class OrderWebConfiguration implements WebMvcConfigurer {
    @Autowired
    LoginUserInterceptor interceptor;
    @Override
    public void addInterceptors(InterceptorRegistry registry){
        registry.addInterceptor(interceptor).addPathPatterns("/**");
    }
}

 订单确认页模型抽取

订单确认页模型:com.tinstu.gulimall.order.vo.OrderConfirmVo

访问/toTrade 时 获取这些内容,并保存到model,返回到订单确认页 confirm.html

订单确认页数据获取

com.tinstu.gulimall.order.service.impl.OmsOrderServiceImpl

Feign远程调用丢失请求头的问题

fegin远程调用的时候相当于新创建了一个请求,

那么原来请求中的cookie就没有了,无法感知当前登录的用户

怎么解决?  创建一个feign的配置文件

@Configuration
public class MyFeignConfig {
    @Bean("requestInterceptor")
    public RequestInterceptor requestInterceptor(){
        return new RequestInterceptor() {
            @Override
            public void apply(RequestTemplate template) {
                // RequestContextHolder拿到刚进来这个请求
                ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
                if(attributes != null){
                    HttpServletRequest request = attributes.getRequest();
                    if(request != null){
                        // 同步请求头数据
                        String cookie = request.getHeader("Cookie");
                        // 给新请求同步Cookie
                        template.header("Cookie", cookie);
                    }
                }
            }
        };
    }
}

Fegin异步调用丢失请求头的问题

ThreadLocal数据在当前线程,如果使用多线程的话,数据将不共享

解决  在每个线程中保存一次数据

     // 1.远程查询所有的收获地址列表
        CompletableFuture<Void> getAddressFuture = CompletableFuture.runAsync(() -> {
            // 因为异步线程需要新的线程,而新的线程里没有request数据,所以我们自己设置进去
            RequestContextHolder.setRequestAttributes(attributes);

            List<MemberAddressVo> address;
            try {
                address = memberFeignService.getAddress(memberRespVo.getId());
                confirmVo.setAddress(address);
            } catch (Exception e) {
                log.warn("\n远程调用会员服务失败 [会员服务可能未启动]");
            }
        }, executor);

 订单确认页数据渲染

confirm.html

订单确认页库存查询

thenRunAsync  再出一个线程去查询商品的库存

订单确认页模拟运费效果

选择地址后进行运费展示

com.tinstu.gulimall.ware.service.impl.WmsWareInfoServiceImpl

接口幂等性讨论

商城:订单服务-接口幂等性与订单业务

 

 

阅读剩余
THE END