在Spring 中配置 Web Flow

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:flow="http://www.springframework.org/schema/webflow-config"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/webflow-config http://www.springframework.org/schema/webflow-config/spring-webflow-config.xsd">

<!-- 装配流程执行器,负责创建和执行流程 -->
<flow:flow-executor id="flowExector" />

<!-- 配置流程注册表,负责加载流程定义,供流程执行器使用 -->
<flow:flow-registry id="flowRegistry" base-path="/WEB-INF/flows">
<!-- 在 base-path 下查找所有匹配的文件作为流程定义 -->
<flow:flow-location-pattern value="*-flow.xml"/>
</flow:flow-registry> <!-- 帮助 Dispatcher 将流程请求发送给 Spring Web Flow -->
<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerMapping">
<property name="flowRegistry" ref="flowRegistry" />
</bean>

<!-- 负责响应流程的请求并进行处理 -->
<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerAdapter">
<property name="flowExecutor" ref="flowExecutor" />
</bean>

</beans>

流程的组件

1、状态

Spring Web Flow 定义了五种不同类型的状态

  • 行为(Action): 行为状态时流程逻辑发生的地方

  • 决策(Decision): 决策流程将流程分成两个方向,基于流程数据确定流程方向

  • 结束(End): 结束状态是流程的最后一站,进入此状态后流程终止

  • 子流程(Subflow): 子流程状态会在当前正在运行的流程上下文中启动一个新的流程

  • 视图(View): 视图状态会暂停流程并邀请用户参与流程

视图状态

视图状态用于为用户展现信息并使用户在流程中发挥作用。实际的视图通常是 JSP 来实现的

在 xml 中定义 <view-state id="welcomt" view="greeting" model="flowScope.paymentDetails" />

如果没有显示指定 view 属性,那么它的值与 id 相同

行为状态

行为状态一般会触发 Spring 所管理的 bean 的一些方法并根据方法调用的执行结果转移到另一个状态

在 xml 中定义

<action-state id="saveOrder">
<evalute expression="pizzaFlowActions.saveOrder(order)" />
<transition to="thankYou" />
</action-state>

决策状态

决策状态能够在流程执行时产生两个分支。决策状态将评估一个 Boolean 类型的表达式,然后在两个状态转移中选择一个

在 xml 中定义

<decision-state id="checkDeliveryArea">
<if test="pizzFlowActions.checkDeliverArea(customer.zipCode)"
then="addCustomer"
else="deliveryWarning" />
</decision-state>

子流程状态

子流程状态允许在一个正在执行的流程中调用另一个流程

在 xml 中定义

<subflow-state id="order" subflow="pizza/order">
<input name="order" value="order" />
<transition on="orderCreated" to="payment" />
</subflow-state>

结束状态

结束状态指定了流程的结束

在 xml 中声明: <end-state id="customerReady" />

2、转移

转移连接了流程中的状态。流程中除结束状态之外的每个状态,至少都需要一个转移状态,分别对应于当前状态结束时可以执行的不同的路径

一般使用<transition>元素来进行定义,作为各种状态元素的的子元素(如上面之前定义内容)

<transition on="phoneEntered" to="lookupCustomer" />

on 属性指定触发转移的事件,to 属性指定流程的下一个状态,异常状态跳转是将on属性改为on-exception="CustomException"

如果转移在多个状态中被使用,可以定义一个全局转移,这样流程中的所有状态都默认拥有此转移

<global-transitions>
<transition on="cancel" to="endState" />
</global-transitions>

3、流程数据

流程数据保存在变量中,而变量可以在流程的各个地方进行引用,它能够以多种方式创建

<var name="customer" class="com.pizza.domain.Customer" />,并且其中的 class 必须实现 Serializable 接口

创建一个新的 Customer 实例并将其放在 customer 变量中

<evaluate resul="viewScope.toppingsList" expression="T(com.pizza.domain.Topping).asList()" />

计算了一个 (SpEL) 表达式并将结果放到了名为 toppingsList 变量中

<set name="flowScope.pizza" value="com.pizza.domain.Pizza()" />

定义流程数据的作用域

Spring Web Flow 定义了五种不同作用域

  • Conversation: 最高层级的流程开始时创建,结束时销毁。被其及其所有子流程共享

  • Flow: 流程开始时创建,结束时销毁。只有在创建它的流程中可见

  • Request: 当一个请求进入流程时创建,流程返回时销毁

  • Flash: 流程开始时创建,结束时销毁。在视图状态渲染结束时被清除

  • View: 进入状态视图时创建,退出这个状态时销毁。只有在视图状态内可见

使用<var>元素声明变量时,变量始终是流程作用域的,也就是在定义变量的流程内有效

使用<set><evaluate>时,作用域通过 name 或 result 属性的前缀指定,如

<set name="flowScope.theAnswer" value="42" />

使用之前介绍的这些流程组件,即可将其组装起来形成一个成熟且完善功能的 web 流程

下面展示一个简单的流程文件(订购披萨流程)

<?xml version="1.0" encoding="UTF-8"?>
<flow xmlns="http://www.springframework.org/schema/webflow"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/webflow
http://www.springframework.org/schema/webflow/spring-webflow-2.3.xsd"
start-state="identifyCustomer">

<var name="order" class="pizza.domain.Order" /> <!-- 调用顾客子流程 -->
<subflow-state id="identifyCustomer" subflow="pizza/customer">
<output name="customer" value="order.customer" />
<transition on="customerReady" to="buildOrder" />
</subflow-state> <!-- 调用订单子流程 -->
<subflow-state id="buildOrder" subflow="pizza/order">
<input name="order" value="order" />
<transition on="orderCreated" to="takePayment" />
</subflow-state> <!-- 调用支付子流程 -->
<subflow-state id="takePayment" subflow="pizza/payment">
<input name="order" value="order" />
<transition on="paymentTaken" to="saveOrder" />
</subflow-state> <!-- 保存订单 -->
<action-state id="saveOrder">
<evaluate expression="pizzaFlowActions.saveOrder(order)" />
<transition to="thankCustomer" />
</action-state>

<!-- 感谢顾客 -->
<view-state id="thankCustomer">
<transition to="endState" />
</view-state> <end-state id="endState" /> <global-transitions>
<transition on="cancel" to="endState" />
</global-transitions>

</flow>

Spring Web Flow 笔记的更多相关文章

  1. Spring实战第八章学习笔记————使用Spring Web Flow

    Spring实战第八章学习笔记----使用Spring Web Flow Spring Web Flow是一个Web框架,它适用于元素按规定流程运行的程序. 其实我们可以使用任何WEB框架写流程化的应 ...

  2. Spring学习笔记4—流程(Spring Web Flow)

    Spring Web Flow是Spring框架的子项目,作用是让程序按规定流程运行. 1 安装配置Spring Web Flow 虽然Spring Web Flow是Spring框架的子项目,但它并 ...

  3. 笔记42 Spring Web Flow——Demo(2)

    转自:https://www.cnblogs.com/lyj-gyq/p/9117339.html 为了更好的理解披萨订购应用,再做一个小的Demo. 一.Spring Web Flow 2.0新特性 ...

  4. 笔记43 Spring Web Flow——订购披萨应用详解

    一.项目的目录结构 二.订购流程总体设计 三.订购流程的详细设计 1.定义基本流程pizza-flow.xml <?xml version="1.0" encoding=&q ...

  5. 笔记41 Spring Web Flow——Demo

    订购披萨的应用整体比较比较复杂,现拿出其中一个简化版的流程:即用户访问首页,然后输入电话号(假定未注册)后跳转到注册页面,注册完成后跳转到配送区域检查页面,最后再跳转回首页.通过这个简单的Demo用来 ...

  6. 笔记39 Spring Web Flow——订单流程(收集顾客信息)

    如果你曾经订购过披萨,你可能会知道流程.他们首先会询问你的电 话号码.电话号码除了能够让送货司机在找不到你家的时候打电话给 你,还可以作为你在这个披萨店的标识.如果你是回头客,他们可以 使用这个电话号 ...

  7. 笔记38 Spring Web Flow——订单流程(定义基本流程)

    做一个在线的披萨订购应用 实际上,订购披萨的过程可以很好地定义在一个流程中.我们首先从 构建一个高层次的流程开始,它定义了订购披萨的整体过程.接下 来,我们会将这个流程拆分成子流程,这些子流程在较低的 ...

  8. 笔记37 Spring Web Flow——流程的组件

    在Spring Web Flow中,流程是由三个主要元素定义的:状态.转移和 流程数据. 一.状态 Spring Web Flow定义了五种不同类型的状态.通过选择Spring Web Flow的状态 ...

  9. 笔记36 Spring Web Flow——配置

    Spring Web Flow是一个Web框架,它适用于元素按规定流程运行的程序.Spring Web Flow是Spring MVC的扩展,它支持开发基于流程的应用程 序.它将流程的定义与实现流程行 ...

随机推荐

  1. 22 Specifications动态查询

    Specifications动态查询 有时我们在查询某个实体的时候,给定的条件是不固定的,这时就需要动态构建相应的查询语句,在Spring Data JPA中可以通过JpaSpecificationE ...

  2. ffmpeg 编程常用 pcm 转 aac aac 转 pcm mp4 h264解码

    ffmpeg 是现在开源的全能编解码器,基本上全格式都支持,纯 c 语言作成,相对比其它的 VLC ,GStreamer glib2 写的,开发更简单些,文档很棒,就是 examples 比较少. 常 ...

  3. 深入理解React key

    一 react 组件元素的 diff 算法 二 key 的理解 概述 react 中的key 属性,它是一个特殊的属性,它的出现不是给开发者用的(例如你为一个组件设置key之后不能获取组件的这个key ...

  4. 取url地址参数

    let url = 'https://i-beta.cnblogs.com/posts/edit?param1=123&param2=second'let arr = url.split('& ...

  5. 《JavaScript 模式》读书笔记(2)— 基本技巧2

    前一篇,简单介绍了一些js代码的基本技巧.那么这篇文章,我们继续后续的内容. 一.for循环 for循环经常用在遍历数组或者类数组对象,如引数(arguments)和HTML容器(HTMLCollti ...

  6. 使用Github Packages功能上传nuget包到Github

    前几天微软收购npm的新闻对于软粉来收很是振奋.微软收购npm很可能是为了加强Github Packages.目前Github,Typescript,VSCode,npm这些开源社区的重磅工具全部都在 ...

  7. 【Weiss】【第03章】练习3.19:计算后缀表达式

    [练习3.19] 编写一个程序计算后缀表达式的值. Answer: 计算的方法书上说得很明白了,看代码行,没写错误检测[因为懒]. 测试代码: #include <iostream> #i ...

  8. 杂谈 | 习得性无助&习得性乐观

    习得性无助和习得性乐观简述 这两个概念均出自积极心理学家Martin Seligman. “习得性无助”的提出是基于一项动物实验. 狗关在笼子里,只要蜂音器一响,就对狗施予电击,狗在笼子里无法躲避电击 ...

  9. Natas25 Writeup(目录遍历、头部注入)

    Natas25: 打开页面,是一段引文以及可以选择语言的下拉list.查看源码,发现关键代码: function setLanguage(){ //选择语言 /* language setup */ ...

  10. scrapy框架在未登录模式下爬取文本,文件和图片的几点收获

    1.什么是API接口? https://baijiahao.baidu.com/s?id=1597881116201407882&wfr=spider&for=pc 2.spider文 ...