JavaRush /Курси /Модуль 5. Spring /Формування відповідей: @ResponseBody, @ModelAttribute

Формування відповідей: @ResponseBody, @ModelAttribute

Модуль 5. Spring
Рівень 7 , Лекція 4
Відкрита

У веб-розробці є два напрямки руху даних:

  1. Клієнт → Сервер (обробка запитів).
  2. Сервер → Клієнт (формування відповідей).

Якщо на перший напрям ми вже поглянули, то другий вимагає нашої пильної уваги. Давай розберемося, як сервер може "відповідати" клієнту і чому це важливо для успішної взаємодії.

Варіанти відповідей

  1. HTML-сторінки.
    • Сервер повертає HTML-код, який браузер рендерить користувачу.
  2. JSON/XML.
    • Серійовані дані для клієнтів (наприклад, у REST API).
  3. Файли або інші ресурси.
    • Наприклад, зображення, PDF або ZIP-файли.

У Spring MVC ми гнучко формуємо відповіді завдяки потужній системі анотацій та інструментів.


Анотація @ResponseBody

Якщо ти прийшов із світу REST API, то фраза "JSON-відповіді" має бути для тебе як музика. Ця анотація саме відповідає за відправку даних у форматі JSON або XML з контролера клієнту.

По суті, @ResponseBody каже Spring: "Досить грати в ці гарні стендапчики з HTML-сторінками. Просто відправ дані клієнту, без зайвої драматургії". Тобто вона скасовує view resolution, і натомість повертає дані безпосередньо в HTTP-відповідь.

Приклад: Відправка JSON-відповіді

Ось найпростіший приклад:


@RestController
@RequestMapping("/api")
public class UserController {

    @GetMapping("/user")
    public User getUser() {
        return new User(1, "John Doe");
    }
}

Тут ми використовуємо @RestController, яка, по суті, є скороченням для @Controller + @ResponseBody. Це означає, що кожен метод повертає JSON-відповідь. Якщо ти повернеш об'єкт, Spring автоматично перетворить його в JSON (серіалізує) завдяки вбудованій бібліотеці Jackson.

Як це працює? Spring вміє серіалізувати об'єкти в JSON завдяки бібліотеці Jackson. Вона входить "з коробки", тож ніяких додаткових танців не потрібно. Але якщо захочеш серіалізувати об'єкт в XML, то знадобиться трохи доопрацювань.

Приклад: Використання @ResponseBody без @RestController

Якщо з якоїсь причини ти використовуєш звичайний контролер, а не @RestController, нічого страшного! Просто додай @ResponseBody до методу.


@Controller
@RequestMapping("/api")
public class UserController {

    @ResponseBody
    @GetMapping("/user")
    public User getUser() {
        return new User(1, "Jane Doe");
    }
}

Ця анотація каже Spring, що дані потрібно повертати напряму, а не шукати представлення.

А можна повернути не тільки JSON?

Звісно. Якщо хочеш повернути, наприклад, рядок або будь-який інший тип даних, @ResponseBody з радістю це зробить.


@Controller
@RequestMapping("/api")
public class ExampleController {

    @ResponseBody
    @GetMapping("/hello")
    public String sayHello() {
        return "Hello, Spring MVC!";
    }
}

Клієнт отримає просто рядок: Hello, Spring MVC!.

Типові помилки при використанні @ResponseBody

  1. Помилка: "Cannot serialize object". Це трапляється, якщо об'єкт не може бути перетворений у JSON. Наприклад, у нього немає public-гетерів, або ти забув підключити Jackson.
  2. Випадкове повернення HTML. Якщо ти забудеш @ResponseBody або використаєш @Controller без неї, Spring може спробувати знайти HTML-сторінку з іменем, що співпадає з поверненим значенням (наприклад, "user" для методу getUser).

Анотація @ModelAttribute

Якщо @ResponseBody — твій найкращий друг для REST API, то @ModelAttribute незамінний для роботи з класичним MVC, де використовують HTML і серверні шаблони.

Анотація @ModelAttribute допомагає передавати дані з контролера у представлення. Вона завантажує об'єкт у модель (ми про org.springframework.ui.Model!), щоб потім передати його в шаблон.

Приклад: передача об'єкта у представлення

Припустимо, у нас є HTML-сторінка, яка відображає інформацію про користувача. Спочатку потрібно передати дані:


@Controller
@RequestMapping("/users")
public class UserController {

    @GetMapping("/profile")
    public String userProfile(Model model) {
        User user = new User(1, "Jane Doe");
        model.addAttribute("user", user);
        return "userProfile";
    }
}

Тут ми додаємо об'єкт user у модель, а потім повертаємо ім'я представлення (userProfile), яке його відобразить. Представлення може бути, наприклад, Thymeleaf-шаблоном.

Використання @ModelAttribute

Але навіщо вручну додавати в модель, якщо є @ModelAttribute?


@Controller
@RequestMapping("/users")
public class UserController {

    @ModelAttribute("user")
    public User getUser() {
        return new User(1, "Jane Doe");
    }

    @GetMapping("/profile")
    public String userProfile() {
        return "userProfile";
    }
}

Spring викличе метод з @ModelAttribute автоматично при будь-якому запиті до контролера, і об'єкт буде доданий у модель під вказаним іменем (user). Це скорочує код і робить твій контролер чистішим.


Приклад: робота з формами

@ModelAttribute також використовується для прив'язки даних з форм у Java-об'єкти.


@Controller
@RequestMapping("/users")
public class UserController {

    @GetMapping("/register")
    public String showRegistrationForm(Model model) {
        model.addAttribute("user", new User());
        return "register";
    }

    @PostMapping("/register")
    public String processRegistration(@ModelAttribute("user") User user) {
        System.out.println("Registered user: " + user);
        return "registrationSuccess";
    }
}
  • GET-запит відображає форму реєстрації з порожнім об'єктом User.
  • POST-запит автоматично зв'язує дані з форми з об'єктом User.

Типові помилки при використанні @ModelAttribute

  1. Помилка: "NullPointerException". Якщо ти забув додати об'єкт у модель, представлення не зможе відрендерити дані.
  2. Помилка прив'язки даних. Якщо в тебе складний об'єкт і дані з форми не можуть бути проставлені, Spring викине помилку. Переконайся, що всі поля форми відповідають полям об'єкта.

Коли використовувати @ResponseBody і @ModelAttribute?

Анотація Коли використовувати
@ResponseBody Коли потрібно повернути JSON/XML або рядок
@ModelAttribute| Коли ти працюєш з HTML-формами або шаблонами

Тепер ти озброєний знаннями про те, як формувати відповіді в Spring MVC. Пам'ятай: @ResponseBody — найкращий вибір для REST API, а @ModelAttribute врятує тебе у світі форм і серверної генерації HTML.

Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ