Зарегистрируйтесь, чтобы продолжить обучение

Флеш-сообщения Java: Веб-технологии

Работая на Хекслете, вы не раз видели сообщение о результатах выполнения любого действия — будь то аутентификация, регистрация или вступление в курс. Выглядят эти сообщения так:

Flash Message

В веб-разработке это называется флеш-сообщениями. Они обычно используются после редиректа для индикации успешности или неудачи предыдущего действия. Например, после регистрации сайт выполняет перенаправление на страницу, с которой пришел пользователь, а затем выводит сообщение «Регистрация выполнена».

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

Иногда фреймворки поддерживают флеш-сообщения самостоятельно или с помощью соответствующих дополнений. В случае Java-фреймворков таких решений нет, но их легко имитировать с помощью механизма сессий. В Javalin нам для этого понадобится два метода:

// Этот метод устанавливает в сессию значение по ключу
ctx.sessionAttribute("key", "value");
// Этот метод читает сообщение из сессии и тут же удаляет его
ctx.consumeSessionAttribute("key");

Метод consumeSessionAttribute() идеально подходит для реализации сессии. Он читает сообщение из сессии и удаляет его, что автоматически прячет сообщение при обновлении страницы или клику по любой ссылке.

Добавим флеш-сообщение в процесс создания курса. Для этого нам понадобится установить сообщение, которое будет выводиться после успешного создания курса:

app.post(NamedRoutes.coursesPath(), ctx -> {
    var name = ctx.formParam("name");
    var description = ctx.formParam("description");

    var course = new Course(name, description);
    CourseRepository.save(course);
    // Добавляем сообщение в сессию
    // Ключ может иметь любое название, здесь мы выбрали flash
    ctx.sessionAttribute("flash", "Course has been created!");
    ctx.redirect(NamedRoutes.coursesPath());
});

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

app.get(NamedRoutes.coursesPath(), ctx -> {
    String flash = ctx.consumeSessionAttribute("flash");
    // Добавляем flash в определение CoursesPage
    var page = new CoursesPage(courses, term, flash);

    ctx.render("courses/index.jte", model("page", page));
});

Метод ctx.consumeSessionAttribute() извлекает данные по указанному ключу и удаляет их. Это важно, потому что повторная загрузка страницы приведет к пропаданию флеш-сообщения. Дальше сообщение передается в CoursePage. Осталось сделать вывод в шаблоне:

@if(page.getFlash() != null)
    <p>${page.getFlash()}</p>
@endif

Использование макета

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

Самый простой способ — это создание базового класса для всех Page, в котором сосредоточится логика работы с флеш-сообщениями:

// src/main/java/org/example/hexlet/dto/BasePage.java
package org.example.hexlet.dto;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class BasePage {
    private String flash;
}

Класс CoursesPage при этом будет наследоваться от базового класса Page

package org.example.hexlet.dto.courses;

import org.example.hexlet.dto.BasePage;
import lombok.AllArgsConstructor;
import lombok.Getter;
// остальные импорты

@AllArgsConstructor
@Getter
public class CoursesPage extends BasePage {
    private List<Course> courses;
    private String term;
}

Теперь в нужном месте мы можем добавлять сообщения так:


app.get(NamedRoutes.coursesPath(), ctx -> {
    var page = new CoursesPage(courses, term);
    page.setFlash(ctx.consumeSessionAttribute("flash"));
    ctx.render("courses/index.jte", model("page", page));
});

Затем мы должны передать этот page в макет в шаблоне этого обработчика:

@import org.example.hexlet.util.NamedRoutes
@import org.example.hexlet.dto.courses.CoursesPage
@param CoursesPage page

@template.layout.page(
    page = page,
    content = @`
      Тут шаблон
    `
)

И наконец вывод в макете:

@import org.example.hexlet.util.NamedRoutes
@import org.example.hexlet.dto.BasePage // Импортируем базовый класс
@import gg.jte.Content
@param Content content
@param BasePage page = null // Если не передали, то игнорируем

<!doctype html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <title>Hexlet Javalin Example</title>
    </head>
    <body>
        @if(page != null && page.getFlash() != null)
            <p>${page.getFlash()}</p>
        @endif
        ${content}
    </body>
</html>

Самостоятельная работа

  1. Проделайте все шаги из урока на своем компьютере
  2. Добавьте в приложение вывод флеш-сообщения об успехе или неудаче при регистрации нового пользователя
  3. Подсветите сообщения разными цветами с помощью Bootstrap:
    • Зеленым — при успешной регистрации
    • Красным — если возникла ошибка
  4. Залейте изменения на GitHub

Дополнительные материалы

  1. Официальная документация Javalin

Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
1000
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов
Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff
Рекомендуемые программы
профессия
от 25 000 ₸ в месяц
Разработка приложений на языке Java
10 месяцев
с нуля
Старт 26 декабря

Используйте Хекслет по-максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»
Изображение Тото

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