18. 系统搭建
本章将向您展示如何设置 Web Flow 系统,适用于任何网页环境。
18.1. Java 配置与 XML 命名空间
Web Flow 为基于 Java 和 XML 的配置提供了专用的配置支持。
要开始基于XML的配置,请声明Webflowconfig XML 命名空间,具体如下:
<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 配置扩展抽象流配置在@Configuration类别如下:
@Configuration
public class WebFlowConfig extends AbstractFlowConfiguration {
}
18.2. 基本系统配置
接下来的两部分展示了在你的应用中设置Web流系统所需的最小配置:
18.2.1. 注册aFlowRegistry
你可以在FlowRegistry以XML形式显示,具体如下:
<webflow:flow-registry id="flowRegistry">
<webflow:flow-location path="/WEB-INF/flows/booking/booking.xml" />
</webflow:flow-registry>
你可以在FlowRegistry在爪哇语中,具体如下:
@Bean
public FlowDefinitionRegistry flowRegistry() {
return getFlowDefinitionRegistryBuilder()
.addFlowLocation("/WEB-INF/flows/booking/booking.xml")
.build();
}
18.2.2. 部署 a流执行器
你可以部署一个流执行器,用于以XML形式执行流程的中央服务,具体如下:
<webflow:flow-executor id="flowExecutor" />
你可以部署一个流执行器,Java 中用于执行流程的中央服务:
@Bean
public FlowExecutor flowExecutor() {
return getFlowExecutorBuilder(flowRegistry()).build();
}
请参阅本指南中的 Spring MVC 集成和 JSF 集成部分,了解如何将 Web Flow 系统分别与 MVC 和 JSF 环境集成。
18.3.流量注册选项
本节探讨流注册表配置选项。
18.3.1. 指定流的位置
你可以使用位置元素来指定你想注册的流定义路径。
默认情况程被分配等于文件名减去文件扩展名的注册表标识符,除非定义了注册表基础路径(参见流程位置基础路径)。
以下示例指定了 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. 分配流元属性
你可以使用流-定义-属性元素用于为注册流分配自定义元属性。
以下示例展示了如何在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. 通过使用位置模式来登记流
你可以使用流-位置-模式元素映射与特定资源位置模式相符的寄存器流。
以下示例展示了如何在 XML 中注册流程:
<webflow:flow-location-pattern value="/WEB-INF/flows/**/*-flow.xml" />
以下示例展示了如何在Java中注册流程:
return getFlowDefinitionRegistryBuilder()
.addFlowLocationPattern("/WEB-INF/flows...
.build();
18.3.5. 流 位置 基础路径
你可以使用基路属性来定义应用中所有流程的基准位置。
所有流的位置相对于基准路径。
基础路径可以是资源路径(例如/网-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();
定义了基础路径后,分配流标识符的算法会略有变化。
流现在被分配等于其基础路径与文件名之间的路径段的注册表标识符。
例如,如果一个流定义位于/网络信息/酒店/预订/booking-flow.xml基路径为/网-inf,通往该流的剩余路径为酒店/预订,即流ID。
|
每个流程定义的目录 最佳实践是将每个流程定义打包在唯一目录中。
这提高了模块化,使得依赖资源可以与流定义打包在一起。
它还防止了使用该约定时两个流的标识符相同。 |
如果没有指定基路径,或者流定义直接在基准路径上,则使用文件名(去扩展名)的流 ID 赋值。
例如,如果一个流定义文件是booking.xml,流标识符简单地为预订.
位置模式与注册表基础路径结合时尤其强大。
而不是流标识符变成*-流,它们基于目录路径。
以下示例将基础路径与 XML 中的流位置模式结合起来:
<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用户/登录,用户/注册,酒店/预订和航班/预订分别。
18.3.6. 配置FlowRegistry层次 结构
你可以使用父母属性用于将两个流注册表以层级方式连接起来。
当查询子注册表时,如果找不到请求的流,则委派给父程序。
以下示例建立了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. 配置自定义流构建器服务业
你可以使用流量-构建器-服务属性(XML 格式)或FlowBuilderServicesJava中的对象,用于自定义用于构建流程的服务和设置。
如果没有流量-构建器-服务元素被指定,默认服务实现被使用。
当元素被指定时,你只需参考你想定制的服务。
以下示例展示了如何用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形式)和转换服务,表达解析器和ViewFactoryCreatorJava中的接口。
这些服务是通过引用你必须定义的自定义豆子来配置的。
以下示例展示了如何用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() {
// ...
}
使用转换服务
你可以使用转换服务属性(XML 格式)或转换服务用于自定义转换服务被 Web Flow 系统使用。
类型转换用于在流执行过程中需要时,比如处理请求参数、调用动作等,从一种类型转换到另一种类型。
支持许多常见对象类型(如数字、类和枚举)。
不过,你可能需要为自定义数据类型提供自己的类型转换和格式化逻辑。
请参阅“执行类型转换”,了解如何提供自定义类型转换逻辑。
使用表达式解析器
你可以使用表达式解析器属性(XML 格式)或表达解析器用于自定义表达解析器被 Web Flow 系统使用。
默认表达解析器如果类路径上有统一表达式语言(Unified Expression Language),则使用统一表达式语言(Unified Expression Language)。
否则,它使用Spring表达式语言。
18.4. 设置流程执行器选项
本节探讨流执行器的配置选项。
18.4.1. 附加流执行监听器
你可以使用流-执行-监听器元素(以XML形式)或addFlowExecutionListener方法(在 Java 中)用于注册观察流执行生命周期的监听者。
以下示例展示了如何在XML中创建流执行监听器:
<webflow:flow-execution-listeners>
<webflow:listener ref="securityListener"/>
<webflow:listener ref="persistenceListener"/>
</webflow:flow-execution-listeners>
folloiwng示例展示了如何在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. 调优流程执行持久性
你可以使用流-执行-存储库元素(以XML形式)或流执行器(在 Java 中)用于调优流执行持久性设置的接口。
以下示例对 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();
}