[Spring Boot] Spring Boot Filter

This page will introduce an example of Spring Boot filter.

Filters can be registered using the FilterRegistrationBean class or the @ Component annotation or the @ ServletComponentScan annotation.

FilterRegistrationBean registers Filter as a Spring Bean, which provides methods such as adding URL mapping and setting Filter order.

When we register a Filter with Spring @Component, we can use the Spring @Order annotation to set the order of filters, but in this case, there is no way to change the default URL mapping relationship.

When we register the Filter with @ ServletComponentScan, our Filter must use @ WebFilter annotation. We can use its urlPatterns property to add URL mapping, but in this case, we cannot set the order of filters.

@ServletComponentScan works only when using an embedded server. On this page, we will provide a complete example of Spring Boot filter, including filter, Servlet and Spring controller.

1. Example tool version

  1. Java 9
  2. Spring 5.0.7.RELEASE
  3. Spring Boot 2.0.3.RELEASE
  4. Maven 3.5.2
  5. Eclipse Oxygen

2. pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.concretepage</groupId>
	<artifactId>spring-boot-app</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>
	<name>spring-boot-app</name>
	<description>Spring Boot Application</description>

	<parent>
	   <groupId>org.springframework.boot</groupId>
	   <artifactId>spring-boot-starter-parent</artifactId>
	   <version>2.0.3.RELEASE</version>
	   <relativePath/>
	</parent>
	<properties>
	   <java.version>9</java.version>
	</properties>
	<dependencies>
	   <dependency>
	      <groupId>org.springframework.boot</groupId>
	      <artifactId>spring-boot-starter-web</artifactId>
	   </dependency>	
           <dependency>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-devtools</artifactId>
              <optional>true</optional>
           </dependency>
	</dependencies> 
	<build>
	   <plugins>
	      <plugin>
	  	 <groupId>org.springframework.boot</groupId>
	 	 <artifactId>spring-boot-maven-plugin</artifactId>
	      </plugin>
	   </plugins>
	</build>
</project> 

3. Register the filter with FilterRegistrationBean

The FilterRegistrationBean registers the filter in the Servlet 3.0 + container.

FilterRegistrationBean registers a filter as a Spring Bean.

Some ways to find it.

setFilter(): sets the filter object.

addUrlPatterns(): add filtered URL mappings.

setOrder(): sets the filtering order.

Find JavaConfig to register the ABCFilter and XYZFilter classes.

WebConfig.java

@Configuration
public class WebConfig {
   //Register ABCFilter 	
   @Bean
   public FilterRegistrationBean<ABCFilter> abcFilter() {
	   FilterRegistrationBean<ABCFilter> filterRegBean = new FilterRegistrationBean<>();
	   filterRegBean.setFilter(new ABCFilter());
	   filterRegBean.addUrlPatterns("/app/*");
	   filterRegBean.setOrder(Ordered.LOWEST_PRECEDENCE -1);
	   return filterRegBean;
   }
   //Register XYZFilter   
   @Bean
   public FilterRegistrationBean<XYZFilter> xyzFilter() {
	   FilterRegistrationBean<XYZFilter> filterRegBean = new FilterRegistrationBean<>();
	   filterRegBean.setFilter(new XYZFilter());
	   filterRegBean.addUrlPatterns("/app/*");	
	   filterRegBean.setOrder(Ordered.LOWEST_PRECEDENCE -2);
	   return filterRegBean;
   }   
   ------
} 

3.1 filtering URL mode

We can use the addUrlPatterns() or setUrlPatterns() methods of FilterRegistrationBean to add a filtered URL pattern.

Suppose we want to use addUrlPatterns() to define the URL patterns as / app1 / * and / app2 / *, which can be implemented as follows.

filterRegBean.addUrlPatterns("/app1/*", "/app2/*"); 

If we use setUrlPatterns(), its implementation is as follows.

filterRegBean.setUrlPatterns(Arrays.asList("/app1/*", "/app2/*")); 

3.2 filter execution sequence

When we register filters using FilterRegistrationBean, we can use its setOrder() method to set the order of the filters. Find code snippets.

filterRegBean.setOrder(Ordered.LOWEST_PRECEDENCE); 

Ordered.HIGHEST_ Precidence: This is the highest priority.
Ordered.LOWEST_ Precidence: This is the lowest priority.

The lower the sequence number, the higher the priority. Find sample priorities.

Example 1

Ordered.LOWEST_PRECEDENCE -2 > Ordered.LOWEST_PRECEDENCE -1 

Example 2

Ordered.HIGHEST_PRECEDENCE +1 > Ordered.HIGHEST_PRECEDENCE +2 

In general, it is safe to let the filter not sort.

Spring boot provides them with a default order, usually Ordered.LOWEST_PRECEDENCE.

If we want to run our custom filter before or after any built-in filter (such as Spring security filter), we need to use FilterRegistrationBean to sort.

This means that if we want to run our custom filter after the Spring security filter, we need to create our own FilterRegistrationBean for the Spring security filter and specify the order.

4. Register the filter with @ Component and @ Order

We can register a filter with @ Component and set the Order with @ Order.

Create a filter that implements Java Filter and annotate it with Spring's @ Component, as shown below.

ABCFilter.java

@Order(Ordered.LOWEST_PRECEDENCE -1)
@Component
public class ABCFilter implements Filter {
  ------
} 

XYZFilter.java

@Order(Ordered.LOWEST_PRECEDENCE -2)
@Component
public class XYZFilter implements Filter {
  ------
} 

Filtering sequence
When we register the filter with @ Component, we can use Spring's @ Order annotation to set the filter Order to

@Order(Ordered.LOWEST_PRECEDENCE)

The filtering URL mode cannot be set with @ Component

The default filter URL pattern is "/ *". If we register the filter with the @ Component annotation, we cannot change it. If we want the URL mapping of the filter, we should register the filter using the filter registration bean.

5. Register the filter using @ ServletComponentScan and @ WebFilter

To register a filter in Spring Boot, we can use @ ServletComponentScan. The filter should be annotated with @ WebFilter annotation.

We need to use @ ServletComponentScan with @ Configuration or @ SpringBootApplication annotations.

@ ServletComponentScan in Spring Boot will scan servlets annotated with @ WebServlet, filters annotated with @ WebFilter and listeners annotated with @ WebListener, which is only true when using embedded Web server.

Suppose we have two filters annotated with @ WebFilter, as follows.

ABCFilter.java

@WebFilter(urlPatterns="/app/*")
public class ABCFilter implements Filter {
  ------
} 

XYZFilter.java

@WebFilter(urlPatterns="/app/*")
public class XYZFilter implements Filter {
  ------
} 

Now use the main class of SpringBootAppStarter.java and @ ServletComponentScan to scan the above filters.

SpringBootAppStarter.java

package com.concretepage;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;

@ServletComponentScan
@SpringBootApplication
public class SpringBootAppStarter {
    public static void main(String[] args) {
        SpringApplication.run(SpringBootAppStarter.class, args);
    }
} 

Filter URL mode

The annotation @ WebFilter has the attribute urlPatterns to map URLs, as shown below.

@WebFilter(urlPatterns= {"/app1/*", "/app2/*"})
public class ABCFilter implements Filter {
   ------
} 

The filtering order cannot be set with @ WebFilter
When we register filters with @ WebFilter, we cannot sort them in Spring Boot@ WebFilter does not provide any properties to set the order.

We can't use Spring's @ Order annotation either, because Spring doesn't recognize the class annotated by @ WebFilter as a Spring Bean.

@WebFilter is a Java annotation, not a Spring annotation.

If we want to set the order, we should register our filters using the FilterRegistrationBean.

6. Complete examples. Spring Boot filter mapping using FilterRegistrationBean

We will provide complete examples of Spring Boot filters and FilterRegistrationBean classes here.

We will create two filters, two servlets, and a Spring controller method in our demo.

We will register filters in JavaConfig using FilterRegistrationBean and register Servlets using the ServletRegistrationBean class. Now look at the complete example.

Locate the project structure for the demo application.

Now find the Java file.

ABCFilter.java

package com.concretepage.filters;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

public class ABCFilter implements Filter {
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
	}
	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		HttpServletRequest req = (HttpServletRequest) request;
		System.out.println("Inside ABCFilter: "+ req.getRequestURI());
		chain.doFilter(request, response);
	}
	@Override
	public void destroy() {
	}
} 

XYZFilter.java

package com.concretepage.filters;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

public class XYZFilter implements Filter {
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
	}
	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		HttpServletRequest req = (HttpServletRequest) request;
		System.out.println("Inside XYZFilter: "+ req.getRequestURI());
		chain.doFilter(request, response);
	}
	@Override
	public void destroy() {
	}
} 

HelloCountryServlet.java

package com.concretepage.servlets;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class HelloCountryServlet extends HttpServlet   {
	private static final long serialVersionUID = 1L;
	public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException{
	    doGet(request,response);
	}
        public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
            response.setContentType("text/html");
            PrintWriter out = response.getWriter();
	    out.println("<h3>Hello India!</h3>");	
	}
} 

HelloStateServlet.java

package com.concretepage.servlets;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class HelloStateServlet extends HttpServlet   {
	private static final long serialVersionUID = 1L;
	public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException{
	   doGet(request,response);
	}
        public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
           response.setContentType("text/html");
           PrintWriter out = response.getWriter();
	   out.println("<h3>Hello Uttar Pradesh!</h3>");	
	}
} 

WebConfig.java

package com.concretepage;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import com.concretepage.filters.ABCFilter;
import com.concretepage.filters.XYZFilter;
import com.concretepage.servlets.HelloCountryServlet;
import com.concretepage.servlets.HelloStateServlet;

@Configuration
public class WebConfig {
   //Register ABCFilter 	
   @Bean
   public FilterRegistrationBean<ABCFilter> abcFilter() {
	   FilterRegistrationBean<ABCFilter> filterRegBean = new FilterRegistrationBean<>();
	   filterRegBean.setFilter(new ABCFilter());
	   filterRegBean.addUrlPatterns("/app/*");
	   filterRegBean.setOrder(Ordered.LOWEST_PRECEDENCE -1);
	   return filterRegBean;
   }
   //Register XYZFilter   
   @Bean
   public FilterRegistrationBean<XYZFilter> xyzFilter() {
	   FilterRegistrationBean<XYZFilter> filterRegBean = new FilterRegistrationBean<>();
	   filterRegBean.setFilter(new XYZFilter());
	   filterRegBean.addUrlPatterns("/app/*");	
	   filterRegBean.setOrder(Ordered.LOWEST_PRECEDENCE -2);
	   return filterRegBean;
   }   
   
   //Register HelloCountryServlet   
   @Bean	
   public ServletRegistrationBean<HelloCountryServlet> countryServlet() {
	   ServletRegistrationBean<HelloCountryServlet> servRegBean = new ServletRegistrationBean<>();
	   servRegBean.setServlet(new HelloCountryServlet());
	   servRegBean.addUrlMappings("/app/country/*");
	   servRegBean.setLoadOnStartup(1);
	   return servRegBean;
   }
   //Register HelloStateServlet   
   @Bean	
   public ServletRegistrationBean<HelloStateServlet> stateServlet() {
	   ServletRegistrationBean<HelloStateServlet> servRegBean = new ServletRegistrationBean<>();
	   servRegBean.setServlet(new HelloStateServlet());
	   servRegBean.addUrlMappings("/app/state/*");
	   servRegBean.setLoadOnStartup(1);
	   return servRegBean;
   }   
} 

HelloWorldController.java

package com.concretepage.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloWorldController {     
	
    @RequestMapping("/app/world")
    public String helloMsg() {
    	String msg = "Hello World!";
        return msg;
    }
} 

SpringBootAppStarter.java

package com.concretepage;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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

7. Test application

We can run our Spring Boot application in the following ways.

7.1 using Maven command

Download the source code of the project. Use the command prompt to go to the root folder of the project and run the command.

mvn spring-boot:run 

The Tomcat server will be started.

7.2 using Eclipse

Use the download link at the end of the article to download the source code of the project. Import the project into eclipse. Using the command prompt, go to the root folder of the project and run.

mvn clean eclipse:eclipse 

Then refresh the project in eclipse. Click Run as - > java application to run the main class SpringBootAppStarter. The Tomcat server will be started.

7.3 using executable jars

Using the command prompt, go to the root folder of the project and run the command.

mvn clean package

We will get the executable JAR spring-boot-app-0.0.1-SNAPSHOT.jar in the target folder. Run the JAR as follows

java -jar target/spring-boot-app-0.0.1-SNAPSHOT.jar 

The Tomcat server will be started.

Now we are ready to test the application. Run the following URL.

http://localhost:8080/app/country 

We will get the following output from the console.

output

Inside XYZFilter: /app/country
Inside ABCFilter: /app/country 

Run the following URL.

http://localhost:8080/app/state 

output

Inside XYZFilter: /app/state
Inside ABCFilter: /app/state 

Run the following URL.

http://localhost:8080/app/world 

output

Inside XYZFilter: /app/world
Inside ABCFilter: /app/world 

reference

[1]Spring Boot Reference Guide
[2]FilterRegistrationBean
[3]@ServletComponentScan
[4]Spring Boot Servlet Mapping
[5]Filter installed ahead of spring security filters
[6]@WebFilter and @Order
[7]Spring Boot Filter

Source download

[1]Register Filter with FilterRegistrationBean
[2]Register Filter with @Component and @Order
[3]Register Filter with @ServletComponentScan and @WebFilter

Tags: Java Spring Spring Boot filter

Posted on Fri, 24 Sep 2021 03:22:30 -0400 by grail