说明:
ThreadLocal的作用就是为了区分各个线程结合过滤器使用目的
就是保存一些数据,为了区分或者在某些时刻使用
场景:
1. 分布式时打印日志太多,无法区分
2. 保存一些数据,为了入库/使用时容易拿到
以保存登陆用户信息为例:此例子使用于web.xml即基于servlet3.0之前
1> 写个bean,存储数据
public class RequestHolder { private static final ThreadLocal<SysUser> userHolder = new ThreadLocal<SysUser>(); private static final ThreadLocal<HttpServletRequest> requestHolder = new ThreadLocal<HttpServletRequest>(); 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(); } }
2> 写个过滤器
@Slf4j public class LoginFilter implements Filter { public void init(FilterConfig filterConfig) throws ServletException { } public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) servletRequest; HttpServletResponse resp = (HttpServletResponse) servletResponse; SysUser sysUser = (SysUser)req.getSession().getAttribute("user"); //为空跳转到登陆页面 if (sysUser == null) { String path = "/signin.jsp"; resp.sendRedirect(path); return; } RequestHolder.add(sysUser); RequestHolder.add(req); filterChain.doFilter(servletRequest, servletResponse); return; } public void destroy() { } }
3> 注册并指定过滤器拦截内容:在web.xml
<filter> <filter-name>loginFilter</filter-name> <filter-class>com.allen.filter.LoginFilter</filter-class> </filter> <filter-mapping> <filter-name>loginFilter</filter-name> <url-pattern>/sys/*</url-pattern> <url-pattern>/admin/*</url-pattern> </filter-mapping>
4> 使用
dept.setOperator(RequestHolder.getCurrentUser().getUsername()); dept.setOperateIp(IpUtil.getRemoteIp(RequestHolder.getCurrentRequest())); dept.setOperateTime(new Date()); sysDeptMapper.insertSelective(dept);
5> 清除(不清楚会导致内存泄漏)
5.1 写个拦截器
@Slf4j public class HttpInterceptor extends HandlerInterceptorAdapter { /** * 请求前 */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return true; } /** * 正常请求会调用 * 场景: * 1.输出每次的请求信息 * 2.监控某个方法耗费事件 */ @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { removeThreadLocalInfo(); } /** * 正常和异常都会调用即100%调用 */ @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { } public void removeThreadLocalInfo() { RequestHolder.remove();; } }
5.2 注册:在XXX-servlet.xml中注册即
<mvc:interceptors> <bean class="com.allen.interceptor.HttpInterceptor" /> </mvc:interceptors>