欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Springboot---过滤器

程序员文章站 2022-05-23 10:12:58
...

1. 拦截器与过滤器区别

  AOP不是一种具体的技术,而是一种编程思想。过滤器和拦截器都属于面向切面编程的具体实现。而两者的主要区别包括以下几个方面:

 

  • 规范不同
  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。
  • 触发时机不同

Springboot---过滤器

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

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

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

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

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

       2. postHandle:是在Controller方法调用之后处理,可以在这个方法中对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 过滤器、拦截器的区别与使用