近况
现在都是4月17日了,一年已经过了三分之一,我也没啥收获,教资考试3月份考完了
报名三科,考了两科,过了一科,最难的科二没过,考完当时就知道自己过不了,考的都是不会的内容
心态上已经炸了,没办法,下半年再学吧,现在的目标放在5月底的软考,9月下半年教资,11月下半年软考
上半年的系统分析师老实说不抱太大希望,没什么动力学习,公司项目上也忙的很,之前学的很多都忘记了
但该学还是得学,起码为下半年架构师打好基础,总之想成长总是要一步一步走,要尽力利用自己的优势
要尽力做自己能做的,一切都是为提升自己的能力而努力,加油!
回归正题,我们公司项目存在一个问题,就是前端和后端都不能很轻松拿到用户的角色信息
前端根本拿不到用户角色信息,后端想获取用户角色信息得去连数据库查才行
我想到之前学习过ThreadLocal的知识点,也看到过很多人利用ThreadLocal实现获取当前用户的角色信息
所以赶紧学习一下是怎么实现的,下面是具体实现步骤
为User实体类新增一个字段,但不映射到数据库表中
public class SysUser{ ... /** * 标识用户角色 */ @TableField(exist = false) private String userRole; /** * 判断是否是平台管理员,true代表是,false代表不是 */ @TableField(exist = false) private Boolean isPlatformManager; }
创建一个ThreadLocal工具类
public class UserContextUtil { /** * 构造方法私有化 */ private UserContextUtil(){}; private static final ThreadLocal<SysUser> CONTEXT = new ThreadLocal<>(); /** * 存放用户信息 * @param sysUser */ public static void set(SysUser sysUser){ CONTEXT.set(sysUser); } /** * 获取用户信息 * @return */ public static SysUser get(){ return CONTEXT.get(); } /** * 清除当前线程内引用,防止内存泄漏 */ public static void remove(){ CONTEXT.remove(); } }
配置一个请求拦截器,拦截所有请求
这里写的并不规范,应该要检验一下token的有效性的,或者拦截所有已经登录的请求
考虑到使用ThreadLocal可能会有内存泄漏的情况,所以在接口执行后,再删除ThreadLocal中的内容
不知道有没有必要,就是怕内存泄漏,写上总归好点。@Component @Slf4j public class UserInfoInterceptor implements HandlerInterceptor { @Autowired private ISysUserService userService; @Value("${oea.platform-manager}") private String platformManager; @Autowired private ISysUserRoleService sysUserRoleService; @Autowired private ISysRoleService sysRoleService; @Autowired private CommonAPI commonAPI; @Autowired @Lazy private RedisUtil redisUtil; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { boolean verifyToken = TokenUtils.verifyToken(request, commonAPI, redisUtil); if (verifyToken){ String userName = JwtUtil.getUserNameByToken(request); SysUser currentUser = userService.getUserByName(userName); if (ObjectUtil.isNotEmpty(currentUser)){ //设置该用户的角色 // 平台管理员的权限,有此权限的用户是平台管理员,可查询所有部门数据 List<String> roles = userService.getRole(currentUser.getUsername()); boolean flag = false; for (String role : roles) { if (ObjectUtil.equals(role,platformManager)){ flag=true; } } currentUser.setIsPlatformManager(flag); currentUser.setUserRole(String.join(",",roles)); UserContextUtil.set(currentUser); } } return true; } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { SysUser sysUser = UserContextUtil.get(); if (ObjectUtil.isNotEmpty(sysUser)){ UserContextUtil.remove(); } } }
创建一个配置类,将拦截器注入Spring容器中
@Configuration public class MyAppConfigurer extends WebMvcConfigurationSupport { @Autowired private UserInfoInterceptor userInfoInterceptor; /** * 拦截器,将用户信息放入threadLocal * @param registry */ @Override protected void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(this.userInfoInterceptor).addPathPatterns("/**"); super.addInterceptors(registry); } }
实际使用
SysUser sysUser = UserContextUtil.get() System.out.println(sysUser.getUserRole) System.out.println(sysUser.getIsPlatformManager)