18. 系统搭建

本章将向您展示如何设置 Web Flow 系统,适用于任何网页环境。spring-doc.cadn.net.cn

18.1. Java 配置与 XML 命名空间

Web Flow 为基于 Java 和 XML 的配置提供了专用的配置支持。spring-doc.cadn.net.cn

要开始基于XML的配置,请声明Webflowconfig XML 命名空间,具体如下:spring-doc.cadn.net.cn

<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类别如下:spring-doc.cadn.net.cn

import org.springframework.context.annotation.Configuration;
import org.springframework.webflow.config.AbstractFlowConfiguration;

@Configuration
public class WebFlowConfig extends AbstractFlowConfiguration {

}

18.2. 基本系统配置

接下来的两部分展示了在你的应用中设置Web流系统所需的最小配置:spring-doc.cadn.net.cn

18.2.1. 注册aFlowRegistry

你可以在FlowRegistry以XML形式显示,具体如下:spring-doc.cadn.net.cn

<webflow:flow-registry id="flowRegistry">
    <webflow:flow-location path="/WEB-INF/flows/booking/booking.xml" />
</webflow:flow-registry>

你可以在FlowRegistry在爪哇语中,具体如下:spring-doc.cadn.net.cn

@Bean
public FlowDefinitionRegistry flowRegistry() {
    return getFlowDefinitionRegistryBuilder()
        .addFlowLocation("/WEB-INF/flows/booking/booking.xml")
        .build();
}

18.2.2. 部署 a流执行器

你可以部署一个流执行器,用于以XML形式执行流程的中央服务,具体如下:spring-doc.cadn.net.cn

<webflow:flow-executor id="flowExecutor" />

你可以部署一个流执行器,Java 中用于执行流程的中央服务:spring-doc.cadn.net.cn

@Bean
public FlowExecutor flowExecutor() {
    return getFlowExecutorBuilder(flowRegistry()).build();
}

请参阅本指南中的 Spring MVC 集成JSF 集成部分,了解如何将 Web Flow 系统分别与 MVC 和 JSF 环境集成。spring-doc.cadn.net.cn

18.3.流量注册选项

本节探讨流注册表配置选项。spring-doc.cadn.net.cn

18.3.1. 指定流的位置

你可以使用位置元素来指定你想注册的流定义路径。 默认情况程被分配等于文件名减去文件扩展名的注册表标识符,除非定义了注册表基础路径(参见流程位置基础路径)。spring-doc.cadn.net.cn

以下示例指定了 XML 中的流位置:spring-doc.cadn.net.cn

<webflow:flow-location path="/WEB-INF/flows/booking/booking.xml" />

以下示例指定了 Java 中的流位置:spring-doc.cadn.net.cn

return getFlowDefinitionRegistryBuilder()
        .addFlowLocation("/WEB-INF/flows/booking/booking.xml")
        .build();

18.3.2. 分配自定义流量标识符

你可以指定一个ID来为流程分配自定义注册表标识符。spring-doc.cadn.net.cn

以下示例展示了如何在XML中分配自定义流程标识符:spring-doc.cadn.net.cn

<webflow:flow-location path="/WEB-INF/flows/booking/booking.xml" id="bookHotel" />

以下示例展示了如何在 Java 中分配自定义流标识符:spring-doc.cadn.net.cn

return getFlowDefinitionRegistryBuilder()
        .addFlowLocation("/WEB-INF/flows/booking/booking.xml", "bookHotel")
        .build();

18.3.3. 分配流元属性

你可以使用流-定义-属性元素用于为注册流分配自定义元属性。spring-doc.cadn.net.cn

以下示例展示了如何在XML中分配流元属性:spring-doc.cadn.net.cn

<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 中分配流元属性:spring-doc.cadn.net.cn

Map<String, Object> attrs = ... ;

return getFlowDefinitionRegistryBuilder()
        .addFlowLocation("/WEB-INF/flows/booking/booking.xml", null, attrs)
        .build();

18.3.4. 通过使用位置模式来登记流

你可以使用流-位置-模式元素映射与特定资源位置模式相符的寄存器流。spring-doc.cadn.net.cn

以下示例展示了如何在 XML 中注册流程:spring-doc.cadn.net.cn

<webflow:flow-location-pattern value="/WEB-INF/flows/**/*-flow.xml" />

以下示例展示了如何在Java中注册流程:spring-doc.cadn.net.cn

return getFlowDefinitionRegistryBuilder()
        .addFlowLocationPattern("/WEB-INF/flows...
        .build();

18.3.5. 流 位置 基础路径

你可以使用基路属性来定义应用中所有流程的基准位置。 所有流的位置相对于基准路径。 基础路径可以是资源路径(例如/网-inf)或类路径上的位置(例如classpath:org/Springframework/Webflow/samples).spring-doc.cadn.net.cn

以下示例展示了如何在XML中设置基础路径:spring-doc.cadn.net.cn

<webflow:flow-registry id="flowRegistry" base-path="/WEB-INF">
    <webflow:flow-location path="/hotels/booking/booking.xml" />
</webflow:flow-registry>

以下示例展示了如何在 Java 中设置基础路径:spring-doc.cadn.net.cn

return getFlowDefinitionRegistryBuilder()
        .setBasePath("/WEB-INF")
        .addFlowLocationPattern("/hotels/booking/booking.xml")
        .build();

定义了基础路径后,分配流标识符的算法会略有变化。 流现在被分配等于其基础路径与文件名之间的路径段的注册表标识符。 例如,如果一个流定义位于/网络信息/酒店/预订/booking-flow.xml基路径为/网-inf,通往该流的剩余路径为酒店/预订,即流ID。spring-doc.cadn.net.cn

每个流程定义的目录
最佳实践是将每个流程定义打包在唯一目录中。 这提高了模块化,使得依赖资源可以与流定义打包在一起。 它还防止了使用该约定时两个流的标识符相同。

如果没有指定基路径,或者流定义直接在基准路径上,则使用文件名(去扩展名)的流 ID 赋值。 例如,如果一个流定义文件是booking.xml,流标识符简单地为预订.spring-doc.cadn.net.cn

位置模式与注册表基础路径结合时尤其强大。 而不是流标识符变成*-流,它们基于目录路径。 以下示例将基础路径与 XML 中的流位置模式结合起来:spring-doc.cadn.net.cn

<webflow:flow-registry id="flowRegistry" base-path="/WEB-INF">
    <webflow:flow-location-pattern value="/**/*-flow.xml" />
</webflow:flow-registry>

以下示例将基础路径与Java中的流位置模式结合:spring-doc.cadn.net.cn

return getFlowDefinitionRegistryBuilder()
        .setBasePath("/WEB-INF")
        .addFlowLocationPattern("...
        .build();

在前面的例子中,假设你的流位于/用户/登录,/用户/注册,/酒店/预订/航班/预订目录网内. 你最终会得到流ID用户/登录,用户/注册,酒店/预订航班/预订分别。spring-doc.cadn.net.cn

18.3.6. 配置FlowRegistry层次 结构

你可以使用父母属性用于将两个流注册表以层级方式连接起来。 当查询子注册表时,如果找不到请求的流,则委派给父程序。spring-doc.cadn.net.cn

以下示例建立了XML中两个流注册表的父关系:spring-doc.cadn.net.cn

<!-- 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中两个流注册表的父关系:spring-doc.cadn.net.cn

@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中的对象,用于自定义用于构建流程的服务和设置。 如果没有流量-构建器-服务元素被指定,默认服务实现被使用。 当元素被指定时,你只需参考你想定制的服务。spring-doc.cadn.net.cn

以下示例展示了如何用XML创建自定义流程构建服务:spring-doc.cadn.net.cn

<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 中创建自定义流程构建服务:spring-doc.cadn.net.cn

@Bean
public FlowDefinitionRegistry flowRegistry() {
	return getFlowDefinitionRegistryBuilder(flowBuilderServices())
            .addFlowLocation("/WEB-INF/flows/booking/booking.xml")
            .build();
}

@Bean
public FlowBuilderServices flowBuilderServices() {
    return getFlowBuilderServicesBuilder().build();
}

可配置的服务包括转换服务,表达式解析器视图-工厂-创建器元素(以XML形式)和转换服务,表达解析器ViewFactoryCreatorJava中的接口。 这些服务是通过引用你必须定义的自定义豆子来配置的。spring-doc.cadn.net.cn

以下示例展示了如何用XML定义可配置服务:spring-doc.cadn.net.cn

<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 中定义可配置服务:spring-doc.cadn.net.cn

@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 系统使用。 类型转换用于在流执行过程中需要时,比如处理请求参数、调用动作等,从一种类型转换到另一种类型。 支持许多常见对象类型(如数字、类和枚举)。 不过,你可能需要为自定义数据类型提供自己的类型转换和格式化逻辑。 请参阅“执行类型转换”,了解如何提供自定义类型转换逻辑。spring-doc.cadn.net.cn

使用表达式解析器

你可以使用表达式解析器属性(XML 格式)或表达解析器用于自定义表达解析器被 Web Flow 系统使用。 默认表达解析器如果类路径上有统一表达式语言(Unified Expression Language),则使用统一表达式语言(Unified Expression Language)。 否则,它使用Spring表达式语言。spring-doc.cadn.net.cn

使用 View Factory 创建器

你可以使用视图-工厂-创建器属性(XML 格式)或ViewFactoryCreator用于自定义ViewFactoryCreator被 Web Flow 系统使用。 默认ViewFactoryCreator生产能够渲染 JSP、Velocity 和 Freemarker 视图的 Spring MVC 视图工厂。spring-doc.cadn.net.cn

可配置的设置有发展. 这些设置是全局配置属性,您可以在流程构建过程中应用。spring-doc.cadn.net.cn

开发模式启动

当你创建流构建服务对象时,可以开启开发模式。 开发模式在对流定义变更(包括消息包等依赖流资源)进行热重载时切换。spring-doc.cadn.net.cn

要在 XML 中开启开发模式,请设置发展属性流量-构建器-服务元素变true. 要在 Java 中开启开发模式,请使用setDevelopment(true)FlowBuilderServices对象。spring-doc.cadn.net.cn

18.4. 设置流程执行器选项

本节探讨流执行器的配置选项。spring-doc.cadn.net.cn

18.4.1. 附加流执行监听器

你可以使用流-执行-监听器元素(以XML形式)或addFlowExecutionListener方法(在 Java 中)用于注册观察流执行生命周期的监听者。spring-doc.cadn.net.cn

以下示例展示了如何在XML中创建流执行监听器:spring-doc.cadn.net.cn

<webflow:flow-execution-listeners>
    <webflow:listener ref="securityListener"/>
    <webflow:listener ref="persistenceListener"/>
</webflow:flow-execution-listeners>

folloiwng示例展示了如何在Java中创建流执行监听器:spring-doc.cadn.net.cn

@Bean
public FlowExecutor flowExecutor() {
    return getFlowExecutorBuilder(flowRegistry())
            .addFlowExecutionListener(securityListener())
            .addFlowExecutionListener(persistenceListener())
            .build();
}

你也可以配置监听器只观察特定的流。spring-doc.cadn.net.cn

以下示例展示了如何配置监听器只监控两个 XML 流:spring-doc.cadn.net.cn

<webflow:listener ref="securityListener" criteria="securedFlow1,securedFlow2"/>

以下示例展示了如何配置监听器仅监控Java中的两个流:spring-doc.cadn.net.cn

@Bean
public FlowExecutor flowExecutor() {
    return getFlowExecutorBuilder(flowRegistry())
            .addFlowExecutionListener(securityListener(), "securedFlow1,securedFlow2")
            .build();
}

18.4.2. 调优流程执行持久性

你可以使用流-执行-存储库元素(以XML形式)或流执行器(在 Java 中)用于调优流执行持久性设置的接口。spring-doc.cadn.net.cn

以下示例对 XML 流程执行进行了调优:spring-doc.cadn.net.cn

<webflow:flow-executor id="flowExecutor" flow-registry="flowRegistry">
    <webflow:flow-execution-repository max-executions="5" max-execution-snapshots="30" />
</webflow:flow-executor>

以下示例调校了 Java 中的流执行:spring-doc.cadn.net.cn

@Bean
public FlowExecutor flowExecutor() {
    return getFlowExecutorBuilder(flowRegistry())
            .setMaxFlowExecutions(5)
            .setMaxFlowExecutionSnapshots(30)
            .build();
}
调音最大执行次数

你可以调音最大执行次数属性(以XML格式)来限制每个用户会话可创建的流执行次数。 当执行次数超过最大时,最早的执行会被移除。spring-doc.cadn.net.cn

最大执行次数属性是按用户会话计算的。 也就是说,它能在任意流定义的实例中工作。
调音最大执行快照

你可以调音最大执行快照属性用于限制每次流程执行可拍摄的历史快照数量。 要禁用快照,将此值设为0。 要启用无限数量的快照,将此值设为 -1。spring-doc.cadn.net.cn

历史快照支持浏览器返回按钮。 当快照被禁用时,按下浏览器返回按钮无法使用。 这样做会使用指向尚未记录快照的执行键。