Spring MVC is the Servlet-based web framework in Spring Framework. Its front
controller, DispatcherServlet, coordinates request mapping, argument
resolution, controller invocation, return-value handling, and exception
translation. Spring WebFlux uses a different reactive runtime and threading
model; the two frameworks must not be treated as interchangeable.
Bootstrap and Dispatch #
A non-Boot Servlet application can register a web application context and
dispatcher through WebApplicationInitializer:
public final class WebInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletContext) {
var context = new AnnotationConfigWebApplicationContext();
context.register(WebConfiguration.class);
var servlet = servletContext.addServlet(
"mvc", new DispatcherServlet(context));
servlet.setLoadOnStartup(1);
servlet.addMapping("/");
}
}Spring Boot performs equivalent registration for an MVC application. Mapping
the dispatcher to / lets the Servlet container retain special handling for
static resources and JSPs; /* also captures those dispatches.
For each request, the dispatcher:
- asks ordered
HandlerMappingimplementations for a handler and interceptors; - selects a
HandlerAdaptercapable of invoking that handler; - invokes pre-handle interceptors and the handler;
- processes the return value as a response body, view, async result, or another supported form; and
- runs exception resolvers and completion interceptors.
MVC strategy objects are beans in the dispatcher context. @EnableWebMvc
imports the standard configuration for a plain Spring application. In Spring
Boot, implement WebMvcConfigurer to extend Boot’s configuration instead of
adding @EnableWebMvc, which takes full control from auto-configuration.
Request Mapping, Binding, and Validation #
Annotated controllers map by path, HTTP method, parameters, headers, consumed media types, and produced media types:
@PostMapping(
path = "/orders",
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE)
ResponseEntity<OrderView> create(@Valid @RequestBody CreateOrder request) {
return ResponseEntity.status(HttpStatus.CREATED)
.body(orderService.create(request));
}HandlerMethodArgumentResolver implementations supply path variables, query
parameters, headers, cookies, principals, Servlet objects, model attributes,
and request bodies. Simple textual values use conversion and formatting.
@ModelAttribute binds named properties through WebDataBinder; define
allowed fields or use a dedicated command type because binding is an input
security boundary. @RequestBody instead delegates media decoding to an
HttpMessageConverter.
@Valid applies Jakarta Bean Validation, while @Validated can also select
validation groups. For model-attribute binding, a BindingResult parameter
immediately following the bound argument lets the controller inspect conversion
and validation errors. Without local handling, MVC translates validation
exceptions through its exception-resolution chain.
Return Values and Content Negotiation #
HandlerMethodReturnValueHandler implementations process values such as
ModelAndView, view names, ResponseEntity, ProblemDetail, and objects
annotated with @ResponseBody. Response-body values are encoded by an
HttpMessageConverter.
Content negotiation compares the handler’s produces conditions, the request’s
acceptable media types, and converter capabilities. A request body with an
unsupported Content-Type produces 415; no acceptable response representation
produces 406. Prefer the Accept header and explicit defaults over path-extension
negotiation.
Exception Resolution #
HandlerExceptionResolver turns failures into a model, status, or response.
The standard annotated configuration includes:
ExceptionHandlerExceptionResolverfor controller and@ControllerAdviceexception methods;ResponseStatusExceptionResolverfor@ResponseStatusandResponseStatusException; andDefaultHandlerExceptionResolverfor framework exceptions.
Central advice should map domain failures to stable status codes and a
consistent error schema. Spring Framework 6 introduced ProblemDetail and
ErrorResponse; Spring 6.1 documentation describes their problem-details
support in terms of RFC 9457, which superseded RFC 7807.
Threads, Async Requests, and Context #
Synchronous MVC handling runs on a Servlet-container thread. Blocking database or HTTP calls retain that thread until completion, so configure deadlines and capacity from the connector through every downstream dependency.
A controller can return Callable, DeferredResult, or WebAsyncTask.
MVC starts Servlet asynchronous processing, releases the container thread, and
performs a later ASYNC dispatch when the result is ready. Async MVC does not
make blocking code non-blocking; it moves work to another executor. Configure
that executor, timeouts, cancellation, and overload behavior explicitly.
Thread-local logging, locale, security, and observation state do not automatically follow arbitrary executor tasks. Use supported interceptors or task decorators, or pass context explicitly, and always clear restored state.
Comments
Read or comment on GitHub (sign-in required to comment)