Interview Blitz 90: What's the Difference Between Filters and Blockers?

Continue to create, accelerate growth! This is the third day of my participation in the "Nuggets Daily New Plan · October Update Challenge", click to view the details of the event

Filter and Interceptor are both based on AOP (Aspect Oriented Programming, Aspect Oriented Programming) and are two "tools" used to solve a certain type of problem in a project, but the two have obvious The difference, let's look at it together.

Implementing filters and interceptors

First of all, let's take a look at the specific implementation of the two in the Spring Boot project, which is of great help for the subsequent understanding of the difference between the two.

a) implement the filter

The filter can use the @WebFilter annotation provided by Servlet 3.0 to configure the filtering URL rules, and then implement the Filter interface and rewrite the doFilter method in the interface. The specific implementation code is as follows:

import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@Component
@WebFilter(urlPatterns = "/*")
public class TestFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("过滤器:执行 init 方法。");
    }
    @Override
    public void doFilter(ServletRequest servletRequest,
                         ServletResponse servletResponse,
                         FilterChain filterChain) throws IOException, ServletException {
        System.out.println("过滤器:开始执行 doFilter 方法。");
        // 请求放行
        filterChain.doFilter(servletRequest, servletResponse);
        System.out.println("过滤器:结束执行 doFilter 方法。");
    }
    @Override
    public void destroy() {
        System.out.println("过滤器:执行 destroy 方法。");
    }
}
复制代码

in:

  • void init(FilterConfig filterConfig): It will be called when the container starts (Filter is initialized), and it will only be called once during the entire program runtime. Used to implement the initialization of the Filter object.

  • void doFilter(ServletRequest request, ServletResponse response, FilterChain chain): The specific filter function implementation code, through which the request is filtered, and the FilterChain parameter is used to call the next filter or execute the next process .

  • void destroy(): Used to complete the recycling of related resources before the Filter is destroyed.

    b) Implement the interceptor

    拦截器的实现分为两步,第一步,创建一个普通的拦截器,实现 HandlerInterceptor 接口,并重写接口中的相关方法;第二步,将上一步创建的拦截器加入到 Spring Boot 的配置文件中。 接下来,先创建一个普通拦截器,实现 HandlerInterceptor 接口并重写 preHandle/postHandle/afterCompletion 方法,具体实现代码如下:

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component
public class TestInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("拦截器:执行 preHandle 方法。");
        return true;
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("拦截器:执行 postHandle 方法。");
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("拦截器:执行 afterCompletion 方法。");
    }
}
复制代码

其中:

  • boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handle):在请求方法执行前被调用,也就是调用目标方法之前被调用。比如我们在操作数据之前先要验证用户的登录信息,就可以在此方法中实现,如果验证成功则返回 true,继续执行数据操作业务;否则就返回 false,后续操作数据的业务就不会被执行了。
  • void postHandle(HttpServletRequest request, HttpServletResponse response, Object handle, ModelAndView modelAndView):调用请求方法之后执行,但它会在 DispatcherServlet 进行渲染视图之前被执行。
  • void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handle, Exception ex):会在整个请求结束之后再执行,也就是在 DispatcherServlet 渲染了对应的视图之后再执行。

最后,我们再将上面的拦截器注入到项目配置文件中,并设置相应拦截规则,具体实现代码如下:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class AppConfig implements WebMvcConfigurer {

    // 注入拦截器
    @Autowired
    private TestInterceptor testInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(testInterceptor) // 添加拦截器
                .addPathPatterns("/*"); // 拦截所有地址
    }
}
复制代码

了解了二者的使用之后,接下来我们来看二者的区别。

过滤器 VS 拦截器

过滤器和拦截器的区别主要体现在以下 5 点:

  1. 出身不同;
  2. 触发时机不同;
  3. 实现不同;
  4. 支持的项目类型不同;
  5. 使用的场景不同。

接下来,我们一一来看。

1.出身不同

过滤器来自于 Servlet,而拦截器来自于 Spring 框架,从上面代码中我们也可以看出,过滤器在实现时导入的是 Servlet 相关的包,如下图所示: image.png 而拦截器在实现时,导入的是 Spring 相关的包,如下图所示: image.png

2.触发时机不同

请求的执行顺序是:请求进入容器 > 进入过滤器 > 进入 Servlet > 进入拦截器 > 执行控制器(Controller),如下图所示: image.png 所以过滤器和拦截器的执行时机也是不同的,过滤器会先执行,然后才会执行拦截器,最后才会进入真正的要调用的方法

3.实现不同

过滤器是基于方法回调实现的,我们在上面实现过滤器的时候就会发现,当我们要执行下一个过滤器或下一个流程时,需要调用 FilterChain 对象的 doFilter 方法进行回调执行,如下图所示: image.png 由此可以看出,过滤器的实现是基于方法回调的。 而拦截器是基于动态代理(底层是反射)实现的,它的实现如下图所示: image.png 代理调用的效果如下图所示: image.png

4.支持的项目类型不同

过滤器是 Servlet 规范中定义的,所以过滤器要依赖 Servlet 容器,它只能用在 Web 项目中;而拦截器是 Spring 中的一个组件,因此拦截器既可以用在 Web 项目中,同时还可以用在 Application 或 Swing 程序中

5.使用的场景不同

Because the interceptor is closer to the business system, the interceptor is mainly used to implement business judgment in the project , such as: login judgment, permission judgment, logging and other services. Filters are usually used to implement general function filtering , such as: sensitive word filtering, character set encoding settings, response data compression and other functions.

Download the source code of this project

gitee.com/mydb/spring…

Summarize

Both filters and interceptors are implemented based on the AOP idea and are used to handle a unified function, but there are five differences between the two: different origins, different trigger timings, different implementations, different types of supported projects, and different types of projects used. Scenarios are different. Filters are usually used for global filtering, while interceptors are used to implement a certain business interception.

References & Acknowledgements

  • blog.csdn.net/wo541075754/article/details/111661213

  • zhuanlan.zhihu.com/p/340397290

It is up to oneself to judge right and wrong, to listen to others, and to count the gains and losses.

Official Account: Analysis of Java Interview Questions

Interview Collection: gitee.com/mydb/interv…

Guess you like

Origin juejin.im/post/7155069405993369631