Skip to main content

LoginUserContextHolder-登录用户上下文持有者

作用​

本Holder类主要用于在微服务架构中,将登录用户信息在进入业务Controller之前,将登录用户信息获取到ThreadLocal中,以便下游代码可以获取到登录用户信息,本类为纯静态类,在Spring MVC的拦截器中设置值以后即可使用,但需要注意,在后置拦截器中要对设置的值进行清空操作,否则会造成内存泄漏。

使用本技术平台的项目所有具备用户登录功能的项目都需要使用本类进行用户信息的传递,并且用户信息实体类必须继承 cn.com.rydeen.base.common.api.vo.GeneralUserVO 类。

API列表​

/**
* 设置用户信息的方法
*
* @param user 用户信息
* @param <T> 用户信息类型
*/
public static <T extends GeneralUserVO> void setUserInfo(T user) {
// to do sth.
}
/**
* 设置用户信息的方法
*
* @param token 用户令牌
*/
public static void setToken(String token) {
// to do sth.
}
/**
* 获取用户信息的方法
*
* @return 用户信息
* @param <T> 用户信息类型
*/
public static <T extends GeneralUserVO> T getUserInfo() {
// to do sth.
}
/**
* 获取用户访问令牌信息的方法
*
* @return 返回用户访问令牌
*/
public static String getToken() {
// to do sth.
}
/**
* 清除用户信息的方法
*/
public static void clear() {
// to do sth.
}

用法​

SpringMVC 的 Interceptor 中的 preHandle 方法中设置用户信息,afterCompletion 方法中清除用户信息。

演示​


/**
* 用户信息拦截器
*
* @author richie696
* @version 1.0
* @since 2023-11-16 10:31:14
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class UserContextInterceptor implements AsyncHandlerInterceptor {

private final GatewayConfig gatewayConfig;

@Override
public boolean preHandle(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response, @NonNull Object handler) throws Exception {
// 忽略微信相关接口
String requestURI = request.getRequestURI();
if (gatewayConfig != null) {
boolean needSkip = gatewayConfig.getToken().getIgnoreUriList().stream().anyMatch(requestURI::matches);
if ("/actuator/health".equals(requestURI) || needSkip) {
return true;
}
}
// 获取session令牌
String token = request.getHeader(JwtUtils.X_ACCESS_TOKEN);
String userKey = JwtUtils.getUserKey(token);
// 获取缓存的用户信息
UserInfoVO userInfo = GlobalCache.getObjectCache(userKey, UserInfoVO.class);
if (Objects.isNull(userInfo) || StringUtils.isBlank(userInfo.getUsername())) {
log.warn(STR."【获取登录用户】用户cacheKey不存在:\{userKey}");
ResultVO<Object> error = ResultVO.getError(String.valueOf(HttpStatus.UNAUTHORIZED.value()), "The user does not exist.");
response.setStatus(HttpStatus.OK.value());
response.setContentType("application/json;charset=UTF-8");
response.getWriter().write(Objects.requireNonNull(JsonUtils.getInstance().serialize(error)));
return false;
}
// 写入用户信息
LoginUserContextHolder.setUserInfo(userInfo);
LoginUserContextHolder.setToken(token);
return true;
}

@Override
public void afterCompletion(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response,
@NonNull Object handler, Exception ex) {
// 一定要清空,否则会造成内存泄漏
LoginUserContextHolder.clear();
}
}