CodeGym /Courses /Module 5. Spring /Spring MVC architecture: controllers, models, views

Spring MVC architecture: controllers, models, views

Module 5. Spring
Level 7 , Lesson 1
Available

Let's start with a small analogy to make Spring MVC easier to grasp. Imagine Spring MVC as if it's compiling and running a program:

  • Model — it's like the compiler that processes source code. It applies logic, checks syntax, optimizes and produces executable code. The compiler doesn't care how the program will be displayed — it focuses on correctly processing data.
  • Controller — it's like the operating system. It receives user commands, routes them to the right processes, manages memory and resources, and coordinates all components.
  • View — it's the graphical interface of the program. It takes processed data and shows it to the user in a readable way — via windows, buttons, forms. This architecture, like Spring MVC, separates data processing, control and presentation into distinct components, making the code more organized and maintainable. Spring MVC implements this pattern by splitting responsibilities across these components. Let's look at each of them in detail.

Controllers: the request conductors

Controllers are the heart of Spring MVC. They accept HTTP requests, handle them and return a result. They're like conductors that manage the interaction between the model and the view.

Creating a controller

Controllers in Spring are marked with the @Controller annotation. Here's an example of a minimal controller:


@Controller
public class HelloController {

    @GetMapping("/hello")
    public String sayHello(Model model) {
        model.addAttribute("message", "Hello, Spring MVC!");
        return "hello"; // Returns the view name
    }
}

How does it work?

  1. When a user opens the link /hello, that request is intercepted by the controller.
  2. The controller adds data to the Model object and returns the view name hello.
  3. The view associated with the name hello will be processed and rendered.

Types of controllers

  • Classic controllers: use the @Controller annotation. They work together with views.
  • REST controllers: use @RestController, optimized for working with REST APIs and return JSON or XML instead of HTML pages.

Example of a REST controller:


@RestController
public class ApiController {

    @GetMapping("/api/greeting")
    public String getGreeting() {
        return "Hello from REST API!";
    }
}
Note:

we'll dig deeper into REST controllers in upcoming topics. For now, let's focus on the classic @Controller.


Models: passing data around

The model in Spring MVC is used to hold data that gets passed from the controller to the view. The main job of the model is to be a "data container."

Let's look at an example:


@Controller
public class UserController {

    @GetMapping("/user")
    public String getUser(Model model) {
        model.addAttribute("username", "John Doe");
        return "user"; // View name
    }
}

The Model object is available in controller methods and lets you add key-value pairs. Those pairs then become available in the view.

Why is the model so important?

Imagine if, without a model, the waiter (the controller) had to prepare the dishes (the data) by themselves. That breaks the separation of concerns, makes the code messy, and eventually the waiter will get confused.

The model lets you clearly separate:

  • Data processing logic (the model).
  • Presentation logic (the view).
  • Request routing logic (the controller).

Views: making things look nice in the browser

The view is the end result of your app that the user sees in the browser. Spring MVC supports several view technologies:

  • JSP (Java Server Pages)
  • Thymeleaf (the recommended modern templating engine)
  • FreeMarker
  • Mustache

We'll focus on Thymeleaf since it's widely used with Spring Boot.

Adding Thymeleaf

To use Thymeleaf, add its dependency to your pom.xml (if you're using Maven):


<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

Then create the view file hello.html in src/main/resources/templates:


<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Hello</title>
</head>
<body>
  <h1 th:text="'Message: ' + ${message}"></h1>
</body>
</html>

Note the th:text attribute. That's Thymeleaf's special syntax for outputting data from the model.

When a user opens /hello, Spring MVC renders that view, and the browser will show: Message: Hello, Spring MVC!


How the components interact

Let's tie it all together. Here's the request processing cycle in Spring MVC:

  1. The user sends an HTTP request (for example, opens /hello).
  2. The request goes to the HelloController, which handles it.
  3. The controller adds necessary data to the model.
  4. The controller returns the name of the view to render.
  5. Spring MVC finds the corresponding view file in the templates folder (or another configured directory).
  6. Thymeleaf renders the HTML with data from the model, and the result is sent to the user.

Practice: Building a basic MVC app

Step 1: Create a new controller


@Controller
public class ProductController {

    @GetMapping("/product")
    public String getProduct(Model model) {
        model.addAttribute("name", "Laptop");
        model.addAttribute("price", 75000);
        return "product";
    }
}

Step 2: Create the product.html file


<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Product</title>
</head>
<body>
  <h1>Product: <span th:text="${name}"></span></h1>
  <p>Price: <span th:text="${price}"></span> ₽</p>
</body>
</html>

Step 3: Run the app

Open your browser, go to http://localhost:8080/product and you'll see the generated page.


Common issues you might hit

  1. Missing dependencies. If you forgot to add Thymeleaf to dependencies, Spring MVC won't find your views and you'll get a TemplateNotFoundException.
  2. Error adding to the model. If you try to put an object into the model that isn't serializable (for example, you didn't override toString or used inner classes), that can cause problems.
  3. View name mismatch. If you return a view name that doesn't exist in the templates folder, Spring MVC will throw TemplateNotFoundException.

MVC matters

Spring MVC plays a key role in building scalable web apps. Splitting into controllers, models and views makes the code more maintainable and understandable. You can easily change one of the views without touching the data processing logic, or add new features without worrying about "breaking" existing stuff.

Knowing how MVC works will help you not only in code but also in interviews. Almost every Java developer interview includes questions about MVC principles and how they're implemented in Spring.

Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION