Что такое Post/Redirect/Get и как сделать его в Spring MVC?
- Как избежать повторной отправки формы при обновлении страницы?
- Что такое flash-атрибуты?
PRG: после успешного POST сервер отвечает редиректом на GET-страницу результата. Обновление страницы повторит безопасный GET, а не POST — заказ не создастся дважды.
- В Spring MVC:
return "redirect:/orders/" + id; - Сообщение «Сохранено» на один показ —
RedirectAttributes.addFlashAttribute - Forward вместо redirect оставляет в истории POST — проблема остаётся
А ещё Для REST API PRG не нужен: там 201 Created с Location
Подробно
Проблема: форма отправлена POST, сервер вернул страницу результата прямо в ответе. Пользователь нажимает «Обновить» — браузер повторяет POST (с предупреждением, которое все пропускают) и создаёт второй заказ.
Post/Redirect/Get:
- браузер отправляет POST;
- сервер обрабатывает и отвечает 303 See Other (или 302) с
Location: /orders/42; - браузер делает 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 вернуть страницу результата напрямую через forward
- ✗Отключить кнопку «Обновить» в браузере
- ✓После успешного POST вернуть redirect на GET-страницу, сообщение — через flash-атрибут
- ✗Использовать GET вместо POST для отправки формы
Что спросят дальше
- Что такое PRG pattern?
- Какие бывают 3xx статусы?
Разбор темы
- Spring MVC: DispatcherServlet и обработка запроса
Конвейер обработки запроса, @Controller против @RestController, маппинги, извлечение данных и контроль ответа.
Связанные вопросы
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.