这个也是一个工具类
场景:比如说我们需要在controller或者service或者dao层用到当前登陆人的信息。我们之前的做法,肯定是从session中取出来。然后哪里需要传哪里。这样很麻烦。这时候我们需要造一个工具类。目的是在任何地方都能获取到当前登陆人的信息。
在这里我们要用到一个对象 ThreadLocal 这个对象 这个类相当于一个map,但是这个类的key是当前的进程。所以说,一个这样类只能放一个对象。这里要注意一下。
为什么要用这样的一个类呢?因为这个类的特性,每个进程的是完全隔离的,避免高并发情况下发生一些错误(我也不知道啥错误,反正就是防止高并发,这个坑回来再填!!!ToDo~~)
1.RequestHolder.java
package com.mmall.common; import com.mmall.model.SysUser; import javax.servlet.http.HttpServletRequest; 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(); } }
说明:这里new了两个这样的类,一个放当前对象,一个放当前request,然后自定义add方法,还有一个remove方法,因为在每次请求完之后,要把ThreadLocal 里面的数据移除掉
2. 然后写一个filter过滤器。拦截所有的请求。没有登录直接返回登录页面,登录了就从session中获取当前对象,然后add进去
LoginFilter.java
package com.mmall.filter; import com.mmall.common.RequestHolder; import com.mmall.model.SysUser; import lombok.extern.slf4j.Slf4j; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * Created by 敲代码的卡卡罗特 * on 2018/3/28 23:49. */ @Slf4j public class LoginFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override 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; } @Override public void destroy() { } }
3.每次请求结束清除当前数据 如何知道每次当前请求结束 请看我这一篇博客
HttpInterceptor.java
package com.mmall.common; import com.mmall.util.JsonMapper; import lombok.extern.slf4j.Slf4j; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Map; @Slf4j public class HttpInterceptor extends HandlerInterceptorAdapter { private static final String START_TIME = "requestStartTime"; @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.obj2String(parameterMap)); long start = System.currentTimeMillis(); request.setAttribute(START_TIME, start); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { String url = request.getRequestURI().toString(); long start = (Long) request.getAttribute(START_TIME); long end = System.currentTimeMillis(); log.info("request finished. url:{}, cost:{}", url, end - start); } @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 completed. url:{}, cost:{}", url, end - start); removeThreadLocalInfo(); } public void removeThreadLocalInfo() { RequestHolder.remove();; } }
4.在web.xml中配置过滤器
<filter> <filter-name>loginFilter</filter-name> <filter-class>com.mmall.filter.LoginFilter</filter-class> </filter> <filter-mapping> <filter-name>loginFilter</filter-name> <url-pattern>/sys/*</url-pattern> <url-pattern>/admin/*</url-pattern> </filter-mapping>