Filter拦截器:
@Slf4j @WebFilter(filterName = "operatorLoginFilter", urlPatterns = "/*") public class OperatorLoginFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest; //登录信息 LoginInfo loginInfo = new LoginInfo(); loginInfo.setIp(stringToInt(httpServletRequest.getHeader("X-Real-IP"))); loginInfo.setDeviceId(httpServletRequest.getHeader("deviceid")); OperatorContext.setLoginInfo(loginInfo); try { //操作人信息 OperatorInfo operatorInfo = new OperatorInfo(); String token = httpServletRequest.getHeader("token"); if (!StringUtils.isEmpty(token)) { //从token取 String deviceId = httpServletRequest.getHeader("deviceid"); operatorInfo = queryOperatorInfo(token, deviceId); } else { //从cookie取 operatorInfo.setUid(getCookie(httpServletRequest, "user_name")); } OperatorContext.setOperatorInfo(operatorInfo); } catch (Exception var14) { log.error("调用用户中心查询用户出错", var14); OperatorContext.release(); } try { filterChain.doFilter(servletRequest, servletResponse); } finally { OperatorContext.release(); } } @Override public void destroy() { } private OperatorInfo queryOperatorInfo(String token, String deviceId){ return new OperatorInfo(); } private static int stringToInt(String s) { return InetAddresses.coerceToInteger(InetAddresses.forString(s)); } private static String getCookie(HttpServletRequest request, String key) { Cookie[] cookies = request.getCookies(); if (cookies == null) { return null; } else { Cookie[] var3 = cookies; int var4 = cookies.length; for(int var5 = 0; var5 < var4; ++var5) { Cookie cookie = var3[var5]; if (key.equals(cookie.getName())) { return cookie.getValue(); } } return null; } } }
ThreadLocal:
public class OperatorContext { private static final ThreadLocal<OperatorInfo> OPERATOR_INFO_THREAD_LOCAL = new ThreadLocal<>(); private static final ThreadLocal<LoginInfo> LOGIN_INFO_THREAD_LOCAL = new ThreadLocal<>(); public OperatorContext() { } public static OperatorInfo getOperatorInfo() { return OPERATOR_INFO_THREAD_LOCAL.get(); } public static void setOperatorInfo(OperatorInfo operatorInfo) { OPERATOR_INFO_THREAD_LOCAL.set(operatorInfo); } public static LoginInfo getLoginInfo() { return LOGIN_INFO_THREAD_LOCAL.get(); } public static void setLoginInfo(LoginInfo loginInfo) { LOGIN_INFO_THREAD_LOCAL.set(loginInfo); } public static void release() { OPERATOR_INFO_THREAD_LOCAL.remove(); LOGIN_INFO_THREAD_LOCAL.remove(); } }
业务逻辑获取登录信息,操作人信息:
public void getOperator() { OperatorInfo operatorInfo = OperatorContext.getOperatorInfo(); log.info("操作人信息:{}", JsonUtil.toJson(operatorInfo)); LoginInfo loginInfo = OperatorContext.getLoginInfo(); log.info("登录信息:{}", JsonUtil.toJson(loginInfo)); }
tips:
1,Filter拦截器拦截请求头信息并校验登录信息,然后调用OperatorContext.setOperatorInfo(operatorInfo)初始化当前线程登录信息,请求完成之后调用OperatorContext.release()清除当前线程登录信息.
2,ThreadLocal用于保存某个线程共享变量,对于同一个static ThreadLocal,不同线程只能从中get,set,remove自己的变量而不会影响其他线程的变量.