Spring Web Flow 2.0 入门 用 subflow 实现添加商品到购物车功能

商品已经有列表了,接下来就要增加把商品放入购物车的功能,在本示例中用 subflow 来实现这一功能,操作步骤如下:

  • 实现 Cart 和 CartItem 两个业务类
  • 在 shopping.xml 中添加配置
  • 在 /WEB-INF/flows 目录下添加 addToCart.xml
  • 在 webflow-config.xml 中添加 addToCart.xml 的位置
  • 修改 viewCart.jsp 页面

实现 Cart 和 CartItem 两个业务类

CartItem 表示存放于购物车中的条目,主要记录相应商品及商品数量,同时不要忘记实现 java.io.Serializable 接口,见清单 29:


清单 29 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++; 
    } 

    /*省略getter和setter*/

} 

 

除去相应的属性外, CartItem 可根据商品的数量算出该商品的总价格( getTotalPrice ),也可通过 increaseQuantity 增加商品数量。

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


清单 30 Cart 类

package samples.webflow;

/* 省略 import 语句 */ 

public class Cart implements Serializable { 

    private static final long serialVersionUID = 7901330827203016310L; 
    private Map<Integer, CartItem> map = new HashMap<Integer, CartItem>(); 

    public List<CartItem> getItems() { 
        return new ArrayList<CartItem>(map.values()); 
    } 

    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)); 
     } 

    public int getTotalPrice() { 
        int total = 0; 
        for (CartItem item : map.values()) 
            total += item.getProduct().getPrice() * item.getQuantity(); 
        return total; 
    } 
}

 

Cart 主要实现三个业务函数, getItems 用于获取当前购物车里的物品, addItem 用于向购物车添加商品, getTotalPrice 用于获取购物车里所有商品的总价格。

 




回页首


在 shopping.xml 中添加配置

在 shopping flow 开始时必须分配一个 Cart 对象,由于要调用 subflow ,这个 Cart 对象应存放于 conversationScope 中。同时要添加一个 subflow-state 用于执行添加商品到购物车的任务。


清单 31 shopping.xml 中添加的配置

<var name="mycart" class="samples.webflow.Cart"/> 
<on-start> 
  <set name="conversationScope.cart" value="mycart"></set> 
</on-start> 
<view-state id="viewCart" view="viewCart" > 
  <on-render> 
    <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>





回页首


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

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


清单 32 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"> 
  <on-start> 
    <set name="requestScope.productId" value="requestParameters.productId"/> 
  </on-start> 
  <action-state id="addToCart"> 
    <evaluate expression="cart.addItem(productService.getProduct(productId))"/> 
    <transition to="productAdded"/> 
  </action-state> 
  <end-state id="productAdded"/> 
</flow>

 

addToCart flow 主要由一个 action-state 构成,完成添加商品到购物车的功能, addToCart flow 的实现需要有输入参数,即 productId 。在本示例中是通过请求参数来传递,通过 requestParameters 来获取该数值。这里还要注意到清单 32 中的 end-state 的 id 为“ productAdded ”,与清单 31 中 subflow-state 中的 transition元素的on属性的名称是对应的。

 




回页首


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

新增加的 flow 不要忘记在 flow-registry 中注册。


清单 33 flow-registry 中注册 addToCart

<webflow:flow-registry id="flowRegistry" flow-builder-services="flowBuilderServices">
  <webflow:flow-location path="/WEB-INF/flows/shopping.xml" id="shopping"/>
  <webflow:flow-location path="/WEB-INF/flows/addToCart.xml" id="addToCart"/> 
</webflow:flow-registry>





回页首


修改 viewCart.jsp 页面

最后就可以来看在视图中如何显示相关的信息,并触发相应的 webflow 事件,见清单 34:


清单 34 完整的 viewCart.jsp 的代码

<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>





回页首


运行效果


图 6 添加购物车后的效果
添加购物车后的效果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值