Spring Web Flow 入門demo(三)嵌套流程與業務結合 附源碼

來源:互聯網
上載者:User

標籤:


上篇部落格我們說Spring web Flow與業務結合的方式主要有三種,下面我們主要介紹一下第三種的應用方式

 

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

SpringWeb Flow 中的這個 <action-state> 是專為執行商務邏輯而設的 state 。如果某個應用的商務邏輯代碼既不適合放在transition 中由用戶端來觸發,也不適合放在 Spring Web Flow 自訂的切入點,那麼就可以考慮添加<action-state> 元素專用於該商務邏輯的執行。更傾向於觸發某個事件來執行。

action-state 樣本:

<action-state id="addToCart"><evaluate expression="cart.addItem(productService.getProduct(productId))"/><transition to="productAdded"/></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:


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><ahref="${flowExecutionUrl}&_eventId=addToCart&productId=${product.id}">[addto 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

 

顯示效果:



再擴充一下:


如果我們將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(三)嵌套流程與業務結合 附源碼

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.