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 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; //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 { }
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; @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; @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; @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; @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.