上篇博客我们说Spring web Flow与业务结合的方式主要有三种,以下我们主要介绍一下第三种的应用方式

3,运行到<action-state> 元素

SpringWeb Flow 中的这个 <action-state> 是专为运行业务逻辑而设的 state 。

假设某个应用的业务逻辑代码既不适合放在transition 中由client来触发,也不适合放在 Spring Web Flow 自己定义的切入点,那么就能够考虑加入<action-state> 元素专用于该业务逻辑的运行。更倾向于触发某个事件来运行。

action-state 演示样例:

  1. <action-state id="addToCart">
  2. <evaluate expression="cart.addItem(productService.getProduct(productId))"/>
  3. <transition to="productAdded"/>
  4. </action-state>

加入subflow 结点

商品列表已经实现了,接下来操作步骤为:

  1. 实现 Cart 和 CartItem 两个业务类
  2. 在 shopping.xml 中加入配置
  3. 在 /WEB-INF/flows 文件夹下加入 addToCart.xml
  4. 在 webflow-config.xml 中加入 addToCart.xml 的位置
  5. 改动 viewCart.jsp 页面

详细demo实现:

Cart:

  1. package samples.webflow;
  2.  
  3. import java.io.Serializable;
  4. import java.util.ArrayList;
  5. import java.util.HashMap;
  6. import java.util.List;
  7. import java.util.Map;
  8.  
  9. //购物车的实现类
  10. public class Cart implements Serializable {
  11.  
  12. private static final long serialVersionUID = 7901330827203016310L;
  13. private Map<Integer, CartItem> map = new HashMap<Integer, CartItem>();
  14.  
  15. //getItems 用于获取当前购物车里的物品
  16. public List<CartItem> getItems() {
  17. return new ArrayList<CartItem>(map.values());
  18. }
  19.  
  20. //addItem 用于向购物车加入商品
  21. public void addItem(Product product) {
  22. int id = product.getId();
  23. CartItem item = map.get(id);
  24. if (item != null)
  25. item.increaseQuantity();
  26. else
  27. map.put(id, new CartItem(product, 1));
  28. }
  29.  
  30. //getTotalPrice 用于获取购物车里全部商品的总价格
  31. public int getTotalPrice() {
  32. int total = 0;
  33. for (CartItem item : map.values())
  34. total += item.getProduct().getPrice() * item.getQuantity();
  35. return total;
  36. }
  37. }

Cart 是购物车的实现类,其相同要实现java.io.Serializable 接口。但它没有像 ProductService 一样成为由 Spring IoC 容器管理的 Bean,每一个客户的购物车是不同的,因此不能使用 Spring IoC 容器默认的 Singleton 模式。

CartItem:

  1. package samples.webflow;
  2.  
  3. import java.io.Serializable;
  4.  
  5. //购物车中的条目
  6. public class CartItem implements Serializable {
  7. private static final long serialVersionUID = 8388627124326126637L;
  8. private Product product;//商品
  9. private int quantity;//数量
  10.  
  11. public CartItem(Product product, int quantity) {
  12. this.product = product;
  13. this.quantity = quantity;
  14. }
  15.  
  16. //计算该条目的总价格
  17. public int getTotalPrice() {
  18. return this.quantity * this.product.getPrice();
  19. }
  20.  
  21. //添加商品的数量
  22. public void increaseQuantity() {
  23. this.quantity++;
  24. }
  25.  
  26. /**
  27. * Return property product
  28. */
  29. public Product getProduct() {
  30. return product;
  31. }
  32.  
  33. /**
  34. * Sets property product
  35. */
  36. public void setProduct(Product product) {
  37. this.product = product;
  38. }
  39.  
  40. /**
  41. * Return property quantity
  42. */
  43. public int getQuantity() {
  44. return quantity;
  45. }
  46.  
  47. /**
  48. * Sets property quantity
  49. */
  50. public void setQuantity(int quantity) {
  51. this.quantity = quantity;
  52. }
  53.  
  54. /* getter setter */
  55.  
  56. }

shopping.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. <!-- 在 shopping flow 開始时必须分配一个 Cart 对象,因为要调用 subflow ,
  8. 这个 Cart 对象应存放于 conversationScope 中。
  9.  
  10. 同一时候要加入一个 subflow-state 用于运行加入商品到购物车的任务。
  11.  
  12. -->
  13. <!-- mycart为一个服务类 -->
  14. <var name="mycart" class="samples.webflow.Cart" />
  15. <on-start>
  16. <set name="conversationScope.cart" value="mycart"></set>
  17. </on-start>
  18. <!-- view-state中的view相应jsp文件夹中的jsp页面,on是触发事件,to相应state id -->
  19. <view-state id="viewCart" view="viewCart">
  20. <!-- 在进入 view 的 render 流程之后。在 view 真正 render出来之前 -->
  21. <on-render>
  22. <!-- 要在 viewCart 页面中显示商品,仅仅需在 view-state 元素的 on-render 切入点调用 productService
  23. 的 getProducts 方法,并将所得结果保存到 viewScope 中就可以 -->
  24. <evaluate expression="productService.getProducts()" result="viewScope.products" />
  25. </on-render>
  26. <transition on="submit" to="viewOrder" />
  27. <transition on="addToCart" to="addProductToCart" />
  28. </view-state>
  29.  
  30. <subflow-state id="addProductToCart" subflow="addToCart">
  31. <transition on="productAdded" to="viewCart" />
  32. </subflow-state>
  33.  
  34. <view-state id="viewOrder" view="viewOrder">
  35. <transition on="confirm" to="orderConfirmed">
  36. </transition>
  37. </view-state>
  38. <view-state id="orderConfirmed" view="orderConfirmed">
  39. <transition on="returnToIndex" to="returnToIndex">
  40. </transition>
  41. </view-state>
  42.  
  43. <end-state id="returnToIndex" view="externalRedirect:servletRelative:/index.jsp">
  44. </end-state>
  45. </flow>

在/WEB-INF/flows 文件夹下加入 addToCart.xml

subflow-state元素的 subflow 属性即指明了这个被调用的 flow 的 id 为“ addToCart ”,如今就要加入addToCart flow的定义。

addToCart.xml:

  1. <?
  2.  
  3. xml version="1.0" encoding="UTF-8"?>
  4. <flow xmlns="http://www.springframework.org/schema/webflow"
  5. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  6. xsi:schemaLocation="http://www.springframework.org/schema/webflow
  7. http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">
  8.  
  9. <!-- flow 运行之前 。productId这个字段内容从viewCart页面中获取-->
  10. <on-start>
  11. <set name="requestScope.productId" value="requestParameters.productId" />
  12. </on-start>
  13.  
  14. <!-- addToCart flow 主要由一个 action-state 构成,完毕加入商品到购物车的功能。
  15. addToCart flow 的实现须要有输入參数。即 productId 。
  16. 本演示样例中是通过请求參数来传递。通过 requestParameters 来获取该数值。
  17.  
  18. 这里还要注意到 end-state 的 id 为“ productAdded ”,
  19. 与 subflow-state 中的 transition元素的on属性的名称是相应的。 -->
  20.  
  21. <action-state id="addToCart">
  22. <evaluate expression="cart.addItem(productService.getProduct(productId))" />
  23. <transition to="productAdded" />
  24. </action-state>
  25. <end-state id="productAdded" />
  26. </flow>

webflow-config.xml 中加入addToCart.xml 的位置

  1. <?xml version="1.0" encoding="utf-8"?
  2.  
  3. >
  4. <beans xmlns="http://www.springframework.org/schema/beans"
  5. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
  6. xsi:schemaLocation="http://www.springframework.org/schema/beans
  7. http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
  8. http://www.springframework.org/schema/context
  9. http://www.springframework.org/schema/context/spring-context-2.5.xsd">
  10. <!-- 搜索 samples.webflow 包里的 @Component 注解,并将其部署到容器中 -->
  11. <context:component-scan base-package="samples.webflow" />
  12. <!-- 启用基于注解的配置 -->
  13. <context:annotation-config />
  14. <import resource="webmvc-config.xml" />
  15. <import resource="webflow-config.xml" />
  16. </beans>

viewCart.jsp:

  1. <?xml version="1.0" encoding="utf-8" ?
  2.  
  3. >
  4. <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
  5. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  6. "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  7. <html xmlns="http://www.w3.org/1999/xhtml">
  8. <head>
  9. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  10. <title>View Cart</title>
  11. </head>
  12. <body>
  13. <h1>View Cart</h1>
  14. <h2>Items in Your Cart</h2>
  15. <c:choose>
  16. <c:when test="${empty cart.items}">
  17. <p>Your cart is empty.</p>
  18. </c:when>
  19. <c:otherwise>
  20. <table border="1" cellspacing="0">
  21. <tr>
  22. <th>Item</th>
  23. <th>Quantity</th>
  24. <th>Unit Price</th>
  25. <th>Total</th>
  26. </tr>
  27.  
  28. <c:forEach var="item" items="${cart.items}">
  29. <tr>
  30. <td>${item.product.description}</td>
  31. <td>${item.quantity}</td>
  32. <td>${item.product.price}</td>
  33. <td>${item.totalPrice}</td>
  34. </tr>
  35. </c:forEach>
  36.  
  37. <tr>
  38. <td>TOTAL:</td>
  39. <td></td>
  40. <td></td>
  41. <td>${cart.totalPrice}</td>
  42. </tr>
  43. </table>
  44. </c:otherwise>
  45. </c:choose>
  46.  
  47. <a href="${flowExecutionUrl}&_eventId=submit">Submit</a>
  48. <h2>Products for Your Choice</h2>
  49.  
  50. <table>
  51. <c:forEach var="product" items="${products}">
  52. <tr>
  53. <td>${product.description}</td>
  54. <td>${product.price}</td>
  55.  
  56. <td><a
  57. href="${flowExecutionUrl}&_eventId=addToCart&productId=${product.id}">[add
  58. to cart]</a></td>
  59.  
  60. </tr>
  61. </c:forEach>
  62.  
  63. </table>
  64. </body>
  65. </html>

viewOrder.jsp:

  1. <?xml version="1.0" encoding="utf-8" ?
  2.  
  3. >
  4. <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
  5. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  6. "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  7. <html xmlns="http://www.w3.org/1999/xhtml">
  8. <head>
  9. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  10. <title>view order</title>
  11. </head>
  12. <body>
  13. <h1>Order</h1>
  14. <c:choose>
  15. <c:when test="${empty cart.items}">
  16. <p>Your cart is empty.</p>
  17. </c:when>
  18. <c:otherwise>
  19. <table border="1" cellspacing="0">
  20. <tr>
  21. <th>Item</th>
  22. <th>Quantity</th>
  23. <th>Unit Price</th>
  24. <th>Total</th>
  25. </tr>
  26.  
  27. <c:forEach var="item" items="${cart.items}">
  28. <tr>
  29. <td>${item.product.description}</td>
  30. <td>${item.quantity}</td>
  31. <td>${item.product.price}</td>
  32. <td>${item.totalPrice}</td>
  33. </tr>
  34. </c:forEach>
  35.  
  36. <tr>
  37. <td>TOTAL:</td>
  38. <td></td>
  39. <td></td>
  40. <td>${cart.totalPrice}</td>
  41. </tr>
  42. </table>
  43. </c:otherwise>
  44. </c:choose>
  45.  
  46. <a href="${flowExecutionUrl}&_eventId=confirm">Confirm</a>
  47. </body>
  48. </html>

訪问地址:

http://localhost:8080/CartApp5/spring/index

显示效果:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaGVqaW5neXVhbjY=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />

再扩展一下:

假设我们将shopping.xml中的配置文件改动一下。改为flowScope时。我们在viewOrder页面也能够获取products数据。

  1. <view-state id="viewCart" view="viewCart">
  2. <!-- 在进入 view 的 render 流程之后,在 view 真正 render出来之前 -->
  3. <on-render>
  4. <!-- 要在 viewCart 页面中显示商品,仅仅需在 view-state 元素的 on-render 切入点调用 productService
  5. 的 getProducts 方法,并将所得结果保存到 viewScope 中就可以 -->
  6. <evaluate expression="productService.getProducts()" result="flowScope.products" />
  7. </on-render>
  8. <transition on="submit" to="viewOrder" />
  9. <transition on="addToCart" to="addProductToCart" />
  10. </view-state>

viewOrder.jsp:

  1. <h2>Products for Your Choice</h2>
  2.  
  3. <table>
  4. <c:forEach var="product" items="${products}">
  5. <tr>
  6. <td>${product.description}</td>
  7. <td>${product.price}</td>
  8. </tr>
  9. </c:forEach>
  10. </table>
  11. <a href="${flowExecutionUrl}&_eventId=confirm">Confirm</a>

效果图:

总结:

Spring Web Flow 应用流程的方式攻克了数据存取范围的问题,并在解决数据存取范围问题的同一时候,通过使用xml的方式来控制页面间的流转顺序以及页面间数据的传输,使得我们页面间的跳转变得更加灵活可控。

附源代码

Spring Web Flow 入门demo(三)嵌套流程与业务结合 附源代码的更多相关文章

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

    第一部分demo仅仅介绍了简单的页面跳转,接下来我们要实现与业务逻辑相关的功能. 业务的逻辑涉及到数据的获取.传递.保存.相关的业务功能函数的调用等内容,这些功能的实现都可用Java 代码来完毕,但定 ...

  2. spring web flow 2.0入门(转)

    Spring Web Flow 2.0 入门 一.Spring Web Flow 入门demo(一)简单页面跳转 附源码(转) 二.Spring Web Flow 入门demo(二)与业务结合 附源码 ...

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

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

  4. Spring Web Flow 2.0 入门

    转载: https://www.ibm.com/developerworks/cn/education/java/j-spring-webflow/index.html 开始之前 关于本教程 本教程通 ...

  5. 笔记41 Spring Web Flow——Demo

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

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

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

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

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

  8. Spring学习笔记4—流程(Spring Web Flow)

    Spring Web Flow是Spring框架的子项目,作用是让程序按规定流程运行. 1 安装配置Spring Web Flow 虽然Spring Web Flow是Spring框架的子项目,但它并 ...

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

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

随机推荐

  1. AC日记——[SCOI2008] 着色方案 bzoj 1079

    1079 思路: dp: 我们如果dp方程为15维,每维记录颜色还有多少种: 不仅tle,mle,它还re: 所以,我们压缩一下dp方程: 方程有6维,第i维记录有多少种颜色还剩下i次: 最后还要记录 ...

  2. Netty源码学习(七)FastThreadLocal

    0. FastThreadLocal简介 如同注释中所说:A special variant of ThreadLocal that yields higher access performance ...

  3. Python与数据库[0] -> 数据库概述

    数据库概述 / Database Overview 1 关于SQL / About SQL 构化查询语言(Structured Query Language)简称SQL,是一种特殊目的的编程语言,是一 ...

  4. 树链剖分【p4315】月下"毛景树"

    Description 毛毛虫经过及时的变形,最终逃过的一劫,离开了菜妈的菜园. 毛毛虫经过千山万水,历尽千辛万苦,最后来到了小小的绍兴一中的校园里. 爬啊爬~爬啊爬毛毛虫爬到了一颗小小的" ...

  5. 解密Java内存溢出之持久代

    垃圾回收是Java程序员了解最少的一部分.他们认为Java虚拟机接管了垃圾回收,因此没必要去担心内存的申请,分配等问题.但是随着应用越来越复杂,垃圾回收也越来越复杂,一旦垃圾回收变的复杂,应用的性能将 ...

  6. Entity Framework贪婪加载筛选问题

    先说一下代码北京,现在有一个Table类,代表桌子,然后Tale里面级联这一系列订单Order,现在要获取这个Table中没有完成的订Order,用完include之后居然发现不知道该怎么写,上网找了 ...

  7. 动态路由协议(3)--ospf

    1.设置pc ip 网关 192.168.1.1 192.168.1.254 192.168.4.1 192.168.4.254 2.设置路由器 (1)设置接口ip Router(config-/ R ...

  8. C++STL中的向量vector

    #include<iostream>#include<vector>#include<algorithm>using namespace std;typedef v ...

  9. 如何给JQ的ajax方法中的success()传入参数?

    当时在使用JQuery提供的Ajax技术的时候,我有个需求,就是要给它请求成功后调用的success()方法传入参数: 所以,我就直接这样子写了: <script> function ge ...

  10. 求逆序对数总结 & 归并排序

    用归并排序方式 最原始的方法的复杂度是O(n^2). 使用归并排序的方式,可以把复杂度降低到O(nlgn). 设A[1..n]是一个包含N个非负整数的数组.如果在i〈 j的情况下,有A〉A[j],则( ...