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

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

 

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

SpringWeb Flow 中的这个 <action-state> 是专为执行业务逻辑而设的 state 。如果某个应用的业务逻辑代码既不适合放在transition 中由客户端来触发,也不适合放在 Spring Web Flow 自定义的切入点,那么就可以考虑添加<action-state> 元素专用于该业务逻辑的执行。更倾向于触发某个事件来执行。

action-state 示例:

[html]  view plain copy print ?
  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


[java]  view plain copy print ?
  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:


[java]  view plain copy print ?
  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:


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

在/WEB-INF/flows 目录下添加 addToCart.xml

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

addToCart.xml:

[html]  view plain copy print ?
  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.     <!-- flow 执行之前 ,productId这个字段内容从viewCart页面中获取-->  
  8.     <on-start>  
  9.         <set name="requestScope.productId" value="requestParameters.productId" />  
  10.     </on-start>  
  11.       
  12.     <!-- addToCart flow 主要由一个 action-state 构成,完成添加商品到购物车的功能,  
  13.      addToCart flow 的实现需要有输入参数,即 productId 。  
  14.      本示例中是通过请求参数来传递,通过 requestParameters 来获取该数值。  
  15.      这里还要注意到 end-state 的 id 为“ productAdded ”,  
  16.      与 subflow-state 中的 transition元素的on属性的名称是对应的。 -->  
  17.       
  18.     <action-state id="addToCart">  
  19.         <evaluate expression="cart.addItem(productService.getProduct(productId))" />  
  20.         <transition to="productAdded" />  
  21.     </action-state>  
  22.     <end-state id="productAdded" />  
  23. </flow>  

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


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

viewCart.jsp:


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

viewOrder.jsp:

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


访问地址:

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

 

显示效果:



再扩展一下:


如果我们将shopping.xml中的配置文件修改一下,改为flowScope时,我们在viewOrder页面也可以获取products数据。

[html]  view plain copy print ?
  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 :


[html]  view plain copy print ?
  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的方式来控制页面间的流转顺序以及页面间数据的传输,使得我们页面间的跳转变得更加灵活可控。


附源码

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值