Рубрики
Без рубрики

Руководство по атрибутам Flash в веб-приложении Spring

Узнайте, как использовать атрибуты flash Spring для реализации рабочего процесса отправки формы Post/Redirect/Get.

Автор оригинала: baeldung.

1. Обзор

Веб-приложения часто зависят от пользовательского ввода для удовлетворения нескольких вариантов их использования. В результате отправка форм является широко используемым механизмом сбора и обработки данных для таких приложений.

В этом уроке мы узнаем, как атрибуты Spring flash могут помочь нам с рабочим процессом отправки форм надежно и надежно.

2. Основы атрибутов Flash

Прежде чем мы сможем комфортно использовать атрибуты flash, нам необходимо создать достойный уровень понимания рабочего процесса отправки форм и нескольких ключевых связанных с ним концепций.

2.1. Опубликовать/Перенаправить/Получить шаблон

Наивным способом создания веб-формы было бы использовать один HTTP POST запрос, который заботится о отправке и возвращает подтверждение через свой ответ. Однако такой дизайн подвергает риску повторную обработку запросов POST в случае, если пользователь в конечном итоге обновит страницу.

Чтобы уменьшить проблему дублирования обработки, мы можем создать рабочий процесс в виде последовательности взаимосвязанных запросов в определенном порядке, а именно POST, REDIRECT и GET . Короче говоря, мы называем это шаблоном Post/Redirect/Get (PRG) для отправки формы.

При получении запроса POST сервер обрабатывает его, а затем передает управление для выполнения запроса GET. Впоследствии страница подтверждения отображается на основе ответа на запрос GET. В идеале, даже если последний запрос GET будет предпринят более одного раза, не должно быть никаких побочных эффектов.

2.2. Жизненный цикл атрибутов Flash

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

К сожалению, мы не можем использовать ни Атрибуты Запроса , ни Атрибуты Сеанса . Это потому, что первый не выдержит перенаправления между различными контроллерами, в то время как второй будет длиться в течение всего сеанса даже после завершения отправки формы.

Но нам не нужно беспокоиться, поскольку веб-фреймворк Spring предоставляет атрибуты flash, которые могут решить именно эту проблему.

Давайте рассмотрим методы в интерфейсе RedirectAttributes , которые могут помочь нам использовать атрибуты flash в нашем проекте:

RedirectAttributes addFlashAttribute(String attributeName, @Nullable Object attributeValue);

RedirectAttributes addFlashAttribute(Object attributeValue);

Map getFlashAttributes();

Атрибуты Flash недолговечны . Таким образом, они временно хранятся в некотором базовом хранилище, непосредственно перед перенаправлением. Они остаются доступными для последующего запроса после перенаправления, а затем исчезают.

2.3. Структура Данных Флэш-Карты

Spring предоставляет абстрактную структуру данных под названием Flash Map для хранения атрибутов flash в виде пар ключ-значение.

Давайте взглянем на определение класса Flash Map :

public final class FlashMap extends HashMap implements Comparable {

    @Nullable
    private String targetRequestPath;

    private final MultiValueMap targetRequestParams 
      = new LinkedMultiValueMap<>(4);

    private long expirationTime = -1;
}

Мы можем заметить, что класс Flash Map наследует свое поведение от класса HashMap . Таким образом, экземпляр Flash Map может хранить сопоставление ключей и значений атрибутов . Кроме того, мы можем привязать экземпляр Flash Map , который будет использоваться только определенным URL-адресом перенаправления.

Кроме того, каждый запрос имеет два экземпляра FlashMap , а именно Input FlashMap и Output FlashMap, которые играют важную роль в шаблоне PRG:

  • Вывод Флэш-карта используется в запросе POST для временного сохранения атрибутов flash и отправки их в следующий запрос GET после перенаправления
  • Input Flash Map используется в окончательном запросе GET для доступа к атрибутам flash, доступным только для чтения, которые были отправлены предыдущим запросом POST перед перенаправлением

2.4. FlashMapManager и RequestContextUtils

Как следует из названия, мы можем использовать FlashMapManager для управления экземплярами Flash Map .

Во – первых, давайте взглянем на определение этого интерфейса стратегии:

public interface FlashMapManager {

    @Nullable
    FlashMap retrieveAndUpdate(HttpServletRequest request, HttpServletResponse response);

    void saveOutputFlashMap(FlashMap flashMap, HttpServletRequest request, HttpServletResponse response);
}

Проще говоря, мы можем сказать, что FlashMapManager позволяет нам читать, обновлять и сохранять экземпляры Flash Map в некотором базовом хранилище.

Далее давайте ознакомимся с несколькими статическими методами, доступными в классе RequestContextUtils abstract utility .

Чтобы сохранить наше внимание в рамках этого руководства, мы ограничим наш охват методами, относящимися к атрибутам flash:

public static Map getInputFlashMap(HttpServletRequest request);

public static FlashMap getOutputFlashMap(HttpServletRequest request);

public static FlashMapManager getFlashMapManager(HttpServletRequest request);

public static void saveOutputFlashMap(String location, 
  HttpServletRequest request, HttpServletResponse response);

Мы можем использовать эти методы для получения экземпляров ввода/вывода FlashMap , получения FlashMapManager для запроса и сохранения экземпляра FlashMap .

3. Пример Использования Формы Подачи

К настоящему времени мы установили базовое понимание различных концепций, связанных с атрибутами flash. Итак, давайте двигаться дальше и использовать их в веб-приложении для конкурса поэзии.

Наше приложение для конкурса поэзии имеет простой вариант использования для приема стихотворных записей от разных поэтов путем подачи формы. Кроме того, конкурсная работа будет содержать необходимую информацию, связанную со стихотворением, такую как название, текст и имя автора.

3.1. Конфигурация Thymeleaf

Мы будем использовать Thymeleaf , который является шаблоном Java для создания динамических веб-страниц с помощью простых HTML-шаблонов.

Во-первых, нам нужно добавить зависимость spring-boot-starter-thymeleaf в вашего проекта pom.xml :


    org.springframework.boot
    spring-boot-starter-thymeleaf
    2.2.1.RELEASE

Затем мы можем определить некоторые свойства Thymeleaf в нашем файле application.properties , расположенном в каталоге src/main/resources :

spring.thymeleaf.cache=false
spring.thymeleaf.enabled=true 
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html

Определив эти свойства, теперь мы можем создать все наши представления в каталоге /src/main/resources/templates . В свою очередь, Spring добавит суффикс .html ко всем представлениям, названным внутри нашего контроллера.

3.2. Модель предметной области

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

public class Poem {
    private String title;
    private String author;
    private String body;
}

Кроме того, мы можем добавить статический метод is Valid Poem() в ваш класс Poem , чтобы помочь нам проверить, что поля не допускают пустых строк:

public static boolean isValidPoem(Poem poem) {
    return poem != null && Strings.isNotBlank(poem.getAuthor()) 
      && Strings.isNotBlank(poem.getBody())
      && Strings.isNotBlank(poem.getTitle());
}

3.3. Создание формы

Теперь мы готовы создать нашу форму подачи заявки. Для этого нам нужна конечная точка //| submit , которая будет обслуживать запрос GET, чтобы показать форму/| пользователю:

@GetMapping("/poem/submit")
public String submitGet(Model model) {
    model.addAttribute("poem", new Poem());
    return "submit";
}

Здесь мы использовали модель в качестве контейнера для хранения специфичных для стихотворения данных, предоставленных пользователем. Кроме того, метод submit Get возвращает представление, обслуживаемое представлением submit .

Кроме того, мы хотим связать форму ЗАПИСИ с атрибутом модели стихотворение :

3.4. Отправка/Перенаправление/Получение потока отправки

Теперь давайте включим действие POST для формы. Для этого мы создадим конечную точку /poem/submit в контроллере Poem Submission для обслуживания запроса POST :

@PostMapping("/poem/submit")
public RedirectView submitPost(
    HttpServletRequest request, 
    @ModelAttribute Poem poem, 
    RedirectAttributes redirectAttributes) {
    if (Poem.isValidPoem(poem)) {
        redirectAttributes.addFlashAttribute("poem", poem);
        return new RedirectView("/poem/success", true);
    } else {
        return new RedirectView("/poem/submit", true);
    }
}

Мы можем заметить, что если отправка прошла успешно, то управление передается в конечную точку //success//. Кроме того, мы добавили данные стихотворения в качестве атрибута flash перед началом перенаправления.

Теперь нам нужно показать пользователю страницу подтверждения, поэтому давайте реализуем функциональность для конечной точки /poem/success/|, которая будет обслуживать запрос GET:

@GetMapping("/poem/success")
public String getSuccess(HttpServletRequest request) {
    Map inputFlashMap = RequestContextUtils.getInputFlashMap(request);
    if (inputFlashMap != null) {
        Poem poem = (Poem) inputFlashMap.get("poem");
        return "success";
    } else {
        return "redirect:/poem/submit";
    }
}

Здесь важно отметить, что нам необходимо проверить флэш-карту , прежде чем мы решим перенаправить на страницу успеха .

Наконец, давайте используем атрибут flash стихотворение внутри нашей страницы успеха, чтобы показать название стихотворения, представленного пользователем:

Click here to submit more.

4. Заключение

В этом уроке мы изучили несколько концепций, связанных с шаблоном Post/Redirect/Get и атрибутами flash. Кроме того, мы также видели атрибуты flash в действии с помощью простой формы-отправки в веб-приложении Spring Boot.

Как всегда, полный исходный код учебника доступен на GitHub .