第八章使用SpringWebFlow咸鱼,也有梦想!

SpringWebFlow是一个web框架,它适用于元素按规定流程运行的程序;

SpringWebFlow是SpringMVC的扩展,它支持开发基于流程的应用程序。它将流程的定义和实现流程行为的类和视图分离开来。

二、为什么要使用SpringWebFlow?

我们可以使用任何Web框架编写流程化的应用程序,但你会发现流程的定义分散在组成流程的各个元素中,没有地方能够描述整个流程。

三、如何使用SpringWebFlow

流程执行器(flowexecutor)驱动流程的执行。当用户进入一个流程时,流程执行器会为用户创建并启动一个流程执行实例。当流程暂停的时候(如为用户展示视图时),流程执行器会在用户执行操作后恢复流程。如下创建一个流程执行器:

流程执行器负责加载和创建流程,但它并不负责加载流程定义。

2、配置流程注册表

流程注册表的工作是加载流程定义并让流程执行器能够使用它们。

配置方式一:

流程的ID就是相对于base-path的路径——或者双星号所代表的路径。

配置方式二:

配置FlowHandleMapping帮助将流程请求发送给SpringWebFlow

FlowHandleMapping装配了流程注册表的引用,这样它就能知道如何将请求的URL匹配到流程上。例如,如果有一个ID为order的流程,FlowHandleMapping就会知道如果请求的URL模式是"/order"的话,就要将其匹配到这个流程上。

配置FlowHandlerAdapter响应请求

FlowHandlerAdapter等同于SpringMVC的控制器,它会响应发送的流程请求并对其进行处理。

4、流程的组件

流程是由三个主要元素定义的:状态、转移和流程数据

状态:流程中事件发生的地点;

转移:连接这些点的公路;

数据:流程的当前状况

SpringWebFlow定义了五种不同类型的状态:

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

决策(Decision):决策状态将流程分成两个方向,它会基于流程数据的评估结果确定流程方向;

结束(End):结束状态是流程的最后一站,一旦进入End状态,流程就会终止;

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

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

视图状态:

视图状态用于为用户展现信息并使用户都在流程中发挥作用,实际的试图实现可以是Spring支持的任意视图类型,但通常是用JSP来实现的。

在流程定义的XML文件中,用于定义视图状态:

在这个简单的示例中,流程ID——welcome有两个含义:它在流程内标识这个状态;流程到达这个状态时要展现的逻辑视图名为welcome

如果你愿意指定另外一个视图名,那可以使用view属性做到这一点:

如果流程为用户展现了一个表单,你可能希望指明表单所绑定的对象。为了做到这一点,可以设置model属性:

这里我们takePayment视图中的表单将绑定流程作用域内的paymentDetails对象。

行为状态:

视图状态会涉及到流程应用程序的用户,而行为状态则是应用程序自身在执行任务。行为状态一般会触发Spring所管理bean的一些方法并根据方法调用的执行结果转移到另一个状态。

尽管不是严格要求的,但元素一般都会有一个作为子元素,元素给出了行为状态要做的事情,expression属性指定了进入这个状态时要评估的表达式。在本例中,给出的expression是SpEL表达式,它表明将会找到ID为pizzaFlowActions的bean并调用其saveOrder()方法。

决策状态:

决策状态能够在流程执行时产生两个分支。

在流程定义的xml中,决策状态通过元素进行定义:

子流程状态:

允许在一个正在执行的流程中调用另一个流程。这类似于在一个方法中调用另一个方法。

在这里,元素用于传递订单对象作为子流程的输入。如果子流程结束的状态ID为customerCreated,那么流程将会转移到名为payment的状态。

结束状态:

在流程定义的xml中,结束状态通过元素进行定义:

当流程到达状态,流程会结束。接下来会发生什么取决于几个因素:

如果结束的流程是一个子流程,那调用它的流程将会从处继续执行。的ID将会用作事件触发从开始的转移;

如果设置了view属性,指定的视图将会被渲染。视图可以是相对于流程路径的视图模板,如果添加“externalRedirect:”前缀的话,将会重定向到流程外部的页面,如果添加“flowRedirect:”将重定向到另一个流程中;

如果结束的流程不是子流程,也没有指定view属性,那这个流程只是会结束而已,浏览器最后将会加载流程的基本URL地址,当前已没有活动的流程,所以会开始一个新的流程实例。

转移:

转移连接了流程中的状态,流程中除结束状态之外的每个状态,至少都需要一个转移,这样就能够知道一旦这个状态完成时流程要去向哪里。

状态可以有多个转移,分别对应于当前状态结束时可以执行的不同的路径。

转移使用元素来进行定义,它会作为各种状态元素(的子元素)。最简单形式就时元素在流程中指定下一个状态:

属性to用于指定流程的下一个状态,如果只使用了to属性,那这个转移就会是当前状态的默认转移选项,如果没有其它可用转移的话,就会使用它。

更常见的转移定义是基于事件的触发来进行的。在视图状态,事件通常会是用户采取的动作;在行为状态,事件是评估表达式得到的结果;在子流程状态,事件取决于子流程结束状态的ID。在任意的事件中,你可以使用on属性来指定触发转移的事件:

在抛出异常时,流程也可以进入另一个状态:

全局转移:

定义完这个全局转移后,流程中的所有状态都会默认拥有这个cancle转移。

流程数据:

创建变量方式一:

创建变量方式二:

在本例中,元素计算了一个表达式(SpEL表达式)并将结果放到了名为toppingsList的变量中,这个变量是视图作用域的。

创建变量方式三:

定义流程数据的作用域

5、组合起来:披萨流程

图中的方框代表了状态而箭头代表了转移。

如下的程序清单展示了使用SpringWebFlow的XML流程定义来实现披萨订单的整体流程:

packagecom.chenjl.domain;importjava.io.Serializable;importjava.util.ArrayList;importjava.util.List;publicclassOrderimplementsSerializable{privatestaticfinallongserialVersionUID=1120635411006621502L;privatePaymentpayment;privateListpizzas;privateCustomercustomer;publicOrder(){pizzas=newArrayList();customer=newCustomer();}publicPaymentgetPayment(){returnpayment;}publicvoidsetPayment(Paymentpayment){this.payment=payment;}publicListgetPizzas(){returnpizzas;}publicvoidaddPizzas(Pizzapizza){pizzas.add(pizza);}publicCustomergetCustomer(){returncustomer;}publicvoidsetCustomer(Customercustomer){this.customer=customer;}publicFloatgetTotal(){return0.00f;}}ViewCode流程定义文件中的第一个状态也会是流程访问中的第一个状态,也可以通过元素的start-state属性将任意状态指定为开始状态

流程变量order将在前三个状态中进行填充并在第四个状态中进行保存。identifyCustomer子流程状态使用了元素来填充order的customer属性,将其设置为顾客子流程收到的输出。builderOrder和takePayment状态使用了不同的方式,它们使用将order流程变量作为输入,这些子流程就能在内部填充order对象。

在订单得到顾客、一些披萨以及支付细节后,就可以对其进行保存了。saveOrder是处理这个任务的行为状态。它使用来调用ID为pizzaFlowActions的bean的saveOrder()方法,并将保存的订单对象传递进来。订单完成保存后,它会转移到thankCustomer。

thankCustomer状态是一个简单的视图状态,后台使用了"/WEB-INF/flows/pizza/thankCustomer.jsp"这个JSP文件,如下所示:

SpringWebFlow为视图的用户提供了一个flowExecutionUrl变量,它包含了流程的URL。结束链接将一个“_eventId”参数关联到URL上,以便回到web流程时触发finished事件。这个事件将会让流程到达结束状态。

6、收集顾客信息

在每个披萨订单开始前的提问和回答阶段可以用下面的流程图表示:

使用Web流程识别饥饿的披萨顾客:

按钮名字的"_eventId_"部分是提供给SpringWebFlow的一个线索,它表明接下来要触发事件。当点击这个按钮提交表单时,会触发phoneEntered事件进而转移到lookupCustomer。

查找顾客:

注册新顾客:

registrationForm状态是要求用户填写配送地址的。就像我们之前看到的其他视图状态,它将被渲染成JSP。JSP文件如下所示:

在顾客提供其地址后,我们需要确认他的地址在配送范围之内。如果Spizza不能派送给他们,那么我们要让顾客知道并建议他们自己到店面里取走披萨。

如果顾客在配送区域内的话,那流程转移到addCustomer状态。否则,顾客被带入到deliveryWarning视图状态。deliveryWarning背后的视图就是"/WEB-INF/flows/pizza/customer/deliveryWarning.jsp",如下所示:

存储顾客数据:

当流程抵达addCustomer状态时,用户已经输入了他们的地址。为了将来使用,这个地址需要以某种方式存储起来(可能会存储在数据库中)。addCustomer状态有一个元素,它会调用pizzaFlowActionsbean的addCustomer()方法,并将customer流程参数传递进去。一旦这个过程完成,会执行默认的转移,流程将会转移到ID为customerReady的结束状态。

结束流程:

当customer流程走完所有正常路径后,它最终会到达ID为customerReady的结束状态。当调用它的披萨流程恢复时,它会接收到一个customerReady事件,这个事件将使得流程转移到buildOrder状态。

customerReady结束状态包含了一个元素。在流程中这个元素等同于Java中的return语句。它从子流程中传递一些数据到调用流程。

7、构建订单

如下显示了如何将图中所阐述的内容转变成SpringWebFlow定义:

createPizza状态是一个表单视图状态,这个表单可以添加新的Pizza对象到订单中。元素添加了一个新的Pizza对象到流程作用域内,当表单提交时,表单的内容会填充到该对象中。需要注意的是,这个视图状态引用的model是流程作用域内的同一个Pizza对象。Pizza对象将绑定到创建披萨的表单中,如下所示:

有两种方法来结束这个流程。用户可以点击showOrder视图中的Cancel按钮或者Checkout按钮。这两种操作都会使流程转移到一个。但是选择的结束状态id决定了退出这个流程时触发事件,进而最终确定了主流程的下一步行为。主流程要么基于cancel事件要么基于orderCreated事件进行状态转移。在前者情况下,外边的主流程会结束;在后者情况下,它将转移到takePayment子流程,这也是接下来我们要看的。

8、支付

像订单子流程一样,支付子流程也使用元素接收一个Order对象作为输入。

进入支付子流程的时候,用户会到达takePayment状态。这是一个视图状态,在这里用户可以选择使用信用卡、支票或现金进行支付。提交支付信息后,将进入verifyPayment状态。这是一个行为状态,它将校验支付信息是否可以接受。

使用XML定义的支付流程如下所示:

PaymentType枚举定义如下:

packagecom.chenjl.domain;importjava.util.Arrays;importjava.util.List;publicenumPaymentType{CASH,CHECK,CREDIT_CARD;publicstaticListasList(){PaymentType[]all=PaymentType.values();returnArrays.asList(all);}@OverridepublicStringtoString(){returncapitalizeFully(name().replace('_',''));}}

THE END
1.电话号码查询号码认证号码举报中心本站提供手机及固话电话号码查询,电话号码归属地查询,全国企事业单位电话号码查询,电话号码认证,电话号码举报,智能号码等服务https://www.114best.com/
2.礼貌的问别人电话号码以下是几种礼貌询问电话号码的方式: 一、 “请问可以方便交换一下联系方式吗?如果需要后续联系,电话号码是最直接的。” 这句话表达了你想与对方保持联系的意愿,并说明了电话号码的便利性。 二、 “我们之后可能还需要沟通,可以麻烦你告诉我你的电话号码吗?” 这句话适用于工作场合或需要后续合作的情境。 三、 https://agents.baidu.com/content/question/7820a9efed92ff08d9012a06
3.询问电话号码的翻译是:Askthephonenumber中文翻译英文意思afriendship directly through the gift they have 友谊直接地通过他们有的礼物[translate] a然后,其它时间呆在家里和家人度过 Ent?o, outro tempo ma?ante no repouso passado com o membro da família[translate] a询问电话号码 Inquires the telephone number[translate]http://eyu.zaixian-fanyi.com/fan_yi_9166612
4.关于街道及社区电话号码的询问信件内容 您好,针对大学生毕业党员关系转接问题需要向街道及社区进行咨询。是否能提供清风街道办事处及东湖路社区办事处的电话号码。谢谢! 回复部门 清风街道 回复时间 2021-06-21 14:32 回复内容 您好,您咨询的事项已收悉。东湖路社区电话号码为:0566-3384364,清风街道办事处电话号码为:0566-3387550。关闭https://www.ahgc.gov.cn/InFeedback/show/33201.html
5.PayPal客户服务电话号码888221他们可能会询问您打电话的原因(而不是菜单) "If you need a minute to find the card number, just say one moment. Or you can say, I don't know it." 与PayPal 的通话摘录 Monday, November 25, 2024 7:45 PM 他们可能会要求您使用拨号盘输入信息 "I don't know it. Or I don't have an https://zh.gethuman.com/a/phone-number/PayPal
6.公安局今天突然打电话给我询问我在外地办的号码是不是我在用,有公安局今天突然打电话给我询问我在外地办的号码是不是我在用,有哪些原因呢? 报告编号:No.20210923*** 【问题分析】您好,您所提出的是关于 【解决方案】***【具体操作】*** 去查看 免费 关于公安局今天突然打电话给我询问我在外地办的号码是不是我在用,有哪些原因呢的律师回答 秦文璞律师 已帮助 114https://m.66law.cn/question/38293813.aspx
7.如何找客户电话如何找客户电话 当客户询问有没有优惠政策时,销售顾问可以假装说现在优惠比较少,可能要过一段时间才会有,如果有的话,一定立马通知客户,于是直接向客户索要电话号码,以便及时通知到位。索要客户电话号码的方法 直接法:就是直接询问顾客的联系方式。比https://www.autohome.com.cn/ask/5422923.html
8.What'syourtelephonenumber?是询问你的.()A.年龄B.电话号码解答答案:B;How old are you是询问年龄的;"What's your telephone number是询问电话号码;What's your name?是询问姓名的;根据英文内容What's your telephone number你的电话号码是多少?可知选项B符合题意;故选B. 点评识记常用的句式,结合给出的语境对汉语意思和英文句意作出分析,然后正确作答即可. http://www.1010jiajiao.com/czyy/shiti_id_45c47ef7c3a5e503f0a8e02609c6ee9e
9.房产经纪人索要客户电话号码的5个绝招,招招管用行业动态3、在客户询问优惠活动时索要 当客户询问有没有价格优惠政策时,经纪人可以假装说现在优惠比较少,可能要过一段时间才会有,如果有的话,一定立马通知客户,于是直接向客户索要电话号码,以便及时通知到位。 4、在客户做出承诺时索要 当客户为了探知价格优惠信息而向经纪人做出购买承诺时,经纪人应该故作怀疑,比如可以说:“http://www.eeeff.com/news/KuaHaiHanHongChuF.html
10.《Spring实战》学习笔记第八章:使用SpringWebFlowflowexecutor顾名思义,流程执行器(flow executor )就是用来驱动流程的执行。当用户进入到一个流程时,流程执行器会为该用户创建并启动一个流程执行器的实例。当流程暂停时(例如为用户展示视图时),流程执行器会在用户执行操作后恢复流程。 在Spring中,<flow:flow-executor>元素可以创建一个流程执行器: https://blog.csdn.net/gebitan505/article/details/51728704
11.接听电话的规范语言礼仪九、替他人接电话更应注意礼貌 作为办公室的工作人员,常常要遵从上级的指示,拦截或回复各种电话,这时更应注意礼貌。如果对方来电话找你的经理时,你就应当用友好的声音询问对方:“我能否告诉我们经理,是谁打给他的吗?”这样,对方会把姓名、单位及打电话的意图告诉你。如果有人打电话约见你的上司,你一定要善意地提https://www.ruiwen.com/liyichangshi/2400987.html
12.礼貌用语如果客人想要转xx房间电话,应重复一边号码,确保准确无误后方可将电话转接过去,同时也要操作准确。输入了电话号码的同时应仔细的核对一边号码,看是否准确,以避免手误将号码输入错误,确保准确无误后再按下发号键。 如果客人要询问事情,应仔细听清楚对方要询问的事情,应耐心,不可有不耐烦的情绪。如果自己知道答案可直接https://www.360doc.cn/article/1368361_158853431.html
13.我只知道名字怎么查他电话号码我想跟他联系3. 直接问对方:如果有可能,直接向对方询问电话号码是最直接的方式,但这需要对方愿意提供给你。需要https://china.findlaw.cn/ask/lawyer_65649230.html
14.医保卡预留的电话号码怎么修改?在手机上就能改现在大多数人都不太愿意更改电话号码,因为号码绑定的东西太多,例如银行卡、微信、邮箱等,一旦更改都要处理一遍。但还是有些小伙伴因一些特殊原因不得不换号码,因此经常会有人询问医保卡预留的电话号码怎么修改?今天希财君就来为大家解答。 医保卡预留的电话号码怎么修改? https://www.csai.cn/shb/1325045.html
15.初中一年级英语上册知识点总结你的电话号码是多少? (回答:My telephone number is---或者It’s ---)注意:读出号码的时候要逐个读出。 5. What class / grade +be + 主语 + in ? 某人在哪一个班级/年级? 例:what class are you in ? I am in Class Five. (注意:Class 和 Five需要大写) what grade are you in ? I am inhttps://www.51test.net/show/9720110.html
16.小班幼儿外出安全习惯——我知道妈妈的手机号(1)出示废旧电话。或手机询问幼儿这是什么?有什么用? (2)邀请一名幼儿现场打电话,激发幼儿的活动兴趣。 二 认识电话 (1)指导幼儿看一看说一说电话是什么样子的? (2)引导幼儿读读电话座机上的不同数字? (3)你们认识这些数字宝宝吗?他们是怎样排序的? https://www.meipian.cn/2ott06gc
17.在iPhone上拨打电话拨打和接听电话 拍摄实况照片 通话期间使用其他 App 添加相机效果 更改音频和视频设置 退出通话或切换到“信息” 阻止不想要的来电号码 打开“购买前询问” 共享订阅和 iCloud 储存空间 与家庭成员共享照片和日历等 定位家庭成员丢失的设备 通过“家人共享”设置“屏幕使用时间” https://support.apple.com/zh-cn/guide/iphone/iph3c993cbc/14.0/ios/14.0
18.浙江人保电话号码浙江人保电话号码 问:中国人保浙江分公司的投诉电话是多少 答:他的工作失误造成了你的不方便,你完全有投诉的必要,国家现在本来就在大力改善保险行业的混乱,这是严厉打击的,我作为PICC保险公司的一名员工劝您一定要把这种业务能力差的人从公司踢出去!~~ 直接打95518然后询问那边的电话!~~ 支持你!~~ https://www.xyz.cn/toptag/huaxiarenshoubaojianhui-155146.html