Spring web flow——披萨订购流程示例(1)

一、Spring web Flow定义

Spring Web Flow(后面简称swf)是一个Web框架,它适用于元素按规定流程运行的程序。Spring Web Flow是Spring MVC的扩展,它支持开发基于流程的应用程序。它将流程的定义于实现流程行为的类和视图分离开来。

下面我们通过生成披萨订单的新Web应用程序。我们会使用Spring Web Flow来定义订单流程。

1.1 swf环境准备

尽管swf是Spring框架的子项目,但它并不是Spring框架的一部分。因此,在构建基于流程的应用程序之前,我们需要在项目的类路径下添加swf。

最新版本的jar包位置(ps:官方网址现在已经不提供直接的jar包下载了)

官方示例参考文档(还是蛮详细的)

API文档

1.2 基于Spring MVC上构建swf

swf是构建于Spring MVC基础之上的。这意味着所有的流程请求都需要首先经过Spring MVC的DispatcherServlet。我们需要在Spring应用上下文中配置一些Bean来处理流程请求并执行流程。

先看看web.xml的配置信息,算是spring mvc的最小配置了,在这里完全体现不出来swf,代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">
  <display-name>order</display-name>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  <servlet>
    <servlet-name>order</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>order</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>

接下来就是swf重点配置了,先直接看配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
     xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    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-4.0.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/webflow-config
    http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.4.xsd">

    <!-- 控制器包路径,对于SWF而言,在这里面增加流程的action -->
    <context:component-scan
    base-package="com.paner.pizza.controller">
    </context:component-scan> 

    <!-- 适配器和视图解析,指定了jsp查找的路径 -->
     <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"
     p:prefix="/WEB-INF/jsp/" p:suffix=".jsp" />

     <!-- 流程执行器 -->
    <flow:flow-executor id="flowExecutor"
                    flow-registry="flowRegistry"></flow:flow-executor>
    <!-- 配置流程注册表 -->
    <flow:flow-registry id="flowRegistry" base-path="/WEB-INF/flows"
      flow-builder-services="flowBuilderService">
        <flow:flow-location-pattern value="/**/*-flow.xml"/>
    </flow:flow-registry> 

    <!-- 这两个配置用于将刚才的视图解析器的方式,作用于swf中 -->
    <flow:flow-builder-services id="flowBuilderService"
        view-factory-creator="mvcViewFactoryCreator"
    />
    <bean id="mvcViewFactoryCreator"
  class="org.springframework.webflow.mvc.builder.MvcViewFactoryCreator">
        <property name="viewResolvers" ref="viewResolver"/>
  </bean>
    <!-- 接下来两个配置项,是为了处理流程的请求 -->
    <bean class="org.springframework.webflow.mvc.servlet.FlowHandlerMapping">
        <property name="flowRegistry" ref="flowRegistry"></property>
    </bean>
    <bean class="org.springframework.webflow.mvc.servlet.FlowHandlerAdapter">
        <property name="flowExecutor" ref="flowExecutor"></property>
    </bean>
</beans>

说明:

  1. 流程执行器

<flow:flow-executor>元素会创建一个流程执行器。流程执行器(flow executor)驱动流程的执行。当用户进入一个流程时,流程执行器会为用户创建并启动一个流程执行实例。当流程暂停的时候,流程执行器会在用户执行操作后恢复流程。当流程暂停的时候,流程执行器会在用户执行操作后恢复流程。

尽管流程执行器负责创建和执行流程,但它并不负责加载流程定义。这个责任落在了流程注册表(flow registry)身上,接下来会创建它。在这里,通过ID来引用了流程注册表。

  1. 配置流程注册表

</flow:flow-registry>元素会创建一个流程注册表。 流程注册表(flow registry)的工作是加载流程定义并让流程执行器能够使用它们。

在这里通过flow-builder-services="flowBuilderService字段定义了jsp的解析方式;<flow:flow-location-pattern value="/**/*-flow.xml"/> 在这里的声明中,流程注册表会在/WEB-INF/flows目录下查找流程定义,这是通过base-path属性指明的。依据 < flow:flow-location-pattern>元素的值,任何文件名以-flow.xml结尾的XML文件都将视为流程定义。

比如我们现在的主流程定义在order-flow.xml文件中,如要在浏览器中加载该流程,只需要输入http://localhost:8080/WebFlow_orderSystem/order,后面的order就是流程默认的id。通过该id找到对应的流程配置文件。

  1. 处理流程请求

    DispatcherServlet一般将请求分发给控制器。但是对于流程而言,我们需要FlowHandlerMapping来帮助DispatcherServlet将流程请求发送给Spring Web Flow。

    你可以看到,FlowHandlerMapping装配了流程注册表的引用,这样他就能知道如何请求的URL匹配到流程上。例如,如果我们有一个ID为springpizza的流程,FlowHandlerMapping就会知道如果请求的URL模式是“/springpizza”的话,就要将其匹配到这个流程上。、

    然而,FlowHandlerMapping的工作仅仅是将流程请求定向到Spring Web Flow上,响应请求的是FlowHandlerAdapter。FlowHandlerAdapter等同于Spring MVC的控制器,它会响应发送的流程请求并对其进行处理。

    这个处理器适配器是DispatcherServlet和Spring Web Flow之间的桥梁。它会处理流程请求并管理基于这些请求的流程。在这里,它装配了流程制定器的引用,而后者是为请求执行的流程。

二、流程的组件

在Spring Web Flow中,流程是由3个主要元素定义的:状态、转移和流程数据

状态(State)是流程中事件发生的地点。如果你将流程想象成公路旅行,那状态就是路途上的城镇、路边饭店以及风景点。流程中的状态是业务逻辑执行、作出决策或将页面展现给用户的地方,而不是在公路旅行中买薯片和可乐的所在。

如果流程状态就像公路旅行中停下来的地点,那转移(transition)就是连接这写点的公路。在流程中,你通过转移的方式从一个状态到另一个状态。

当你在城镇之间旅行的时候,你可能要买一些纪念品、留下一些记忆并在路上获取一些空的零食袋。类似地,在流程处理中,它要收集一些数据:流程的当前状况。

2.1 状态

Spring Web Flow定义了5中不同的类型的状态,如下表所示。

通过选择Spring Web Flow的状态几乎可以把任意的安排功能构造成会话式的Web应用程序。

  • 视图状态用来为用户展现信息并使用用户在流程中发挥作用。实际的视图实现可以是Spring支持的任意视图类型,但通常使用JSP来实现的;
  • 视图状态涉及流程应用程序的用户,而行为状态则是应用程序自身在执行任务。行为状态一般会触发Spring所管理Bean的一些方法并根据方法调用的执行结果转移到另一个状态。
  • 有可能流程会完全按照线性执行,从一个状态进入另一个状态,没有其他的替代路线。但是更常见的情况是流程中某一个点根据流程的当前情况进入不同的分支。
  • 决策状态能够使得在流程执行时产生两个分支。决策将评估一个Boolean类型的表达式,然后在两个状态转移中选择一个,这是要取决于表达式会计算出true还是false。在XML流程定义中,决策状态通过元素进行定义。
  • 你可能不会将应用程序的所有逻辑写在一个方法中,而是将其分散到多个类、方法以及其他结构中。
  • 当到达状态,流程会结束。接下来发生什么取决于几个因素。
    • 如果结束的流程是一个子流程,那调用它的流程将会从处继续执行。的ID将会用作事件触发从开始的转移。
    • 如果设置了view属性,指定的视图将会被渲染。视图可以是相对于流程的路径也可以是流程模板。加externalRedirect:前缀将重定向到流程外部的页面而添加flowRedirect:将重定向到另一个流程中。
    • 如果结束的流程不是子流程也没有指定view属性,那这个流程只是会结束。浏览器最后会加载流程的基本URL地址,当前已没有活动的流程,所以会开始一个新的流程实例。
2.2 转移

转移连接流程中的状态。流程中除结束状态的每个状态,至少需要由一个转移,这样能够知道一旦这个状态完成时流程要去向哪里。状态可以由多个转移,分别对应于当前状态结束时可以执行的不同的路径。

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

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

2.2 流程数据

当流程从一个状态进行到另一个状态时,它会带走一些数据。有时候,这些数据只需要很短的时间。有时候,这些数据会在整个流程中传递并在流程结束的时候使用。

声明变量

流程数据保存在变量中,而变量可以在流程的任意地方进行引用。它能够以多种方式创建。在流程中创建变量的最简单形式是使用元素:

<var name="customer" class="com.spring.pizza.domain.Customer" />

作为行为状态的一部分或者作为视图状态的入口,你可能会使用元素来创建变量。

<evaluate result="viewScope.toppingsList"

expression="T(com.spring.pizza.domain.Tooping).asList()" />

元素也可以设置变量的值:<set name="flowScope.pizza"

value="new com.spring.pizza.domain.Pizza()" />

元素与元素很类似,都是将变量设置为表达式计算的结果。

定义流程数据的作用域

流程中携带的数据会拥有不同的生命作用域和可见性,这取决于保存数据的变量本身的作用域。Spring Web Flow定义了5种作用域,如表所示:

到此,swf相关的基本知识已经介绍完了。下面开始进入披萨流程了

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-19 13:02:58

Spring web flow——披萨订购流程示例(1)的相关文章

《Spring实战》学习笔记-第八章:使用Spring Web Flow

第四版的第八章内容与第三版基本一致. 本章内容: 创建会话式web应用程序 定义流程状态和行为 保护web流程 互联网的一个奇特之处就在于它很容易让人迷失.有如此多的内容可以查看和阅读,而超链接是其强大魔力的核心所在. 有时候,web应用程序需要控制web冲浪者的导向,引导他们一步步地访问应用.比如电子商务网站的付款流程,从购物车开始,应用程序会引导你依次经过配送详情.账单信息以及最终的订单确认. Spring Web Flow是一个web框架,它适用于元素规定流程运行的程序.本章中,我们将会探

用Spring Web Flow和Terracotta搭建Web应用

什么是Spring Web Flow? Spring Web Flow是Spring Framework中的web应用组件,它提供了一种编写有状态和基于会话的web应用的简便手段.Spring Web Flow 使得逻辑流程成为web应用中的一等公民,它能让你定义为自包含模块,以独立于应用的其它部分来配置和重用.它不依赖于框架从而能够方便的与可选的web应用框架一同使用,比如Spring MVC.Struts或者JSF等. 页面流转使用一种领域定义语言(DSL)来配置,这个语言专门开发用来定义和

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

上篇博客我们说Spring web Flow与业务结合的方式主要有三种,下面我们主要介绍一下第三种的应用方式 3,执行到<action-state> 元素 SpringWeb Flow 中的这个 <action-state> 是专为执行业务逻辑而设的 state .如果某个应用的业务逻辑代码既不适合放在transition 中由客户端来触发,也不适合放在 Spring Web Flow 自定义的切入点,那么就可以考虑添加<action-state> 元素专用于该业务逻辑

Spring Web Flow 学习笔记(2)-流程的组件

1.在Spring Web Flow中,流程由三个主要元素定义的:状态.转移和流程数据. 状态是流程中事件发生的地点,类似公路旅行中停下来的地点,转移就类似与连接这些地点的公路 2.状态 Spring Web Flow 定义了5种不同类型的状态: 状态类型 作用 行为(Action) 是流程逻辑发生的地方 决策(Decision) 将流程分成两个方向,它会基于流程数据的评估结果确定流程的方向 结束(End) 是流程的最后一站,一旦进入End状态,流程就会结束 子流程(Subflow) 会在当前的

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

上篇博客我们说Spring web Flow与业务结合的方式主要有三种,以下我们主要介绍一下第三种的应用方式 3,运行到<action-state> 元素 SpringWeb Flow 中的这个 <action-state> 是专为运行业务逻辑而设的 state . 假设某个应用的业务逻辑代码既不适合放在transition 中由client来触发,也不适合放在 Spring Web Flow 自己定义的切入点,那么就能够考虑加入<action-state> 元素专用于

Spring Web Flow 笔记

在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.sprin

spring web flow 2.0入门(转:http://luanxiyuan.iteye.com/blog/2282126)

Spring Web Flow 2.0 入门详解 博客分类: spring 目录: 参考文献 购物车用例 什么情况下可以使用 Spring Web Flow? 配置 Spring Web MVC 配置 Spring Web Flow 2.0 的基础 在购物车示例应用中配置 Spring Web Flow 用 Unified EL 实现业务逻辑 用 subflow 实现添加商品到购物车功能 global transition 简介 1.参考文献 参考1:http://www.ibm.com/dev

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

第一部分demo仅仅介绍了简单的页面跳转,接下来我们要实现与业务逻辑相关的功能. 业务的逻辑涉及到数据的获取.传递.保存,相关的业务功能函数的调用等内容,这些功能的实现都可用Java 代码来完成,但定义 Spring Web Flow 的语法与 Java 是无关的,这就要求 Spring Web Flow 提供与 Java代码的整合机制.要了解这种机制,关键在于搞清楚两个问题: 业务逻辑代码在什么时候被调用? 业务逻辑代码在调用后得到的数据如何保存.传递? 业务逻辑代码在什么时候被调用? 在 S

Spring Web Flow 入门demo(一)附源码

Spring Web Flow (SWF)是Spring Framework的一个脱离模块.这个模块是Spring Web应用开发模块栈的一部分,Spring Web包含Spring MVC. Spring Web Flow的目标是成为管理Web应用页面流程的最佳方案.当你的应用需要复杂的导航控制,例如向导,在一个比较大的事务过程中去指导用户经过一连串的步骤的时候,SWF将会是一个功能强大的控制器. 下面我们还是从一个简单的demo开始了解它: 这个例子是结合Springmvc来实现,项目结构: