SpringWebFlow实现产品购买流程详解
立即解锁
发布时间: 2025-08-18 00:45:36 阅读量: 2 订阅数: 6 

精通Spring MVC与Web Flow框架
### Spring Web Flow 实现产品购买流程详解
#### 1. 实现流程定义的挑战
在掌握了基本构建模块后,实现流程定义面临两大挑战:
- 定义流程的状态
- 定义状态之间可能的转换以及这些状态转换的事件驱动标准
#### 2. 第一个流程:产品购买用例
假设你有一个可构建并部署到 Servlet 容器的 Spring MVC 项目,接下来将使用 Spring Web Flow 实现产品购买用例。
##### 2.1 安装 Spring Web Flow
可在 [http://opensource2.atlassian.com/confluence/spring/display/WEBFLOW/Home](http://opensource2.atlassian.com/confluence/spring/display/WEBFLOW/Home) 找到下载和安装 Spring Web Flow 的说明。
##### 2.2 建议的流程目录结构
将 Spring Web Flow 配置信息划分为负责各自关注点的文件片段是最佳实践。以下是一个合理的目录结构示例:
```plaintext
your-domain-servlet.xml
flows.xml
Standard Spring
MVC-servlet.xml
Infrastructure common
across *all* Spring Web
Flows
WEB-INF
a-flow.xml
Definition of first
web flow
x-flow.xml
Definition of xth
web flow
a-context.xml
Bean Factory for
first web flow
x-context.xml
BeanFactory for
xth web flow
WEB-INF/flows
```
#### 3. 产品购买流程定义
流程定义可以通过多种方式实现,许多用户使用 XML 定义流程,因其可读且易于使用工具处理。也可以用 Java(通过扩展 `AbstractFlowBuilder`)或自定义格式(通过实现自定义 `FlowBuilder`)定义。这里的产品购买示例流程将使用 XML。
##### 3.1 实现第一步:视图状态
流程的第一步是输入购买信息,用户需提供以下信息:
- 产品的销售价格
- 本次订单要销售的产品数量
这是流程的起始状态,也是用户参与的视图状态。视图状态会选择一个视图进行渲染,让用户参与流程。以下是 `/WEB-INF/flows/purchase-flow.xml` 的示例代码:
```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE flow PUBLIC "-//SPRING//DTD WEBFLOW 1.0//EN"
"http://www.springframework.org/dtd/spring-webflow-1.0.dtd">
<flow start-state="enterPurchaseInformation">
<view-state id="enterPurchaseInformation" view="purchaseForm">
…
</view-state>
</flow>
```
上述代码表示:“当此流程开始执行时,进入 `enterPurchaseInformation` 状态。然后选择 `purchaseForm` 视图显示给用户,并暂停流程执行,直到收到用户事件。”
##### 3.2 转换
当前的视图状态定义不完整,所有可转换的状态类型(包括视图状态)必须定义至少一个指向其他状态的转换。转换由事件触发,视图状态事件由用户触发,用于传达用户的操作,如用户按下“提交”或“取消”按钮。以下是包含转换的 `/WEB-INF/flows/purchase-flow.xml` 代码:
```xml
<flow start-state="enterPurchaseInformation">
<view-state id="enterPurchaseInformation" view="purchaseForm">
<transition on="submit" to="requiresShipping">
<transition on="cancel" to="cancel"/>
</view-state>
</flow>
```
上述转换指令可解读为:“当提交事件发生时,转换到 `requiresShipping` 状态;当取消事件发生时,转换到 `cancel` 状态。”
##### 3.3 动作
目前已定义了一个简单的视图状态,可显示表单并响应“提交”和“取消”事件。接下来需要定义上述转换的目标状态。
大多数表单视图通常有一些典型要求,如显示前需要准备表单,即通常需要执行视图预渲染逻辑,可能加载要在表单中编辑的“支持表单对象”,或从数据库加载对象集合用于下拉菜单或选择框显示。同样,表单提交时通常需要执行提交或回发逻辑,主要涉及数据绑定(将表单输入参数复制到“支持表单对象”的属性中)和数据验证(验证表单对象的新状态)。
在 Spring Web Flow 中,通过执行实现 `org.springframework.webflow.Action` 接口的动作来调用任意命令逻辑,如预渲染和回发逻辑。以下是 `org.springframework.webflow.Action` 接口的代码:
```java
public interface Action {
Event execute(RequestContext context);
}
```
该接口简单,只有一个方法。动作在请求上下文中被调用时执行任意逻辑,执行完成后返回结果事件,调用流程可对其做出响应。
动作在流程生命周期中有多个执行点,如下表所示:
| 执行点 | 描述 |
| --- | --- |
| 流程开始时 | 流程开始时执行一个或多个“开始动作” |
| 流程结束时 | 流程结束时执行一个或多个“结束动作” |
| 状态进入时 | 状态进入时执行一个或多个“进入动作” |
| 状态退出时 | 状态退出时执行一个或多个“退出动作” |
| 转换前 | 执行转换前执行一个或多个“转换动作” |
在这个例子中,当进入 `enterPurchaseInformation` 状态时执行视图预渲染逻辑,提交转换时执行数据绑定和验证回发逻辑。以下是包含进入动作的 `/WEB-INF/flows/purchase-flow.xml` 代码:
```xml
<flow start-state="enterPurchaseInformation">
<view-state id="enterPurchaseInformation" view="purchaseForm">
<entry-actions>
<action bean="formAction" method="setupForm"/>
</entry-actions>
<transition on="submit" to="requiresShipping">
<action bean="formAction" method="bindAndValidate"/>
</transition>
<transition on="cancel" to="cancel"/>
</view-state>
</flow>
```
上述代码表示:“当此流程开始执行时,进入 `enterPurchaseInformation` 状态。状态进入时,先执行 `formAction` 的 `setupForm()` 方法。然后选择 `purchaseForm` 视图显示给用户,并暂停流程执行,直到收到用户事件。”提交转换指令表示:“当提交事件发生时,如果 `formAction` 的 `bindAndValidate()` 方法成功执行,则转换到 `requiresShipping` 状态。”
##### 3.4 动作 Bean 定义
在流程定义中引用了 `formAction` 标识符的动作 Bean,但尚未定义该标识符与具体动作实现之间的映射。Spring Web Flow 使用 Spring 驱动流程工件(如动作)的配置。以下是 `/WEB-INF/flows/purchase-flow.xml` 导入 Spring Bean 的代码:
```xml
<flow start-state="enterPurchaseInformation">
<view-state id="enterPurchaseInformation" view="purchaseForm">
<entry-actions>
<action bean="formAction" method="setupForm"/>
</entry-actions>
<transition on="submit" to="requiresShipping">
<action bean="formAction" method="bindAndValidate"/>
</transition>
<transition on="cancel" to="cancel"/>
</view-state>
<import resource="purchase-flow-context.xml"/>
</flow>
```
`/WEB-INF/flow/purchase-flo
0
0
复制全文


