在用户每一次发起请求都会在tomcat服务器请求一个新的线程,我们在生成JWT token的时候将登录的用户信息注入到threadlocal中,那么这个线程进行其他请求都会携带着用户信息,我们可以在其他功能中得到当前的登录的用户信息,比如得到当前登录的用户信息
1.封装ThreadLocal使用的工具类
public class BaseContext {public static ThreadLocal<Long> threadLocal = new ThreadLocal<>();public static void setCurrentId(Long id) {threadLocal.set(id);}public static Long getCurrentId() {return threadLocal.get();}public static void removeCurrentId() {threadLocal.remove();}}
2.在生成JWT令牌时将登录的用户信息使用工具类存放在当前线程的ThreadLocal中
//2、校验令牌try {log.info("jwt校验:{}", token);Claims claims = JwtUtil.parseJWT(jwtProperties.getAdminSecretKey(), token);Long empId = Long.valueOf(claims.get(JwtClaimsConstant.EMP_ID).toString());log.info("当前员工id:{}", empId);BaseContext.setCurrentId(empId);//3、通过,放行return true;} catch (Exception ex) {//4、不通过,响应401状态码response.setStatus(401);return false;}
3.在进行数据修改时需要提供当前进行修改的用户ID,使用存放在ThreadLocal中的ID,这里使用AOP完成对公共字段的填充
public void autoFill(JoinPoint joinPoint) {log.info("开始进行公共字段的填充");//拦截mapper上有 @AutoFill注解的方法//获得当前被拦截方法上的数据库操作类型MethodSignature signature = (MethodSignature) joinPoint.getSignature();AutoFill autoFill = signature.getMethod().getAnnotation(AutoFill.class);//获得方法上的注解OperationType operationType = autoFill.value();//获取被拦截当前方法的实体对象Object[] args = joinPoint.getArgs();if (args == null || args.length == 0) {return;}Object entity = args[0];//准备赋值数据LocalDateTime now = LocalDateTime.now();Long currentId = BaseContext.getCurrentId();//通过反射为实体对象的公共属性根据操作类型赋值if (operationType == OperationType.INSERT) {try {Method setCreateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class);Method setCreateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_USER, Long.class);Method setUpdateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);Method setUpdateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);//通过反射为对象属性赋值setCreateTime.invoke(entity, now);setCreateUser.invoke(entity, currentId);setUpdateTime.invoke(entity, now);setUpdateUser.invoke(entity, currentId);} catch (Exception e) {e.printStackTrace();}} else if (operationType == OperationType.UPDATE) {try {Method setUpdateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);Method setUpdateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);setUpdateTime.invoke(entity, now);setUpdateUser.invoke(entity, currentId);} catch (Exception e) {e.printStackTrace();}}