Spring Web Flow — определение потоков (defining flows)

3. Определение потоков

3.1. Вступление

Эта глава начинает раздел пользователя. Здесь показано как реализовать потоки используя язык определения потоков (flow definition language). По окончанию этой главы вы будете должны обладать достаточным пониманием о языке построения и способны реализовать поток.

 3.2. Что такое поток?

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

Бронирование отеля| Spring Web FLow

Карта сайта иллюстрирующая поток.

3.3. Какова структура обычного потока?

В Spring Web Flow поток состоит из ряда шагов под названием «state» (состояние). Вход в состояние, как правило, отображается для пользователя. На этом отображении (view-state) события перехватываются (обрабатываются) данным состоянием. События могут вызывать переходы в другие состояния (transition on=» « to= » «), которые определены в данном «view-state«.

Пример ниже показывает структуру потока book hotel из предыдущей диаграммы:

Поток SWF

3.4 Как определяются потоки?

Потоки определяются разработчиками веб-приложения, используя обычный XML файл. Следующие шаги этого руководства покажут вам как это реализуется.

3.5 Основной язык элементов

3.5.1. flow

Каждый поток начинается со следующего корневого элемента (<flow .. /flow>):

Все состояния потока определяются в пределах этого элемента. Определенное первоначальное состояние потока становится его отправной точкой.

3.5.2. view-state

Используйте view-state элемент для определения шагов в потоке, для отображения необходимых view:

По соглашению, состояние (view-state) отображает свой идентификатор в шаблон, в котором находится поток. Например из примера выше состояние может отрисовать /WEB-INF/hotels/booking/enterBookingDetails.xhtml, если поток находится в директории /WEB-INF/hotels/booking.

3.5.3. transition

Используйте элемент <transition> для перехвата событий, происходящих в состоянии (view-state):

Это переход между состояниями (между разными view-state).

3.5.4. end-state

Используйте элемент <end-state> для определения выхода из потока:

Когда поток переходит в <end-state>, то он завершается и возвращает отображение.

3.5.5. Чекпоинт: Необходимые элементы языка

С тремя элементами view-state, transition и end-state, вы можете быстро реализовать логику навигации. Часто, команды реализуют её до добавления поведения потока, таким образом разработчики могут сосредоточиться на разработке пользовательского интерфейса приложения с конечными пользователями в начале. Ниже представлен пример потока, реализующего логику навигации с использованием этих элементов:

3.6. Actions

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

Поток имеет несколько точек, в которых можно выполнять действия (рассмотрены в 6 главе):

  • Старт потока (on-start)
  • Вход в состояние (on-entry)
  • Рендер представления (on-render)
  • Выполнение перехода (transition execution)
  • Выход из состояния (end-state)
  • Завершение потока (on-exit)

Действия определяются с помощью краткого языка выражений. Spring Web Flow используется Unified EL по умолчанию. Следующие несколько разделов будут охватывать основные элементы языка для определения действий.

3.6.1. evaluate

Элементы action наиболее часто используются в элементе evaluate. Используйте элемент evaluate для вычисления выражения в точке (описаны выше) в пределах вашего потока. С помощью этого одиночного тега вы можете вызывать методы Spring бинов или других переменных потока. Пример:

Присвоение полученного результата

Если выражение возвращает значение, то оно может быть сохранено в модели данных потока под названием flowScope:

Преобразование полученного результата

Если возвращаемое значение должно быть преобразовано, то необходимо указать нужный тип с помощью атрибута result-type:

3.6.2. Чекпоинт: flow actions

Теперь рассмотрим пример бронирования отеля с добавленными действиями:

Этот поток создает при старте объект Booking в области видимости потока (flow scope). ID отеля для бронирования достается из атрибута <input> потока.

3.7. Input/Output Mapping

Каждый поток имеет четко определенный вход\выход. Потоки могут получить атрибуты когда они стартуют, а так же вернуть выходные атрибуты по своему завершению. В этом смысле поток концептуально похож на вызов метода с следующей сигнатурой:

… где FlowOutcome имеет следующую сигнатуру:

3.7.5. input

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

Входные значения сохраняются в области видимости потока под именем атрибута. В примере выше, входные данные будут сохранены в атрибуте под именем hotelId.

Определение типа входных данных

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

Если входное значение не будет соответствовать указанному типу, то будет предпринята попытка преобразования к указанному типу.

Назначение входного значения

Используйте атрибут value, чтобы указать куда присвоить входное значение:

Если тип значения выражения может быть определён, то метаданные будут приведены к этому типу, если нет — необходимо задать атрибут type.

Пометка input как «требуется»

Используйте атрибут required для указания, что значение input не может быть null или пустым:

3.7.2. output

Используйте элемент output для определения атрибута при выходе из потока. Выходные атрибуты указываются в состояниях end-state и определяют выходные результаты (outcomes) потока.

Выходные значения достаются из области видимости потока по имени атрибута. Из примера выше, при выходе из потока, значения будут присвоены переменной bookingId.

3.7.3. Чекпоинт: input/output mapping

Обзор примера потока бронирования отеля с использованием input\output:

Теперь поток принимает атрибут hotelId и возвращает bookingId в качестве выходного атрибута при подтверждении бронирования.

3.8. Переменные

Поток может объявить одну или несколько переменных экземпляра. Эти переменные выделяются при запуске потока. Любые @Autowired временные ссылки, удерживаемые переменными, так же переопределяется при возобновлении потока.

3.8.1. var

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

Убедитесь, что классы, содержащие переменные, реализуют java.io.Serializable и переменная экземпляра сохраняется между запросами потока.

3.9. Области видимости переменных

Web Flow может хранить переменные в одном из нескольких областей видимости:

3.9.1. Flow Scope

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

3.9.2 .View Scope

View Scope выделяется когда поток входит в состоянии view-state и уничтожается при выходе из состояния. View scope переменные можно увидеть только из этого состояния view-state. Согласно реализации по умолчанию, любой объект сохраненный в этой области видимости должен быть сериализован.

3.9.3. Request Scope

Request scope выделяется при вызове потока и уничтожается при возврате.

3.9.4. Flash Scope

Flash scope выделяется при старте потока, очищается при каждом рендере, и уничтожается при завершении потока. Согласно реализации по умолчанию, любой объект сохраненный в этой области видимости должен быть сериализован.

3.9.5. Conversation Scope

Conversation scope вызывается при старте родительского потока и уничтожается при его завершении. Conversation scope виден в родительском потоке, а так же для всех его подпотоков. Согласно реализации по умолчанию, объекты conversation scope сохраняются в HTTP сессии и должны быть сереализованы для конкретной сессии.

Использование этой области видимости часто определяется из контекста, например зависит от того где была определена переменная — при старте определения потока (flow scope), внутри состояния (view scope) и т.д.. В других случаях, например в EL выражениях и Java коде, необходимо указывать значение явно. Следующие разделы поясняют как это можно сделать.

3.10. Вызов подпотоков

Поток может вызвать другой поток в качестве подпотока. Поток будет ждать пока подпоток вернет выходное значение, а затем отреагирует на возвращаемое значение (outcome).

3.10.1. subflow-state

Используйте элемент subflow-state для вызова другого потока в качестве подпотока:

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

Передача данных в подпоток

Используйте элемент input для передачи данных в подпоток:

Маппинг выходных данных подпотока

Просто обратитесь к выходному атрибуту подпотока по его имени на выходном переходе:

В этом примере guest — имя выходного атрибута, который возвращается выходным переходом guestCreated.

3.10.2. Чекпоинт: вызов подпотоков

Пример потока бронирования отеля с вызовом подпотока:

Поток вызывает подпоток createGuest для добавления нового гостя в гостевой список.

Share Button
4
9147 Total Views 5 Views Today

One thought on “Spring Web Flow — определение потоков (defining flows)

  1. Eugene:

    Определенное первоначальное состояние потока становится его отправной точкой.

    Это загадочное «определенное» состояние —  не что иное, как самое первое описанное в теге <flow> состояние

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