Главная » Spring » Интеграция Spring Web Flow с другими фреймворками

0

В этой главе мы занимались созданием веб-приложения на осно- ве фреймворка Spring Web Flow, входящего в состав Spring MVC. Однако, возможно, кому-то будет интересно узнать, что Spring Web

Flow не требует обязательного использования Spring MVC. Факти- чески фреймворк Spring Web Flow обладает встроенной поддержкой следующих фреймворков:

#  Jakarta Struts;

#  JavaServer Faces;

#  Spring Portlet MVC.

В списке проблем фреймворка Spring Web Flow открытой оста- ется проблема интеграции с фреймворком WebWork 2 (который, по всей видимости, также должен работать в Struts 2). Познакомиться с проблемами интеграции с фреймворком WebWork, а также с со- стоянием дел в этом направлении можно по адресу: http://opensource. atlassian.com/projects/spring/browse/SWF-76.

Независимо от того, какой веб-фреймворк будет выбран для встраивания последовательностей, определение этих последова- тельностей останется переносимым для всех поддерживаемых фреймворков. Единственное отличие между ними составляют точ- ки интеграции (например, в приложениях на основе Spring MVC используется компонент FlowController, а в приложениях на основе Struts – компонент FlowAction).

Прежде чем завершить обсуждение фреймворка Spring Web Flow, посмотрим, как Spring Web Flow обеспечивает поддержку интегра- ции с фреймворком JSF.

JavaServer Faces

Чтобы иметь возможность определять последовательности Spring Web Flow в приложениях на основе фреймворка JSF, в файле faces- config.xml необходимо настроить некоторые элементы Spring Web Flow. Эти настройки демонстрируются в следующем фрагменте файла   faces-config.xml:

<application>

<navigation-handler> org.springframework.webflow.executor.jsf.FlowNavigationHandler

</navigation-handler>

<property-resolver> org.springframework.webflow.executor.jsf.FlowPropertyResolver

</property-resolver>

<variable-resolver> org.springframework.webflow.executor.jsf.FlowVariableResolver

</variable-resolver>

<variable-resolver> org.springframework.web.jsf.DelegatingVariableResolver

</variable-resolver>

<variable-resolver> org.springframework.web.jsf.WebApplicationContextVariableResolver

</variable-resolver>

</application>

Навигация в JSF обычно реализуется с применением элементов

<navigation-rule> в файле faces-config.xml. Однако в Spring Web Flow навигация реализуется с применением элементов <transition>. По- этому, чтобы обеспечить интеграцию фреймворка Spring Web Flow с JSF, необходимо настроить компонент FlowNavigationHandler, обра- ботчик механизма навигации, использующий определение последо- вательности для реализации навигации в пределах последователь- ности (с возвратом к использованию компонента NavigationHandler при выполнении вне последовательности).

Кроме того, нам может понадобиться обращаться из JSF к пере- менным и их свойствам в области видимости последовательности. К сожалению, механизм JSF доступа к переменным и свойствам по умолчанию ничего не знает о переменных в области видимости по- следовательностей. Однако в Spring Web Flow имеются компоненты FlowVariableResolver и FlowPropertyResolver, позволяющие фреймворку JSF отыскивать данные последовательностей, снабженные префик- сом flowScope   (например,  flowScope.order.total).

Кроме того, необходимо настроить еще два механизма разреше- ния переменных: компоненты DelegatingVariableResolver и WebApplicat ionContextVariableResolver. Эти компоненты удобно использовать для обращения к переменным JSF как к компонентам из контекста при- ложения Spring.

Наконец, для интеграции фреймворка Spring Web Flow с JSF необходимо добавить еще одну настройку в файл faces-config.xml. Информация, касающаяся выполнения последовательности, должна сохраняться между запросами и восстанавливаться в начале обра- ботки каждого запроса. Для этого можно использовать компонент FlowPhaseListener, входящий в состав Spring Web Flow, который явля- ется реализацией интерфейса PhaseListener в JSF и управляет выпол- нением последовательности от имени JSF. Ниже приводится пример настройки компонента в файле faces-config.xml:

<lifecycle>

<phase-listener>

org.springframework.webflow.executor.jsf.FlowPhaseListener

</phase-listener>

</lifecycle>

Компонент FlowPhaseListener решает три задачи, каждая из кото- рых связана с определенным этапом в жизненном цикле JSF:

# на этапе BEFORE_RESTORE_VIEW компонент FlowPhaseListener вос-

станавливает информацию о выполнении последовательно- сти, опираясь на идентификатор в аргументах запроса (если указан), определяющий блок информации для выполняемой последовательности;

# на этапе BEFORE_RENDER_RESPONSE компонент FlowPhaseListener соз-

дает новый идентификатор сохраняемого блока информации для выполняемой последовательности;

# на этапе AFTER_RENDER_RESPONSE компонент FlowPhaseListener со-

храняет блок информации для выполняемой последователь- ности, используя идентификатор, сгенерированный на этапе BEFORE_RENDER_RESPONSE.

После добавления в файл faces-config.xml всех необходимых опре- делений можно начинать пользоваться последовательностями. Сле- дующий фрагмент JSF создает ссылку, запускающую последователь- ность с именем Order-flow:

<h:commandLink

value="Order Pizza" action="flowId:Order-flow"/>

В заключение

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

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

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

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

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

По теме:

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