ThreadLocal和过滤器结合实现请求拦截

2 篇文章 0 订阅

说明:

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>

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值