Получить доступ

Что такое Post/Redirect/Get и как сделать его в Spring MVC?

MiddleSpring MVC и RESTSpring
Ещё спрашивают так:
  • Как избежать повторной отправки формы при обновлении страницы?
  • Что такое flash-атрибуты?
Коротко

PRG: после успешного POST сервер отвечает редиректом на GET-страницу результата. Обновление страницы повторит безопасный GET, а не POST — заказ не создастся дважды.

  • В Spring MVC: return "redirect:/orders/" + id;
  • Сообщение «Сохранено» на один показ — RedirectAttributes.addFlashAttribute
  • Forward вместо redirect оставляет в истории POST — проблема остаётся

А ещё Для REST API PRG не нужен: там 201 Created с Location

Так подсказку видит пользователь sotto на живом собеседовании — за пару секунд, пока вы думаете вслух.

Подробно

Проблема: форма отправлена POST, сервер вернул страницу результата прямо в ответе. Пользователь нажимает «Обновить» — браузер повторяет POST (с предупреждением, которое все пропускают) и создаёт второй заказ.

Post/Redirect/Get:

  1. браузер отправляет POST;
  2. сервер обрабатывает и отвечает 303 See Other (или 302) с Location: /orders/42;
  3. браузер делает GET /orders/42 и показывает результат.

В истории браузера остаётся GET, обновление безопасно.

В Spring MVC:

@PostMapping("/orders")
String create(@Valid OrderForm form, BindingResult errors, RedirectAttributes ra) {
    if (errors.hasErrors()) return "orders/new";          // ошибки — показать форму без редиректа
    long id = service.create(form);
    ra.addFlashAttribute("message", "Заказ оформлен");    // переживёт ровно один редирект
    return "redirect:/orders/" + id;
}

Flash-атрибуты хранятся в сессии до следующего запроса и удаляются после показа. Обычные addAttribute попадают в URL.

Forward не подходит: он происходит внутри сервера, URL и метод в браузере остаются POST.

Что хотят услышать

  • Проблема повторной отправки формы.
  • Шаги PRG и коды 303/302.
  • redirect: и flash-атрибуты в Spring MVC.
  • Почему не forward.

Частые ошибки

  • Делать forward после POST.
  • Редиректить и при ошибках валидации, теряя введённые данные.

Проверьте себя

Один верный вариант. Подумайте, потом откройте ответ.

Показать варианты и ответ
  • ✓После успешного POST вернуть redirect (303/302) на GET-страницу результата; сообщение на один показ передать через RedirectAttributes.addFlashAttribute
  • ✗После POST вернуть страницу результата напрямую через forward
  • ✗Отключить кнопку «Обновить» в браузере
  • ✗Использовать GET вместо POST для отправки формы

Что спросят дальше

  • Что такое PRG pattern?
  • Какие бывают 3xx статусы?

Разбор темы

Связанные вопросы

Закрытая бета

Подсказки на собеседовании — в реальном времени

sotto слышит вопрос интервьюера и показывает короткий ответ и план, как в блоке «Коротко». Оставьте контакт — пришлём доступ и промокод.

  • Промокод на 2 часа — сверх пробных 30 минут
  • Программа для Windows — скачать сразу, войти — через Яндекс ID или VK ID
  • Прямая связь с разработчиком: что улучшить — сделаем