Spring Web Flow 入门demo(三)嵌套流程与业务结合 附源码
2016-09-21 10:35
435 查看
Spring Web Flow 入门demo(三)嵌套流程与业务结合 附源码
2015-07-03 14:42 2320人阅读 评论(3) 举报分类:
JAVA(105)
Spring
Web Flow(2)
版权声明:本文为博主原创文章,未经博主允许不得转载。
上篇博客我们说Spring web Flow与业务结合的方式主要有三种,下面我们主要介绍一下第三种的应用方式
3,执行到<action-state> 元素
SpringWeb Flow 中的这个 <action-state> 是专为执行业务逻辑而设的 state 。如果某个应用的业务逻辑代码既不适合放在transition 中由客户端来触发,也不适合放在 Spring Web Flow 自定义的切入点,那么就可以考虑添加<action-state> 元素专用于该业务逻辑的执行。更倾向于触发某个事件来执行。
action-state 示例:
[html] view
plain copy
print?
<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:
[java] view
plain copy
print?
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:
[java] view
plain copy
print?
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:
[html] view
plain copy
print?
<?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:
[html] view
plain copy
print?
<?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 的位置
[html] view
plain copy
print?
<?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:
[html] view
plain copy
print?
<?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:
[html] view
plain copy
print?
<?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
显示效果:
再扩展一下:
如果我们将shopping.xml中的配置文件修改一下,改为flowScope时,我们在viewOrder页面也可以获取products数据。
[html] view
plain copy
print?
<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:
[html] view
plain copy
print?
<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(三)嵌套流程与业务结合 附源码
- Spring Web Flow 入门demo(三)嵌套流程与业务结合 附源码
- Spring Web Flow 入门demo(二)与业务结合 附源码
- Spring Web Flow 入门demo(二)与业务结合 附源码
- Spring Web Flow 入门demo(二)与业务结合 附源码
- Spring Web Flow 入门demo(二)与业务结合 附源代码
- Spring Web Flow 入门demo(一)简单页面跳转 附源码
- Spring Web Flow 入门demo(一)简单页面跳转 附源码
- Spring Web Flow 入门demo(一)简单页面跳转 附源码
- Spring Web Flow 2简化页面流的开发,结合Spring MVC更俊,Spirng Security 3添加安全机制
- Spring Web Flow 2.0入门 - 什么情况下可以使用Spring Web Flow?
- Spring Web Flow 2.0 入门详解
- Spring web flow——披萨订购流程示例(1)
- 使用Spring Web Flow-程序流程定义
- 转 Spring Web Flow 2.0入门 - 配备Spring Web Flow 2.0的基础
- Spring Web Flow 2.0 入门
- 第十二篇 Spring Web Flow 2简化页面流的开发,结合Spring MVC更俊,Spirng Security 3添加安全机制
- Spring Web Flow 2.0 入门详解
- 深入剖析Spring Web源码(十) - 处理器映射,处理器适配器以及处理器的实现 - 基于HTTP请求处理器流程的实现