Skip to content

What Is DispatcherServlet in Spring? The Core Component Every Boot Developer Needs to Understand

Problem

When I work with Spring Boot developers, I often see a pattern: they can create @Controller classes, add @GetMapping methods, and requests magically route correctly. Everything “just works.” But when something breaks—a 404 that shouldn’t exist, a filter not executing, or a custom configuration not applying—they have no idea what’s happening under the hood.

The core issue: Spring Boot developers often skip learning DispatcherServlet because the framework abstracts it away completely.

One developer on Reddit put it well: “If you start with Boot, just make sure to eventually learn the Spring MVC core concepts (like the DispatcherServlet, the Request Lifecycle, and Annotations), because when something breaks or performance drops, you’ll need to know how the underlying ‘engine’ actually works to fix it.”

I think of Spring Boot as Spring MVC with “auto-pilot” turned on. DispatcherServlet is part of understanding that underlying engine.

What DispatcherServlet Actually Is

DispatcherServlet is Spring MVC’s implementation of the Front Controller pattern—a single servlet that receives all HTTP requests and coordinates the entire request processing pipeline.

Think of it as the traffic controller at a busy intersection. Every request passes through it, and it directs each one to its destination.

+--------------------------------------------------+
| DispatcherServlet |
| (The Front Controller) |
+--------------------------------------------------+
| | |
v v v
+-----------+ +-----------+ +-----------+
|ControllerA| |ControllerB| |ControllerC|
+-----------+ +-----------+ +-----------+
| | |
v v v
/users /products /orders

Without DispatcherServlet, you’d need a separate servlet for each URL pattern. With it, you have one central point that:

  • Receives every HTTP request
  • Routes requests to the correct controller method
  • Handles view rendering
  • Manages the complete request-response lifecycle

How DispatcherServlet Processes Requests

When a request hits your Spring Boot application, here’s what happens:

HTTP Request (GET /users/123)
|
v
+------------------------+
| DispatcherServlet | <-- 1. Receives all requests
+------------------------+
|
v
+------------------------+
| HandlerMapping | <-- 2. Finds which controller method
+------------------------+ should handle this URL
|
v
+------------------------+
| HandlerAdapter | <-- 3. Invokes the controller method
+------------------------+
|
v
+------------------------+
| Controller Method | <-- 4. Your @GetMapping method executes
+------------------------+
|
v
+------------------------+
| ModelAndView | <-- 5. Returns data + view name
| or @ResponseBody | (or just data for REST APIs)
+------------------------+
|
v
+------------------------+
| ViewResolver | <-- 6. Finds the actual view template
+------------------------+ (if returning a view)
|
v
+------------------------+
| View | <-- 7. Renders the response
+------------------------+
|
v
HTTP Response (JSON or HTML)

Let me show you what this looks like in code. Here’s a simple controller:

UserController.java
@RestController
@RequestMapping("/api/users")
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
@GetMapping("/{id}")
public ResponseEntity<User> getUser(@PathVariable Long id) {
return userService.findById(id)
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
}

When a request comes to GET /api/users/123, DispatcherServlet:

  1. Receives the request
  2. Asks HandlerMapping: “Which method handles /api/users/{id}?”
  3. HandlerMapping returns the getUser method on UserController
  4. HandlerAdapter invokes that method with id = 123
  5. The method returns a ResponseEntity
  6. Since it’s @RestController, the response body is serialized to JSON

Why Boot Developers Need to Understand This

You might wonder: “If Spring Boot configures everything automatically, why do I need to know this?”

Here are scenarios where understanding DispatcherServlet is critical:

Debugging 404 Errors

Your controller looks correct, but requests return 404. Without understanding the HandlerMapping step, you’re guessing. The issue could be:

  • URL pattern mismatch
  • Component scanning not picking up your controller
  • Multiple HandlerMappings conflicting

Understanding Filter vs Interceptor Order

Request
|
v
+------------------+ Filters execute here
| Filter A | (Servlet level)
+------------------+
|
v
+------------------+
| Filter B |
+------------------+
|
v
+------------------------+
| DispatcherServlet | <-- Interceptors execute here
+------------------------+ (Spring MVC level)
|
v
+------------------+
| Interceptor 1 |
+------------------+
|
v
+------------------+
| Interceptor 2 |
+------------------+
|
v
Controller

Filters run before DispatcherServlet; Interceptors run after. This matters when you need to intercept requests at the right level.

Customizing Error Handling

When you create a @ControllerAdvice with @ExceptionHandler, it only catches exceptions from controllers. Exceptions thrown in filters won’t be caught. Why? Because filters execute before DispatcherServlet, so your controller advice never sees them.

Adding Custom Argument Resolvers

If you need to inject custom objects into controller methods:

CurrentUserArgumentResolver.java
public class CurrentUserArgumentResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.getParameterType().equals(User.class)
&& parameter.hasParameterAnnotation(CurrentUser.class);
}
@Override
public Object resolveArgument(MethodParameter parameter,
ModelAndViewContainer mavContainer,
NativeWebRequest webRequest,
WebDataBinderFactory binderFactory) {
// Extract user from request/session
return webRequest.getAttribute("user", RequestAttributes.SCOPE_REQUEST);
}
}

You register this with DispatcherServlet:

WebConfig.java
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(new CurrentUserArgumentResolver());
}
}

Multipart File Uploads

When configuring file upload limits, you’re configuring DispatcherServlet:

application.properties
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=10MB

These properties configure the MultipartResolver that DispatcherServlet uses.

Common Mistakes I See

MistakeWhy It’s WrongWhat to Do Instead
Thinking controllers receive requests directlyDispatcherServlet invokes themUnderstand the front controller pattern
Not knowing why filters run before interceptorsDifferent levels in the stackFilters are servlet-level, interceptors are MVC-level
Assuming Boot’s auto-configuration covers all scenariosSometimes you need to customizeLearn when and how to override defaults
Ignoring request lifecycle when debuggingEverything flows through DispatcherServletTrace requests through the pipeline
Not understanding @ControllerAdvice scopeOnly catches controller exceptionsKnow what exceptions it can and can’t catch

A Mental Model That Helps Me

I think of the Spring request handling like a company:

+------------------------+
| Client (Browser) | <-- Customer
+------------------------+
|
v
+------------------------+
| DispatcherServlet | <-- Receptionist (routes all requests)
+------------------------+
|
v
+------------------------+
| HandlerMapping | <-- Directory (finds the right department)
+------------------------+
|
v
+------------------------+
| Controller | <-- Department (handles specific requests)
+------------------------+
|
v
+------------------------+
| Service | <-- Specialist (does the actual work)
+------------------------+
|
v
+------------------------+
| Repository | <-- Archive (stores/retrieves data)
+------------------------+

The receptionist (DispatcherServlet) doesn’t do the work—they route requests to the right department. Each department (Controller) has specialists (Services) who do the actual work.

What Happens Without DispatcherServlet

In traditional Java web development without Spring MVC, you’d have something like this:

UserServlet.java (Without Spring MVC)
@WebServlet("/users/*")
public class UserServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String pathInfo = req.getPathInfo();
if (pathInfo == null || pathInfo.equals("/")) {
// Handle list users
List<User> users = userService.findAll();
resp.setContentType("application/json");
resp.getWriter().write(objectMapper.writeValueAsString(users));
} else {
// Handle get single user
Long id = Long.parseLong(pathInfo.substring(1));
User user = userService.findById(id);
if (user == null) {
resp.setStatus(404);
} else {
resp.setContentType("application/json");
resp.getWriter().write(objectMapper.writeValueAsString(user));
}
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// Handle create user
User user = objectMapper.readValue(req.getInputStream(), User.class);
userService.save(user);
resp.setStatus(201);
}
}

For every URL pattern, you need a separate servlet. No centralized routing, no consistent error handling, no view resolution. DispatcherServlet solves all of this.

Summary

In this post, I explained what DispatcherServlet is and why understanding it matters for Spring Boot developers.

The key points are:

  • DispatcherServlet is the front controller—a single entry point that receives all HTTP requests and coordinates the entire request processing pipeline
  • It routes requests through HandlerMapping to controllers, invokes methods via HandlerAdapter, and handles view resolution
  • Even though Boot auto-configures it, you need to understand it for debugging 404s, configuring filters vs interceptors, and customizing error handling
  • The request lifecycle is fixed: Request → DispatcherServlet → HandlerMapping → HandlerAdapter → Controller → Response
  • Without understanding DispatcherServlet, you’re flying blind when things break

I recommend learning DispatcherServlet even if you start with Spring Boot. The convenience of auto-configuration is great for productivity, but when something goes wrong, you need to understand the engine under the hood.

Final Words + More Resources

My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me

Here are also the most important links from this article along with some further resources that will help you in this scope:

Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!

Comments