【微服务】记录-登录信息传递过程
开发业务的时候,只需要在通过UserContext提供的getUser()方法就可以拿到用户id了
在这个拦截器中,获取到用户信息后保存到了UserContext中,这是一个基于ThreadLocal的工具,可以确保不同的请求之间互不干扰,避免线程安全问题发生:
public class UserContext {private static final ThreadLocal<Long> TL = new ThreadLocal<>();/*** 保存用户信息* @param userId 用户id*/public static void setUser(Long userId){TL.set(userId);}/*** 获取用户* @return 用户id*/public static Long getUser(){return TL.get();}/*** 移除用户信息*/public static void removeUser(){TL.remove();}
}
然后是微服务中的获取请求头中的用户信息的拦截器。由于这个拦截器在每个微服务中都需要,与其重复编写,不如抽取到一个模块中。
public class UserInfoInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 1.尝试获取头信息中的用户信息String authorization = request.getHeader(JwtConstants.USER_HEADER);// 2.判断是否为空if (authorization == null) {return true;}// 3.转为用户id并保存try {Long userId = Long.valueOf(authorization);UserContext.setUser(userId);return true;} catch (NumberFormatException e) {log.error("用户身份信息格式不正确,{}, 原因:{}", authorization, e.getMessage());return true;}}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {// 清理用户信息UserContext.removeUser();}
}