Understanding Spring MVC Request Flow: Controllers, Handlers, and Adapters
This guide explains Spring MVC's request handling flow, detailing core components like DispatcherServlet, HandlerMapping, and HandlerAdapter, and demonstrates multiple controller definitions—including @RestController, HttpRequestHandler, Controller interface, and HttpServlet extensions—along with necessary configuration snippets.
Environment: Spring Boot 2.4.11
Overview
When a request arrives, Spring processes it through a series of core components.
Spring MVC processing flow
DispatcherServlet : entry point for all requests.
HandlerMapping : maps request URLs to handler methods.
HandlerAdapter : invokes the matched handler.
HandlerMethodArgumentResolver : resolves method arguments.
HandlerMethodReturnValueHandler : processes the return value.
ViewResolver : resolves a view when a ModelAndView is returned.
Typical @RestController definition
<code>@RestController
@RequestMapping("/users")
public class UsersController {
@GetMapping("/save")
public Object save(Users users) {
return users;
}
}
</code>This is the most common way to define a controller in Spring MVC.
Using HttpRequestHandler
<code>@Component("/others/chrh")
public class ControllerHttpRequestHandler implements HttpRequestHandler {
@Override
public void handleRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf8");
PrintWriter out = response.getWriter();
out.print("<h1>Hello, HttpRequestHandler</h1>");
out.close();
}
}
</code>Implementing
HttpRequestHandlerrequires a bean name that starts with “/”. BeanNameUrlHandlerMapping registers this bean with the URL as the key.
Implementing the Controller interface
<code>@Component("/others/custom")
public class CustomController implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
response.setContentType("text/html;charset=utf8");
PrintWriter out = response.getWriter();
out.print("<h1>Controller interface</h1>");
out.close();
return null;
}
}
</code>The bean name also starts with “/”, so BeanNameUrlHandlerMapping associates it.
Extending HttpServlet
<code>@Component("/others/servlet")
public class ControllerServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void service(HttpServletRequest req, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf8");
PrintWriter out = response.getWriter();
out.print("<h1>Hello HttpServlet</h1>");
out.close();
}
}
</code>To make this work you must register a
SimpleServletHandlerAdapter:
<code>@Configuration
public class WebConfig implements WebMvcConfigurer {
@Bean
public SimpleServletHandlerAdapter simpleServletHandlerAdapter() {
return new SimpleServletHandlerAdapter();
}
}
</code>You can also annotate the servlet with
@WebServlet("/others/servlet")and enable scanning with
@ServletComponentScanon a configuration class.
These are the main ways Spring MVC supports controller definitions. The next article will analyze the source code to show how a request selects a HandlerMapping and which HandlerAdapter processes it.
Spring Full-Stack Practical Cases
Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.