购物车vo分析
ThreadLocal 同一个线程中,数据可以共享
//同一个线程中,数据可以共享。
public static ThreadLocal<UserInfoTo> toThreadLocal = new ThreadLocal<>();
情形:用户进行登录的时候,将用户信息存到ThreadLocal变量中,其目的是为了登录后把用户放到本地内存,而不是每次都去远程session里查。
ThreadLocal获取数据在同一个线程内共享
ThreadLocal是JDK包提供的,它提供线程本地变量,如果创建一乐ThreadLocal变量,那么访问这个变量的每个线程都会有这个变量的一个副本,在实际多线程操作的时候,操作的是自己本地内存中的变量,从而规避了线程安全问题,如下图所示。
登录拦截器
通用登录拦截器
因为订单系统必然涉及到用户信息,因此进入订单系统的请求必须是已经登录的,所以我们需要通过拦截器对未登录订单请求进行拦截
1.先注入拦截器HandlerInterceptor组件
2.在config中实现WebMvcConfigurer接口.addInterceptor()方法
3.拦截器和认证器的关系我在前面认证模块讲过,可以翻看,这里不赘述了
@Component
public class LoginUserInterceptor implements HandlerInterceptor {
public static ThreadLocal<MemberRespVo> threadLocal = new ThreadLocal<>();
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
String uri = request.getRequestURI();
// 这个请求直接放行
boolean match = new AntPathMatcher().match("/order/order/status/**", uri);
if(match){
return true;
}
// 获取session
HttpSession session = request.getSession();
// 获取登录用户
MemberRespVo memberRespVo = (MemberRespVo) session.getAttribute(AuthServerConstant.LOGIN_USER);
if(memberRespVo != null){
threadLocal.set(memberRespVo);
return true;
}else{
// 没登陆就去登录
session.setAttribute("msg", AuthServerConstant.NOT_LOGIN);
response.sendRedirect("http://auth.gulimall.com/login.html");
return false;
}
}
}
@Configuration
public class GulimallWebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**");
}
}
加上ThreadLocal共享数据,是为了登录后把用户放到本地内存,而不是每次都去远程session里查
在auth-server中登录成功后会把会话设置到session中
MemberRespVo data = login.getData("data",new TypeReference<MemberRespVo>);
session.setAttribute(AuthServerConstant.LOGIN_USER,data);
购物车的登录拦截器
因为购物车允许临时用户,所以自定义购物车拦截器
而登录操作在其他服务页面里完成即可。也可以重定向解决
具体代码去购物车博文里找