1.可以使用request 携带数据。但springmvc不推荐;
2.使用Threadlocal线程,请求产生响应前,处于同一个线程中。
比如在一个登录拦截器中,在preHandle
方法中登录成功后,放行前,想把user对象传到controller或service中
新建类 LoginInterceptor
public class LoginInterceptor extends HandlerInterceptorAdapter {
private JwtProperties jwtProperties;
private JwtProperties jwtProperties;
// 定义一个线程域,存放登录用户
private static final ThreadLocal<UserInfo> tl = new ThreadLocal<>();
public LoginInterceptor(JwtProperties jwtProperties) {
this.jwtProperties = jwtProperties;
}
@Override
public boolean preHandle( HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 查询token
String token = CookieUtils.getCookieValue(request, jwtProperties.getCookieName());
if (StringUtils.isBlank(token)) {
// 未登录,返回401
response.setStatus(HttpStatus.UNAUTHORIZED.value());
return false;
}
// 有token,查询用户信息
try {
// 解析成功,证明已经登录
UserInfo user = JwtUtils.getUserInfo(jwtProperties.getPublicKey(),token);
// 放入线程域
tl.set(user);
//request.setAttribute("user", user);
return true;
} catch (Exception e){
// 抛出异常,证明未登录,返回401
response.setStatus(HttpStatus.UNAUTHORIZED.value());
return false;
}
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
//程序运行结束之后,删除线程
tl.remove();
}
public static UserInfo getLoginUser() {
return tl.get();
}
}
- 这里我们使用了
ThreadLocal
来存储查询到的用户信息,线程内共享,因此请求到达Controller
后可以共享User - 并且对外提供了静态的方法:
getLoginUser()
来获取User信息
配置springmvc,使拦截器
@Configuration
@EnableConfigurationProperties(JwtProperties.class)
public class MvcConfig implements WebMvcConfigurer {
@Autowired
private JwtProperties jwtProperties;
@Bean
public LoginInterceptor loginInterceptor() {
return new LoginInterceptor(jwtProperties);
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(loginInterceptor()).addPathPatterns("/**");
}
}