[JAVA] Use Servlet filter in Spring Boot [Spring Boot 1.x, 2.x compatible]

environment

2018-03-09 Addendum It was the same behavior when I upgraded to Spring Boot 2.0.0.RELEASE.

2018-12-20 postscript Added the explanation of Spring Boot 2.1.

Basic Filter registration method

Use the FilterRegistrationBean class provided by Spring Boot. When you define a FilterRegistrationBean, the Filter is fetched in the Spring Boot Auto Configuration class and registered with the Embedded Server.

@Configuration
public class SomeConfig {

    @Bean
    public FilterRegistrationBean hogeFilter() {
        //New Filter and pass it to the FilterRegistrationBean constructor
        FilterRegistrationBean bean = new FilterRegistrationBean(new HogeFilter());
        //Filter url-Specify pattern (variadic argument allows multiple specifications)
        bean.addUrlPatterns("/*");
        //Filter execution order. Performed for aiming at integer values
        bean.setOrder(Integer.MIN_VALUE);
        return bean;
    }

    @Bean
    public FilterRegistrationBean fugaFilter() {
        FilterRegistrationBean bean = new FilterRegistrationBean(new FugaFilter());
        bean.addUrlPatterns("/*");
        //Executed after HogeFilter
        bean.setOrder(Integer.MIN_VALUE + 1);
        return bean;
    }

    //Any number of Filters can be defined
}

Use other beans in Filter

The @Bean method can accept other beans as arguments. This is a feature that Spring originally has. It is OK if the Bean received as an argument is received by the constructor of Filter.

public class HogeFilter extends OncePerRequestFilter { //Of course, "implements Filter" is also OK
    private final FugaBean fugaBean; //Create field

    public HogeFilter(FugaBean fugaBean) { //Receive the bean in the constructor
        this.fugaBean = fugaBean;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
        //Write pre-processing here
        chain.doFilter(request, response);
        //Write post-processing here
    }
}
@Configuration
public class HogeConfig {

    @Bean
    public FilterRegistrationBean hogeFilter(FugaBean fugaBean) {
        //Pass the bean to the Filter constructor
        FilterRegistrationBean bean = new FilterRegistrationBean(new HogeFilter(fugaBean));
        // ...
        return bean;
    }
}

The FugaBean must be bean-defined somewhere else (such as another Config class or component scan).

Note that the Filter itself is not a bean. That is, you cannot DI a bean to a Filter with @ Autowired or apply an AOP to a Filter.

See the list of application order of all filters

It is a class called ServletContextInitializerBeans that extracts Filter from FilterRegistrationBean and registers it in Embedded Server. It is OK if you output the DEBUG log of this class (Note: TRACE log after Spring Boot 2.1). Filter is executed in ascending order of the value of  Ľorder`.

application.properties


# Boot 2.After 1 is trace instead of debug
logging.level.org.springframework.boot.web.servlet.ServletContextInitializerBeans=debug

Standard output


...
2018-02-28 11:58:37.611 DEBUG 4323 --- [ost-startStop-1] o.s.b.w.s.ServletContextInitializerBeans : Added existing Filter initializer bean 'loggingFilter1'; order=-2147483648, resource=com.example.Application
2018-02-28 11:58:37.611 DEBUG 4323 --- [ost-startStop-1] o.s.b.w.s.ServletContextInitializerBeans : Added existing Filter initializer bean 'loggingFilter2'; order=-2147483647, resource=com.example.Application
2018-02-28 11:58:37.612 DEBUG 4323 --- [ost-startStop-1] o.s.b.w.s.ServletContextInitializerBeans : Added existing Filter initializer bean 'loggingFilter3'; order=-2147483646, resource=com.example.Application
2018-02-28 11:58:37.612 DEBUG 4323 --- [ost-startStop-1] o.s.b.w.s.ServletContextInitializerBeans : Added existing Servlet initializer bean 'dispatcherServletRegistration'; order=2147483647, resource=class path resource [org/springframework/boot/autoconfigure/web/DispatcherServletAutoConfiguration$DispatcherServletRegistrationConfiguration.class]
2018-02-28 11:58:37.638 DEBUG 4323 --- [ost-startStop-1] o.s.b.w.s.ServletContextInitializerBeans : Created Filter initializer for bean 'characterEncodingFilter'; order=-2147483648, resource=class path resource [org/springframework/boot/autoconfigure/web/HttpEncodingAutoConfiguration.class]
2018-02-28 11:58:37.638 DEBUG 4323 --- [ost-startStop-1] o.s.b.w.s.ServletContextInitializerBeans : Created Filter initializer for bean 'hiddenHttpMethodFilter'; order=-10000, resource=class path resource [org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration.class]
2018-02-28 11:58:37.638 DEBUG 4323 --- [ost-startStop-1] o.s.b.w.s.ServletContextInitializerBeans : Created Filter initializer for bean 'httpPutFormContentFilter'; order=-9900, resource=class path resource [org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration.class]
2018-02-28 11:58:37.638 DEBUG 4323 --- [ost-startStop-1] o.s.b.w.s.ServletContextInitializerBeans : Created Filter initializer for bean 'requestContextFilter'; order=-105, resource=class path resource [org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter.class]
...

What if you define the Filter itself as a Bean?

It is OK to define the Filter itself as a bean, but I cannot specify the url-pattern or execution order. Even if you specify the @ Order annotation in the @ Bean method, it seems to be ignored (regardless of the value of @ Order, the value of order output to the log will be 2147483647).

    @Bean
    @Order(Integer.MIN_VALUE) //This value seems to be ignored (not sure if it's a spec)
    public HogeFilter hogeFilter() {
        return new HogeFilter();
    }

So let's use FilterRegistrationBean.

Reference material

Spring Boot Reference https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-embedded-container-servlets-filters-listeners-beans Javadoc https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/web/servlet/FilterRegistrationBean.html

Recommended Posts

Use Servlet filter in Spring Boot [Spring Boot 1.x, 2.x compatible]
Use DynamoDB query method in Spring Boot
DI SessionScope Bean in Spring Boot 2 Filter
Use cache with EhCashe 2.x with Spring Boot
Spring Boot Servlet mapping
Use Interceptor in Spring
SSO with GitHub OAuth in Spring Boot 1.5.x environment
How to use CommandLineRunner in Spring Batch of Spring Boot
Set context-param in Spring Boot
Spring Boot + Springfox springfox-boot-starter 3.0.0 Use
Use Spring JDBC with Spring Boot
Major changes in Spring Boot 1.5
NoHttpResponseException in Spring Boot + WireMock
Spring Boot 1.x will reach EOL in the next year.
How to call and use API in Java (Spring Boot)
Use thymeleaf3 with parent without specifying spring-boot-starter-parent in Spring Boot
Use @ControllerAdvice, @ExceptionHandler, HandlerExceptionResolver in Spring Boot to catch exceptions
Login with HttpServletRequest # login in Spring Security of Servlet 3.x environment
How to use Lombok in Spring
Spring Boot 2.x context path settings
Use Basic Authentication with Spring Boot
Spring Boot Hello World in Eclipse
Spring Boot application development in Eclipse
Write test code in Spring Boot
Cassandra x Spring Boot struggle record
Implement REST API in Spring Boot
What is @Autowired in Spring boot?
Use DBUnit for Spring Boot test
Implement Spring Boot application in Gradle
How to use ModelMapper (Spring boot)
Beginning with Spring Boot 0. Use Spring CLI
Thymeleaf usage notes in Spring Boot
Launch (old) Spring Boot project in IntelliJ
Build Spring Boot + Docker image in Gradle
Static file access priority in Spring boot
Output Spring Boot log in json format
Local file download memorandum in Spring Boot
Create Java Spring Boot project in IntelliJ
Loosen Thymeleaf syntax checking in Spring Boot
[Practice! ] Display Hello World in Spring Boot
How Dispatcher servlet works in Spring MVC
I want to use @Autowired in Servlet
Change session timeout time in Spring Boot
SameSite cookie in Spring Boot (Spring Web MVC + Tomcat)
Test controller with Mock MVC in Spring Boot
Asynchronous processing with regular execution in Spring Boot
Use Thymeleaf text template mode from Spring Boot
Run a Spring Boot project in VS Code
How to use built-in h2db with spring boot
How to use Spring Boot session attributes (@SessionAttributes)
How to add a classpath in Spring Boot
Java tips-Create a Spring Boot project in Gradle
[Java] Hello World with Java 14 x Spring Boot 2.3 x JUnit 5 ~
How to bind to property file in Spring Boot
[JAVA] [Spring] [MyBatis] Use IN () with SQL Builder
Annotations used in Spring Boot task management tool
LINE Bot x Java (Spring Boot) construction procedure
View the Gradle task in the Spring Boot project
Challenge Spring Boot
Spring Boot Form
Spring Boot Memorandum