Spring Web Flow — системные настройки (system setup)
10. Spring Web Flow — системные настройки (system setup)
10.1. Введение
Эта глава покажет как настроить систему Web Flow для использования в любой веб-среде.
10.2. Java конфигурация и пространство имён XML
Web Flow предоставляет полную поддержку конфигураций двух видов — Java или XML.
Чтобы начать с конфигурации через XML необходимо объявить пространство имен webflow config XML:
1 2 3 4 5 6 7 8 9 10 11 12 |
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:webflow="http://www.springframework.org/schema/webflow-config" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/webflow-config http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.4.xsd"> <!-- Setup Web Flow here --> </beans> |
Для использования Java конфигурации необходимо расширить AbstractFlowConfiguration в классе @Configuration:
1 2 3 4 5 6 7 |
import org.springframework.context.annotation.Configuration; import org.springframework.webflow.config.AbstractFlowConfiguration; @Configuration public class WebFlowConfig extends AbstractFlowConfiguration { } |
10.3. Базовая системная конфигурация
Следующий раздел показывает минимальные настройки, требующиеся для подключения системы Web Flow в ваше приложение.
10.3.1. FlowRegistry
Зарегистрируйте ваши потоки в FlowRegistry используя XML:
1 2 3 |
<webflow:flow-registry id="flowRegistry"> <webflow:flow-location path="/WEB-INF/flows/booking/booking.xml" /> </webflow:flow-registry> |
Зарегистрируйте ваши потоки в FlowRegistry с использованием Java:
1 2 3 4 5 6 |
@Bean public FlowDefinitionRegistry flowRegistry() { return getFlowDefinitionRegistryBuilder() .addFlowLocation("/WEB-INF/flows/booking/booking.xml") .build(); } |
10.3.2. FlowExecutor
Разверните FlowExecutor — главный сервис для выполнения потоков с использованием XML:
1 |
<span class="hl-tag"><webflow:flow-executor</span> <span class="hl-attribute">id</span>=<span class="hl-value">"flowExecutor"</span><span class="hl-tag"> /></span> |
Разверните FlowExecutor — главный сервис для выполнения потоков с использованием Java:
1 2 3 4 |
@Bean public FlowExecutor flowExecutor() { return getFlowExecutorBuilder(flowRegistry()).build(); } |
Обратитесь к разделам Spring MVC и Spring Faces данного руководства, чтобы узнать как объединить Web Flow с MVC и JSF окружением соответственно.
10.4. Опции flow-registry
Этот раздел рассматривает различные опции настроек flow-registry.
10.4.1. Указание местоположения потока
Используйте элемент location для указания пути к файлу описания потока. По умолчанию потокам будут назначены идентификаторы соответствующие их именам файлов без расширения, в случае, если не указан другой путь.
В XML:
1 |
<webflow:flow-location path="/WEB-INF/flows/booking/booking.xml" /> |
В Java:
1 2 3 |
return getFlowDefinitionRegistryBuilder() .addFlowLocation("/WEB-INF/flows/booking/booking.xml") .build(); |
10.4.2. Назначение собственного идентификатора потока
Укажите id для присвоения собственного идентификатора потока. XML:
1 |
<webflow:flow-location path="/WEB-INF/flows/booking/booking.xml" id="bookHotel" /> |
Укажите id для присвоения собственного идентификатора потока. Java:
1 2 3 |
return getFlowDefinitionRegistryBuilder() .addFlowLocation("/WEB-INF/flows/booking/booking.xml", "bookHotel") .build(); |
10.4.3. Назначение мета-атрибутов потока
Используйте элемент flow-definition-attributes для указания собственных мета-атрибутов в зарегистрированном потоке.
В XML:
1 2 3 4 5 |
<webflow:flow-location path="/WEB-INF/flows/booking/booking.xml"> <webflow:flow-definition-attributes> <webflow:attribute name="caption" value="Books a hotel" /> </webflow:flow-definition-attributes> </webflow:flow-location> |
В Java:
1 2 3 4 5 |
Map<String, Object> attrs = ... ; return getFlowDefinitionRegistryBuilder() .addFlowLocation("/WEB-INF/flows/booking/booking.xml", null, attrs) .build(); |
10.4.4. Регистрация потоков с использованием шаблона местонахождения
Используйте элемент flow-location-patterns для регистрации потоков, соответствующих шаблону местонахождения ресурсов:
XML:
1 |
<webflow:flow-location-pattern value="/WEB-INF/flows/**/*-flow.xml" /> |
Java:
1 2 3 |
return getFlowDefinitionRegistryBuilder() .addFlowLocationPattern("/WEB-INF/flows/**/*-flow.xml") .build(); |
10.4.5. Базовый путь местонахождения потоков
Используйте атрибут base-path для определения базового местонахождения всех потоков в приложении. Все местонахождения потоков будут относительными к базовому пути. Базовый путь может быть путём к ресурсам, таким как ‘/WEB-INF’ или ‘classpath:org/springframework/webflow/samples’.
XML:
1 2 3 |
<webflow:flow-registry id="flowRegistry" base-path="/WEB-INF"> <webflow:flow-location path="/hotels/booking/booking.xml" /> </webflow:flow-registry> |
Java:
1 2 3 4 |
return getFlowDefinitionRegistryBuilder() .setBasePath("/WEB-INF") .addFlowLocationPattern("/hotels/booking/booking.xml") .build(); |
После указания базового пути алгоритм присвоения идентификаторов потока немного изменится. Теперь потоки будут доступны по идентификаторам соответствующими сегменту между базовым путем и именем файла. Например, если поток определен в ‘/WEB-INF/hotels/booking/booking-flow.xml’ и базовый путь указан как ‘/WEB-INF’ то оставшийся путь к этому потоку ‘hotels/booking’ станет id потока.
Директория для определения потока | |
---|---|
Напомним, что лучшей практикой является распределение каждого потока в уникальную директорию. Это улучшает модульность, а так же позволяет расположить зависимые ресурсы в папке где определен поток. Это также предотвратит наличие у двух потоков одинаковых идентификаторов при использовании этого соглашения при присвоении идентификаторов. |
Если базовый путь не назначен или если определение потока находится прямо в базовой директории, то поток получит идентификатор по имени файла без расширения. Для примера, если поток определен в файле ‘booking.xml’, то идентификатором потока будет просто ‘booking’.
Шаблоны местонахождения являются особенно мощны в сочетании с регистрацией базового пути. В замен идентификатора потока вроде ‘*-flow‘, они будут основаны на базовой директории. Пример в XML:
1 2 3 |
<webflow:flow-registry id="flowRegistry" base-path="/WEB-INF"> <webflow:flow-location-pattern value="/**/*-flow.xml" /> </webflow:flow-registry> |
Java:
1 2 3 4 |
return getFlowDefinitionRegistryBuilder() .setBasePath("/WEB-INF") .addFlowLocationPattern("/**/*-flow.xml") .build(); |
В примере выше, если предположить, что потоки расположены в директориях /user/login, /user/registration, /hotels/booking и /flights/booking внутри WEB-INF, то идентификаторы id будут соответственно: user/login, user/registration, hotels/booking и flights/booking.
10.4.6. Конфигурирование иерархии FlowRegistry
Используйте атрибут parent для указания иерархии двух зарегистрированных потоков. В случае, если не будет найден запрашиваемый дочерний поток, то запрос будет передан его родителю.
XML:
1 2 3 4 5 6 7 8 9 |
<!-- my-system-config.xml --> <webflow:flow-registry id="flowRegistry" parent="sharedFlowRegistry"> <webflow:flow-location path="/WEB-INF/flows/booking/booking.xml" /> </webflow:flow-registry> <!-- shared-config.xml --> <webflow:flow-registry id="sharedFlowRegistry"> <!-- Global flows shared by several applications --> </webflow:flow-registry> |
Java:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
@Configuration public class WebFlowConfig extends AbstractFlowConfiguration { @Autowired private SharedConfig sharedConfig; @Bean public FlowDefinitionRegistry flowRegistry() { return getFlowDefinitionRegistryBuilder() .setParent(this.sharedConfig.sharedFlowRegistry()) .addFlowLocation("/WEB-INF/flows/booking/booking.xml") .build(); } } @Configuration public class SharedConfig extends AbstractFlowConfiguration { @Bean public FlowDefinitionRegistry sharedFlowRegistry() { return getFlowDefinitionRegistryBuilder() .addFlowLocation("/WEB-INF/flows/shared.xml") .build(); } } |
10.4.7. Конфигурирование собственного сервиса FlowBuilder
Используйте атрибут flow-builder-services для модификации сервисов и настроек, используемых для создания потоков в flow-registry. Если не указан тег flow-builder-services, то будет использована реализация по умолчанию. Когда тег определен, то необходимо указать ссылки на сервисы, которые будут использованы в собственных настройках.
XML:
1 2 3 4 5 |
<webflow:flow-registry id="flowRegistry" flow-builder-services="flowBuilderServices"> <webflow:flow-location path="/WEB-INF/flows/booking/booking.xml" /> </webflow:flow-registry> <webflow:flow-builder-services id="flowBuilderServices" /> |
Java:
1 2 3 4 5 6 7 8 9 10 11 |
@Bean public FlowDefinitionRegistry flowRegistry() { return getFlowDefinitionRegistryBuilder(flowBuilderServices()) .addFlowLocation("/WEB-INF/flows/booking/booking.xml") .build(); } @Bean public FlowBuilderServices flowBuilderServices() { return getFlowBuilderServicesBuilder().build(); } |
Сервисы, которые нужно модифицировать это — onversion-service, expression-parser и view-factory-creator.
Эти сервисы настраиваются путем указания ссылки на собственные бины, которые вы определили.
Пример с использованием XML:
1 2 3 4 5 6 7 8 |
<webflow:flow-builder-services id="flowBuilderServices" conversion-service="conversionService" expression-parser="expressionParser" view-factory-creator="viewFactoryCreator" /> <bean id="conversionService" class="..." /> <bean id="expressionParser" class="..." /> <bean id="viewFactoryCreator" class="..." /> |
Java:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
@Bean public FlowBuilderServices flowBuilderServices() { return getFlowBuilderServicesBuilder() .setConversionService(conversionService()) .setExpressionParser(expressionParser) .setViewFactoryCreator(mvcViewFactoryCreator()) .build(); } @Bean public ConversionService conversionService() { // ... } @Bean public ExpressionParser expressionParser() { // ... } @Bean public ViewFactoryCreator viewFactoryCreator() { // ... } |
conversion-service
Используйте атрибут conversion-service для модификации ConversionService, используемого системой Web Flow. Тип преобразования используется для конвертации из одного типа в другой, когда это требуется при выполнении потока, например при обработке параметров запроса, внедрения действий и т.д.. Поддерживается большинство общих типов объектов, таких как числа, классы и перечисления. Однако вам возможно понадобится свой собственный тип преобразования или форматирования для собственных типов данных. Для этого обратитесь к Section 5.7, “Performing type conversion” для получения важной информации по предоставлению собственной логики преобразования типов.
expression-parser
Используйте атрибут expression-parser для модификации ExpressionParser, использующегося системой Web Flow. По умолчанию ExpressionParser использует Unified EL если он доступен в classpath, в противном случае используется OGNL.
view-factory-creator
Используйте атрибут view-factory-creator для модификации ViewFactoryCreator, использующегося системой Web Flow. Использующийся по умолчанию ViewFactoryCreator предоставляется Spring MVC ViewFactories способный к отрисовке представлений JSP, Velocity и Freemarker.
Настраиваемые настройки это development. Эти настройки — глобальные конфигурационные атрибуты, которые могут быть доступны на протяжении всего процесса построения потока.
development
Установите в значение true, чтобы переключить поток в development mode. Development mode переключает в горячую перезагрузку изменений в описании потока, включая изменения в зависимых для потока ресурсах, например в message bundles.
10.5. Опции flow-executor
В этом разделе рассматриваются опции настройки flow-executor.
10.5.1. Прикрепление слушателей flow execution
Используйте элемент flow-execution-listeners для регистрации слушателя, который будет наблюдать на протяжении жизненного цикла выполнения потока. Пример XML:
1 2 3 4 |
<webflow:flow-execution-listeners> <webflow:listener ref="securityListener"/> <webflow:listener ref="persistenceListener"/> </webflow:flow-execution-listeners> |
Java:
1 2 3 4 5 6 7 |
@Bean public FlowExecutor flowExecutor() { return getFlowExecutorBuilder(flowRegistry()) .addFlowExecutionListener(securityListener()) .addFlowExecutionListener(persistenceListener()) .build(); } |
Вы также можете настроить слушателя для наблюдения только за конкретными потоками. Пример XML:
1 |
<webflow:listener ref="securityListener" criteria="securedFlow1,securedFlow2"/> |
Java:
1 2 3 4 5 6 |
@Bean public FlowExecutor flowExecutor() { return getFlowExecutorBuilder(flowRegistry()) .addFlowExecutionListener(securityListener(), "securedFlow1,securedFlow2") .build(); } |
10.5.2. Настройка персистенции FlowExecution
Используйте элемент flow-execution-repository для дополнения к настройкам персистентности.
XML:
1 2 3 |
<webflow:flow-executor id="flowExecutor" flow-registry="flowRegistry"> <webflow:flow-execution-repository max-executions="5" max-execution-snapshots="30" /> </webflow:flow-executor> |
Java:
1 2 3 4 5 6 7 |
@Bean public FlowExecutor flowExecutor() { return getFlowExecutorBuilder(flowRegistry()) .setMaxFlowExecutions(5) .setMaxFlowExecutionSnapshots(30) .build(); } |
max-executions
Настройте атрибут max-executions aдля указания числа выполняемых потоков, которые могут быть созданы на протяжении пользовательской сессии. Когда будет достигнуто максимальное кол-во выполняемых потоков, то наиболее старые будут удалены.
Важно | |
---|---|
Атрибут max-executions указывается для пользовательской сессии, таким образом он будет работать внутри любого экземпляра из определения потока |
max-execution-snapshots
Настройте атрибут max-execution-snapshots для указания числа сохраняемых snapshots, которые можно получить на протяжении выполнения потока. Для отключения snapshotting, установите значение в 0. Для включения неограниченного количества, установите значение в -1.
Важно | |
---|---|
История snapshots включает поддержку кнопки назад в браузере. Если snapshotting выключено, то кнопка назад в браузере работать не будет.Это результат попытки запроса выполняемого ключа, который указывает на snapshot, но не может быть записан. |