Correct posture for using Filter in SpringBoot

Filter is a component of the Servlet specification in JavaEE, located in the package javax.servlet, which can be processed by one or more Filters before the HTTP request reaches the servlet.

Its workflow is as follows:

This feature of Filter has a wide range of applications in production environments, such as: modifying requests and responses, preventing xss attacks, wrapping binary streams so that they can be read multiple times, and so on.

In actual work, we all use SpringBoot for business development. This article summarizes three Filter usages. The SpringBoot version adopts the latest v2.3.1.RELEASE.

Write Filter

To write a Filter, just implement the javax.servlet.Filter interface

public class MyFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("MyFilter");
        // To continue processing requests, filterChain.doFilter() must be added
        filterChain.doFilter(servletRequest,servletResponse);
    }
}

The Filter interface has three methods: init(),doFilter(),destroy().

Among them, doFilter() needs to be implemented by yourself, and the other two are default, so you don't need to implement them.

Note: If Filter wants to keep the request processed, it must call filterChain.doFilter()!

Note: If Filter wants to keep the request processed, it must call filterChain.doFilter()!

Note: If Filter wants to keep the request processed, it must call filterChain.doFilter()!

Important things said three times! ! !

Configure Filter to be managed by Spring

There are three ways to implement the custom Filter to be managed by Spring's IOC container, each with its own advantages and disadvantages. The following class representatives will summarize for you:

Use @Component+@Order

Adding the @Component annotation to the MyFilter class just defined can be managed by Spring. Adding the @Order annotation is just for sorting, and it can be omitted.

@Component
@Order(1)
public class MyFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("MyFilter");
        // To continue processing requests, filterChain.doFilter() must be added
        filterChain.doFilter(servletRequest,servletResponse);
    }
}

That's right, it's that simple, so MyFilter takes effect, and you can see the effect by writing a Controller and calling it.

When there are multiple Filter s, the @Order(1) annotation here will specify the execution order. The smaller the number, the higher the priority. If only @Order is written, the default order value is Integer.MAX_VALUE.

The @Component + @Order annotation method is simple 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.

@WebFilter+@ServletComponentScan

Add the @WebFilter annotation to MyFilter, and add the @ServletComponentScan("com.zhengxl.filterdemo.filter") annotation to the startup class. The parameter is the package path where the Filter is located, which is equivalent to telling SpringBoot where to scan the Filter

// filter class
@WebFilter(urlPatterns = "/*")
public class MyFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("MyFilter");
        // To continue processing requests, filterChain.doFilter() must be added
        filterChain.doFilter(servletRequest,servletResponse);
    }
}

// main class
@SpringBootApplication
@ServletComponentScan("com.zhengxl.filterdemo.filter")
public class FilterDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(FilterDemoApplication.class, args);
    }

}

The @WebFilter+@ServletComponentScan annotation supports matching the specified URL to the Filter, but does not support the execution order of the specified Filter.

JavaConfig configuration method

@Configuration
public class FilterConfig {
    @Bean
    public FilterRegistrationBean registerMyFilter(){
        FilterRegistrationBean<MyFilter> bean = new FilterRegistrationBean<>();
        bean.setOrder(1);
        // new MyFilter() is a common class that inherits the Filter interface, not managed by Spring or WebFilter
        bean.setFilter(new MyFilter());
        // Match all url s below "/hello/"
        bean.addUrlPatterns("/hello/*");
        return bean;
    }
    @Bean
    public FilterRegistrationBean registerMyAnotherFilter(){
        FilterRegistrationBean<MyAnotherFilter> bean = new FilterRegistrationBean<>();
        bean.setOrder(2);
        bean.setFilter(new MyAnotherFilter());
        // match all url s
        bean.addUrlPatterns("/*");
        return bean;
    }
}

Explicitly configure Filter through Java code, which is powerful and flexible in configuration. You only need to declare each custom Filter as a Bean and hand it over to Spring for management. You can also set the matching URL and specify the order of Filters.

Three ways to compare

After the introduction of the three Filter postures in SpringBoot, it is very simple. The following table summarizes:

How to use sort Specify URL
@Component @Order 1 0
@WebFilter @ServletComponentScan 0 1
JavaConfig 1 1

In the actual use process, you can choose the appropriate usage method according to your business requirements. For example, if you write a filter that intercepts all requests and does not need to specify the URL, then it is very appropriate to choose the simplest @Component+@Order.

PS: In fact, there is a fourth type, web.xml configuration, but this is all in 2020. Isn't it more convenient to use SpringBoot's automatic assembly or JavaConfig?

This article is transferred from WeChat public account - Java class representative

👇Follow Java class representatives to get the latest Java dry goods👇

Tags: Spring Boot filter

Posted by hannah415 on Tue, 31 May 2022 07:07:19 +0530