Spring拦截器和过滤器的区别及详解

时间:2022-11-02 08:56:02

拦截器和filter的功能都是拦截,filter是在servlet前执行的,拦截器拦截的是Spring MVC定义的概念。过滤器中包含拦截器,发送一个请求,先进行过滤器处理,看程序是否受理该请求。过滤器放过后,程序中的拦截器再进行处理。

Spring拦截器和过滤器的区别及详解

 1. 拦截器(Interceptor)

拦截器它是链式调用,一个应用中可以同时存在多个拦截器Interceptor,一个请求也可以触发多个拦截器,而每个拦截器的调用会依据它的声明顺序依次执行。spring中拦截器主要分两种:HandlerInterceptor和MethodInterceptor。

1.1 HandlerInterceptor拦截方式--HandlerInterceptor是springMVC中的拦截器,它拦截的目标是请求的地址,比MethodInterceptor先执行。其工作原理是当请求来时先进性预处理。HandlerInterceptoer拦截的是请求地址,所以针对请求地址做一些验证、预处理等操作比较合适

1.1.1 下面用代码进行展示:编写一个简单的拦截器处理类,请求的拦截是通过HandlerInterceptor 来实现

/**
 * preHandle() :这个方法将在请求处理之前进行调用。如果该方法的返回值为false ,将视为当前请求结束,不仅自身的拦截器会失效,还会导致其他的拦截器也不再执行。
 * postHandle():只有在 preHandle() 方法返回值为true 时才会执行。会在Controller 中的方法调用之后,DispatcherServlet 返回渲染视图之前被调用。
 * afterCompletion():只有在 preHandle() 方法返回值为true 时才会执行。在整个请求结束之后, DispatcherServlet 渲染了对应的视图之后执行。
 */
@Component
public class MyControllerInterceptor implements HandlerInterceptor {
    /**
     * 在controller调用之前执行
     */
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        String string1 = request.getParameter("string1");
        if(string1.equals("123")){
            return true;
        }
        System.out.println(request.getRequestURI()+"开始执行");
        return false;
    }

    /**
     * 在controller调用中执行
     */
    public void postHandle(
            HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
            throws Exception {
    }

    /**
     * 在controller调用后执行
     */
    public void afterCompletion(
            HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        System.out.println(request.getRequestURI()+"执行结束");
    }
}

1.1.2 将自定义好的拦截器处理类进行注册,并通过addPathPatterns、excludePathPatterns等属性设置需要拦截或需要排除的 URL。 

@Configuration
public class IntercepterConfig implements WebMvcConfigurer {

    @Autowired
    private MyControllerInterceptor myControllerInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //addPathPatterns用于添加拦截路径    /**表示拦截所有的路径
        //excludePathPatterns用于添加不拦截的路径
        registry.addInterceptor(myControllerInterceptor).addPathPatterns("/test1/**");

    }

    //此方法用于配置静态资源路径
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**").addResourceLocations("classpath:/mapper/");
    }
}

1.2 MethodInterceptor拦截方式--MethodInterceptor是AOP项目中的拦截器,它拦截的目标是方法,常用AOP。这里就不过多的介绍了。

2. 过滤器(filter)

过滤器的配置,直接实现Filter接口,也可以通过@WebFilter注解实现对特定URL拦截

下面用代码进行展示:

@Component
public class MyFilter implements Filter {

    /**
     * init() :该方法在tomcat容器启动初始化过滤器时被调用,它在 Filter 的整个生命周期只会被调用一次。
     * doFilter() :容器中的每一次请求都会调用该方法, FilterChain(放行) 用来调用下一个过滤器 Filter。
     * destroy(): 当容器销毁过滤器实例时调用该方法,在方法中销毁或关闭资源,在过滤器 Filter 的整个生命周期也只会被调用一次。
     */
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("Filter 前置");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("Filter 处理中");
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {
        System.out.println("Filter 后置");
    }
}

过滤器和拦截器的区别总结:

(1)拦截器是基于java的反射机制,过滤器是基于函数回调。
(2)Filter是依赖于Servlet容器,属于Servlet规范的一部分,而拦截器则是独立存在的,可以在任何情况下使用。
(3)Filter的生命周期由Servlet容器管理,而拦截器则可以通过IoC容器来管理,因此可以通过注入等方式来获取其他Bean的实例,因此使用会更方便。