二、订单子流程  

在识别完顾客之后,主流程的下一件事情就是确定他们想要什么类型 的披萨。订单子流程就是用于提示用户创建披萨并将其放入订单中 的,如下图所示。

  showOrder状态位于订单子流程的中心位置。这是用 户进入这个流程时看到的第一个状态,它也是用户在添加披萨到订单 后要转移到的状态。它展现了订单的当前状态并允许用户添加其他的 披萨到订单中。要添加披萨到订单时,流程会转移到createPizza状态。这是另外 一个视图状态,允许用户选择披萨的尺寸和面饼上面的配料。在这 里,用户可以添加或取消披萨,两种事件都会使流程转移回 showOrder状态。  从showOrder状态,用户可能提交订单也可能取消订单。两种选择 都会结束订单子流程,但是主流程会根据选择不同进入不同的执行路 径。

订单子流程定义,用于展示订单和添加披萨。

 <?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.0.xsd"> <input name="order" required="true" /> <!-- Order -->
<view-state id="showOrder">
<transition on="createPizza" to="createPizza" />
<transition on="checkout" to="orderCreated" />
<transition on="cancel" to="cancel" />
</view-state> <view-state id="createPizza" model="flowScope.pizza">
<on-entry>
<set name="flowScope.pizza"
value="new com.springinaction.pizza.domain.Pizza()" /> <evaluate result="viewScope.toppingsList"
expression="T(com.springinaction.pizza.domain.Topping).asList()" />
</on-entry>
<transition on="addPizza" to="showOrder">
<evaluate expression="order.addPizza(flowScope.pizza)" />
</transition>
<transition on="cancel" to="showOrder" />
</view-state> <!-- End state -->
<end-state id="cancel" />
<end-state id="orderCreated" />
</flow>

  这个子流程实际上会操作主流程创建的Order对象。因此,我们需要以某种方式将Order从主流程传到子流程。在这里,使用<input>元素来接收Order对象。如果你觉得这个流程与Java中的方法有 些类似地话,那这里使用的<input>元素实际上就定义了这个子流 程的签名。这个流程需要一个名为order的参数。 showOrder状态,它是一个基本的视图状态并 具有三个不同的转移,分别用于创建披萨、提交订单以及取消订单。

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

通过将流程作用域的对象绑定到HTML表单,实现 添加披萨到订单中。

createPizza.jsp

 <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<div> <h2>Create Pizza</h2>
<form:form commandName="pizza">
<input type="hidden" name="_flowExecutionKey"
value="${flowExecutionKey}" /> <b>Size: </b>
<br />
<form:radiobutton path="size" label="Small (12-inch)" value="SMALL" />
<br />
<form:radiobutton path="size" label="Medium (14-inch)" value="MEDIUM" />
<br />
<form:radiobutton path="size" label="Large (16-inch)" value="LARGE" />
<br />
<form:radiobutton path="size" label="Ginormous (20-inch)"
value="GINORMOUS" />
<br />
<br /> <b>Toppings: </b>
<br />
<form:checkboxes path="toppings" items="${toppingsList}"
delimiter="<br/>" />
<br />
<br /> <input type="submit" class="button" name="_eventId_addPizza"
value="Continue" />
<input type="submit" class="button" name="_eventId_cancel"
value="Cancel" />
</form:form>
</div>

  当通过当通过Continue按钮提交订单时,尺寸和配料选择将会绑定 到Pizza对象中并且触发addPizza转移。与这个转移关联的 <evaluate>元素表明在转移到showOrder状态之前,流程作用域 内的Pizza对象将会传递给订单的addPizza()方法中。

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

三、支付

  在披萨流程要结束的时候,最后的子流程提示用户输入他们的支付信息。这个简单 的流程如下图所示。

  支付子流程也使用<input>元素接收一 个Order对象作为输入。

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

  使用XML定义的支付流程如下所示,支付子流程有一个视图状态和一个行为状态。

 <?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.0.xsd"> <input name="order" required="true"/> <view-state id="takePayment" model="flowScope.paymentDetails">
<on-entry>
<set name="flowScope.paymentDetails"
value="new com.springinaction.pizza.domain.PaymentDetails()" /> <evaluate result="viewScope.paymentTypeList"
expression="T(com.springinaction.pizza.domain.PaymentType).asList()" />
</on-entry>
<transition on="paymentSubmitted" to="verifyPayment" />
<transition on="cancel" to="cancel" />
</view-state> <action-state id="verifyPayment">
<evaluate result="order.payment" expression=
"pizzaFlowActions.verifyPayment(flowScope.paymentDetails)" />
<transition to="paymentTaken" />
</action-state> <!-- End state -->
<end-state id="cancel" />
<end-state id="paymentTaken" />
</flow>

  在流程进入takePayment视图时,<on-entry>元素将构建一个支付表单并使用SpEL表达式在流程作用域内创建一 个PaymentDetails实例,这是支撑表单的对象。它也会创建视图 作用域的paymentTypeList变量,这个变量是一个列表包含了 PaymentType枚举(如下所示)的值。在这里,SpEL的 T()操作用于获得PaymentType类,这样就可以调用静态的 asList()方法。

 package com.springinaction.pizza.domain;

 import java.util.Arrays;
import java.util.List; import org.apache.commons.lang3.text.WordUtils; public enum PaymentType {
CASH, CHECK, CREDIT_CARD; public static List<PaymentType> asList() {
PaymentType[] all = PaymentType.values();
return Arrays.asList(all);
} @Override
public String toString() {
return WordUtils.capitalizeFully(name().replace('_', ' '));
}
}

  在面对支付表单的时候,用户可能提交支付也可能会取消。根据做出的选择,支付子流程将以名为paymentTaken或cancel的<end-state>结束。就像其他的子流程一样,不论哪种<end-state>都 会结束子流程并将控制交给主流程。但是所采用<end-state>的id 将决定主流程中接下来的转移。

笔记40 Spring Web Flow——订单流程(构建订单)的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

  7. 笔记41 Spring Web Flow——Demo

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

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

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

  9. Spring Web Flow 入门demo(三)嵌套流程与业务结合 附源代码

    上篇博客我们说Spring web Flow与业务结合的方式主要有三种,以下我们主要介绍一下第三种的应用方式 3,运行到<action-state> 元素 SpringWeb Flow 中 ...

随机推荐

  1. Ubuntu 14.04 Sublime Text3 Java编译运行(最简单的方法)

    Sublime,结果发现只能编译,无法直接运行,于是就在网上搜解决方法,发现大部分方法都是告诉你要进入Java.sublime-packag这个文件,然后再修改JavaC.sublime-build, ...

  2. linux 虚拟机网卡配置

     第一种虚拟机   我们常用的虚拟机vmware虚拟机 今天为了学习ngnix,所以配了两台虚拟机.一个centos7 ,一个redhat. 哇啦哇啦安装,so easy,对吧....我选择的是精简版 ...

  3. Java数据库事务四大特性以及隔离级别

    四大特性ACID 原子性(Atomicity) 原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚.失败回滚的操作事务,将不能对数据库有任何影响 一致性(Consistency) 一致性是指事 ...

  4. Java里的参数类型/返回值类型

    参数类型/返回值类型: ##数据类型: ###基本类型: ###引用类型: ####数组 ####类 ####接口 参数类型/返回值类型是类和接口的情况: 1.参数类型是普通类的情况 为什么写成静态, ...

  5. leetcode-163周赛-1262-可被3整除的最大和

    题目描述: 方法一:动态规划 O(N) class Solution: def maxSumDivThree(self, nums: List[int]) -> int: dp = [0, -1 ...

  6. java 获取String出现最多次数的字段

    package hello; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator ...

  7. 【Flutter学习】基本组件之图标组件Icon

    一,概述 图标组件(Icon)为展示图标的组件,该组件不可交互,要实现可交互的图标,可以考虑使用IconButton组件. 图标组件相关的几个组件: IconButton:可交互的Icon: Icon ...

  8. Delphi 文件操作(路径、目录)

    Delphi利用系统环境变量获取常用系统目录 //譬如 %WINDIR% 是表示系统目录的系统变量, 可以这样获取: var s: string; begin s := GetEnvironmentV ...

  9. 让IE8兼容识别css3选择器——selectivizr-min.js

    html: <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF ...

  10. AutoCAD2016安装破解教程

    AutoCAD2016安装破解教程.本人亲自实验,破解成功,有效.以64位为例. 工具/原料   笔记本电脑 AutoCAD2016安装包 AutoCAD2016注册机(xf-adsk2016_x64 ...