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


    做一个在线的披萨订购应用

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

    一、定义基本流程

    当顾客访问Spizza站点时,他们需要进行用户识别,选择一个 或更多披萨添加到订单中,提供支付信息然后提交订单。

    订购披萨的整个流程很简单且是线性的。

    1.使用Spring Web Flow的XML流程定义来实现披萨订单的整体流程。

    pizza-flow.xml

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <flow xmlns="http://www.springframework.org/schema/webflow"
     3   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     4   xsi:schemaLocation="http://www.springframework.org/schema/webflow 
     5   http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">
     6 
     7     <var name="order" class="com.springinaction.pizza.domain.Order"/>
     8     
     9     <!-- Customer -->
    10     <subflow-state id="customer" subflow="pizza/customer">
    11       <input name="order" value="order"/>
    12       <transition on="customerReady" to="order" />
    13     </subflow-state>
    14     
    15     <!-- Order -->
    16     <subflow-state id="order" subflow="pizza/order">
    17       <input name="order" value="order"/>
    18       <transition on="orderCreated" to="payment" />
    19     </subflow-state>
    20         
    21     <!-- Payment -->
    22     <subflow-state id="payment" subflow="pizza/payment">
    23       <input name="order" value="order"/>
    24       <transition on="paymentTaken" to="saveOrder"/>      
    25     </subflow-state>
    26         
    27     <action-state id="saveOrder">
    28         <evaluate expression="pizzaFlowActions.saveOrder(order)" />
    29         <transition to="thankYou" />
    30     </action-state>
    31     
    32     <view-state id="thankYou">
    33       <transition to="endState" />
    34     </view-state>
    35                 
    36     <!-- End state -->
    37     <end-state id="endState" />
    38     
    39     <global-transitions>
    40       <transition on="cancel" to="endState" />
    41     </global-transitions>
    42 </flow>

    在流程定义中,第一件事就是order变量的声明。每次流程开始的时候,都会创建一个order实例。order类会带有关于订单的所有信息,包含顾客信息、订购的披萨列表以及支付详情。

    2. order带有披萨订单的所有细节信息

     1 package com.springinaction.pizza.domain;
     2 
     3 import java.io.Serializable;
     4 import java.util.ArrayList;
     5 import java.util.List;
     6 
     7 public class Order implements Serializable {
     8     private static final long serialVersionUID = 1L;
     9     private Customer customer;
    10     private List<Pizza> pizzas;
    11     private Payment payment;
    12 
    13     public Order() {
    14         pizzas = new ArrayList<Pizza>();
    15         customer = new Customer();
    16     }
    17 
    18     public Customer getCustomer() {
    19         return customer;
    20     }
    21 
    22     public void setCustomer(Customer customer) {
    23         this.customer = customer;
    24     }
    25 
    26     public List<Pizza> getPizzas() {
    27         return pizzas;
    28     }
    29 
    30     public void setPizzas(List<Pizza> pizzas) {
    31         this.pizzas = pizzas;
    32     }
    33 
    34     public Payment getPayment() {
    35         return payment;
    36     }
    37 
    38     public void setPayment(Payment payment) {
    39         this.payment = payment;
    40     }
    41

      流程定义的主要组成部分是流程的状态。默认情况下,流程定义文件 中的第一个状态也会是流程访问中的第一个状态。在本例中,也就 是identifyCustomer状态(一个子流程)。但是如果你愿意的 话,你可以通过<flow>元素的start-state属性将任意状态指定 为开始状态。

      识别顾客、构造披萨订单以及支付这样的活动太复杂了,并不适合将 其强行塞入一个状态,应该单独定义为流程。但是为了更好地整体了解披萨流程,这些活动都是以 <subflow-state>元素来进行展现的。 

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

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

    3.感谢页面(thankCustomer.jsp)

     

     1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
     2 <%
     3 String path = request.getContextPath();
     4 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
     5 %>
     6 
     7 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
     8 <html>
     9   <head>
    10     <base href="<%=basePath%>">
    11     
    12     <title>My JSP 'thankCustomer.jsp' starting page</title>
    13     
    14     <meta http-equiv="pragma" content="no-cache">
    15     <meta http-equiv="cache-control" content="no-cache">
    16     <meta http-equiv="expires" content="0">    
    17     <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    18     <meta http-equiv="description" content="This is my page">
    19     <!--
    20     <link rel="stylesheet" type="text/css" href="styles.css">
    21     -->
    22 
    23   </head>
    24   
    25   <body>
    26     <h2>Thank you for your order!</h2>
    27     <a href="${flowExecutionUrl}&_eventId=finished">Finish</a>
    28   </body>
    29 </html>

     

      在感谢页面中,会感谢顾客的订购并为其提供一个完成流程的连接。Spring Web Flow为视图的用户提供了一个flowExecutionUrl变 量,它包含了流程的URL。结束链接将一个“_eventId”参数关联到 URL上,以便回到Web流程时触发finished事件。这个事件将会让 流程到达结束状态。流程将会在结束状态完成。鉴于在流程结束后没有下一步做什么的具 体信息,流程将会重新从identifyCustomer状态开始,以准备接 受另一个披萨订单。

    目前还缺少的子流程:identifyCustomer、buildOrder、takePayment。

  • 相关阅读:
    .Net常见笔试题
    冒泡排序算法 C#版
    Bundle捆绑压缩技术
    异步Ajax
    HtmlHelper总结
    HtmlHelper的扩展分页方法
    WCF
    程序猿值得看的几个技术网站(记录)
    Struts2和SpringMVC的区别
    nginx配置文件作用介绍
  • 原文地址:https://www.cnblogs.com/lyj-gyq/p/9102707.html
Copyright © 2020-2023  润新知