官网资料

Spring Web Flow overview
Spring Web Flow API Doc.
Spring Web Flow Reference Guide


1. 介绍

1.1 环境需求

  • Java 1.8 及以上
  • Spring 5.0 及以上

1.2 基于Maven的Jar包引入

<dependency><groupId>org.springframework.webflow</groupId><artifactId>spring-webflow</artifactId><version>x.y.z.RELEASE</version>
</dependency>

如果使用的是Java Server Faces,则引入以下依赖(包含了:spring-binding & spring-webflow)

<dependency><groupId>org.springframework.webflow</groupId><artifactId>spring-faces</artifactId><version>x.y.z.RELEASE</version>
</dependency>

2. 定义流

2.1 什么是流

流:就是将可用于不同情境下的可重复使用的步骤提取出来。

例如:酒店订饭的流程

2.2 一个流是怎么组装的

在Spring Web Flow中,一个流是由一个个“状态”组装而成的一系列步骤。进入都每一个“状态”时,通常会有对应的视图展示给到用户。在视图中,用户的事件将交由“状态”做处理。这些事件可以触发到其他状态的转换,从而导致视图切换。

下面的例子展现了上面流程图中:book hotel流的结构

2.3 怎么创建流

流是由web应用程序开发人员使用简单的基于xml的流定义语言编写的

2.4 Essential language elements

2.4.1 flow

所有的flow都从这个根元素开始

<?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/webflowhttp://www.springframework.org/schema/webflow/spring-webflow.xsd"></flow>

所有的状态都在这个元素内定义。第一个定义的状态将作为flow的起点。

2.4.2 view-state

使用view-state元素,用于定义一个渲染视图的步骤

<view-state id="enterBookingDetails" />

按照惯例,view-state将其id映射到flow所在目录中的视图模板。

例如:如果flow是位于:/WEB-INF/hotels/booking这个目录下的,那么上面的例子则对应的是 /WEB-INF/hotels/booking/enterBookingDetails.xhtml 这个视图。

2.4.3 transition

使用transition元素处理状态中发生的事件:

<view-state id="enterBookingDetails"><transition on="submit" to="reviewBooking" />
</view-state>

触发submit事件时,将跳转到reviewBooking页面

2.4.4 end-state

定义结束元素

<end-state id="bookingCancelled" />

当流转换到结束状态时,它将终止并返回结果。

2.4.5 综合例子

<flow xmlns="http://www.springframework.org/schema/webflow"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/webflowhttp://www.springframework.org/schema/webflow/spring-webflow.xsd"><view-state id="enterBookingDetails"><transition on="submit" to="reviewBooking" /></view-state><view-state id="reviewBooking"><transition on="confirm" to="bookingConfirmed" /><transition on="revise" to="enterBookingDetails" /><transition on="cancel" to="bookingCancelled" /></view-state><end-state id="bookingConfirmed" /><end-state id="bookingCancelled" /></flow>

2.5 Actions

大多数流需要表达的不仅仅是视图导航逻辑。通常,它们还需要调用应用程序的业务服务或其他操作。
在流中,您可以在几个点上执行操作:

  • On flow start
  • On state entry
  • On view render
  • On transition execution
  • On state exit
  • On flow end

2.5.1 evaluate

evaluate将会是你使用最多的元素。使用 evaluate元素在流中的某一点对表达式求值。通过这个标签,您可以调用Spring bean或任何其他流变量上的方法。例如:

<evaluate expression="entityManager.persist(booking)" />

数据赋值

如果表达式返回一个值,那么这个值可以保存在flowScope的数据模型上

<evaluate expression="bookingService.findHotels(searchCriteria)" result="flowScope.hotels" />

数据转换

如果表达式返回的值需要被转换,可以使用result-type这个元素

<evaluate expression="bookingService.findHotels(searchCriteria)" result="flowScope.hotels" result-type="dataModel"/>

2.5.2 综合例子

<flow xmlns="http://www.springframework.org/schema/webflow"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/webflowhttp://www.springframework.org/schema/webflow/spring-webflow.xsd"><input name="hotelId" /><on-start><evaluate expression="bookingService.createBooking(hotelId, currentUser.name)"result="flowScope.booking" /></on-start><view-state id="enterBookingDetails"><transition on="submit" to="reviewBooking" /></view-state><view-state id="reviewBooking"><transition on="confirm" to="bookingConfirmed" /><transition on="revise" to="enterBookingDetails" /><transition on="cancel" to="bookingCancelled" /></view-state><end-state id="bookingConfirmed" /><end-state id="bookingCancelled" /></flow>

2.6 Input/Output Mapping

每个流都有一个定义良好的输入/输出约定。流开始时可以传递输入属性,结束时可以返回输出属性。在这方面,调用流在概念上类似于使用以下签名调用方法。

FlowOutcome flowId(Map<String, Object> inputAttributes);
public interface FlowOutcome {public String getName();public Map<String, Object> getOutputAttributes();
}

2.6.1 input

使用input元素来定义一个流中的输入值

<input name="hotelId" />

输入值保存在流作用域中属性的名称下。例如,上面的输入将保存在名称hotelId下。

定义输入值的类型

使用type属性来定义输入值的类型

<input name="hotelId" type="long" />

如果输入值与声明的类型不匹配,将尝试做类型转换。

输入值的分配

使用value属性指定要为其分配输入值的表达式

<input name="hotelId" value="flowScope.myParameterObject.hotelId" />

设定输入值为必填项

使用required属性,使得输入值不为空

<input name="hotelId" type="long" value="flowScope.hotelId" required="true" />

2.6.2 output

使用output元素来定义flow中的output属性。output属性在end-states标签中定义。

<end-state id="bookingConfirmed"><output name="bookingId" />
</end-state>

指定输出值的源

使用value属性表示特定的输出值表达式

<output name="confirmationNumber" value="booking.confirmationNumber" />

2.6.3 综合例子

<flow xmlns="http://www.springframework.org/schema/webflow"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/webflowhttp://www.springframework.org/schema/webflow/spring-webflow.xsd"><input name="hotelId" /><on-start><evaluate expression="bookingService.createBooking(hotelId, currentUser.name)"result="flowScope.booking" /></on-start><view-state id="enterBookingDetails"><transition on="submit" to="reviewBooking" /></view-state><view-state id="reviewBooking"><transition on="confirm" to="bookingConfirmed" /><transition on="revise" to="enterBookingDetails" /><transition on="cancel" to="bookingCancelled" /></view-state><end-state id="bookingConfirmed" ><output name="bookingId" value="booking.id"/></end-state><end-state id="bookingCancelled" /></flow>

2.7 Variables

流可以声明一个或多个实例变量。这些变量在流开始时分配。当流恢复时,变量持有的任何@Autowired临时引用也会被重新连接

2.7.1 var

使用var元素声明一个流变量

<var name="searchCriteria" class="com.mycompany.myapp.hotels.search.SearchCriteria"/>

确保variable对应的class实现了java.io.Serializable

2.8 Variable Scopes

Web Flow可以在几种作用域中存储变量

2.8.1 Flow Scope

Flow Scope在流开始时分配,在流结束时销毁。使用默认实现,Flow Scope中存储的任何对象都需要是可序列化的。

2.8.2 View Scope

View Scope作用于view-state的开始和结束期间。View Scope只能作用于view-state,且也是需要可序列化的。

2.8.3 Request Scope

Request Scope在调用流时分配,在流返回时销毁

2.8.4 Flash Scope

Flash Scope在流开始时分配,在每次视图渲染后清除,在流结束时销毁。在默认实现的情况下,任何存储在Flash Scope的对象都需要序列化

2.8.5 Conversation Scope

Conversation scope gets allocated when a top-level flow starts and destroyed when the top-level flow ends. Conversation scope is shared by a top-level flow and all of its subflows. With the default implementation, conversation scoped objects are stored in the HTTP session and should generally be Serializable to account for typical session replication.

The scope to use is often determined contextually, for example depending on where a variable is defined – at the start of the flow definition (flow scope), inside a a view state (view scope), etc. In other cases, for example in EL expressions and Java code, it needs to be specified explicitly. Subsequent sections explain how this is done.

<evaluate expression="searchService.findHotel(hotelId)" result="conversationScope.hotel" />

2.9 Calling subflows

流可以调用另一个流作为子流(subflows)。流将等待直到子流返回,然后响应子流结果。

2.9.1 subflow-state

使用subflow-state去调用另一个流作为它的子流。

<subflow-state id="addGuest" subflow="createGuest"><transition on="guestCreated" to="reviewBooking"><evaluate expression="booking.guests.add(currentEvent.attributes.guest)" /></transition><transition on="creationCancelled" to="reviewBooking" />
</subflow-state>

上面的例子中,将会调用 createGuest 流并且等待它的结束。当createGuest流结束并返回时,新的顾客将会添加到顾客预订列表中。

Passing a subflow input

使用input标签,将值传入到子流中

<subflow-state id="addGuest" subflow="createGuest"><input name="booking" /><transition to="reviewBooking" />
</subflow-state>

Mapping subflow output

When a subflow completes, its end-state id is returned to the calling flow as the event to use to continue navigation.

The subflow can also create output attributes to which the calling flow can refer within an outcome transition as follows:

<transition on="guestCreated" to="reviewBooking"><evaluate expression="booking.guests.add(currentEvent.attributes.guest)" />
</transition>

在上面的例子中,guestguestCreated结果返回的输出属性的名称。

综合例子

<flow xmlns="http://www.springframework.org/schema/webflow"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/webflowhttp://www.springframework.org/schema/webflow/spring-webflow.xsd"><input name="hotelId" /><on-start><evaluate expression="bookingService.createBooking(hotelId, currentUser.name)"result="flowScope.booking" /></on-start><view-state id="enterBookingDetails"><transition on="submit" to="reviewBooking" /></view-state><view-state id="reviewBooking"><transition on="addGuest" to="addGuest" /><transition on="confirm" to="bookingConfirmed" /><transition on="revise" to="enterBookingDetails" /><transition on="cancel" to="bookingCancelled" /></view-state><subflow-state id="addGuest" subflow="createGuest"><transition on="guestCreated" to="reviewBooking"><evaluate expression="booking.guests.add(currentEvent.attributes.guest)" /></transition><transition on="creationCancelled" to="reviewBooking" /></subflow-state><end-state id="bookingConfirmed" ><output name="bookingId" value="booking.id" /></end-state><end-state id="bookingCancelled" /></flow>

3. Expression Language (EL)

3.1 Introduction

EL用于流中的许多事情,包括:

  1. 访问客户端数据,例如声明流输入或引用请求参数
  2. 访问Web流的RequestContext中的数据,例如flowScopecurrentEvent
  3. 通过操作调用spring管理对象上的方法
  4. 解析表达式,如状态转换标准、子流id和视图名称

3.1.1 Expression types

在Web Flow中,有两个非常重要的概念需要理解。分别是:standard expressions 和 template expressions

Standard Expressions

这些表达式直接由EL计算,不需要加**#{}**

<evaluate expression="searchCriteria.nextPage()" />

上面的表达式是一个标准表达式,在求值时调用searchCriteria变量上的nextPage方法。如果您试图用特殊的分隔符(如#{})括起这个表达式,将会得到一个IllegalArgumentException。在此上下文中,分隔符被视为多余。expression属性唯一可接受的值是单个表达式字符串。

Template expressions

第二种类型的表达式是模板表达式。模板表达式允许将文本与一个或多个标准表达式混合使用。每个标准表达式块都显式地由 #{} 分隔符包围。

<view-state id="error" view="error-#{externalContext.locale}.xhtml" />

上面的表达式是一个模板表达式。求值的结果将是一个字符串,将诸如error-和.xhtml等文本与externalContext.locale对应的值的结果连接起来。这里需要显式分隔符 #{} 来划分模板中的标准表达式。

4.2 EL Implementations

4.2.1 Spring EL

Web Flow使用Spring表达式语言(Spring EL)。Spring EL的创建是为了提供一种单一的、支持性好的表达式语言,用于Spring中的所有产品。它在Spring框架中作为一个单独的jar包 org.springframework发布。

Spring Expression Language (SpEL)

4.2.2 Unified EL

使用统一EL也意味着对EL -api的依赖,尽管这通常是由web容器提供的。虽然Spring EL是默认的和推荐使用的表达式语言,但是如果您愿意,也可以将其替换为统一EL。您需要以下Spring配置,以插入WebFlowELExpressionParserflow-builder-services

<webflow:flow-builder-services expression-parser="expressionParser"/><bean id="expressionParser" class="org.springframework.webflow.expression.el.WebFlowELExpressionParser"><constructor-arg><bean class="org.jboss.el.ExpressionFactoryImpl" /></constructor-arg>
</bean>

请注意,如果您的应用程序正在注册自定义转换器,那么一定要确保WebFlowELExpressionParser配置了具有这些自定义转换器的转换服务

<webflow:flow-builder-services expression-parser="expressionParser" conversion-service="conversionService"/><bean id="expressionParser" class="org.springframework.webflow.expression.el.WebFlowELExpressionParser"><constructor-arg><bean class="org.jboss.el.ExpressionFactoryImpl" /></constructor-arg><property name="conversionService" ref="conversionService"/>
</bean><bean id="conversionService" class="somepackage.ApplicationConversionService"/>

4.3 EL portability

通常,您会发现Spring EL和Unified EL具有非常相似的语法

但是请注意,Spring EL有一些优点。例如,Spring EL与Spring 3的类型转换紧密集成,这允许您充分利用其特性。具体来说,目前只有Spring EL支持泛型类型的自动检测格式化注释的使用。

当从统一EL升级到Spring EL时,需要注意一些小的变化,如下所示:

  1. ${} 要转换成 #{}
  2. #{currentEvent == ‘submit’} 转换成 #{currentEvent.id == ‘submit’}
  3. 解析 #{currentUser.name} 时如果没有做 #{currentUser != null ? currentUser.name : null} 的判空处理,则可能会抛NullPointerException。更好的做法是:#{currentUser?.name}

4.4 Special EL variables

请记住这条一般规则。引用数据作用域的变量(flowScope, viewScope, requestScope,等等)应该仅在为其中一个作用域分配新变量时使用。

例如,当将调用bookingService.findHotels(searchCriteria)的结果分配给名为hotels的新变量时,必须在其前面加上一个范围变量,以便让Web Flow知道您希望将其存储在何处

<?xml version="1.0" encoding="UTF-8"?>
<flow xmlns="http://www.springframework.org/schema/webflow" ... ><var name="searchCriteria" class="org.springframework.webflow.samples.booking.SearchCriteria" /><view-state id="reviewHotels"><on-render><evaluate expression="bookingService.findHotels(searchCriteria)" result="viewScope.hotels" /></on-render></view-state></flow>

但是,在设置/修改现有变量的值时,不需要加scope variables。

<?xml version="1.0" encoding="UTF-8"?>
<flow xmlns="http://www.springframework.org/schema/webflow" ... ><var name="searchCriteria" class="org.springframework.webflow.samples.booking.SearchCriteria" /><view-state id="reviewHotels"><transition on="sort"><set name="searchCriteria.sortBy" value="requestParameters.sortBy" /></transition></view-state></flow>

4.4.1 flowScope

4.4.2 viewScope

4.4.3 requestScope

4.4.4 flashScope

4.4.5 conversationScope

4.4.6 requestParameters

使用requestParameters访问客户端请求参数

<set name="requestScope.hotelId" value="requestParameters.id" type="long" />

4.4.7 currentEvent

使用currentEvent访问当前事件的属性

<evaluate expression="booking.guests.add(currentEvent.attributes.guest)" />

4.4.8 currentUser

Use currentUser to access the authenticated Principal:

<evaluate expression="bookingService.createBooking(hotelId, currentUser.name)"result="flowScope.booking" />

4.4.9 messageContext

使用messageContext访问上下文,以检索和创建流执行消息,包括错误和成功消息

<evaluate expression="bookingValidator.validate(booking, messageContext)" />

4.4.10 resourceBundle

使用resourceBundle访问消息资源。

<set name="flashScope.successMessage" value="resourceBundle.successMessage" />

Spring Web Flow 文档学习相关推荐

  1. Spring Web Flow 2中的流管理持久性

    Spring Web Flow是一个创新的Java™Web框架,它扩展了Spring MVC技术. 使用Spring Web Flow进行应用程序开发是围绕用例定义的,这些用例被定义为Web流. 根据 ...

  2. Spring Framework 5.3文档学习(一)

    Spring Framework 5.3文档学习(一) Overview 1.What We Mean by "Spring" 2. History of Spring and t ...

  3. Spring文档学习

    Spring文档学习 参考Spring Framework Documentation学习 1. IoC 容器 1.1 容器实例化 <beans><import resource=& ...

  4. Spring学习笔记之Spring Web Flow

    Spring Web Flow 是Spring MVC 的扩展,它支持开发基于流程的应用程序.它将流程的定义与实现流程行为的类和视图分离开来. 1.配置Web Flow 在Spring MVC上下文定 ...

  5. Spring Web Flow 2.0 入门

    Spring Web Flow 2.0 入门 本教程分析了 Spring Web Flow 2.0 的技术要点,并且通过创建一个示例应用程序,展示了 Spring Web Flow 2.0 的基本知识 ...

  6. MESSL(maven + extjs + spring portlet mvc + spring web flow + liferay )整合架构 5

    流控制文件很简单,就是根元素是<view>,然后用<view-state>来代表一个一个的页面,用<transition>来代表从一个状态到另外一个状态的跳转,如果 ...

  7. Spring Web Flow实例教程

    目录: 参考文献 购物车用例 什么情况下可以使用 Spring Web Flow? 配置 Spring Web MVC 配置 Spring Web Flow 2.0 的基础 在购物车示例应用中配置 S ...

  8. Spring Web Flow 2.0 入门详解

    目录: 参考文献 购物车用例 什么情况下可以使用 Spring Web Flow? 配置 Spring Web MVC 配置 Spring Web Flow 2.0 的基础 在购物车示例应用中配置 S ...

  9. Spring Web Flow 入门demo(二)与业务结合 附源码

    转载地址 http://blog.csdn.net/hejingyuan6/article/details/46516287 第一部分demo仅仅介绍了简单的页面跳转,接下来我们要实现与业务逻辑相关的 ...

最新文章

  1. 《2022城市大脑建设标准研究报告》在京正式发布
  2. [Sdoi2017]硬币游戏 [高斯消元 KMP]
  3. css不换行属性_CSS强制不换行的whitespace:nowrap的坑,你会填么?
  4. 也许是被忽略的update语句
  5. ARKit从入门到精通(5)-ARScnView介绍
  6. 2021牛客多校6 - Gambling Monster(分治FWT优化期望dp)
  7. liferay如何在struts2中調用ajax
  8. 对比Ruby和Python的垃圾回收(2):代式垃圾回收机制
  9. flask接口mysql开发例子,使用Flask开发简单接口3–引入MySQL
  10. 如果写文档发博客,你还在用Word文档你就out了,写文档神器Markdown的前世今生来了。(持续更新,欢迎关注点赞)
  11. Hadoop-2.2.0中文文档——MapReduce 下一代 -——集群配置
  12. 卷积神经网络中feature map的含义
  13. 在VBA中使用正则表达式
  14. 深度linux运行浏览器中毒,使用深度Deepin系统的用户可在商店中安装360安全浏览器正式版...
  15. Java精品源码第83期在线旅游网站系统(推荐)
  16. 蜀门锻造费用统计(武器/坐骑锻造)
  17. 大数据分析:数字化企业转型的关键
  18. 2022年5月月度总结
  19. java 成绩_java输出各种学生成绩
  20. 对前端的一些粗浅的认识

热门文章

  1. 超详细如何配置VRRP备份组
  2. cesium系列 - 错误收集
  3. 卷积神经网络推理特征图可视化查看,附录imagenet类别和编号对应查询表。通过观察法进行深度学习可解释研究
  4. Collect things
  5. 数据库事务的简单学习(一)
  6. 中创09校园招聘试题
  7. Qt 之 show,hide,setVisible,setHidden,close 等小结
  8. 路由策略 route-policy filter-policy 笔记
  9. multimap学习之插入数据操作insert,emplace ,emplace_hint
  10. 淘宝封我账号店铺2个月了, 都没退保证金货款给我,商品客户早就确认了,聚投诉投诉淘宝,但是没人处理