此拦截器的功能为:拦截用户请求,从请求中获取cookie中的token,对token进行解析,获取token中用户的信息,对获得的信息通过ThreadLocal进行传递,保证线程安全,并在拦截器的后置处理中释放线程
1.编写拦截器类,继承HandlerInterceptorAdapter类,重写preHandle(),并加入到Spring容器中
@Component public class LoginInterceptor extends HandlerInterceptorAdapter { private static final ThreadLocal<UserInfo> THREAD_LOCAL = new ThreadLocal<>(); @Autowired private JwtProperties jwtProperties; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 获取cookie信息 String token = CookieUtils.getCookieValue(request, jwtProperties.getCookieName()); String userKey = CookieUtils.getCookieValue(request, jwtProperties.getUserKeyName()); // 如果都为空,设置userKey。 if (StringUtils.isBlank(token) && StringUtils.isBlank(userKey)){ userKey = UUID.randomUUID().toString(); CookieUtils.setCookie(request, response, jwtProperties.getUserKeyName(), userKey, jwtProperties.getExpire()); } // 不管有没有登录都要设置userKey UserInfo userInfo = new UserInfo(); userInfo.setUserKey(userKey); // token不为空,解析token if (StringUtils.isNotBlank(token)){ Map<String, Object> map = JwtUtils.getInfoFromToken(token, jwtProperties.getPublicKey()); if (!CollectionUtils.isEmpty(map)) { userInfo.setId(new Long(map.get("id").toString())); } } // 保存到threadlocal THREAD_LOCAL.set(userInfo); // 如果token不为空, return true; } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { THREAD_LOCAL.remove(); } //对外提供静态方法,获取ThreadLocal public static UserInfo getUserInfo(){ return THREAD_LOCAL.get(); } }注意:
这里我们使用了ThreadLocal来存储查询到的用户信息,线程内共享,对外提供get方法,因此请求到达Controller后可以共享User并且对外提供了静态的方法:getUserInfo()来获取User信息在完成逻辑任务后,要进行释放,否则会内存泄漏2.配置拦截器
@Configuration public class MvcConfig implements WebMvcConfigurer { @Autowired private LoginInterceptor loginInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(loginInterceptor).addPathPatterns("/**"); } }