【Spring】使用ThreadLocal获取当前用户的信息

引入:

一提到获取用户信息,大部分人想到的都是通过session来获取用户信息,当要想获取到session,就需要获取对应的request,这样,就会增加代码的耦合性,基于以上缺陷,我们可以使用ThreadLocal来将当前的用户信息存入一个session,需要的时候,直接从全局的ThreadLocal中取出来即可

接下来我们实践操作一波:

创建一个RequestHolder类,定义相关的set和get用户信息的方法

/**
 * @author evan_qb
 * @date 2018/8/29 15:09
 */
public class RequestHolder {
    private static final ThreadLocal<SysUser> userHolder = new ThreadLocal<SysUser>();

    private static final ThreadLocal<HttpServletRequest> requestHolder = new ThreadLocal<>();

    public static void add(SysUser sysUser){
        userHolder.set(sysUser);
    }

    public static void add(HttpServletRequest request){
        requestHolder.set(request);
    }

    public static SysUser getCurrentUser(){
        return userHolder.get();
    }

    public static HttpServletRequest getCurrentRequest(){
        return requestHolder.get();
    }

    public static void remove(){
        userHolder.remove();
        requestHolder.remove();
    }

}

然后定义一个拦截器用于移除对应的ThreadLocal对象,防止内存泄漏

public class HttpInterceptor extends HandlerInterceptorAdapter {

    private static final String START_TIME = "requestStartTime";

    /**
     * 处理前
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String url = request.getRequestURI().toString();
        Map parameterMap = request.getParameterMap();
        log.info("request start url:{},params:{}",url,JsonMapper.object2String(parameterMap));
        long startTime = System.currentTimeMillis();
        request.setAttribute(START_TIME,startTime);
        return true;
    }

    /**
     * 处理后调用(正常)
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     * @throws Exception
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        /*String url = request.getRequestURI().toString();
        Map parameterMap = request.getParameterMap();
        log.info("request finish url:{},params:{}",url,JsonMapper.object2String(parameterMap));*/

    }

    /**
     * 处理后调用(任何情况)
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        String url = request.getRequestURI().toString();
        long start = (long) request.getAttribute(START_TIME);
        long end = System.currentTimeMillis();
        log.info("request exception url:{},cost:{}ms",url,end - start);
        removeThreadLocalInfo();
    }

    /**
     * 移除信息
     */
    public void removeThreadLocalInfo(){
        RequestHolder.remove();
    }
}

这时,我们需要利用一个过滤器LoginFilter,将每次的请求,和每次的用户信息存入ThreadLocal中

/**
 * @author evan_qb
 * @date 2018/8/29 15:29
 */
public class LoginFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;
        String path = req.getServletPath();

        SysUser sysUser = (SysUser) WebUtils.getSessionAttribute(req,"user");
        if (sysUser == null){
            resp.sendRedirect("/signin.jsp");
            return;
        }
        RequestHolder.add(sysUser);
        RequestHolder.add(req);
        chain.doFilter(request,response);
        return;
    }

    @Override
    public void destroy() {

    }
}

同时在web.xml中配置好LoginFilter

<filter>
  <filter-name>loginFilter</filter-name>
  <filter-class>cn.qblank.filter.LoginFilter</filter-class>
</filter>
<filter-mapping>
  <filter-name>loginFilter</filter-name>
  <url-pattern>/sys/*</url-pattern>
  <url-pattern>/admin/*</url-pattern>
</filter-mapping>

当我们需要用户的信息时,我们可以直接通过RequestHolder的方法直接获取

 

 

展开阅读全文

没有更多推荐了,返回首页