Back to: Spring Boot Tutorials
Spring Boot Interceptor with Examples
In this article, I am going to discuss Spring Boot Interceptor with Examples. Please read our previous article where we discussed Spring Boot Exception Handling.
What is a Spring Boot Interceptor?
An interceptor is a piece of code that executes before an action. In Spring Boot, the interceptor can execute in three situations:
- Before sending a request to the controller: Normally when a request is received, it is sent to the controller directly. When the interceptor is implemented, a request will be sent to the interceptor. If the interceptor returns true, the request may then be sent to the controller. This helps us to validate data before it is sent to the controller. This is done using a preHandle() method.
- Before sending a response to the client: When a request is handled, a response needs to be sent to the client. Interceptor executes before this response is sent. This type of interceptor does not have a return type. This is done using a postHandle() method.
- After sending the response to the client: When the response is sent to the client, this interceptor will execute. This is done using the afterCompletion() method.
How to Add Interceptors in Spring Boot?
To add interceptors to Spring Boot, two classes are required: one to place the interceptor code and another one to configure the interceptors. Let us use the fruit project from the previous exercise.
Step 1: Create the interceptor code file. Create a file called in FruitServiceInterceptor.java file in the src/main/java/com/dotnet/restful directory.
Step 2: Import the following packages into the class:

Step 3: Modify the code as follows:

We have performed the following modifications:
- Added @Component annotation to FruitServiceInterceptor class.
- Implemented HandlerInterceptor interface in FruitServiceInterceptor class.
- Added function prototypes for preHandle(), postHandle(), and afterCompletion() functions.
Step 3: Add interceptor code. Although more complex code can be added to interceptors, we shall add simple print statements just to let us know that the interceptors are executing.

Step 4: Create an interceptor configuration file. Create a file called in FruitServiceInterceptorAppConfig.java file in the src/main/java/com/dotnet/restful directory.
Step 5: Import the following packages into the class:

Step 6: Modify the code as follows:

We have performed the following modifications:
- Added @Component annotation to FruitServiceInterceptorAppConfig class.
- Implemented WebMvcConfigurer interface in FruitServiceInterceptorAppConfig class.
- Added code to newly defined interceptors to Interceptor Registry.
Step 7: Execute the application. Ensure that compilation is successful.

Step 8: Open Postman and send a GET request to the server. It must be successful and the output must be displayed in Postman. Meanwhile, our print statements (in the interceptors) shall execute:

Congratulations! You have now learned how to add interceptors to Spring Boot!
The Complete Example Code
Fruits.java – The POJO Class
package com.dotnet.restful;
public String getId() {return id;}
public void setId(String id) {this.id = id;}
public String getName() {return name;}
public void setName(String name) {this.name = name;}
public Fruits (String nid, String nname)
package com.dotnet.restful;
public class Fruits {
private String id;
private String name;
public String getId() {return id;}
public void setId(String id) {this.id = id;}
public String getName() {return name;}
public void setName(String name) {this.name = name;}
public Fruits (String nid, String nname)
{
id = nid;
name = nname;
}
}
package com.dotnet.restful;
public class Fruits {
private String id;
private String name;
public String getId() {return id;}
public void setId(String id) {this.id = id;}
public String getName() {return name;}
public void setName(String name) {this.name = name;}
public Fruits (String nid, String nname)
{
id = nid;
name = nname;
}
}
FruitServiceController.java – The Class Providing the RESTful Services
package com.dotnet.restful;
import java.util.HashMap;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
public class FruitServiceController {
private static Map<String, Fruits> productRepo = new HashMap<>();
Fruits apple = new Fruits("1","Apple");
productRepo.put(apple.getId(), apple);
Fruits banana = new Fruits("2","Banana");
productRepo.put(banana.getId(), banana);
Fruits chiku = new Fruits("3","Chiku");
productRepo.put(chiku.getId(), chiku);
Fruits dragon = new Fruits("4","Dragon Fruit");
productRepo.put(dragon.getId(), dragon);
@RequestMapping(value = "/products/{id}", method = RequestMethod.DELETE)
public ResponseEntity<Object> delete(@PathVariable("id") String id)
if (!productRepo.containsKey(id)) throw new FruitNotFoundException();
return new ResponseEntity<>("Fruit is deleted!", HttpStatus.OK);
@RequestMapping(value = "/products/{id}", method = RequestMethod.PUT)
public ResponseEntity<Object> updateProduct(@PathVariable("id") String id, @RequestBody Fruits product)
if (!productRepo.containsKey(id)) throw new FruitNotFoundException();
productRepo.put(id, product);
return new ResponseEntity<>("Fruit is updated!", HttpStatus.OK);
@RequestMapping(value = "/products", method = RequestMethod.POST)
public ResponseEntity<Object> createProduct(@RequestBody Fruits product) {
productRepo.put(product.getId(), product);
return new ResponseEntity<>("Fruit is created!", HttpStatus.CREATED);
@RequestMapping(value = "/products")
public ResponseEntity<Object> getProduct() {
return new ResponseEntity<>(productRepo.values(), HttpStatus.OK);
package com.dotnet.restful;
//Map classes
import java.util.HashMap;
import java.util.Map;
//Required web classes
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class FruitServiceController {
private static Map<String, Fruits> productRepo = new HashMap<>();
static {
Fruits apple = new Fruits("1","Apple");
productRepo.put(apple.getId(), apple);
Fruits banana = new Fruits("2","Banana");
productRepo.put(banana.getId(), banana);
Fruits chiku = new Fruits("3","Chiku");
productRepo.put(chiku.getId(), chiku);
Fruits dragon = new Fruits("4","Dragon Fruit");
productRepo.put(dragon.getId(), dragon);
}
@RequestMapping(value = "/products/{id}", method = RequestMethod.DELETE)
public ResponseEntity<Object> delete(@PathVariable("id") String id)
{
if (!productRepo.containsKey(id)) throw new FruitNotFoundException();
productRepo.remove(id);
return new ResponseEntity<>("Fruit is deleted!", HttpStatus.OK);
}
@RequestMapping(value = "/products/{id}", method = RequestMethod.PUT)
public ResponseEntity<Object> updateProduct(@PathVariable("id") String id, @RequestBody Fruits product)
{
if (!productRepo.containsKey(id)) throw new FruitNotFoundException();
productRepo.remove(id);
product.setId(id);
productRepo.put(id, product);
return new ResponseEntity<>("Fruit is updated!", HttpStatus.OK);
}
@RequestMapping(value = "/products", method = RequestMethod.POST)
public ResponseEntity<Object> createProduct(@RequestBody Fruits product) {
productRepo.put(product.getId(), product);
return new ResponseEntity<>("Fruit is created!", HttpStatus.CREATED);
}
@RequestMapping(value = "/products")
public ResponseEntity<Object> getProduct() {
return new ResponseEntity<>(productRepo.values(), HttpStatus.OK);
}
}
package com.dotnet.restful;
//Map classes
import java.util.HashMap;
import java.util.Map;
//Required web classes
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class FruitServiceController {
private static Map<String, Fruits> productRepo = new HashMap<>();
static {
Fruits apple = new Fruits("1","Apple");
productRepo.put(apple.getId(), apple);
Fruits banana = new Fruits("2","Banana");
productRepo.put(banana.getId(), banana);
Fruits chiku = new Fruits("3","Chiku");
productRepo.put(chiku.getId(), chiku);
Fruits dragon = new Fruits("4","Dragon Fruit");
productRepo.put(dragon.getId(), dragon);
}
@RequestMapping(value = "/products/{id}", method = RequestMethod.DELETE)
public ResponseEntity<Object> delete(@PathVariable("id") String id)
{
if (!productRepo.containsKey(id)) throw new FruitNotFoundException();
productRepo.remove(id);
return new ResponseEntity<>("Fruit is deleted!", HttpStatus.OK);
}
@RequestMapping(value = "/products/{id}", method = RequestMethod.PUT)
public ResponseEntity<Object> updateProduct(@PathVariable("id") String id, @RequestBody Fruits product)
{
if (!productRepo.containsKey(id)) throw new FruitNotFoundException();
productRepo.remove(id);
product.setId(id);
productRepo.put(id, product);
return new ResponseEntity<>("Fruit is updated!", HttpStatus.OK);
}
@RequestMapping(value = "/products", method = RequestMethod.POST)
public ResponseEntity<Object> createProduct(@RequestBody Fruits product) {
productRepo.put(product.getId(), product);
return new ResponseEntity<>("Fruit is created!", HttpStatus.CREATED);
}
@RequestMapping(value = "/products")
public ResponseEntity<Object> getProduct() {
return new ResponseEntity<>(productRepo.values(), HttpStatus.OK);
}
}
FruitNotFoundException.java – The class defining the exception
package com.dotnet.restful;
public class FruitNotFoundException extends RuntimeException
package com.dotnet.restful;
public class FruitNotFoundException extends RuntimeException
{
}
package com.dotnet.restful;
public class FruitNotFoundException extends RuntimeException
{
}
FruitExceptionController.java – The exception controller class
package com.dotnet.restful;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
public class FruitExceptionController
@ExceptionHandler(value = FruitNotFoundException.class)
public ResponseEntity<Object> exception (FruitNotFoundException e)
return new ResponseEntity<>("Fruit not found!", HttpStatus.NOT_FOUND);
package com.dotnet.restful;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
@ControllerAdvice
public class FruitExceptionController
{
@ExceptionHandler(value = FruitNotFoundException.class)
public ResponseEntity<Object> exception (FruitNotFoundException e)
{
return new ResponseEntity<>("Fruit not found!", HttpStatus.NOT_FOUND);
}
}
package com.dotnet.restful;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
@ControllerAdvice
public class FruitExceptionController
{
@ExceptionHandler(value = FruitNotFoundException.class)
public ResponseEntity<Object> exception (FruitNotFoundException e)
{
return new ResponseEntity<>("Fruit not found!", HttpStatus.NOT_FOUND);
}
}
RestfulApplication.java – The application containing the main() function
package com.dotnet.restful;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
public class RestfulApplication {
public static void main(String[] args) {
SpringApplication.run(RestfulApplication.class, args);
package com.dotnet.restful;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class RestfulApplication {
public static void main(String[] args) {
SpringApplication.run(RestfulApplication.class, args);
}
}
package com.dotnet.restful;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class RestfulApplication {
public static void main(String[] args) {
SpringApplication.run(RestfulApplication.class, args);
}
}
FruitServiceInterceptor.java
package com.dotnet.restful;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
public class FruitServiceInterceptor implements HandlerInterceptor
public boolean preHandle (HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception
System.out.println("In the preHandle() method: Before sending request to controller.");
public void postHandle (HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception
System.out.println("In the postHandle() method: Before sending response to client.");
public void afterCompletion (HttpServletRequest request, HttpServletResponse response, Object handler, Exception exception) throws Exception
System.out.println("In the afterCompletion() method: After sending response to client.");
package com.dotnet.restful;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
@Component
public class FruitServiceInterceptor implements HandlerInterceptor
{
@Override
public boolean preHandle (HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception
{
System.out.println("In the preHandle() method: Before sending request to controller.");
return true;
}
@Override
public void postHandle (HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception
{
System.out.println("In the postHandle() method: Before sending response to client.");
}
@Override
public void afterCompletion (HttpServletRequest request, HttpServletResponse response, Object handler, Exception exception) throws Exception
{
System.out.println("In the afterCompletion() method: After sending response to client.");
}
}
package com.dotnet.restful;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
@Component
public class FruitServiceInterceptor implements HandlerInterceptor
{
@Override
public boolean preHandle (HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception
{
System.out.println("In the preHandle() method: Before sending request to controller.");
return true;
}
@Override
public void postHandle (HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception
{
System.out.println("In the postHandle() method: Before sending response to client.");
}
@Override
public void afterCompletion (HttpServletRequest request, HttpServletResponse response, Object handler, Exception exception) throws Exception
{
System.out.println("In the afterCompletion() method: After sending response to client.");
}
}
FruitServiceInterceptorAppConfig.java
package com.dotnet.restful;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
public class FruitServiceInterceptorAppConfig implements WebMvcConfigurer
FruitServiceInterceptor fruitServiceInterceptor;
public void addInterceptors (InterceptorRegistry registry)
registry.addInterceptor(fruitServiceInterceptor);
package com.dotnet.restful;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Component
public class FruitServiceInterceptorAppConfig implements WebMvcConfigurer
{
@Autowired
FruitServiceInterceptor fruitServiceInterceptor;
@Override
public void addInterceptors (InterceptorRegistry registry)
{
registry.addInterceptor(fruitServiceInterceptor);
}
}
package com.dotnet.restful;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Component
public class FruitServiceInterceptorAppConfig implements WebMvcConfigurer
{
@Autowired
FruitServiceInterceptor fruitServiceInterceptor;
@Override
public void addInterceptors (InterceptorRegistry registry)
{
registry.addInterceptor(fruitServiceInterceptor);
}
}
In the next article, I am going to discuss Spring Boot Servlet Filters. Here, in this article, I try to explain Spring Boot Interceptor with Examples. I hope you enjoy this Spring Boot Interceptor article.
About the Author: Pranaya Rout
Pranaya Rout has published more than 3,000 articles in his 11-year career. Pranaya Rout has very good experience with Microsoft Technologies, Including C#, VB, ASP.NET MVC, ASP.NET Web API, EF, EF Core, ADO.NET, LINQ, SQL Server, MYSQL, Oracle, ASP.NET Core, Cloud Computing, Microservices, Design Patterns and still learning new technologies.