Jin Jiu Yin 10 lost the first battle, what is the difference between filter and interceptor, this time it can be regarded as a meeting

This is a problem I encountered during an interview not long ago. I was immediately confused at the time. Although the two singles were not complete, they probably knew that the request could be intercepted. It was a headache to compare them together.

In fact, I went to learn a wave after the interview before, but I didn't summarize it in time at that time. I will summarize it now, so as not to encounter such problems in the future and forget it.

To understand this kind of problem, rote memorization may be useful at the time, and it will be almost forgotten after a while. To really remember, we have to do it.

Use of Filter

First, to use Filter, you must implement the javax.servlet.Filter interface:

public interface Filter {
	//web应用加载进容器,Filter对象创建之后,执行init方法初始化,用于加载资源,只执行一次。	
    public default void init(FilterConfig filterConfig) throws ServletException {}
	//每次请求或响应被拦截时执行,可执行多次。
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException;
	//web应用移除容器,服务器被正常关闭,则执行destroy方法,用于释放资源,只执行一次。
    public default void destroy() {}
}
  • Init and destroy are the default methods, and the implementation class does not need to be implemented.
  • doFilter must be implemented, that is, as a filter, doFilter must be defined.
  • The FilterChain object passed in in the doFlilter method is used to call the next filter.

Use of interceptors

public interface HandlerInterceptor {
	//拦截handler的执行 --> 在HanlerMapping决定适合的handler之后,[在HandlerAdater调用handler之前执行。]
	default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {		return true;
	}	//拦截handler的执行 --> [在HandlerAdapter调用handler之后],在DispatcherServlet渲染视图之前执行
	default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			@Nullable ModelAndView modelAndView) throws Exception {	}	//视图渲染后调用,且只有preHandle结果为true,才会调用
	default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
			@Nullable Exception ex) throws Exception {	}}
//DispatcherServlet
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
    return; //遍历所有的interceptors,调用preHandle方法,只有返回true,才能进行下去
}
// 这里也就是处理Contrller
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
//视图渲染
applyDefaultViewName(processedRequest, mv);
//视图渲染之后调用
mappedHandler.applyPostHandle(processedRequest, response, mv);

What is the difference between a filter and an interceptor?

1. The realization principle is different

  • The implementation of the filter is based on the callback function
  • The interceptor is implemented based on Java's reflection mechanism [dynamic proxy].

Two, the scope of use is different

  • The filter is a Servlet specification and needs to implement the javax.servlet.Filter interface. The use of the Filter needs to depend on containers such as Tomcat.
  • The interceptor is a Spring component, defined in the org.springframework.web.servlet package, and managed by the Spring container [has a richer cycle processing method, fine-grained, and can use Spring resources], and does not rely on Tomcat Wait for the container.

Three, the trigger timing is different

This paragraph can be found in the annotation of the HandlerInterceptor class, the trigger timing of the two is different:

Jin Jiu Yin 10 lost the first battle, what is the difference between filter and interceptor, this time

 

  • Filter: Process the request before or after entering the servlet.
  • Interceptor: The request is processed before and after the handler [Controller].

Jin Jiu Yin 10 lost the first battle, what is the difference between filter and interceptor, this time

 

Fourth, the execution order is different

When both filters and interceptors are configured:

MyFilter1 前
MyFilter2 前
MyInterceptor1 在Controller前执行
MyInterceptor2 在Controller前执行
controller方法执行...
MyInterceptor2 Controller之后,视图渲染之前
MyInterceptor1 Controller之后,视图渲染之前
MyInterceptor2 视图渲染完成之后执行
MyInterceptor1 视图渲染完成之后执行
MyFilter2 后
MyFilter1 后
  • Order of filters

Each time the chain object is passed in to achieve the effect of the final interface callback:

Jin Jiu Yin 10 lost the first battle, what is the difference between filter and interceptor, this time

 

  • Interceptor order

preHandle1 -> preHande2 -> [Controller] -> postHandle2 -> postHandle1 -> afterCompletion2 -> afterCompletion1 preHandle is in the order of registration, and the last two are opposite to the order of registration.

  • If the preHandle of an interceptor is false, all subsequent interceptors will not be executed.
  • If the preHandle of an interceptor is true, the triggerAfterCompletion of this interceptor will be executed.
  • Only if all interceptors preHandler are true, that is, they are executed normally, postHandle will execute.
boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
    HandlerInterceptor[] interceptors = getInterceptors();    if (!ObjectUtils.isEmpty(interceptors)) {
        for (int i = 0; i < interceptors.length; i++) {
            HandlerInterceptor interceptor = interceptors[i];            //一旦当前拦截器preHandle的返回值为false,那么从上一个可用的拦截器的afterCompletion开始
            if (!interceptor.preHandle(request, response, this.handler)) {
                triggerAfterCompletion(request, response, null);
                return false; //这里返回false意为 后续不进行下去了。
            }            this.interceptorIndex = i;//interceptorIndex初始化为-1,只有当前拦截器preHandle为true,才会赋值当前的i。
        }    }    return true;
}void applyPostHandle(HttpServletRequest request, HttpServletResponse response, @Nullable ModelAndView mv)    throws Exception {    HandlerInterceptor[] interceptors = getInterceptors();    if (!ObjectUtils.isEmpty(interceptors)) {
        for (int i = interceptors.length - 1; i >= 0; i--) {
            HandlerInterceptor interceptor = interceptors[i];            interceptor.postHandle(request, response, this.handler, mv);
        }    }}void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, @Nullable Exception ex)    throws Exception {    HandlerInterceptor[] interceptors = getInterceptors();        for (int i = this.interceptorIndex; i >= 0; i--) 
}

Five, the control execution sequence is different

Both use the registration order by default. If you want to control the order of execution, the way is slightly different:

  • If you want to force the filter to change, you can use the @Order annotation.
  • If the interceptor uses the order() method
@Order(2)
@Component
public class MyFilter1 implements Filter {}
@Component
public class WebAdapter implements WebMvcConfigurer {
    @Autowired
    MyInterceptor1 myInterceptor1;    @Autowired
    MyInterceptor2 myInterceptor2;    @Override
    public void addInterceptors(InterceptorRegistry registry) {        registry.addInterceptor(myInterceptor1).addPathPatterns("/**").order(2);
        registry.addInterceptor(myInterceptor2).addPathPatterns("/**").order(1);
    }}

to sum up

  • In principle, the filter is based on callback implementation, and the interceptor is based on dynamic proxy.
  • Control granularity: Both filters and interceptors can realize the interception function of requests, but there is a big difference in the granularity of interception, and the granularity of the interceptor for access control is finer.
  • Usage scenarios: Interceptors are often used for permission checking, log records, etc., filters are mainly used for filtering invalid parameters in requests and security verification.
  • Dependent on the container: The filter depends on the Servlet container and is limited to the web, while the interceptor depends on the Spring framework and can use the resources of the Spring framework, not limited to the web.
  • Timing of triggering: The filter is executed before and after the servlet, and the interceptor is executed before and after the handler. Now most web applications are based on Spring, and the interceptor is more detailed.

If you think this article is helpful to you, please click to support it.

You can also follow my public account, there are more technical dry goods articles and related information sharing on it, everyone learns and progresses together!

 

Guess you like

Origin blog.csdn.net/weixin_50205273/article/details/108565814