spring framework - filter vs dispatcher servlet vs interceptor vs controller

Old note from 2022. May be outdated.

Hello everyone. In this article, we are going to look at Filter, Dispatcher Servlet, Interceptor, and Controller in the Spring framework. Understanding these components is a bit difficult initially for most Java developers as they sound similar. Each of these components has a specific purpose and knowing them well allows a developer to use them correctly. I have simplified the concepts with diagrams and examples.

Before reading this, please go through my article about Servlets to have a deep understanding of Servlets and its terminologies

What is a Filter?

As seen in the diagram above, Filters are part of the Servlet Container of the web server. It does not belong to any framework like Struts or Spring. Filters are used to manipulate the requests and the requests can even be blocked before it reaches the Servlet. It can also act on responses, and modify them before reaching the client

Spring Security uses filters for authentication and authorization. Spring Security can intercept all incoming and outgoing traffic and hence Spring Security can be used outside the Spring MVC framework.

Following are the list of the task we can perform with servlet filters:

  • Server-side logging.
  • Logging request parameter to log files.
  • Auditing
  • Server-side authentication and authorization.
  • Compression and decompression.
  • Encryption and decryption.
  • Server-side validation.

Spring MVC and Dispatcher Servlet?

Spring MVC is the most popular Java web framework based on the Model-View-Controller (MVC) design pattern. The core element of Spring MVC is the Dispatcher Servlet, which is the front controller that handles all requests and provides an entry point for all the requests inside the Spring framework. It is responsible for directing incoming HTTP requests to all of an application’s other handlers and controllers. It is fully integrated with the Spring IOC container and supports all the features of Spring.

Before the advent of Spring Boot, the Dispatcher Servlet was declared in the web.xml file as shown below

<web-app>  
  
    <servlet>  
        <servlet-name>example</servlet-name>  
        <servlet class> org.springframework.web.servlet  
               .DispatcherServlet  
        </servlet-class>  
        <load-on-startup>1</load-on-startup>  
    </servlet>  
  
    <servlet-mapping>  
        <servlet-name>test</servlet-name>  
        <url-pattern>.test</url-pattern>  
    </servlet-mapping>  
  
</web-app>

The DispatcherServlet is actual Servlet and it inherits from the HttpServlet base class. Spring Boot provides out-of-the-box support for Spring MVC without defining any configuration for Dispatcher Servlet.

Spring Boot provides the spring-boot-starter-web library for developing web applications using Spring MVC. Autoconfiguration is one of the important features of Spring Boot and using that, Spring boot registers and configures the DispatcherServlet automatically. Hence, we don’t need to register the DispatcherServlet manually in the web.xml file

By default, the spring-boot-starter-web starter configures DispatcherServlet to the URL pattern “/”. However, If we want, we can customize the URL pattern using server.servlet.* in the application.properties file as follows

server.servlet.context-path=/hello  
spring.mvc.servlet.path=/world

With the configuration above, DispatcherServlet is configured to handle the URL pattern /world and the root context path will be /hello. Thus, DispatcherServlet listens at http://localhost:8080/hello/world.

What is a Handler Interceptor?

HandlerInterceptors are part of the Spring MVC framework and they sit between the DispatcherServlet and the controllers. They are used to intercept the request before reaching the controller or before and after the view is rendered.

For example, we can use an interceptor to add a request header before sending the request to the controller and add the response header before sending the response to the client.

Handler Interceptors reduce duplication and allow for more fine-grained functionality such as:

  • Handling cross-cutting concerns such as application logging
  • Detailed authorization checks
  • Manipulating the Spring context or model

A Spring interceptor is a class that either extends the HandlerInterceptorAdapter class or implements the HandlerInterceptor interface.

The HandlerInterceptor contains three main methods:

  • prehandle() — called before the execution of the actual handler
  • postHandle() — called after the handler is executed
  • afterCompletion() — called after the complete request is finished and the view is generated

As seen in the above diagram, the preHandle method is called before the controller is invoked. After the controller class is executed, the postHandle method is executed. Once the view is rendered, the request and response are ready, then the afterCompletion method is executed.

What is a Controller?

In Spring Boot, the controller class is responsible for processing incoming REST API requests, preparing a model, and returning the view to be rendered as a response. The controller classes in Spring are annotated either by the @Controller or the @RestController annotation.

Controller

@Controller is used to mark classes as Spring MVC Controller. The @Controller annotation is a specialization of the generic stereotype @Component annotation. Using Controller annotation allows a class to be recognized as a Spring-managed component. We can return a view in Spring MVC using the Controller.

If we use Controller, we can have handlers that return the view and also handlers that return JSON response to the API. In this case, we need to use @ResponseBody on every handler method that needs to return a JSON response

In the below example, we have used Controller annotation and used 2 handler methods. The first method returns a view called hello.jsp or hello.html while the second one is a Rest API that returns the employee object in the form of JSON. This is because of the ResponseBody annotation that converts the Objects into JSON Response.

@Controller@RequestMapping("employees")
public class MVCController {  
 
  @GetMapping("/hello")  
  public String hello(Locale locale, Model model) {  
  		Date date = new Date();  
  		model.addAttribute("serverTime", formattedDate);  
  		return "hello";  
  }
  
  @GetMapping(value = "/{name}")  
  @ResponseBody
  public Employee getEmployeeByName(@PathVariable String name) {  
    return employee;  
  }
}

Hence with Controller annotation, we can use it both as an MVC Controller that returns a View and also a Rest Controller by using ResponseBody on the Handler Methods.

RestController

Nowadays, most of the applications use Rest APIs that are consumed by the front-end frameworks like Angular/React JS, etc which expect JSON response, unlike the older applications that expect a JSP page to be rendered. Hence we mostly use Rest Controller these days rather than using the MVC Controller.

RestController is used for making restful web services with the help of the @RestController annotation. This annotation is used at the class level and allows the class to handle the requests made by the client. The RestController allows you to handle all REST APIs such as GET, POST, Delete, and PUT requests.

@RestController = @Controller + @ResponseBody

In the below example, we see that the RestController is used instead of the Controller annotation. We don’t need to specify ResponseBody for the handler methods as it is already implemented inside the RestController annotation.

@RestController@RequestMapping("employees")
public class MVCController {
 
  @GetMapping(value = "/{name}")  
  public Employee getEmployeeByName(@PathVariable String name) {  
    return employee;  
  }
}

So if we want our controller to handle only the Rest APIs, then we can use RestController annotation.

In this article, we saw in detail the Filter, Dispatcher Servlet, Handler Interceptor, and Controller. The filter is a part of the Servlet Container while the other three components are a part of Spring Framework. The important takeaway from this article is the order of execution of these components. Filters are the first to get executed followed by Dispatcher Servlet, Handler Interceptor, and then finally the Controller.