Spring Web Flow 入门demo(三)嵌套流程与业务结合 附源代码
上篇博客我们说Spring web Flow与业务结合的方式主要有三种,以下我们主要介绍一下第三种的应用方式
3,运行到<action-state> 元素
SpringWeb Flow 中的这个 <action-state> 是专为运行业务逻辑而设的 state 。
假设某个应用的业务逻辑代码既不适合放在transition 中由client来触发,也不适合放在 Spring Web Flow 自己定义的切入点,那么就能够考虑加入<action-state> 元素专用于该业务逻辑的运行。更倾向于触发某个事件来运行。
action-state 演示样例:
- <action-state id="addToCart">
- <evaluate expression="cart.addItem(productService.getProduct(productId))"/>
- <transition to="productAdded"/>
- </action-state>
加入subflow 结点
商品列表已经实现了,接下来操作步骤为:
- 实现 Cart 和 CartItem 两个业务类
- 在 shopping.xml 中加入配置
- 在 /WEB-INF/flows 文件夹下加入 addToCart.xml
- 在 webflow-config.xml 中加入 addToCart.xml 的位置
- 改动 viewCart.jsp 页面
详细demo实现:
Cart:
- package samples.webflow;
- import java.io.Serializable;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- //购物车的实现类
- public class Cart implements Serializable {
- private static final long serialVersionUID = 7901330827203016310L;
- private Map<Integer, CartItem> map = new HashMap<Integer, CartItem>();
- //getItems 用于获取当前购物车里的物品
- public List<CartItem> getItems() {
- return new ArrayList<CartItem>(map.values());
- }
- //addItem 用于向购物车加入商品
- public void addItem(Product product) {
- int id = product.getId();
- CartItem item = map.get(id);
- if (item != null)
- item.increaseQuantity();
- else
- map.put(id, new CartItem(product, 1));
- }
- //getTotalPrice 用于获取购物车里全部商品的总价格
- public int getTotalPrice() {
- int total = 0;
- for (CartItem item : map.values())
- total += item.getProduct().getPrice() * item.getQuantity();
- return total;
- }
- }
Cart 是购物车的实现类,其相同要实现java.io.Serializable 接口。但它没有像 ProductService 一样成为由 Spring IoC 容器管理的 Bean,每一个客户的购物车是不同的,因此不能使用 Spring IoC 容器默认的 Singleton 模式。
CartItem:
- package samples.webflow;
- import java.io.Serializable;
- //购物车中的条目
- public class CartItem implements Serializable {
- private static final long serialVersionUID = 8388627124326126637L;
- private Product product;//商品
- private int quantity;//数量
- public CartItem(Product product, int quantity) {
- this.product = product;
- this.quantity = quantity;
- }
- //计算该条目的总价格
- public int getTotalPrice() {
- return this.quantity * this.product.getPrice();
- }
- //添加商品的数量
- public void increaseQuantity() {
- this.quantity++;
- }
- /**
- * Return property product
- */
- public Product getProduct() {
- return product;
- }
- /**
- * Sets property product
- */
- public void setProduct(Product product) {
- this.product = product;
- }
- /**
- * Return property quantity
- */
- public int getQuantity() {
- return quantity;
- }
- /**
- * Sets property quantity
- */
- public void setQuantity(int quantity) {
- this.quantity = quantity;
- }
- /* getter setter */
- }
shopping.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">
- <!-- 在 shopping flow 開始时必须分配一个 Cart 对象,因为要调用 subflow ,
- 这个 Cart 对象应存放于 conversationScope 中。
- 同一时候要加入一个 subflow-state 用于运行加入商品到购物车的任务。
- -->
- <!-- mycart为一个服务类 -->
- <var name="mycart" class="samples.webflow.Cart" />
- <on-start>
- <set name="conversationScope.cart" value="mycart"></set>
- </on-start>
- <!-- view-state中的view相应jsp文件夹中的jsp页面,on是触发事件,to相应state id -->
- <view-state id="viewCart" view="viewCart">
- <!-- 在进入 view 的 render 流程之后。在 view 真正 render出来之前 -->
- <on-render>
- <!-- 要在 viewCart 页面中显示商品,仅仅需在 view-state 元素的 on-render 切入点调用 productService
- 的 getProducts 方法,并将所得结果保存到 viewScope 中就可以 -->
- <evaluate expression="productService.getProducts()" result="viewScope.products" />
- </on-render>
- <transition on="submit" to="viewOrder" />
- <transition on="addToCart" to="addProductToCart" />
- </view-state>
- <subflow-state id="addProductToCart" subflow="addToCart">
- <transition on="productAdded" to="viewCart" />
- </subflow-state>
- <view-state id="viewOrder" view="viewOrder">
- <transition on="confirm" to="orderConfirmed">
- </transition>
- </view-state>
- <view-state id="orderConfirmed" view="orderConfirmed">
- <transition on="returnToIndex" to="returnToIndex">
- </transition>
- </view-state>
- <end-state id="returnToIndex" view="externalRedirect:servletRelative:/index.jsp">
- </end-state>
- </flow>
在/WEB-INF/flows 文件夹下加入 addToCart.xml
subflow-state元素的 subflow 属性即指明了这个被调用的 flow 的 id 为“ addToCart ”,如今就要加入addToCart flow的定义。
addToCart.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">
- <!-- flow 运行之前 。productId这个字段内容从viewCart页面中获取-->
- <on-start>
- <set name="requestScope.productId" value="requestParameters.productId" />
- </on-start>
- <!-- addToCart flow 主要由一个 action-state 构成,完毕加入商品到购物车的功能。
- addToCart flow 的实现须要有输入參数。即 productId 。
- 本演示样例中是通过请求參数来传递。通过 requestParameters 来获取该数值。
- 这里还要注意到 end-state 的 id 为“ productAdded ”,
- 与 subflow-state 中的 transition元素的on属性的名称是相应的。 -->
- <action-state id="addToCart">
- <evaluate expression="cart.addItem(productService.getProduct(productId))" />
- <transition to="productAdded" />
- </action-state>
- <end-state id="productAdded" />
- </flow>
webflow-config.xml 中加入addToCart.xml 的位置
- <?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:context="http://www.springframework.org/schema/context"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
- http://www.springframework.org/schema/context
- http://www.springframework.org/schema/context/spring-context-2.5.xsd">
- <!-- 搜索 samples.webflow 包里的 @Component 注解,并将其部署到容器中 -->
- <context:component-scan base-package="samples.webflow" />
- <!-- 启用基于注解的配置 -->
- <context:annotation-config />
- <import resource="webmvc-config.xml" />
- <import resource="webflow-config.xml" />
- </beans>
viewCart.jsp:
- <?xml version="1.0" encoding="utf-8" ?
- >
- <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <title>View Cart</title>
- </head>
- <body>
- <h1>View Cart</h1>
- <h2>Items in Your Cart</h2>
- <c:choose>
- <c:when test="${empty cart.items}">
- <p>Your cart is empty.</p>
- </c:when>
- <c:otherwise>
- <table border="1" cellspacing="0">
- <tr>
- <th>Item</th>
- <th>Quantity</th>
- <th>Unit Price</th>
- <th>Total</th>
- </tr>
- <c:forEach var="item" items="${cart.items}">
- <tr>
- <td>${item.product.description}</td>
- <td>${item.quantity}</td>
- <td>${item.product.price}</td>
- <td>${item.totalPrice}</td>
- </tr>
- </c:forEach>
- <tr>
- <td>TOTAL:</td>
- <td></td>
- <td></td>
- <td>${cart.totalPrice}</td>
- </tr>
- </table>
- </c:otherwise>
- </c:choose>
- <a href="${flowExecutionUrl}&_eventId=submit">Submit</a>
- <h2>Products for Your Choice</h2>
- <table>
- <c:forEach var="product" items="${products}">
- <tr>
- <td>${product.description}</td>
- <td>${product.price}</td>
- <td><a
- href="${flowExecutionUrl}&_eventId=addToCart&productId=${product.id}">[add
- to cart]</a></td>
- </tr>
- </c:forEach>
- </table>
- </body>
- </html>
viewOrder.jsp:
- <?xml version="1.0" encoding="utf-8" ?
- >
- <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <title>view order</title>
- </head>
- <body>
- <h1>Order</h1>
- <c:choose>
- <c:when test="${empty cart.items}">
- <p>Your cart is empty.</p>
- </c:when>
- <c:otherwise>
- <table border="1" cellspacing="0">
- <tr>
- <th>Item</th>
- <th>Quantity</th>
- <th>Unit Price</th>
- <th>Total</th>
- </tr>
- <c:forEach var="item" items="${cart.items}">
- <tr>
- <td>${item.product.description}</td>
- <td>${item.quantity}</td>
- <td>${item.product.price}</td>
- <td>${item.totalPrice}</td>
- </tr>
- </c:forEach>
- <tr>
- <td>TOTAL:</td>
- <td></td>
- <td></td>
- <td>${cart.totalPrice}</td>
- </tr>
- </table>
- </c:otherwise>
- </c:choose>
- <a href="${flowExecutionUrl}&_eventId=confirm">Confirm</a>
- </body>
- </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数据。
- <view-state id="viewCart" view="viewCart">
- <!-- 在进入 view 的 render 流程之后,在 view 真正 render出来之前 -->
- <on-render>
- <!-- 要在 viewCart 页面中显示商品,仅仅需在 view-state 元素的 on-render 切入点调用 productService
- 的 getProducts 方法,并将所得结果保存到 viewScope 中就可以 -->
- <evaluate expression="productService.getProducts()" result="flowScope.products" />
- </on-render>
- <transition on="submit" to="viewOrder" />
- <transition on="addToCart" to="addProductToCart" />
- </view-state>
viewOrder.jsp:
- <h2>Products for Your Choice</h2>
- <table>
- <c:forEach var="product" items="${products}">
- <tr>
- <td>${product.description}</td>
- <td>${product.price}</td>
- </tr>
- </c:forEach>
- </table>
- <a href="${flowExecutionUrl}&_eventId=confirm">Confirm</a>
效果图:
总结:
Spring Web Flow 应用流程的方式攻克了数据存取范围的问题,并在解决数据存取范围问题的同一时候,通过使用xml的方式来控制页面间的流转顺序以及页面间数据的传输,使得我们页面间的跳转变得更加灵活可控。
Spring Web Flow 入门demo(三)嵌套流程与业务结合 附源代码的更多相关文章
- Spring Web Flow 入门demo(二)与业务结合 附源代码
第一部分demo仅仅介绍了简单的页面跳转,接下来我们要实现与业务逻辑相关的功能. 业务的逻辑涉及到数据的获取.传递.保存.相关的业务功能函数的调用等内容,这些功能的实现都可用Java 代码来完毕,但定 ...
- spring web flow 2.0入门(转)
Spring Web Flow 2.0 入门 一.Spring Web Flow 入门demo(一)简单页面跳转 附源码(转) 二.Spring Web Flow 入门demo(二)与业务结合 附源码 ...
- 笔记42 Spring Web Flow——Demo(2)
转自:https://www.cnblogs.com/lyj-gyq/p/9117339.html 为了更好的理解披萨订购应用,再做一个小的Demo. 一.Spring Web Flow 2.0新特性 ...
- Spring Web Flow 2.0 入门
转载: https://www.ibm.com/developerworks/cn/education/java/j-spring-webflow/index.html 开始之前 关于本教程 本教程通 ...
- 笔记41 Spring Web Flow——Demo
订购披萨的应用整体比较比较复杂,现拿出其中一个简化版的流程:即用户访问首页,然后输入电话号(假定未注册)后跳转到注册页面,注册完成后跳转到配送区域检查页面,最后再跳转回首页.通过这个简单的Demo用来 ...
- 笔记38 Spring Web Flow——订单流程(定义基本流程)
做一个在线的披萨订购应用 实际上,订购披萨的过程可以很好地定义在一个流程中.我们首先从 构建一个高层次的流程开始,它定义了订购披萨的整体过程.接下 来,我们会将这个流程拆分成子流程,这些子流程在较低的 ...
- 笔记37 Spring Web Flow——流程的组件
在Spring Web Flow中,流程是由三个主要元素定义的:状态.转移和 流程数据. 一.状态 Spring Web Flow定义了五种不同类型的状态.通过选择Spring Web Flow的状态 ...
- Spring学习笔记4—流程(Spring Web Flow)
Spring Web Flow是Spring框架的子项目,作用是让程序按规定流程运行. 1 安装配置Spring Web Flow 虽然Spring Web Flow是Spring框架的子项目,但它并 ...
- 笔记39 Spring Web Flow——订单流程(收集顾客信息)
如果你曾经订购过披萨,你可能会知道流程.他们首先会询问你的电 话号码.电话号码除了能够让送货司机在找不到你家的时候打电话给 你,还可以作为你在这个披萨店的标识.如果你是回头客,他们可以 使用这个电话号 ...
随机推荐
- AC日记——[SCOI2008] 着色方案 bzoj 1079
1079 思路: dp: 我们如果dp方程为15维,每维记录颜色还有多少种: 不仅tle,mle,它还re: 所以,我们压缩一下dp方程: 方程有6维,第i维记录有多少种颜色还剩下i次: 最后还要记录 ...
- Netty源码学习(七)FastThreadLocal
0. FastThreadLocal简介 如同注释中所说:A special variant of ThreadLocal that yields higher access performance ...
- Python与数据库[0] -> 数据库概述
数据库概述 / Database Overview 1 关于SQL / About SQL 构化查询语言(Structured Query Language)简称SQL,是一种特殊目的的编程语言,是一 ...
- 树链剖分【p4315】月下"毛景树"
Description 毛毛虫经过及时的变形,最终逃过的一劫,离开了菜妈的菜园. 毛毛虫经过千山万水,历尽千辛万苦,最后来到了小小的绍兴一中的校园里. 爬啊爬~爬啊爬毛毛虫爬到了一颗小小的" ...
- 解密Java内存溢出之持久代
垃圾回收是Java程序员了解最少的一部分.他们认为Java虚拟机接管了垃圾回收,因此没必要去担心内存的申请,分配等问题.但是随着应用越来越复杂,垃圾回收也越来越复杂,一旦垃圾回收变的复杂,应用的性能将 ...
- Entity Framework贪婪加载筛选问题
先说一下代码北京,现在有一个Table类,代表桌子,然后Tale里面级联这一系列订单Order,现在要获取这个Table中没有完成的订Order,用完include之后居然发现不知道该怎么写,上网找了 ...
- 动态路由协议(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 ...
- C++STL中的向量vector
#include<iostream>#include<vector>#include<algorithm>using namespace std;typedef v ...
- 如何给JQ的ajax方法中的success()传入参数?
当时在使用JQuery提供的Ajax技术的时候,我有个需求,就是要给它请求成功后调用的success()方法传入参数: 所以,我就直接这样子写了: <script> function ge ...
- 求逆序对数总结 & 归并排序
用归并排序方式 最原始的方法的复杂度是O(n^2). 使用归并排序的方式,可以把复杂度降低到O(nlgn). 设A[1..n]是一个包含N个非负整数的数组.如果在i〈 j的情况下,有A〉A[j],则( ...