Cookie创建临时用户

业务逻辑

离线购物车(用户未登陆)是通过cookie是传递数据的,创建一个UserInfo(用户id,user-key的值,是否是临时用户 )用来保存用户信息,用户信息在发送请求Controller之前获取,用户信息提供给Controller层调用

  1. 判断用户是否登陆,如果用户已登陆,则set 用户id 到UserInfo
  2. 看cookie中有没有name叫user-key的,有就set到UserInfo,没有就自己创建一个,cookie中的user-key代表临时用户
  3. 最后把UserInfo放到本地线程,提供给后面postHandle()调用
  4. 如果UserInfo中的临时用户标志没有被set为true,代表没有临时用户(user-key),就往浏览器中保存一个临时用户的cookie

ThreadLocal

每个请求tomcat会开一个线程,执行当前请求 直到结束
例:拦截器 —> controller —> service —> dao 都是同一线程

拦截器

相当于在我Controller请求之前加了层if判断,这里是判断是否存在临时用户并作出处理
(1)自定义拦截器规则

/*** 购物车拦截器*/
public class CartIntercept implements HandlerInterceptor {/*** preHandle放行 -> controller(购物车请求) ->*//***  tomcat会开一个线程,执行当前请求 直到结束* 拦截器 ->  controller -> service -> dao 都是同一线程* 在执行目标方法之前,判断用户的登录状态.并封装传递给controller目标请求*/public static ThreadLocal<UserInfoTo> toThreadLocal = new ThreadLocal<>();/**** 目标方法执行之前** 1.判断用户是否登陆,如果用户已登陆,则set 用户id* 2.只有登陆了才会设置userId,user-key有就从cookie中取,没有就自己创建set一个uuid* 3.看cookie中有没有name叫user-key的,有就set到UserInfo,没有就自己创建一个临时用户* 4.最后把UserInfo放到本地线程,提供给*/@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {/***  cookie**  user-key(代表临时用户)     xxxxxx*/UserInfoTo userInfoTo = new UserInfoTo();HttpSession session = request.getSession();//获得当前登录用户的信息MemberResponseVo memberResponseVo = (MemberResponseVo) session.getAttribute(AuthServiceConstant.LOGIN_USER);/*** 只有登陆了才会设置userId,user-key有就从cookie中取,没有就自己创建set一个uuid*/if (memberResponseVo != null) {//用户登录了userInfoTo.setUserId(memberResponseVo.getId());}/*** 看cookie中有没有user-key,有就set到UserInfo,没有就自己创建一个临时用户*/Cookie[] cookies = request.getCookies();if (cookies != null && cookies.length > 0) {for (Cookie cookie : cookies) {//user-keyString name = cookie.getName();if (name.equals(CartConstant.TEMP_USER_COOKIE_NAME)) {userInfoTo.setUserKey(cookie.getValue());//标记为已是临时用户userInfoTo.setTempUser(true);}}}//如果没有临时用户一定分配一个临时用户if (StringUtils.isEmpty(userInfoTo.getUserKey())) {String uuid = UUID.randomUUID().toString();userInfoTo.setUserKey(uuid);}//目标方法执行之前toThreadLocal.set(userInfoTo);//全部放行return true;}/*** 业务执行之后,浏览器保存cookie的临时用户*/@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {//获取当前用户的值UserInfoTo userInfoTo = toThreadLocal.get();//如果有临时用户信息就不用去设置cookieif (!userInfoTo.getTempUser()) {//创建一个cookieCookie cookie = new Cookie(CartConstant.TEMP_USER_COOKIE_NAME, userInfoTo.getUserKey());//扩大作用域cookie.setDomain("gulimall");//设置过期时间cookie.setMaxAge(CartConstant.TEMP_USER_COOKIE_TIMEOUT);response.addCookie(cookie);}}}

(2)将拦截器放入容器

@Configuration
public class GulimallWebConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new CartIntercept())//注册拦截器.addPathPatterns("/**");}
}

Cookie创建临时用户

业务逻辑

离线购物车(用户未登陆)是通过cookie是传递数据的,创建一个UserInfo(用户id,user-key的值,是否是临时用户 )用来保存用户信息,用户信息在发送请求Controller之前获取,用户信息提供给Controller层调用

  1. 判断用户是否登陆,如果用户已登陆,则set 用户id 到UserInfo
  2. 看cookie中有没有name叫user-key的,有就set到UserInfo,没有就自己创建一个,cookie中的user-key代表临时用户
  3. 最后把UserInfo放到本地线程,提供给后面postHandle()调用
  4. 如果UserInfo中的临时用户标志没有被set为true,代表没有临时用户(user-key),就往浏览器中保存一个临时用户的cookie

ThreadLocal

每个请求tomcat会开一个线程,执行当前请求 直到结束
例:拦截器 —> controller —> service —> dao 都是同一线程

拦截器

相当于在我Controller请求之前加了层if判断,这里是判断是否存在临时用户并作出处理
(1)自定义拦截器规则

/*** 购物车拦截器*/
public class CartIntercept implements HandlerInterceptor {/*** preHandle放行 -> controller(购物车请求) ->*//***  tomcat会开一个线程,执行当前请求 直到结束* 拦截器 ->  controller -> service -> dao 都是同一线程* 在执行目标方法之前,判断用户的登录状态.并封装传递给controller目标请求*/public static ThreadLocal<UserInfoTo> toThreadLocal = new ThreadLocal<>();/**** 目标方法执行之前** 1.判断用户是否登陆,如果用户已登陆,则set 用户id* 2.只有登陆了才会设置userId,user-key有就从cookie中取,没有就自己创建set一个uuid* 3.看cookie中有没有name叫user-key的,有就set到UserInfo,没有就自己创建一个临时用户* 4.最后把UserInfo放到本地线程,提供给*/@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {/***  cookie**  user-key(代表临时用户)     xxxxxx*/UserInfoTo userInfoTo = new UserInfoTo();HttpSession session = request.getSession();//获得当前登录用户的信息MemberResponseVo memberResponseVo = (MemberResponseVo) session.getAttribute(AuthServiceConstant.LOGIN_USER);/*** 只有登陆了才会设置userId,user-key有就从cookie中取,没有就自己创建set一个uuid*/if (memberResponseVo != null) {//用户登录了userInfoTo.setUserId(memberResponseVo.getId());}/*** 看cookie中有没有user-key,有就set到UserInfo,没有就自己创建一个临时用户*/Cookie[] cookies = request.getCookies();if (cookies != null && cookies.length > 0) {for (Cookie cookie : cookies) {//user-keyString name = cookie.getName();if (name.equals(CartConstant.TEMP_USER_COOKIE_NAME)) {userInfoTo.setUserKey(cookie.getValue());//标记为已是临时用户userInfoTo.setTempUser(true);}}}//如果没有临时用户一定分配一个临时用户if (StringUtils.isEmpty(userInfoTo.getUserKey())) {String uuid = UUID.randomUUID().toString();userInfoTo.setUserKey(uuid);}//目标方法执行之前toThreadLocal.set(userInfoTo);//全部放行return true;}/*** 业务执行之后,浏览器保存cookie的临时用户*/@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {//获取当前用户的值UserInfoTo userInfoTo = toThreadLocal.get();//如果有临时用户信息就不用去设置cookieif (!userInfoTo.getTempUser()) {//创建一个cookieCookie cookie = new Cookie(CartConstant.TEMP_USER_COOKIE_NAME, userInfoTo.getUserKey());//扩大作用域cookie.setDomain("gulimall");//设置过期时间cookie.setMaxAge(CartConstant.TEMP_USER_COOKIE_TIMEOUT);response.addCookie(cookie);}}}

(2)将拦截器放入容器

@Configuration
public class GulimallWebConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new CartIntercept())//注册拦截器.addPathPatterns("/**");}
}