Spring Web Flow —— 基礎 - 011

基礎

  Web Flow將一個流程分爲若干個狀態(可以理解爲步驟),每個流程由若干個狀態組成,通過特性的方式在步驟之間進行跳轉,協同完成整個流程。
  常用標籤如下

  • <view-state> - 視圖狀態,用於渲染視圖
  • <action-state> - 動作狀態,用於專門執行操作
  • <transition> - 轉移,用於狀態間轉移,轉移由事件觸發
  • <end-state> - 結束狀態,流程的最後一個狀態
  • <evaluate> - 執行具體操作,是上述各個標籤的子標籤,用於所有需要執行操作的位置

view-state

如下聲明瞭視圖狀態,在該狀態會繪製一個視圖,view的解析依賴於具體的視圖解析器

<view-state id="result" view="flow/view/result"/>

可以不指定view屬性,此時,會在flow文件同目錄下尋找和id相同文件名的視圖文件進行渲染

<view-state id="enterBookingDetails" />

可以在聲明同時指定model屬性,該屬性配合前端spring taglib可將表單數據綁定到model指定的bean中

<view-state id="init" view="flow/view/input" model="searchForm">
    <binder>
        <binding property="name"/>
        <binding property="gender"/>
    </binder>
    <transition on="submit" to="validate"/>
</view-state>
...
<!-- 對應的JSP代碼 -->
...
<sf:form action="${flowExecutionUrl}&_eventId=submit" commandName="searchForm" method="post">
    Name: <sf:input path="name"/><br/>
    gender:
       <sf:select path="gender">
           <sf:option value="">- Please Select -</sf:option>
       </sf:select>
       <input type="submit" value="Submit">
</sf:form>
...

action-state

action-state將單獨一個操作設置爲一個狀態,除了不能渲染視圖外,其它功能和view-state基本一致

<action-state id="validate">
    <evaluate  expression="flowController.performValidate(searchForm)"/>
    <transition on="success" to="result"/>
    <transition on="fail" to="input"/>
</action-state>

transition

transaction可以根據事件id從一個state跳轉到另一個state,如下,當發生submit時間時,將跳轉到id爲reviewBooking的state

<view-state id="enterBookingDetails">
        <transition on="submit" to="reviewBooking" />
</view-state>

事件id定義的方式比較特殊,最典型的從view中觸發事件的方式:

<!-- 該超鏈接被點擊時,會觸發submit事件 -->
<a href="${flowExecutionUrl}"&_eventId="submit">Submit</a>

transition還可以作爲的子元素,此時on中的內容就是EL表達式,或者執行方法所返回的字符串

<action-state id="validate">
    <evaluate  expression="flowController.performValidate(searchForm)" result="flashScope.resultMap"/>
    <!-- EL表達式方式,去resultMap對象中errors值得hasErrors()方法,成立時跳轉 -->
    <transition on="resultMap.errors.hasErrors() == true" to="result"/>
</action-state>
... ...
<action-state id="validate">
    <evaluate  expression="flowController.performValidate(searchForm)"/>
    <!-- 方法返回事件id -->
    <transition on="success" to="result"/>
    <transition on="fail" to="input"/>
</action-state>

view中觸發事件的幾種方式

  • 使用submit按鈕
<input type="submit" name="_eventId_proceed" value="Proceed" />

  原理:當web-flow發現請求參數中有以eventId字符串開頭的參數時,會把該字符串中剩餘字符串當做eventId。該方法可用於一次性觸發多個事件

  • 使用hidden域
<input type="hidden" name="_eventId" value="proceed" />

  原理:web-flow檢測到請求參數中有名爲_eventId的參數時,會將其值作爲eventId進行觸發

  • 使用url參數
<a href="${flowExecutionUrl}&_eventId=cancel">Cancel</a>

  原理同上

  • web-flow檢測eventId的邏輯
    首先檢查有沒有eventId的參數,如果沒有,檢查有沒有以_eventId開頭的參數名,都沒有時,則沒有事件會被觸發。

end-tate

  定義流程結束狀態

  • 當該流程是子流程時,會接着下面的流程繼續進行,的id屬性將會作爲event id
  • 當該流程添加了view時,該view會被渲染。還可以添加屬性,使得進行重定向之類的
  • 當不是子流程也沒有指定view,則該流程結束,並且重新開啓一個新的流程實例

evaluate

Web Flow允許我們在如下幾個切入點執行我們自己的業務邏輯,而執行業務邏輯使用<evaluate>標籤。該標籤可以調用所用Spring中管理的bean和flow中聲明的變量的方法

  • flow開始 - 對應<on-start>標籤,定義在根標籤<flow>
<on-start>
    <!-- 僅調用方法 -->
    <evaluate expression="flowController.performInit()"/>
</on-start>
  • state進入時 - 對應<on-entry>標籤,可定義在所有state標籤下
<view-state id="init" view="flow/view/input">
    <on-entry>
        <!-- 調用方法,並將方法返回的對象存在flow變量modelMap中 -->
        <evaluate expression="flowController.performInit()" result="flashScope.modelMap"/>
    </on-entry>
    ... ...
</view-state>
  • view渲染時 - 對應<on-render>標籤,定義在<view-state>
<view-state id="init" view="flow/view/input">
    <on-render>
        <!-- 調用方法,並將方法返回的對象轉型成目標類型,然後存儲在flow變量modelMap中 -->
        <evaluate expression="flowController.performInit()" result="flashScope.modelMap" resultType="java.util.Map"/>
    </on-render>
    ... ...
</view-state>
  • transition執行時 - 對應<transition>標籤
<view-state id="init" view="flow/view/input">
    <transition on="submit" to"validate">
        <evaluate expression="flowController.performTransition()"/>
    </transition>
</view-state>
  • state退出時 - 對應<on-entry>標籤,可定義在所有state標籤下
<action-state id="validate">
    ... ...
    <on-exit>
        <evaluate expression="flowController.performExit()"/>
    </on-exit>
</action-state>
  • flow結束時 - 對應<on-start>標籤,定義在根標籤<flow>
<on-end>
    <evaluate expression="flowController.performEnd()"/>
</on-end>

進階

變量

可以在流程中定義多個變量,這些變量將在流程開始被分配。被聲明變量的類必須實現serializable,因爲在兩個state之間,變量需要被保存。

<var name="searchCriteria" class="com.mycompany.myapp.hotels.search.SearchCriteria"/>

變量的分配方式

  • 直接分配
<var name="searchCriteria" class="com.mycompany.myapp.hotels.search.SearchCriteria"/>
  • 賦值的時候分配
<!-- 創建InitMap對象,並將方法返回的對象賦值給InitMap -->
<evaluate expression="flowController.performInit()" result="flowScope.InitMap" />

變量的使用方法

  • jsp中使用
    使用jsp中的el表達式訪問flow中聲明的變量,如${modelMap.name},訪問了flow變量modelMap的name屬性
  • flow文件中使用
    直接使用Spring EL表達式進行訪問
<transition on="modelMap.name == null" to="result"/>
  • 方法中使用
    將變量傳給調用方法,即可在方法中使用
<evaluate expression="flowController.performSearch(modelMap)"/>

變量作用域

  • flowScope:流程開始時分配,流程結束時銷燬
  • viewScope:在<view-state>進入時創建,退出時銷燬
  • requestScope:當流程被調用時分配,流程返回時銷燬。比flowScope作用域稍微大一點
  • flashScope:在流程開始時分配,流程結束時銷燬,但是在每一個view渲染後都會被清零
  • conversation Scope:最頂層的流程開始時分配,最頂層的流程結束時銷燬。該作用域的變量是存儲在Session中的。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章