SpringBoot(六):拦截器过滤器

/ SpringBoot / 3 条评论 / 248人围观

过滤器

实现javax.servlet.Filter接口即可

/**
 * description
 *
 * @author 70KG
 * @date 2018/10/25
 */
@Component
@WebFilter(urlPatterns = {"/*"})// 表示所有的请求都会过滤一下
public class TimeFilter implements Filter{

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("过滤器初始化");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("----------开始执行过滤器----------");
        Long start = new Date().getTime();
        filterChain.doFilter(servletRequest, servletResponse);
        System.out.println("【过滤器】耗时 " + (new Date().getTime() - start));
        System.out.println("----------结束执行过滤器----------");
    }

    @Override
    public void destroy() {
        System.out.println("过滤器销毁");
    }
}

拦截器

实现HandlerInterceptor接口

/**
 * description
 *
 * @author 70KG
 * @date 2018/10/25
 */
@Component
public class TimeInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest httpsServletRequest, HttpServletResponse httpsServletResponse, Object o) throws Exception {
        System.out.println("处理拦截之前");
        // 进入目标方法开始时间
        httpsServletRequest.setAttribute("startTime", new Date().getTime());
        // 全限定性类名
        System.out.println(((HandlerMethod) o).getBean().getClass().getName());
        // 方法名
        System.out.println(((HandlerMethod) o).getMethod().getName());
        System.out.println("========================================");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpsServletRequest, HttpServletResponse httpsServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        System.out.println("开始处理拦截");
        // 获取开始时间
        Long start = (Long) httpsServletRequest.getAttribute("startTime");
        System.out.println("【拦截器】耗时 " + (new Date().getTime() - start));
        System.out.println("========================================");
    }

    @Override
    public void afterCompletion(HttpServletRequest httpsServletRequest, HttpServletResponse httpsServletResponse, Object o, Exception e) throws Exception {
        System.out.println("处理拦截之后");
        Long start = (Long) httpsServletRequest.getAttribute("startTime");
        System.out.println("【拦截器】耗时 " + (new Date().getTime() - start));
        System.out.println("异常信息 " + e);
        System.out.println("========================================");
    }
}

通过这三个方法的参数可以看到,相较于过滤器,拦截器多了Object和Exception对象,所以可以获取的信息比过滤器要多的多。但拦截器仍无法获取到方法的参数等信息,可以通过切面编程来实现这个目的。

配置类

需要将拦截器注册进去

/**
 * Description:向mvc中添加自定义组件
 * Author:70kg
 * Date 2018/5/11 13:35
 */
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {

    @Autowired
    private TimeInterceptor timeInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(timeInterceptor);
    }

}

输出测试

处理拦截之前
com.example.demo.controller.DemoController
testDemo
========================================
开始处理拦截
【拦截器】耗时 1058
========================================
处理拦截之后
【拦截器】耗时 1058
异常信息 null
========================================

执行时机

----------开始执行过滤器----------
处理拦截之前
com.example.demo.controller.DemoController
testDemo
========================================
开始处理拦截
【拦截器】耗时 1039
========================================
处理拦截之后
【拦截器】耗时 1039
异常信息 null
========================================
【过滤器】耗时 1055
----------结束执行过滤器----------

可见过滤器要先于拦截器执行,晚于拦截器结束。

算上切面,他们的执行时机如下图:

请输入图片描述

  1. 哥哥你真棒

    回复

    @路遥 低调哦

    回复
  2. 的方法更烦烦烦

    回复