Pattern PRG (Post/Redirect/Get) в Java

Шаблон веб проектирования PRG (Post/Redirect/Get) предотвращает повторную отправку данных. Примеры использования:

  • Ввод данных пользователя
  • Финансовые операции

Для пояснения проблемы двойной отправки данных возьмем картинку из википедии:

Post/Redirect/Get в Spring MVC

Пользователь заполняет форму и отправляет её нажимая кнопку SUBMIT. С помощью метода POST выполняется отправка этих данных (к примеру по атрибуту указанному в action в теге forward) на какую-либо страницу. Далее происходит вставка данных в БД и возврат подтверждения 2xx (например 200-«ОК»). Тут может возникнуть ситуация, что пользователь обновит страницу и данные отправятся еще раз (думаю видели сообщение «Повторите отправку формы»), т.к. браузер попытается отправить запрос предшествующий переходу на данную страницу. Отправить свой платеж повторно мало кому захочется. Вот здесь и необходим паттерн PRG.

PostRedirectGet_DoubleSubmitSolution

Проблема решается разбиением запроса пользователя на несколько этапов. Первый этап (POST) отправка пользователем данных и после выполнения метода POST происходит следующее — клиент получает не 2хх статус, а 3хх (Redirect). Второй этап (Redirect) — перенаправление на нужную страницу (например «операция успешно выполнена») и теперь когда пользователь обновит страницу, то запрос (GET) уже будет не к странице с заполненной формой,  а к перенаправленной странице (где обычно сообщение об статусе операции).

Важно подчеркнуть момент с перенаправлением на другую страницу и как происходит очищение данных пользователя, чтобы он не смог их отправить повторно. Рассмотрим отличия операций Forward  и Redirect.

Forward

  • forward выполняется внутри одного сервлета
  • браузер не знает о том что происходит перенаправление и исходный URL остается неизменным
  • в любом браузере при обновлении страницы просто повторится оригинальный запрос с изначальным URL (тут данные опять и отправятся)

Redirect

  • redirect двухшаговый процесс, когда приложение заставляет браузер дать другой URL, отличный от оригинального
  • когда браузер обновляет страницу с другим URL не происходит повторения оригинального запроса, а выполняется новый запрос (чистый) на пришедший (другой) URL
  • redirect медленнее forward, т.к. требуется два запроса вместо одного
  • объекты помещенные в оригинальном запросе не доступны при втором запросе

Таким образом redirect нужно использовать в случаях сохранения информации в БД. С точки зрения SQL при операциях SELECT нужно использовать forward, а для INSERT, UPDATE, DELETEredirect.

Пример с использованием Spring MVC

Реализация шаблона проектирования PRG с использованием Spring MVC.

Share Button
12
15763 Total Views 1 Views Today

Добавить комментарий