1. 拦截器与过滤器区别

过滤器和拦截器都属于面向切面编程的具体实现。而两者的主要区别包括以下几个方面:

 

  • 规范不同
  1. Filter是在Servlet规范中定义的,依赖于Servlet容器;
  2. 拦截器是在Spring容器中,是Spring框架支持的;
  • 使用范围不同
  1. Filter是Servlet规范定义的,只能应用在web程序中;
  2. 拦截器既可以应用在web程序中,也可以应用于Application、Swing程序中;
  • 使用资源不同
  1. 拦截器可以获取和使用IOC容器中的各个bean,而过滤器就不行,因为拦截器是spring提供并管理的,spring的功能可以被拦截器使用,在拦截器里注入一个service,可以调用业务逻辑。而过滤器是JavaEE标准,只需依赖servlet api ,不需要依赖spring。
  • 触发时机不同

spring有哪些过滤器 spring过滤器作用_spring有哪些过滤器

Filter和拦截器触发时机不一样;

Filter是在Servlet前后起作用:Filter在请求进入容器(tomcat服务器)后,但请求进入servlet之前进行预处理;请求结束返回也是,是在servlet处理完后,返回给前端之前。 

控制粒度比较粗,可以对请求和响应进行包装

拦截器:提供更精细的控制

       1. preHandle:是在执行Controller之前调用;

ModelAndView对象进行操作;

       3. afterCompletion:是在整个请求结束之后执行,一般用于资源清理工作。

1.1 小结

拦截器相比Filter有更细粒度的控制,依赖于Spring容器,可以在请求之前或之后启动,过滤器主要依赖于servlet,过滤器能做的,拦截器基本上都能做。

 

2. Filter使用

过滤器Filter,是在Servlet规范中定义的,是Servlet容器支持的,该接口定义在 javax.servlet包下,主要是在客户端请求(HttpServletRequest)进行预处理,以及对服务器响应(HttpServletResponse)进行后处理。接口代码如下:

package javax.servlet;

import java.io.IOException;

public interface Filter {
    void init(FilterConfig var1) throws ServletException;

    void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException;

    void destroy();
}
  • init(FilterConfig): 初始化接口,在用户自定义的Filter初始化时被调用,它与Servlet的 init方法的作用是一样的。
  • doFilter(ServletRequest,ServletResponse,FilterChain): 在每个用户的请求进来时这个方法都会被调用,并在Servlet的service方法之前调用(如果我们是开发Servlet项目),而FilterChain就代表当前的整个请求链,通过调用 FilterChain.doFilter可以将请求继续传递下去,如果想拦截这个请求,可以不调用FilterChain.doFilter,那么这个请求就直接返回了,所以Filter是一种责任链设计模式,在spring security就大量使用了过滤器,有一条过滤器链。
  • destroy: 当Filter对象被销毁时,这个方法被调用,注意,当Web容器调用这个方法之后,容器会再调用一次doFilter方法。

2.1 Filter两种使用方式: 

  1. 使用spring boot提供的FilterRegistrationBean注册Filter 
  2. 使用原生servlet注解(@WebFilter)定义Filter 

两种方式的本质都是一样的,都是去FilterRegistrationBean注册自定义Filter

 

2.1.1 使用FilterRegistrationBean注册Filter

1. 自定义Filter:实现Filter接口

import javax.servlet.*;
import java.io.IOException;

public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        // do something 处理request 或response
        System.out.println("filter1");
        // 调用filter链中的下一个filter
        filterChain.doFilter(servletRequest,servletResponse);
    }
    @Override
    public void destroy() {

    }
}

2. 使用FilterRegistrationBean注册自定义Filter:

@Configuration
public class FilterConfig {

    @Bean
    public FilterRegistrationBean registrationBean() {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new MyFilter());
        filterRegistrationBean.addUrlPatterns("/*");
        filterRegistrationBean.setName("filter1");
        return filterRegistrationBean;
    }
}

2.1.2 使用@WebFilter注解

// 注入spring容器
@Component
// 定义filterName 和过滤的url
@WebFilter(filterName = "my2Filter" ,urlPatterns = "/*")
public class My2Filter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

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

    }
}

 

参考:springboot系列文章之过滤器 vs 拦截器、 spring boot 过滤器、拦截器的区别与使用