Почнемо з невеликої аналогії, щоб було простіше зрозуміти суть Spring MVC. Давай порівняємо Spring MVC з компіляцією і запуском програми:
- Модель — це компілятор, який обробляє вихідний код. Він застосовує логіку, перевіряє синтаксис, оптимізує і створює виконуваний код. Компілятор не париться тим, як програма буде відображатися — він фокусується на коректній обробці даних.
- Контролер — це операційна система. Вона отримує команди користувача, спрямовує їх потрібним процесам, керує пам'яттю і ресурсами, координує роботу всіх компонентів.
- Представлення — це графічний інтерфейс програми. Воно бере оброблені дані і показує їх користувачу зрозуміло — через вікна, кнопки, форми. Ця архітектура, як і Spring MVC, розділяє обробку даних, управління і відображення на окремі компоненти, роблячи код більш організованим і підтримуваним. Spring MVC реалізує цей патерн, розділяючи відповідальність між цими компонентами. Давай подивимось на кожен з них детальніше.
Контролери: диригенти запитів
Контролери — це серце Spring MVC. Вони приймають HTTP-запити, обробляють їх і повертають результат. Це свого роду диригенти, які керують взаємодією між моделлю і представленням.
Створення контролера
Контролери в Spring позначаються за допомогою анотації @Controller. Ось приклад найпростішого контролера:
@Controller
public class HelloController {
@GetMapping("/hello")
public String sayHello(Model model) {
model.addAttribute("message", "Привіт, Spring MVC!");
return "hello"; // Повертає ім'я представлення
}
}
Як це працює?
- Коли користувач відкриває посилання
/hello, цей запит перехоплюється контролером. - Контролер додає дані в об'єкт
Modelі повертає ім'я представленняhello. - Представлення, пов'язане з ім'ям
hello, буде оброблене і відображене.
Типи контролерів
- Класичні контролери: використовують анотацію
@Controller. Вони працюють у парі з представленнями. - REST-контролери: використовують
@RestController, оптимізовані для роботи з REST API і повертають JSON або XML, а не HTML-сторінки.
Приклад REST-контролера:
@RestController
public class ApiController {
@GetMapping("/api/greeting")
public String getGreeting() {
return "Привіт з REST API!";
}
}
ми будемо глибше вивчати REST-контролери в наступних темах. Ну а поки що зосередимось на класичному @Controller.
Моделі: передача даних
Модель у Spring MVC використовується для зберігання даних, які передаються від контролера до представлення. Основне завдання моделі — бути "контейнером" даних.
Давай розглянемо приклад:
@Controller
public class UserController {
@GetMapping("/user")
public String getUser(Model model) {
model.addAttribute("username", "John Doe");
return "user"; // Ім'я представлення
}
}
Об'єкт Model доступний в методах контролера і дозволяє додавати пари "ключ-значення". Ці пари потім стають доступні в представленні.
Чому модель така важлива?
Уяви, що без моделі офіціанту (контролеру) довелося б готувати страви (дані) самостійно. Це порушує принцип розділення відповідальності, ускладнює код, і в результаті офіціант почне плутатися.
Модель дозволяє чітко розділити:
- Логіку обробки даних (модель).
- Логіку їх представлення (представлення).
- Логіку маршрутизації запитів (контролер).
Представлення: краса в браузері
Представлення — це кінцевий результат роботи вашого додатку, який користувач бачить у браузері. Spring MVC підтримує кілька технологій представлення:
- JSP (Java Server Pages)
- Thymeleaf (рекомендований сучасний шаблонізатор)
- FreeMarker
- Mustache
Ми зосередимося на Thymeleaf, бо він активно використовується в Spring Boot.
Підключення Thymeleaf
Щоб використовувати Thymeleaf, додай його залежність у твій pom.xml (якщо працюєш з Maven):
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
Далі створи файл представлення hello.html в директорії src/main/resources/templates:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hello</title>
</head>
<body>
<h1 th:text="'Повідомлення: ' + ${message}"></h1>
</body>
</html>
Зверни увагу на атрибут th:text. Це спеціальний синтаксис Thymeleaf для виводу даних з моделі.
Коли користувач відкриває /hello, Spring MVC рендерить це представлення, і в браузері виводиться: Повідомлення: Привіт, Spring MVC!
Взаємодія компонентів
Давай зв'яжемо все докупи. Ось як виглядає цикл обробки запитів у Spring MVC:
- Користувач відправляє HTTP-запит (наприклад, відкриває
/hello). - Запит потрапляє до контролера
HelloController, який його обробляє. - Контролер додає необхідні дані в модель.
- Контролер повертає ім'я представлення, яке потрібно відобразити.
- Spring MVC знаходить відповідний файл представлення у папці
templates(або іншій налаштованій директорії). - Thymeleaf рендерить HTML з даними з моделі, і результат відправляється користувачу.
Практика: Створення базового MVC-додатку
Крок 1: Створюємо новий контролер
@Controller
public class ProductController {
@GetMapping("/product")
public String getProduct(Model model) {
model.addAttribute("name", "Ноутбук");
model.addAttribute("price", 75000);
return "product"; // Ім'я представлення
}
}
Крок 2: Створи файл product.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Product</title>
</head>
<body>
<h1>Продукт: <span th:text="${name}"></span></h1>
<p>Ціна: <span th:text="${price}"></span> ₽</p>
</body>
</html>
Крок 3: Запускаємо додаток
Відкрий браузер, перейди за адресою http://localhost:8080/product і побачиш згенеровану сторінку.
Які проблеми можна зустріти?
- Пропущені залежності. Якщо ти забув додати Thymeleaf у залежності, Spring MVC не знайде твої представлення, і ти отримаєш помилку
TemplateNotFoundException. - Помилка при додаванні моделі. Якщо ти намагаєшся вставити в модель об'єкт, який не серіалізується (наприклад, не перевизначив
toStringабо використав внутрішні класи), це може спричинити проблеми. - Несумісність імені представлення. Якщо ти повертаєш ім'я представлення, якого немає в папці
templates, Spring MVC викличеTemplateNotFoundException.
MVC — це важливо
Spring MVC грає ключову роль у створенні масштабованих веб-додатків. Розділення на контролери, моделі і представлення робить код більш підтримуваним і зрозумілим. Ти можеш легко змінити одне з представлень, не торкнувшись логіки обробки даних, або додати новий функціонал, не боячись "зламати" існуюче.
Навички роботи з архітектурою MVC пригодяться тобі не тільки в коді, але й на співбесідах. Практично кожне інтерв'ю на позицію Java-розробника включає питання про принципи MVC і їхню реалізацію в Spring.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ