简介

说明

        本文介绍如何使用ThreadLocal保存每次请求的用户信息。

        保存之后,后边的业务操作就可以获取(Controller或者Service都可以,只要在一个请求中)。

相关网址

也可以使用request的attribute保存每次请求的用户信息,见 :SpringBoot--使用attribute保存每次请求的用户信息_IT利刃出鞘的博客

代码

用户实体类

package com.knife.common.entity;

import lombok.Data;

@Data
public class UserDTO {
private Long userId;

private String userName;
}

定义ThreadLocal 

package com.knife.common.util;

import com.knife.common.entity.UserDTO;

public class UserThreadLocal {
/**
* 构造函数私有
*/
private UserThreadLocal() {
}

private static final ThreadLocal<UserDTO> USER_INFO_THREAD_LOCAL =
new ThreadLocal<>();

/**
* 清除用户信息
*/
public static void clear() {
USER_INFO_THREAD_LOCAL.remove();
}

/**
* 存储用户信息
*/
public static void set(UserDTO userDTO) {
USER_INFO_THREAD_LOCAL.set(userDTO);
}

/**
* 获取当前用户信息
*/
public static UserDTO getCurrentUser() {
return USER_INFO_THREAD_LOCAL.get();
}
}

保存属性

可以放到以下任意一个地方:

  1. 过滤器
  2. 拦截器
  3. ControllerAdvice
  4. AOP

本处我使用拦截器。

拦截器类

package com.knife.common.interceptor;

import com.knife.common.entity.UserDTO;
import com.knife.common.util.UserThreadLocal;
import lombok.NonNull;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class UserInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(@NonNull HttpServletRequest request,
@NonNull HttpServletResponse response,
@NonNull Object handler) {

// 此处实际应该根据header的token解析出用户
// 本处为了简单,直接虚构一个用户
UserDTO userDTO = new UserDTO();
userDTO.setUserId(3L);
userDTO.setUserName("Tony");
UserThreadLocal.set(userDTO);
return true;
}

@Override
public void afterCompletion(@NonNull HttpServletRequest request,
@NonNull HttpServletResponse response,
@NonNull Object handler,
Exception e) {
UserThreadLocal.clear();
}
}

注册拦截器

package com.knife.common.config;

import com.knife.common.interceptor.UserInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {

@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new UserInterceptor());
}
}

获取属性

package com.knife.controller;

import com.knife.common.entity.UserDTO;
import com.knife.common.util.UserThreadLocal;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

@RestController
public class HelloController {

@GetMapping("/test")
public String test() {
UserDTO currentUser = UserThreadLocal.getCurrentUser();
System.out.println(currentUser.toString());
return "test success";
}
}

测试

请求:​​http://localhost:8080/test​

结果:后台打印如下内容:

SpringBoot--使用ThreadLocal保存每次请求的用户信息_java