Главная » Spring » Элементы последовательности операций Spring

0

В Spring Web Flow последовательность операций (flow) опреде- ляется тремя основными элементами: состояниями, переходами и данными последовательности.

Состояния – это точки в последовательности, где что-то проис-

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

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

Если состояния в последовательности можно сравнить с точками на карте, где выполняются остановки, то переходы – это дороги, со- единяющие эти точки. Выполняя последовательность, приложение перемещается от одного состояния к другому посредством переходов.

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

Посмотрим, как эти три элемента определяются в Spring Web Flow.

Состояния

Фреймворк Spring Web Flow определяет пять различных типов состояний, которые перечислены в табл. 9.1.

Набор состояний, предоставляемых фреймворком Spring Web Flow, позволяет конструировать диалоговые веб-приложения прак- тически любой сложности. Разумеется, далеко не все последователь- ности требуют использования всех состояний, описанных в табл. 9.1, но рано или поздно вам наверняка придется использовать их все.

Таблица 9.1. Набор состояний, определяемых фреймворком Spring Web Flow

Состояние

Описание

Действие

Действие – это место в последовательности, где выполняется некоторая логика

Решение

Решение – это точка ветвления последовательности на два направления, исходя из накопленных данных

Конец

Конец – это последняя остановка в последовательности.

По достижении этого состояния выполнение последователь- ности завершается

Подпоследо- вательность

В состоянии «подпоследовательность» запускается новая последовательность, выполняющаяся в контексте текущей последовательности

Представление

Представление вызывает приостановку последовательности и дает пользователю возможность принять участие

в процессе выполнения

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

Состояния-представления

Состояния-представления используются для вывода информа- ции и дают пользователю возможность принять активное участие в выполнении последовательности. Фактически роль состояния- представления может играть любое представление, поддерживаемое фреймворком Spring MVC, но чаще всего они реализуются в виде страниц JSP.

Для объявления состояния-представления в XML-файле с опре- делением последовательности используется элемент <view-state>:

<view-state  id="welcome"  />

В этом простом примере атрибут id играет двоякую роль. Во- первых, он идентифицирует состояние внутри последовательности. А во-вторых, поскольку здесь отсутствует явная ссылка на пред- ставление, определяет логическое имя представления welcome, кото- рое должно отображаться при достижении данного состояния.

При необходимости с помощью атрибута view можно явно указать логическое имя используемого представления:

<view-state  id="welcome"  view="greeting"  />

Если представление является формой, в атрибуте model можно указать объект, который должен быть связан с формой:

<view-state id="takePayment" model="flowScope.paymentDetails"/>

Здесь определено, что форма в представлении takePayment должна быть связана с объектом paymentDetails, в области видимости данной последовательности. (Подробнее об областях видимости последова- тельностей и данных рассказывается ниже.)

Состояния-действия

Состояния-представления вовлекают в работу последовательно- сти пользователя, а состояния-действия сами выполняют некоторую работу. Состояния-действия обычно вызывают некоторые методы

компонентов, управляемых фреймворком Spring, и затем выпол- няют переход к другому состоянию, в зависимости от результатов, возвращаемых методом.

В определении последовательности состояния-действия объявля- ются с помощью элемента <action-state>. Например:

<action-state  id="saveOrder">

<evaluate expression="pizzaFlowActions.saveOrder(order)" />

<transition to="thankYou" />

</action-state>

Хотя это и не обязательно, но элементы <action-state> часто включают вложенный элемент <evaluate>. Этот элемент дает состоя- нию-действию возможность выполнить некоторую работу. Атрибут expression определяет выражение, которое должно быть вычислено при входе в состояние. В данном случае в атрибуте expression ука- зано выражение на языке SpEL1, которое должно вызвать метод saveOrder()  компонента с идентификатором pizzaFlowActions.

Состояния-решения

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

Состояния-решения позволяют продолжить выполнение последо- вательности в одном из двух направлений. Состояние-решение вы- числяет логическое выражение и, исходя из результата, выбирает один из двух переходов. В определении последовательности состоя- ния-решения объявляются с помощью элемента <decision-state>. Ни- же представлен типичный пример объявления состояния-решения:

<decision-state id="checkDeliveryArea">

<if    test="pizzaFlowActions.checkDeliveryArea(customer.zipCode)" then="addCustomer"

else="deliveryWarning" />

</decision-state>

1 Начиная с версии 2.1.0, фреймворк Spring Web Flow использует язык вы- ражений Spring Expression Language, но при желании можно также ис- пользовать OGNL или Unified EL.

Как видите, элемент <decision-state> действует не в одиночку. Основой состояния-решения является элемент <if>. Именно в нем вычисляется выражение. Если выражение вернет true, последова- тельность выполнит переход к состоянию, определяемому атрибу- том then. В противном случае будет выполнен переход к состоянию, определяемому атрибутом else.

Состояния-подпоследовательности

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

Точно так же бывает полезно разбить последовательность на дис- кретные части. Элемент <subflow-state> позволяет вызвать другую последовательность из текущей последовательности. Это напоми- нает вызов метода из другого метода.

Ниже приводится пример объявления элемента <subflow-state>:

<subflow-state id="order"  subflow="pizza/order">

<input  name="order"  value="order"/>

<transition on="orderCreated" to="payment" />

</subflow-state>

Здесь элемент <input> используется для передачи объекта заказа в подпоследовательность. И, если подпоследовательность завершит- ся в конечном состоянии <end-state> с идентификатором orderCreated, текущая последовательность выполнит переход к состоянию с иден- тификатором payment.

Но не будем забегать вперед. Мы еще не знакомы с элементом <end- state> и с переходами. О переходах рассказывается в разделе 9.2.2. А что касается конечных состояний, рассмотрим их прямо сейчас.

Конечные состояния

Рано или поздно выполнение любой последовательности должно завершиться. Именно это и случится по достижении конечного со- стояния. Элемент <end-state> обозначает конец последовательности и обычно объявляется, как показано ниже:

<end-state  id="customerReady"  />

Когда последовательность достигает элемента <end-state>, ее вы- полнение завершается. Что происходит дальше, зависит от несколь- ких факторов.

# Если завершившаяся последовательность является подпосле- довательностью, управление вернется вызвавшей последова- тельности, которая продолжит выполнение с элемента <subflow- state>. Значение атрибута id элемента <end-state> будет ис- пользоваться как имя события для перехода из состояния

<subflow-state>.

# Если элемент <end-state> имеет атрибут view, будет отображено указанное в нем представление. Имя представления в атри- буте view может определять путь к шаблону представления относительно последовательности, предваряться приставкой externalRedirect: для ссылки на внешнюю для последователь- ности  страницу  или  приставкой  flowRedirect:  для  перехода в другую последовательность.

# Если завершившаяся последовательность не является подпо-

следовательностью и атрибут view в элементе <end-state> не определен, тогда последовательность просто завершит выпол- нение. Браузер остановится на базовом URL последователь- ности, при повторном обращении к которому (в отсутствие ак- тивной последовательности) будет запущен новый экземпляр последовательности.

Важно понимать, что последовательность может иметь несколько конечных состояний. Поскольку идентификатор конечного состоя- ния определяет имя события, возбуждаемого в элементе <subflow- state>, иногда бывает желательно обеспечить возможность заверше- ния последовательности в разных точках, чтобы возбудить разные события в вызывающей последовательности. Даже последователь- ности, которые никогда не будут вызываться как подпоследователь- ности, могут иметь несколько конечных состояний, отображающих различные конечные страницы, в зависимости от условий, сложив- шихся к моменту завершения.

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

Источник:   Уоллс К., Spring в действии. – М.: ДМК Пресс, 2013. – 752 с.: ил.

По теме:

  • Комментарии