Cognition of Filter and interceptor in java

1, Filter configuration

  • First of all, from the perspective of cognition, if you are really unfamiliar with or forget Filter and interceptor, you can write a Demo in the IDEA to see the differences between the two. This is also a process of self cognition. Start with Filter
public class TestFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("TestFilter init complete");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
          System.out.println("implement TestFilter  doFIlter");
    }

    @Override
    public void destroy() {
        System.out.println("TestFilter destroy");
    }
}

The above code initializes the FIlter when the project starts.

ps: if Filter wants the request to continue to be processed, it must call filterchain doFilter()!

The code intuitively shows that Filter is based on Servlet. We click on the source code of Filter to see what is done inside. For example, the explanation of notes is very clear. The execution process is as follows:

Application scenario of filter:
The following is the official explanation from Filter

Filters are configured in the deployment descriptor of a web application
Examples that have been identified for this design are

  1. Authentication Filters / / Authentication Filters
  2. Logging and Auditing Filters / / Logging and Auditing Filters
  3. Image conversion Filters / / Image conversion Filters
  4. Data compression Filters / / Data compression Filters
  5. Encryption Filters / / Encryption Filters
  6. Tokenizing Filters / / tag filters
  7. Filters that trigger resource access events / / filters that trigger resource access events
  8. XSL/T filters //XSLT filters
  9. Mime-type chain Filter
  • Configure the Filter and leave it to Spring for management
    Mode 1
    Use @ Component+@Order
    Add @ component and @ Order(1) annotations to the TestFilter class to hand over the current Filter to Spring for management. When there are multiple filters, the @ Order(1) annotation here will specify the execution Order. The smaller the number, the more priority. If only @ Order is written, the default Order value is integer MAX_ VALUE.

@Component + @Order annotation is easy to configure and supports custom Filter order. The disadvantage is that only all URLs can be intercepted, and the specified URL cannot be intercepted through configuration.

Mode 2
Use @ WebFilter+@ServletComponentScan
@ServletComponentScan can be added to the current Filter class or the startup class.

Mode 3
Configuring classes using javaConfig

@Configuration
public class FilterConfig {
    @Bean
    public FilterBean filterBean(){
        FilterBean <TestFilter> bean = new FilterBean<>();
        bean.setOrder(1);
        bean.setFilter(new TestFilter());
        // Match all URLs under "/ test /"
        bean.addUrlPatterns("/test/*");
        return bean;
    }
    @Bean
    public FilterBean2 filterBean2(){
        FilterBean2 <TestFilter2> bean = new FilterBean2<>();
        bean.setOrder(2);
        bean.setFilter(new TestFilter2());
        // Match all URLs
        bean.addUrlPatterns("/*");
        return bean;
    }
}

Comparison between using @ Component/@Order annotation and configuring Filter with Config
First, define two filters, one using @ Component/@Order and the other using the configuration file FilterRegistrationBean

@Component
@Order(-1)
public class TestFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("TestFilter init complete");
    }
    /**
     * Address to ignore
     */
    private static final String[] IGNORES = new String[]{
           "/"
    };
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        long start = System.currentTimeMillis();
        filterChain.doFilter(servletRequest,servletResponse);
        System.out.println("TestFilter Execute cost="+(System.currentTimeMillis()-start));
    }

    @Override
    public void destroy() {
        System.out.println("TestFilter  destroy Destroy");
    }
}

FilterRegistrationBeanConfig configuration class

@Configuration
public class FilterConfig {
    @Bean
    public FilterRegistrationBean filterRegistrationBean(){
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new LogCostFilter());
        registration.addUrlPatterns("/*");
        registration.setName("LogCostFilter");
        registration.setOrder(2);
        return registration;
    }


}



public class LogCostFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        long start = System.currentTimeMillis();
        filterChain.doFilter(servletRequest,servletResponse);
        System.out.println("Execute cost="+(System.currentTimeMillis()-start));
    }
}

The execution result is based on the set priority.

Note: attributes annotated with @ WebFilter

Attribute name type describe
filterName String Specifies the name attribute of the filter, which is equivalent to filter name
value String[] This attribute is equivalent to the urlPatterns attribute. But both should not be used at the same time
urlPatterns String[] Specifies the URL matching pattern for a set of filters. Equivalent to label.
servletNames String[] Specifies which servlets the filter will be applied to. The value is the value of the name attribute in the @ WebServlet, or web Value in XML.
dispatcherTypes DispatcherType Specifies the forwarding mode of the filter. Specific values INCLUDE ASYNC, ERROR, FORWARD, INCLUDE and REQUEST.
initParams WebInitParam[] Specifies a set of filter initialization parameters, equivalent to labels.
asyncSupported boolean Declare whether the filter supports asynchronous operation mode, which is equivalent to label.
description String The description information of the filter is equivalent to the label.
displayName String The display name of the filter, usually used with tools, is equivalent to a label.

Execution sequence
For example:

encodingFilter.java

permissionFilter.java

Execute EncodingFilter Java is executing permissionfilter java

2, Interceptor configuration

  • First, we implement the interceptor class:
public class TestInterceptor implements HandlerInterceptor {
    long start = System.currentTimeMillis();
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        start = System.currentTimeMillis();
        return true;
    }
 
    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        System.out.println("Interceptor cost="+(System.currentTimeMillis()-start));
    }
 
    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
    }
}


Here, we need to implement the HandlerInterceptor interface, which includes three methods,

  1. preHandle is executed before the request is executed,
  2. postHandler is a request to end execution, but it will be executed only when the preHandle method returns true,
  3. afterCompletion is executed only after the view rendering is completed. Similarly, the preHandle needs to return true. This method is usually used to clean up resources and other work. In addition to implementing the above interfaces, we also need to configure them:
@Configuration
public class InterceptorConfig extends WebMvcConfigurerAdapter {
 
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new TestInterceptor()).addPathPatterns("/**");
        super.addInterceptors(registry);
    }
}

Here, we inherit WebMVCConfigurerAdapter, which we used when configuring static resource directories. Here, we rewrite the addInterceptors method to configure the interceptor. There are two main configuration items: one is to specify the interceptor and the other is to specify the intercepting URL. Now we can restart the system and access any URL.

Added by janey on Sat, 15 Jan 2022 17:08:40 +0200