18. 系统设置
本章介绍如何设置 Web 流系统以在任何 Web 环境中使用。
18.1. Java 配置和 XML 命名空间
Web Flow 为基于 Java 和 XML 的配置提供专用配置支持。
要开始使用基于 XML 的配置,请声明 config XML 命名空间,如下所示:webflow
<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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/webflow-config
https://www.springframework.org/schema/webflow-config/spring-webflow-config.xsd">
<!-- Setup Web Flow here -->
</beans>
要开始使用 Java 配置,请在类中扩展,如下所示:AbstractFlowConfiguration
@Configuration
@Configuration
public class WebFlowConfig extends AbstractFlowConfiguration {
}
18.2. 基本系统配置
接下来的两节显示了在应用程序中设置 Web 流系统所需的最低配置:
18.2.1. 注册FlowRegistry
您可以在 XML 中注册您的流,如下所示:FlowRegistry
<webflow:flow-registry id="flowRegistry">
<webflow:flow-location path="/WEB-INF/flows/booking/booking.xml" />
</webflow:flow-registry>
您可以在 Java 中注册您的流,如下所示:FlowRegistry
@Bean
public FlowDefinitionRegistry flowRegistry() {
return getFlowDefinitionRegistryBuilder()
.addFlowLocation("/WEB-INF/flows/booking/booking.xml")
.build();
}
18.2.2. 部署FlowExecutor
您可以部署 ,这是用于在 XML 中执行流的中央服务,如下所示:FlowExecutor
<webflow:flow-executor id="flowExecutor" />
您可以部署一个 ,这是用于在 Java 中执行流的中央服务:FlowExecutor
@Bean
public FlowExecutor flowExecutor() {
return getFlowExecutorBuilder(flowRegistry()).build();
}
有关如何将 Web 流系统与 MVC 和 JSF 环境分别集成的 Spring MVC 集成和 JSF 集成部分,请参阅本指南的 Spring MVC 集成和 JSF 集成部分。
18.3. 选项flow-registry
本节探讨 flow-registry 配置选项。
18.3.1. 指定流位置
您可以使用该元素指定要注册的流定义的路径。
默认情况下,除非定义了注册表基本路径,否则会为流程分配等于其文件名减去文件扩展名的注册表标识符(请参阅流程位置基本路径)。location
以下示例在 XML 中指定流位置:
<webflow:flow-location path="/WEB-INF/flows/booking/booking.xml" />
以下示例在 Java 中指定流位置:
return getFlowDefinitionRegistryBuilder()
.addFlowLocation("/WEB-INF/flows/booking/booking.xml")
.build();
18.3.2. 分配自定义流标识符
您可以指定一个 ID 以将自定义注册表标识符分配给流。
以下示例显示如何在 XML 中分配自定义流标识符:
<webflow:flow-location path="/WEB-INF/flows/booking/booking.xml" id="bookHotel" />
以下示例显示如何在 Java 中分配自定义流标识符:
return getFlowDefinitionRegistryBuilder()
.addFlowLocation("/WEB-INF/flows/booking/booking.xml", "bookHotel")
.build();
18.3.3. 分配 Flow 元属性
您可以使用该元素将自定义元属性分配给已注册的流。flow-definition-attributes
以下示例显示了如何在 XML 中分配流元属性:
<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 中分配流元属性:
Map<String, Object> attrs = ... ;
return getFlowDefinitionRegistryBuilder()
.addFlowLocation("/WEB-INF/flows/booking/booking.xml", null, attrs)
.build();
18.3.4. 使用位置模式注册流
您可以使用该元素注册与特定资源位置模式匹配的流。flow-location-patterns
以下示例演示如何在 XML 中注册流:
<webflow:flow-location-pattern value="/WEB-INF/flows/**/*-flow.xml" />
以下示例演示如何在 Java 中注册流:
return getFlowDefinitionRegistryBuilder()
.addFlowLocationPattern("/WEB-INF/flows...
.build();
18.3.5. 流位置基本路径
您可以使用该属性为应用程序中的所有流定义基本位置。
然后,所有流位置都相对于基本路径。
基本路径可以是资源路径(例如 )或类路径上的位置(例如 )。base-path
/WEB-INF
classpath:org/springframework/webflow/samples
以下示例演示如何在 XML 中设置基本路径:
<webflow:flow-registry id="flowRegistry" base-path="/WEB-INF">
<webflow:flow-location path="/hotels/booking/booking.xml" />
</webflow:flow-registry>
以下示例演示如何在 Java 中设置基本路径:
return getFlowDefinitionRegistryBuilder()
.setBasePath("/WEB-INF")
.addFlowLocationPattern("/hotels/booking/booking.xml")
.build();
定义基本路径后,分配流标识符的算法会略有变化。
现在,为流分配了注册表标识符,该标识符等于其基本路径和文件名之间的路径段。
例如,如果流定义位于 且基本路径为 ,则此流的剩余路径为 ,该路径将成为流 ID。/WEB-INF/hotels/booking/booking-flow.xml
/WEB-INF
hotels/booking
每个流定义的目录 最佳实践是将每个流定义打包到一个唯一的目录中。
这提高了模块化,让依赖资源与流定义打包在一起。
它还可以防止两个流在使用约定时具有相同的标识符。 |
如果未指定基本路径,或者流定义直接位于基本路径上,则使用文件名(不包括扩展名)中的流 ID 分配。
例如,如果流定义文件为 ,则流标识符仅为 。booking.xml
booking
位置模式在与注册表基路径结合使用时特别强大。
流标识符不是变成 ,而是基于目录路径。
以下示例将基本路径与 XML 中的流位置模式组合在一起:*-flow
<webflow:flow-registry id="flowRegistry" base-path="/WEB-INF">
<webflow:flow-location-pattern value="/**/*-flow.xml" />
</webflow:flow-registry>
以下示例将基本路径与 Java 中的流位置模式相结合:
return getFlowDefinitionRegistryBuilder()
.setBasePath("/WEB-INF")
.addFlowLocationPattern("...
.build();
在前面的示例中,假设您的流位于 、 、 和 目录中。
您最终将分别得到 、、 和 的流 ID。/user/login
/user/registration
/hotels/booking
/flights/booking
WEB-INF
user/login
user/registration
hotels/booking
flights/booking
18.3.6. 配置层次结构FlowRegistry
您可以使用该属性将层次结构中的两个流注册表链接在一起。
查询子注册表时,如果找不到请求的流,则会委托给其父注册表。parent
以下示例在 XML 中为两个流注册表建立父关系:
<!-- 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 中的两个流注册表建立父关系:
@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();
}
}
18.3.7. 配置自定义服务FlowBuilder
您可以使用属性(在 XML 中)或对象(在 Java 中)来自定义用于在流注册表中构建流的服务和设置。
如果未指定 element,则使用默认服务实现。
指定元素后,您只需引用要自定义的服务。flow-builder-services
FlowBuilderServices
flow-builder-services
以下示例显示如何在 XML 中创建自定义流生成器服务:
<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 中创建自定义流构建器服务:
@Bean
public FlowDefinitionRegistry flowRegistry() {
return getFlowDefinitionRegistryBuilder(flowBuilderServices())
.addFlowLocation("/WEB-INF/flows/booking/booking.xml")
.build();
}
@Bean
public FlowBuilderServices flowBuilderServices() {
return getFlowBuilderServicesBuilder().build();
}
可配置的服务是 、 和 元素(在 XML 中)和 、 和 接口(在 Java 中)。
这些服务是通过引用必须定义的自定义 bean 来配置的。conversion-service
expression-parser
view-factory-creator
ConversionService
ExpressionParser
ViewFactoryCreator
以下示例显示了如何在 XML 中定义可配置服务:
<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 中定义可配置服务:
@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
您可以使用属性(在 XML 中)或接口(在 Java 中)来自定义 Web 流系统使用的 。
类型转换用于在流程执行期间需要时(例如在处理请求参数、调用操作等)时从一种类型转换为另一种类型。
支持许多常见的对象类型(例如数字、类和枚举)。
但是,您可能需要为自定义数据类型提供自己的类型转换和格式设置逻辑。
有关如何提供自定义类型转换逻辑的重要信息,请参阅执行类型转换。conversion-service
ConversionService
ConversionService
使用 Expression Parser
您可以使用属性(在 XML 中)或接口(在 Java 中)来自定义 Web 流系统使用的 。
默认情况下,如果 Classpath 上可用,则使用 Unified Expression Language。
否则,它使用 Spring 表达式语言。expression-parser
ExpressionParser
ExpressionParser
ExpressionParser
18.4. 设置 Flow Executor 选项
本节探讨 Flow Executor 配置选项。
18.4.1. 附加流执行侦听器
您可以使用 element (在 XML 中) 或 method (在 Java 中) 来注册观察流执行生命周期的侦听器。flow-execution-listeners
addFlowExecutionListener
以下示例显示如何在 XML 中创建流执行侦听器:
<webflow:flow-execution-listeners>
<webflow:listener ref="securityListener"/>
<webflow:listener ref="persistenceListener"/>
</webflow:flow-execution-listeners>
以下示例显示了如何在 Java 中创建流执行侦听器:
@Bean
public FlowExecutor flowExecutor() {
return getFlowExecutorBuilder(flowRegistry())
.addFlowExecutionListener(securityListener())
.addFlowExecutionListener(persistenceListener())
.build();
}
您还可以将侦听器配置为仅观察某些流。
以下示例说明如何将侦听器配置为仅监控 XML 中的两个流:
<webflow:listener ref="securityListener" criteria="securedFlow1,securedFlow2"/>
以下示例说明如何将侦听器配置为仅监控 Java 中的两个流:
@Bean
public FlowExecutor flowExecutor() {
return getFlowExecutorBuilder(flowRegistry())
.addFlowExecutionListener(securityListener(), "securedFlow1,securedFlow2")
.build();
}
18.4.2. 调整 Flow 执行持久性
您可以使用元素(在 XML 中)或接口(在 Java 中)来调整流执行持久性设置。flow-execution-repository
FlowExecutor
以下示例调整 XML 中的流执行:
<webflow:flow-executor id="flowExecutor" flow-registry="flowRegistry">
<webflow:flow-execution-repository max-executions="5" max-execution-snapshots="30" />
</webflow:flow-executor>
以下示例调整 Java 中的流执行:
@Bean
public FlowExecutor flowExecutor() {
return getFlowExecutorBuilder(flowRegistry())
.setMaxFlowExecutions(5)
.setMaxFlowExecutionSnapshots(30)
.build();
}