开发业务的时候,只需要在通过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 {
@Override
public 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;
}
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
// 清理用户信息
UserContext.removeUser();
}
}