Definition

  • Spring MVC is a web framework based on the spring-webmvc module.
  • It describes the specific roles and responsibilities within the top layer of the Layered Architecture (the Controller/Presentation Layer)
  • The Spring MVC Web framework is included in the spring-boot-starter-web dependency (Spring Boot Starter)

Reasons to use

  • Separation of Concern (SoC)
    • The Default Web Pattern: Spring essentially mandates the use of MVC for web applications.
      • The spring-boot-starter-web dependency automatically configures the entire MVC framework.
    • Clear Division of Labor: It cleanly separates the application into distinct layers
      • Model: Represents the data.
      • View (or Client): Renders the data (e.g., as JSON for a REST API).
      • Controller: Manages user requests, calls the appropriate business logic, and returns the model.
    • Backend Standard: This separation is the most dominant and proven architectural pattern for backend development in general, not just in Spring.
  • Enables Powerful & Efficient Testing
    • Independent Layers: Because each layer is independent, you can test them in isolation.
    • Easy Mocking: It’s simple to write unit tests by “mocking” dependencies. For example, you can test a Controller’s logic without needing a real database or service layer.
    • Fast Verification: This leads to rapid feature validation and very fast test execution speeds.

Diagram (w/ Layered Architecture)

M-V-C (Main Roles)

These are the high-level, conceptual “job titles” in your application. They describe the what and the why.

Controller

  • The Controller in MVC is the exact same thing as the Controller Layer (or Presentation Layer) in the Layered Architecture
  • It is the entry point to your application’s backend logic.
    • Receive incoming HTTP requests from the client.
    • Process the request by calling the appropriate Service method.
    • Return a response back to the client (Model)
  • Using DTOs
  • It’s role is to receive the HttpServletRequest from the DispatcherServlet, call the appropriate method, and prepare the model and view for the response.
@RestController
@RequestMapping("/v1/coffee")
public class CoffeeController {
 
    private final CoffeeService coffeeService;
 
    public CoffeeController(CoffeeService coffeeService) {
        this.coffeeService = coffeeService;
    }
 
    @GetMapping("/{coffee-id}")
    public Coffee getCoffee(@PathVariable("coffee-id") long coffeeId) {
        return coffeeService.findCoffee(coffeeId);
    }
}
  • The Coffee object returned in the code above is passed to the View and is automatically converted into a JSON response.
  • Practical Tip
    • The Controller must only return DTO or Entity objects.
    • @RestController is a combination of @Controller + @ResponseBody, and it is mainly used when returning JSON.

Model

  • It is simply a container for data.
    • the “package” that the Controller prepares to send to the View (usually JSON)
    • Its only job is to hold the information that the Controller wants to show to the user.
    • It doesn’t do anything. It doesn’t have logic. It just holds stuff.
  • In a REST API, the Java object you return from your controller (e.g., ProductDto) is the Model.
    • Spring uses Jackson to serialize the UserDto (Model) into a JSON string.
    • Spring sends this JSON string back across the internet inside an HTTP Response.
  • (NO overlap with the service layer)

View

  • Simply what the user sees
  • When it gets the Model (JSON) from the Controller
    • The JavaScript code in the browser parses this JSON string, extracts the data (name, email, etc.), and uses it to render or update the HTML on the screen.
  • Completely separate from SpringBoot, made from tools like React
  • Two main ways to create it:
    • Server-Side Rendering (Old)
      • Your Spring Boot application generates the full HTML page on the server (using a template engine like Thymeleaf).
      • The complete page is sent to the user’s browser.
      • Pro: Great for SEO.
      • Con: Can feel less interactive than a modern app.
    • Client-Side Rendering (The New Way using SPAs)
      • Your Spring Boot application acts as a REST API and only sends raw data (usually JSON).
      • A Single Page Application (SPA), built with a library like React, runs in the user’s browser. It fetches the JSON data from your Spring backend and generates the HTML screen dynamically.
      • SEO sucks for this tho
      • Trend - JSON + a Single-Page Application (SPA) framework like React or Vue Types of Views
Output FormatDescription
HTMLCreates the screen using a View template (e.g., Thymeleaf, JSP).
JSONA response containing data for the client to process (e.g., for SPAs, mobile apps).
DocumentA response converted into a format like PDF or Excel.

The Framework’s Implementation

DispatcherServlet

Definition

The core of the Spring MVC architecture and the entry point for all HTTP requests.

  • It operates based on the Front Controller Pattern, receiving the client’s request and taking full responsibility for the subsequent processing flow.
  • Read more in the context of Spring Servlet: Spring Servlet - DispatcherServlet
  • The Front controller Pattern
    • EVERYTHING PASSES THROUGH THIS
  • Main roles
    • Request Reception - It is the first component to receive all HTTP requests sent by the client.
    • Handler Search Request - It delegates to the HandlerMapping to find the Controller that will process the request.
    • Handler Execution Delegation - It delegates to the HandlerAdapter to execute the Controller’s method.
    • Response Rendering Control - It receives the processing result (Model and View) and generates a response through the ViewResolver and View.
  • In practice, if a client request comes in with an incorrect URL or if there is no appropriate handler, a 404 error will occur. In this case, by setting the DispatcherServlet’s log level to DEBUG, you can check how far the request progressed

HandlerMapping - Address Book

Role

HandlerMapping plays the role of connecting (mapping) a client’s request URI to the Controller method that will handle it.

  • Implemented as key + value
  • Purpose
    • The DispatcherServlet then ASKS the HandlerMapping (the Directory), “Hey, I have a letter addressed to /coffee/42 with a GET method. Who does this go to?”
    • The HandlerMapping (the Directory) does the lookup. It “analyzes” its internal list and finds the entry.
    • The HandlerMapping then tells the DispatcherServlet, “That letter belongs to the getCoffeeById() method in the CoffeeController.”
  • Answers - “Which controller method handles this specific URL and HTTP method?”
    • That’s it/ It’s just a directory or a map.
  • Handler = Your Controller Method
    • annotated with @GetMapping, @PostMapping
  • When your SpringBoot application starts up
    • HandlerMapping scans all classes annotated with @RestController or @Controller
    • It then builds a dictionary for methods with annotations like `@GetMapping(“/coffee/{id})
      • This entry links the request details (the HTTP method GET and the URL pattern /coffee/*) to a specific handler object (a reference to your CoffeeController.getCoffeeById method)`
    • When an actual HTTP request like GET /coffee/42 arrives at the DispatcherServlet, the DispatcherServlet asks the HandlerMapping a simple question: “I have a GET request for /coffee/42. Which handler is registered for this?”
    • The HandlerMapping looks at its map, finds the match, and returns the handler object (the CoffeeController.getCoffeeById method) back to the DispatcherServlet.
      • HandlerExecutionChain

Main Implementations and Characteristics

ImplementationDescription
RequestMappingHandlerMappingAnnotation-based mapping. It analyzes annotations like @GetMapping and @PostMapping to store mapping information. Used in most Spring projects.
SimpleUrlHandlerMappingUsed in XML-based configurations, it connects URLs and handlers within the bean configuration file.
BeanNameUrlHandlerMappingAutomatically maps if the bean’s name is the same as the request URI.
  • In practice, RequestMappingHandlerMapping is used in most cases.
  • If a mapping conflict or omission occurs, it is important to check the path configuration in @RequestMapping or verify the URL spelling.

HandlerAdapter

Role

An abstraction to solve this exact problem (핸들러 호출 추상화)

  • The bridge between DIspatcherServlet and COntroller
  • It “adapts” the generic request into a specific call to your unique method signature. That’s its only job.
  • Mapping VS Adapter
    • HandlerMapping finds WHO should do the work.
    • HandlerAdapter knows HOW to talk to them, get them to do the work, and bring back the result.
  • After HandlerMapping
    • Now the DispatcherServlet knows what method to call, but it doesn’t know how to call it.
      • Your method signature might be complex: public CoffeeDto getCoffeeById(@PathVariable Long id, @RequestHeader("X-Source") String source).
      • The DispatcherServlet is not smart enough to pull "42" out of the URL, convert the String "42" into a Long 42, get the "X-Source" header value, etc
    • Now, the HandlerAdapter knows exactly HOW to execute your specific handler method
      • Adapting the Inputs: It looks at the handler method the DispatcherServlet gives it & inspects the method’s parameters (@PathVariable, @RequestBody, @RequestParam, etc.).
        • It then takes the raw HttpServletRequest, pulls out all the required information, converts it to the correct Java types (String to Long, JSON to a DTO object), and prepares the arguments for the method call.
      • Invoking the Method: It then uses this prepared list of arguments to actually invoke your controller method.
        • HandlerInterceptor
          • set of gatekeepers or checkpoints that you can place around your controller method
            • preHandle() - before the handler
            • postHandle() - after the handler
            • afterCompletion() - after the response is sent
        • HttpMessageConverter
          • HandlerAdapter uses this in order to pass the correct object as the argument
          • only used after preHandle() checkpoint passed
      • Handling the Output:
        • REST API
          • Your method runs and returns a Java object (e.g., a CoffeeDto).
          • The HandlerAdapter takes this return value and hands it back to the DispatcherServlet.
          • The DTO will get converted to JSON (using HttpMessageConverter)
          • Usually used with @RestController
        • SSR method
          • Your method runs and returns a String (the view name) or a ModelAndView object.
          • The HandlerAdapter takes this return value and hands it back to the DispatcherServlet.
          • The ModelAndView will be used by the ViewResolver to find and render an HTML template.
          • Usually used with @Controller
  • In practice, if you use a custom handler, you must implement a HandlerAdapter yourself and register it with Spring.

Response Processing Components (ViewResolver, HttpMessageConverter )

ViewResolver
  • Relevant for SSR Application (NOT Rest API) - Your Spring Boot backend is responsible for generating the full HTML page and sending it to the browser
  • A Controller usually returns only a View name (logical name of the view).
    • Ex) "home", "coffee/list".
    • The ViewResolver’s job is to find the actual JSP, Thymeleaf template file, etc., that corresponds to this name.
  • Basically
    • The DispatcherServlet asks the ViewResolver to find the actual View (like a template file) using the view name it received.
    • The ViewResolver finds the correct View object and returns it.
    • The DispatcherServlet gives the Model data to this View object and tells it to create the final response.
    • The View generates the final data (like an HTML page) and sends it back to the DispatcherServlet, which then delivers it to the client.
HttpMessageConverter
  • Relevant for building a REST API (for React, Vue, etc)
  • API responses return data directly as JSON, XML, etc., instead of a View.
    • The component that serializes (or deserializes) a Java object for this purpose is the HttpMessageConverter.
  • Main Roles
    • It converts the object returned from the Controller into the appropriate format for the HTTP Response Body.
    • It can also reverse-convert (deserialize) the client’s request body into a Java object (for @RequestBody).
    • It automatically selects the appropriate converter based on the Content-Type header of the response.
  • In practice, if a JSON serialization issue occurs, you should check the registration order of your HttpMessageConverters and the ObjectMapper configuration.

Main Implementations

ImplementationDescription
MappingJackson2HttpMessageConverterConverts between Java objects ↔ JSON (The default).
StringHttpMessageConverterUsed when returning simple text.
FormHttpMessageConverterHandles application/x-www-form-urlencoded data.

CSR vs SSR 😭

FeatureSSR Method (Server-Side Rendering)REST API Method
ControllerUses @ControllerUses @RestController
Handler’s Responsibility (What your method must return)Returns the View Name and Model dataReturns the Data Object (DTO)
RenderingViewResolver, ViewHTTPMessageConverter
HandlerAdapter’s Output (handed back to `DispatcherServlet)A ModelAndView objectThe raw DTO object
The result sent back to clientHTML screen (JSP, Thymeleaf)JSON data

Summary

  • Everything is connected through DispatcherServlet
ComponentMain RolePractical Checkpoints
DispatcherServletOrchestrates the entire request flow.Request flow tracing, exception handling.
HandlerMappingFinds the handler for a request URI.Duplicate or missing @RequestMapping.
HandlerAdapterAbstracts handler execution.Ability to process custom handlers.
ViewResolverConverts a View name to an actual View.Checking prefix/suffix settings.
HttpMessageConverterConverts between objects ↔ HTTP messages.JSON serialization errors, Content-Type issues.