- 作者简介
- 内容提要
- 关于本书
- 路线图
- 代码规范与下载
- 作者在线
- 封面插图简介
- 前言
- 译者序
- 致谢
- 第1部分 Spring 的核心
- 第1章 Spring 之旅
- 第2章 装配 Bean
- 第3章 高级装配
- 第4章 面向切面的 Spring
- 第2部分 Web 中的 Spring
- 第5章 构建 Spring Web 应用程序
- 第6章 渲染 Web 视图
- 第7章 Spring MVC 的高级技术
- 第8章 使用 Spring Web Flow
- 第9章 保护 Web 应用
- 第3部分 后端中的 Spring
- 第10章 通过 Spring 和 JDBC 征服数据库
- 第11章 使用对象-关系映射持久化数据
- 第12章 使用 NoSQL 数据库
- 第13章 缓存数据
- 第14章 保护方法应用
- 第4部分 Spring 集成
- 第15章 使用远程服务
- 第16章 使用 Spring MVC 创建 REST API
- 第17章 Spring消息
- 第18章 使用 WebSocket 和 STOMP 实现消息功能
- 第19章 使用 Spring 发送 Email
- 第20章 使用 JMX 管理 Spring Bean
- 第21章 借助 Spring Boot 简化 Spring 开发
8.2.1 状态
Spring Web Flow定义了五种不同类型的状态,如表8.1所示。通过选择Spring Web Flow的状态几乎可以把任意的安排功能构造成会话式的Web应用。尽管并不是所有的流程都需要表8.1所描述的状态,但最终你可能会经常使用它们中的大多数。
表8.1 Spring Web Flow可供选择的状态
状 态 类 型 | 它是用来做什么的 |
行为(Action) | 行为状态是流程逻辑发生的地方 |
决策(Decision) | 决策状态将流程分成两个方向,它会基于流程数据的评估结果确定流程方向 |
结束(End) | 结束状态是流程的最后一站。一旦进入End状态,流程就会终止 |
子流程(Subflow) | 子流程状态会在当前正在运行的流程上下文中启动一个新的流程 |
视图(View) | 视图状态会暂停流程并邀请用户参与流程 |
稍后我们将会看到如何将这些不同类型的状态组合起来形成一个完整的流程。但首先,让我们了解一下这些流程元素在Spring Web Flow定义中是如何表现的。
视图状态
视图状态用于为用户展现信息并使用户在流程中发挥作用。实际的视图实现可以是Spring支持的任意视图类型,但通常是用JSP来实现的。
在流程定义的XML文件中,<view-state>用于定义视图状态:
在这个简单的示例中,id属性有两个含义。它在流程内标示这个状态。除此以外,因为在这里没有在其他地方指定视图,所以它也指定了流程到达这个状态时要展现的逻辑视图名为welcome。
如果你愿意显式指定另外一个视图名,那可以使用view属性做到这一点:
如果流程为用户展现了一个表单,你可能希望指明表单所绑定的对象。为了做到这一点,可以设置model属性:
这里我们指定takePayment视图中的表单将绑定流程作用域内的paymentDetails对象。(稍后,我们将会更详细地介绍流程作用域和数据。)
行为状态
视图状态会涉及到流程应用程序的用户,而行为状态则是应用程序自身在执行任务。行为状态一般会触发Spring所管理bean的一些方法并根据方法调用的执行结果转移到另一个状态。
在流程定义XML中,行为状态使用<action-state>元素来声明。这里是一个例子:
尽管不是严格需要的,但是<action-state>元素一般都会有一个<evaluate>作为子元素。<evaluate>元素给出了行为状态要做的事情。expression属性指定了进入这个状态时要评估的表达式。在本示例中,给出的expression是SpEL表达式,它表明将会找到ID为pizzaFlowActions的bean并调用其saveOrder()方法。
Spring Web Flow与表达式语言
在这几年以来,Spring Web Flow在选择的表达式语言方面,经过了一些变化。在1.0版本的时候,Spring Web Flow使用的是对象图导航语言(Object-Graph Navigation Language ,OGNL)。随后的2.0版本又换成了统一表达式语言(Unified Expression Language ,Unified EL)。在2.1版本中,Spring Web Flow使用的是SpEL。
尽管可以使用上述的任意表达式语言来配置Spring Web Flow,但SpEL是默认和推荐使用的表达式语言。因此,当定义流程的时候,我们会选择使用SpEL,忽略掉其他的可选方案。
决策状态
有可能流程会完全按照线性执行,从一个状态进入另一个状态,没有其他的替代路线。但是更常见的情况是流程在某一个点根据流程的当前情况进入不同的分支。
决策状态能够在流程执行时产生两个分支。决策状态将评估一个Boolean类型的表达式,然后在两个状态转移中选择一个,这要取决于表达式会计算出true还是false。在XML流程定义中,决策状态通过<decision-state>元素进行定义。典型的决策状态示例如下所示:
你可以看到,<decision-state>并不是独立完成工作的。<if>元素是决策状态的核心。这是表达式进行评估的地方,如果表达式结果为true,流程将转移到then属性指定的状态中,如果结果为false,流程将会转移到else属性指定的状态中。
子流程状态
你可能不会将应用程序的所有逻辑写在一个方法中,而是将其分散到多个类、方法以及其他结构中。
同样,将流程分成独立的部分是个不错的主意。<subflow-state>允许在一个正在执行的流程中调用另一个流程。这类似于在一个方法中调用另一个方法。
<subflow-state>可以这样声明:
在这里,<input>元素用于传递订单对象作为子流程的输入。如果子流程结束的<end-state>状态ID为orderCreated,那么流程将会转移到名为payment的状态。
在这里,我有点超出进度了,我们还没有讨论到<end-state>元素和转移。我们很快就会在8.2.2小节介绍转移。对于结束状态,这正是接下来要介绍的。
结束状态
最后,所有的流程都要结束。这就是当流程转移到结束状态时所做的。<end-state>元素指定了流程的结束,它一般会是这样声明的:
当到达<end-state>状态,流程会结束。接下来会发生什么取决于几个因素:
如果结束的流程是一个子流程,那调用它的流程将会从<subflow-state>处继续执行。<end-state>的ID将会用作事件触发从<subflow-state>开始的转移。
如果<end-state>设置了view属性,指定的视图将会被渲染。视图可以是相对于流程路径的视图模板,如果添加“externalRedirect:”前缀的话,将会重定向到流程外部的页面,如果添加“flowRedirect:”将重定向到另一个流程中。
如果结束的流程不是子流程,也没有指定view属性,那这个流程只是会结束而已。浏览器最后将会加载流程的基本URL地址,当前已没有活动的流程,所以会开始一个新的流程实例。
需要意识到流程可能会有不止一个结束状态。子流程的结束状态ID确定了激活的事件,所以你可能会希望通过多种结束状态来结束子流程,从而能够在调用流程中触发不同的事件。即使不是在子流程中,也有可能在结束流程后,根据流程的执行情况有多个显示页面供选择。
现在,已经看完了流程中的各个状态,我们应当看一下流程是如何在状态间迁移的。让我们看看如何在流程中通过定义转移来完成道路铺设的。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论