DEV Community

Nilanchal
Nilanchal

Posted on • Updated on • Originally published at stacktips.com

Using Interceptor in Spring Boot

Interceptors in Spring are used to intercept client requests or response before they are handled by the controller or before the response is sent back to the client.

Interceptors are part of the Spring Web MVC framework and provide a way to add pre/post-processing logic to your application's request-response lifecycle.

Learn interceptors with this full video tutorial here.

Realtime Use Cases of Interceptors

Some of the the common use cases for interceptors include tasks, such as:

  • Logging: Interceptors can be used to log HTTP requests and responses. This can be useful for debugging or tracking the performance of an application.
  • Security: Interceptors can be used to enforce security policies. For example, an interceptor could be used to check that a user is authenticated before allowing them to access a resource.
  • Caching: Interceptors can be used to cache HTTP requests and responses. This can improve the performance of an application by reducing the number of times that requests need to be made to the underlying resources.
  • Transformation: Interceptors can be used to transform HTTP requests and responses. For example, an interceptor could be used to convert JSON requests to XML responses.

Spring Request Life-Cycle

In a typical Spring Boot application flow, when the client sends an HTTP request to a specific endpoint(URL), the request is first received by the web server (e.g., Apache Tomcat or Jetty) and then forwarded to the Spring Boot application.

The Dispatcher Servlet is the entry point for incoming requests in the Spring Boot application. Once the DispatcherServlet receives the request, it consults the HandlerMapping.

The HandlerMapping is responsible for determining which controller should process the incoming request based on the URL mapping defined within your controller.

Interceptors in Spring Boot

Creating Interceptor in Spring Boot

To create an interceptor in Spring Boot, you typically create a class that implements the HandlerInterceptor interface.

The HandlerInterceptor interface has three methods:

  1. preHandle(): The preHandle() method is the most important method in the HandlerInterceptor. This method is executed before the actual controller method is called. It returns a boolean value indicating whether the request should continue to the controller or be stopped.

  2. postHandle(): This method is executed after the controller method is called but before the response is sent to the client. It allows you to modify the model and view before rendering the response. You can use this method to perform any tasks that you need to do after the request has been handled. For example, you could use the postHandle() method to add additional information to the response, or to log the response.

  3. afterCompletion(): This method is executed after the response has been sent to the client. This method is called even if an exception was thrown during the processing of the request. It's useful for cleanup or resource release tasks.

Interceptor to Check Basic Authentication

Let us now create an interceptor to perform the basic authentication check. This interceptor will be invoked only for a specific /products/new endpoint. It will do the basic authentication check before allowing access to the controller.

For this example, we will hardcode a username and password to verify the credentials passed by the user.

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

@Slf4j
public class BasicAuthInterceptor implements HandlerInterceptor {
    private static final String USERNAME = "admin";
    private static final String PASSWORD = "admin";

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("BasicAuthInterceptor::preHandle()");

        String authHeader = request.getHeader("Authorization");
        if (authHeader != null && authHeader.startsWith("Basic ")) {

            String base64Credentials = authHeader.substring("Basic ".length());
            byte[] decodedCredentials = Base64.getDecoder().decode(base64Credentials);
            String credentials = new String(decodedCredentials, StandardCharsets.UTF_8);

            String[] parts = credentials.split(":");
            String username = parts[0];
            String password = parts[1];

            if (USERNAME.equals(username) && PASSWORD.equals(password)) {
                return true;
            }
        }

        response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
        return false;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        log.info("BasicAuthInterceptor::postHandle()");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        log.info("BasicAuthInterceptor::afterCompletion()");
    }
}
Enter fullscreen mode Exit fullscreen mode

Registering Interceptor in Spring Boot

Once you have created your custom interceptor, you need to register it with the Spring Boot application using WebMvcConfigurer configuration:

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new BasicAuthInterceptor())
                .addPathPatterns("/products/new");
    }
}
Enter fullscreen mode Exit fullscreen mode

This tutorial is first published on stacktips.com. If you like this article, follow me on twitter @ask_nilan or checkout my Youtube channel @TheTechMojo for more such contents.

Happy learning!

Top comments (2)

Collapse
 
guilhrib profile image
Guilherme Ribeiro de Souza

Very nice content. Which version of Spring Framework did you use in this example?

Collapse
 
nilan profile image
Nilanchal

I have tested this on the latest spring boot version (3.1.2), but this remains the same for older spring, spring boot version as well.