Spring Boot – Servlet Filter
Last Updated :
26 Nov, 2023
Spring boot Servlet Filter is a component used to intercept & manipulate HTTP requests and responses. Servlet filters help in performing pre-processing & post-processing tasks such as:
- Logging and Auditing: Logging operations can be performed by the servlet filter logging the request and response which assists in debugging and troubleshooting.
- Authentication and Authorization: Authentication and Authorization refer to the process of providing access and checking if a user has certain privilege permissions to access a resource
- Caching: Caching is a mechanism that allows us to store data temporarily for faster access in the future. It can be done by caching response in servlet filters.
- Routing: Servlet filters can also be used for routing responses to different controllers giving us more control over handling requests
Example of Servlet Filter
Let us discuss some Real-Life examples to better understand the Spring Boot Servlet Filter.
1. Food Ordering: While ordering food on online platforms, a user may give specific cooking instructions like excluding onion or any other substance that a user may be allergic to.
So, this request made by the user will first go through a different procedure – Excluding onions while cooking their food. This same procedure will be applied to all the users who make similar requests. You can think of this procedure as a FILTER for these types of requests.
2. E-Commerce website: It offers bulky discounts when products are purchased in the given time span. So, all the requests made by clients will be applied to a filter of discounts during this time span!
Servlet Filter – Real-World Example
In the above diagrams, we are applying a servlet filter for all those requests with a time stamp between 12:00 and 13:00. If a request is made by a client anywhere all over the world in this time span, it will go through this filter and be given high discounts.
- All the requests made before or after this timestamp will be treated as normal requests and won’t go through a filter.
Spring boot is an extension of the Spring framework & has an inbuilt mechanism for implementing servlet filters easily by using @Component Annotation. Furthermore, if we have more than one filter in our application then we can set the order using @Order annotation to set the execution order of servlet filters.
Here’s the order of execution of the Servlet Filter :
Servlet Filter – Request
Now, while working with Custom Servlet filters, we will require the following classes and interfaces in our code in spring boot :
- Filter – Interface that our custom filter class must implement
- FilterRegistrationBean – This bean registers our Custom Servlet Filter with the spring context. This allows us to configure the servlet filter for our specific needs such as –
- URL Patterns
- Dispatcher type
- Invocation etc.
However, this one is optional in some cases
Types of Servlet Filters
There are mainly two types of servlet filters:
- Pre-Built Servlet Filter: Pre-built servlet Filters are a convenient and efficient way to implement a specific functionality such as
- authentication – Authentication Filter
- logging – CommonsRequestLoggingFilter
- authorization filter – FilterSecurityInterceptor
- These are some of the pre-built servlet filters provided by Spring Boot, that save us the time and effort of writing a customized filter.
- However, depending on our requirements we may need to implement a filter specific to our needs that’s where Custom Filters are.
- Custom Filters: Custom filters based on our specific needs can be implemented by implementing the Filter Interface.
In this article, we’ll be exploring how to build a custom servlet filter.
Step-By-Step Implementation
Step 1: Go to spring Initializr and create a configuration file with the following dependency :
Configuration File
Step 2: Extract the zip file, and go to your favorite IDE, we’ll use Intellij in this article
Step 3: Now create two packages – Filter and REST, and further two classes in them – MyFilter and ServletController (appropriately). Your final directory structure should look something like this:-
Directory Structure
Settings file for our Spring Boot Project i.e. pom.xml
XML
<? xml version = "1.0" encoding = "UTF-8" ?>
< modelVersion >4.0.0</ modelVersion >
< parent >
< groupId >org.springframework.boot</ groupId >
< artifactId >spring-boot-starter-parent</ artifactId >
< version >3.1.5</ version >
< relativePath />
</ parent >
< groupId >com.GeeksForGeeks</ groupId >
< artifactId >ServletFilterExample</ artifactId >
< version >0.0.1-SNAPSHOT</ version >
< name >ServletFilterExample</ name >
< description >Demo project for Spring Boot</ description >
< properties >
< java.version >17</ 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-starter-test</ artifactId >
< scope >test</ scope >
</ dependency >
</ dependencies >
< build >
< plugins >
< plugin >
< groupId >org.springframework.boot</ groupId >
< artifactId >spring-boot-maven-plugin</ artifactId >
</ plugin >
</ plugins >
</ build >
</ project >
|
Step 4: Implementing the Filter. Write the following business logic in the class – MyFilter.
Servlet Filter
In the following example, we’ve defined a custom filter. This custom Filter is annotated with @Component so that it can be recognized by spring context. And overrides the doFilter() method that takes 3 parameters –
- ServletRequest
- ServletResponse
- FilterChain
Java
import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import java.io.IOException;
import org.springframework.stereotype.Component;
@Component
public class MyFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest,
ServletResponse servletResponse,
FilterChain filterChain)
throws IOException, ServletException{
System.out.println( "This is a Servlet doFilter() Method !" );
System.out.println( "Remote Host : " + servletRequest.getRemoteHost());
System.out.println( "Remote Address : " + servletRequest.getRemoteAddr());
filterChain.doFilter(servletRequest,servletResponse);
}
}
|
Code Explanation:
- The doFilter() method is invoked for every request that comes to our controller.
- And we’ve simply printed the remote data in this method
- filterChain is a crucial component in this, we must call this method, or else our request will never reach the desired controller. This is important because this method will execute the next filter according to the specified order.
For example, if we’ve added 3 filters annotated with @Order Annotation, then they will be executed in order and chained by this method
Step 5: Create a simple REST API endpoint inside the REST package.
Rest Controller
We’ve defined a simple rest controller for demo purposes. By default, our Fitler can recognize any URL pattern so we don’t have to worry about mapping in this example. However, if we need the filter to be invoked only for specific URLs, then we need to specify that before which we will see in the next example.
Java
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping ( "/api" )
public class ServletController {
@GetMapping ( "/" )
public String hello(){
return "This is a sample API for testing Servlet Filter - Spring Boot!" ;
}
}
|
Output:
Web-Browser Output
Console Output:
Console Output
Other ways we can use servlet filters involve –
- For a category of URL Patterns
- Multiple servlet filters chained with @Order annotation and many more.
Servlet filters with a specific or group of URL Patterns
Servlet filters are by default configured to be executed for every URL pattern but they can also be applied only to a group of controllers, we can choose which controller/requests will be applied to a certain filter. For example, when a user is logging in, we can apply an authorization filter for /login endpoint.
We will require a FilterRegistrationBean to restrict a Servlet Filter to specific URL Patterns. Then inside it, we can specify the URL pattern it is to be applied to, and its order of execution and we can configure it in any way we want.
Java
@Bean
public FilterRegistrationBean<AuthorizationFilter> filterRegistrationBean() {
FilterRegistrationBean<AuthorizationFilter> registrationBean = new FilterRegistrationBean();
registrationBean.setFilter( new AuthorizationFilter());
registrationBean.addUrlPatterns( "/login/*" );
registrationBean.setOrder( 2 );
return registrationBean;
}
|
Multiple Servlet Filter Ordering
We can specify the order of execution of servlet filters in the Deployment Descriptor. However, in Spring Boot, we can do it in a much easier way by using @Order Annotation.
Java
@Order ( 1 )
@Component
public class AuthorizationFilter implements Filter {
}
@Order ( 2 )
@Component
public class LoggingFilter implements Filter {
}
@Order ( 3 )
@Component
public class DebugFilter implements Filter {
}
|
The above code demonstrates how the ordering of filters can be specified easily in Spring Boot using @Order Annotation.
- The AuthorizationFilter will execute first, then filterChain.doFilter() method will call the next filter that is, LoggingFilter, and so on until all the filters are executed in a chained fashion.
Order of Execution
Conclusion
Spring boot Servlet filter is a powerful tool to intercept and manipulate requests and responses. It helps in implementing various functionalities such as authentication, logging, debugging, etc.
- Spring Boot – Servlet Filter is easy to implement, the core interface required here is the filter interface.
- @Component and @Bean annotations help us implement Servlet Filters according to our specific needs.
- Filter Chaining and order of executions are a core mechanism that builds the foundation of servlets and help us perform pre and post-processing operations on requests and responses.
- Another real-world example – Let’s say a user is logging in to our application for the first time. Then, they will be offered a special discount for premium access. This premium access discount is given through a servlet filter noting the login count of the user.
Share your thoughts in the comments
Please Login to comment...