Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 18

Spring MVC Request Handling Architecture

Recommended resources

Introduction

Welcome to the first lesson in our module on building REST APIs. In our previous module, we finalized our tour of application setup by looking at Spring Profiles. You learned how to create distinct configuration sets for different environments (dev, prod, etc.) and activate them externally. This ensures that a single, packaged application can be deployed anywhere with the correct settings.

Now that we have a configured Spring Boot application ready to run, the next logical question is: what happens when an HTTP request arrives? How does the request from a user's browser or another microservice make its way to the specific line of code you've written to handle it?

This lesson addresses exactly that. We will explore the Spring MVC request handling architecture. Your goal is to understand the journey of an HTTP request through the framework's core components. We'll focus on the central player in this process: the DispatcherServlet. Given your background in system design, you'll find this is a classic application of established software patterns, which Spring uses to create a flexible and powerful web layer. Understanding this internal mechanism is the foundation for effectively building and debugging web endpoints, which we will start doing in the next lesson.


The Front Controller Pattern

Before we dive into Spring's specific classes, let's talk about the core design pattern at play: the Front Controller. In many web frameworks, instead of having multiple entry points for different URLs (which can lead to duplicated code for concerns like security and logging), all incoming requests are funneled through a single handler. This handler, the front controller, doesn't perform the business logic itself. Instead, it acts as a central dispatcher, inspecting the request and routing it to the appropriate component for actual processing.

To build some intuition for this pattern, watch the following video. It uses a simple analogy to explain the role of a front controller and how it delegates tasks.

Setting up Dispatcher Servlet | What is a Front Controller | Run first Spring MVC app | Deep Dive

This video from Selenium Express explains the front controller concept and introduces Spring's implementation, the DispatcherServlet. Focus on the conceptual explanation of how a central point receives all requests and dispatches them.

Watch from the beginning to 08:17. The video uses a family analogy to illustrate the front controller's responsibilities: it handles every request and knows which specialized 'controller' is the right one to handle a specific task.

As you saw, the front controller provides a single, centralized point of control for managing the request-response cycle. In Spring MVC, this role is filled by a servlet called the DispatcherServlet. In modern Spring Boot applications, this servlet is automatically configured to handle all incoming HTTP requests.


The Spring MVC Request Lifecycle

When a request arrives at the DispatcherServlet, it doesn't just magically find your code. It kicks off a well-defined workflow involving several key components that work together. Think of the DispatcherServlet as an orchestra conductor, directing a group of specialized musicians.

Here is a high-level diagram of the full request lifecycle. Don't worry about understanding every arrow just yet; we will break it down step-by-step.

Spring MVC Request Lifecycle
This diagram illustrates the step-by-step flow of a request within Spring MVC. The DispatcherServlet (1) is at the center, orchestrating interactions with other components like the HandlerMapping (2), HandlerAdapter (4), and the Controller (5) you will write.

The Cast of Characters

Before we trace the flow, let's meet the main components involved. These are the "musicians" in our orchestra, each with a specific job.

Demystifying Spring MVC Internals: A Deep Dive Into Annotations ...

The article 'Demystifying Spring MVC Internals' provides an excellent, technically deep overview of the framework. We'll use it to understand the core components and the request flow. First, let's get acquainted with the key classes.

Read the section titled '4.2 The Key Classes in Spring MVC'. This section lists the main components and their responsibilities. Pay close attention to DispatcherServlet, HandlerMapping, HandlerAdapter, and HttpMessageConverter.

To summarize the key players for building REST APIs:

  • DispatcherServlet: The Front Controller. It receives every request and orchestrates the entire process.
  • HandlerMapping: The "router." Its job is to inspect the incoming request (its URL, HTTP method, headers, etc.) and find the appropriate handler—typically, a method in one of your controller classes.
  • HandlerAdapter: The "executor." Once the HandlerMapping finds what method to call, the HandlerAdapter knows how to call it. It handles details like preparing method arguments.
  • HttpMessageConverter: The "translator." This component is responsible for serializing and deserializing data. For REST APIs, this most often means converting a Java object to a JSON string for the response, and converting an incoming JSON request body into a Java object.

The Request Handling Flow: A Step-by-Step Guide

Now, let's follow a request for GET /api/users/42 as it travels through this architecture. The following reading walks through this process in detail. We will break it down into the most critical steps.

Demystifying Spring MVC Internals: A Deep Dive Into Annotations ...

We will now read the core section of the 'Demystifying Spring MVC Internals' article, which details the request handling flow. This provides the technical depth behind the diagram we saw earlier.

Read the section titled '4.3 Request Handling Flow (Controller Method Call)'. As you read, focus on tracing the numbered steps I've outlined below, which correspond to the subsections in the article. You can skim the code snippets; focus on the explanatory text.

Let's dissect the journey based on that reading:

  1. Request Arrives at DispatcherServlet: An HTTP request hits the embedded server (e.g., Tomcat), which routes it to the DispatcherServlet because Spring Boot registers it to handle all paths (/). The DispatcherServlet's doDispatch() method is invoked.

  2. Finding the Handler (HandlerMapping): The DispatcherServlet iterates through its registered HandlerMapping beans to find a handler for the request. For modern Spring applications, the primary one is RequestMappingHandlerMapping. It maintains a routing table built at startup by scanning your code for annotations like @GetMapping, @PostMapping, etc. For our GET /api/users/42 request, it finds the specific controller method you wrote to handle that endpoint.

  3. Choosing the Adapter (HandlerAdapter): The DispatcherServlet now has the handler method but needs a component that knows how to execute it. It queries its registered HandlerAdapter beans. For methods annotated with @RequestMapping, it selects the RequestMappingHandlerAdapter.

  4. Invoking the Controller Method: This is where the RequestMappingHandlerAdapter does its most important work.

    • Argument Resolution: It inspects the signature of your controller method. If it sees parameters like @PathVariable Long id or @RequestBody UserDto user, it uses a chain of HandlerMethodArgumentResolver beans to extract those values from the request. For @RequestBody, it uses an HttpMessageConverter (like Jackson) to deserialize the JSON body into a Java object.
    • Method Invocation: Once all arguments are resolved, the adapter uses Java reflection to call your controller method with the prepared arguments. This is the point where your application's business logic begins to execute.
  5. Handling the Return Value: Your controller method returns a value (e.g., a UserDto object). The DispatcherServlet doesn't just send this object back.

    • It uses a chain of HandlerMethodReturnValueHandler beans to process the return value. For @RestController methods, this is typically the RequestResponseBodyMethodProcessor.
    • This handler, in turn, uses an HttpMessageConverter to serialize the return value (the UserDto object) into the desired response format, usually JSON. It writes this JSON string to the HTTP response body.
  6. Response Sent: The DispatcherServlet completes the response (setting headers, status codes, etc.), and the server sends it back to the client.


Visual Summary

The process involves many components, so a visual walkthrough can help solidify your understanding. The following video explains the same sequence of events we just covered.

Understanding Spring MVC Architecture | DispatcherServlet

This video from Java Guides provides another excellent, clear walkthrough of the Spring MVC architecture and the request lifecycle. It reinforces the steps we just discussed in a more visual format.

Watch the section from 05:54 to 08:53. This segment meticulously breaks down the 10-step request processing flow, which maps directly to the concepts we've covered.


Conclusion

In this lesson, you've peeled back the layers of Spring MVC to understand its core request handling architecture. This is not just abstract theory; knowing this flow is invaluable for debugging tricky issues related to request mapping, data binding, or response serialization.

Key Takeaways:

  • Spring MVC is designed around the Front Controller pattern, with the DispatcherServlet acting as the central entry point for all requests.
  • The DispatcherServlet orchestrates a workflow but delegates the actual work to specialized components.
  • HandlerMapping acts as a router, finding the correct controller method for a request based on annotations like @GetMapping.
  • HandlerAdapter is responsible for executing the found method, including resolving its arguments.
  • HttpMessageConverter is the key to REST APIs, handling the serialization (Java object to JSON) and deserialization (JSON to Java object) of request and response bodies.

You now have the foundational knowledge of what happens when a request comes in. In the next lesson, we will put this knowledge into practice by writing our first REST controller. You'll learn how to use @RestController, @GetMapping, and @PostMapping to define endpoints and begin building the API layer of our application.