什么是webflow:
Spring Web Flow構建於Spring MVC之上,允許實現Web應用程序的“流程”。流程封裝了一系列步驟,指導用戶執行某些業務任務。它跨越多個HTTP請求,具有狀態,處理事務數據,可重用,並且可能是動態的,並且本質上是長期運行的。
Spring Web Flow的最佳位置是具有受控導航功能的有狀態Web應用程序,例如辦理登機手續,申請貸款,購物車結帳,甚至向表單添加確認步驟。這些場景的共同點是以下一個或多個特征:
- 有一個明確的開始和結束點。
 - 用戶必須按特定順序瀏覽一組屏幕。
 - 直到最后一步,更改才會完成。
 - 一旦完成,就不可能意外地重復交易
 
以上是Spring官網中給出的解釋,我覺得也非常准確就直接引用一下~~
如何在現有項目中引入webflow:
1.添加相關依賴(因為webflow2.X版本是構建於SpringMVC之上的,所以請自行添加其余依賴)
<dependencies>
    <dependency>
        <groupId>org.springframework.webflow</groupId>
        <artifactId>spring-webflow</artifactId>
        <version>2.4.5.RELEASE</version>
    </dependency>
</dependencies>
 
        2.在已有的SpringMVC配置中引入如下配置:(如此處已引入過類似配置可忽略相關內容)
    <!-- 配置包掃描器 -->
    <context:component-scan base-package="*****"/>
    <!-- 配置注解驅動 -->
    <mvc:annotation-driven/>
    <import resource="webmvc-config.xml"/>
    <import resource="webflow-config.xml"/>
 
        webmvc-config.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"
        xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="viewResolver"
          class="org.springframework.web.servlet.view.InternalResourceViewResolver">
          <!--class="org.springframework.web.servlet.view.UrlBasedViewResolver">-->
        <property name="viewClass"
                  value="org.springframework.web.servlet.view.JstlView"/>
        <property name="prefix" value="/WEB-INF/views/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
    <bean id="flowHandlerMapping" class="org.springframework.webflow.mvc.servlet.FlowHandlerMapping">
        <property name="flowRegistry" ref="flowRegistry"/>
        <property name="defaultHandler">
            <!-- UrlFilenameViewController 會將 "/index" 這樣的請求映射成名為 "index" 的視圖 -->
            <bean class="org.springframework.web.servlet.mvc.UrlFilenameViewController" />
        </property>
    </bean>
    <bean id="flowHandlerAdapter" class="org.springframework.webflow.mvc.servlet.FlowHandlerAdapter">
        <property name="flowExecutor" ref="flowExecutor"/>
    </bean>
</beans>
 
        webflow-config.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:webflow="http://www.springframework.org/schema/webflow-config"
       xsi:schemaLocation=" http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
        http://www.springframework.org/schema/webflow-config
        http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.0.xsd">
    <!-- 裝配流程執行期:為用戶創建和啟動一個流程執行實例,不負責加載流程定義-->
    <webflow:flow-executor id="flowExecutor" />
    <!-- 配置流程注冊表,其功能為:負責加載流程定義-->
    <!-- 所有 flow的定義文件它的位置在這里進行配置, flow-builder-services 用於配置 flow 的特性 -->
    <webflow:flow-registry id="flowRegistry" flow-builder-services="flowBuilderServices">
        <webflow:flow-location path="/WEB-INF/flows/shopping.xml" id="index" />
        <webflow:flow-location path="/WEB-INF/flows/test.xml" id="test" />
        <webflow:flow-location path="/WEB-INF/flows/shopping-sub.xml" id="subflow"/>
        <!-- 在這個聲明中,流程注冊表會在該path下查找流程定義-->
    </webflow:flow-registry>
    <!--Web Flow 中的視圖通過 MVC 框架的視圖技術來呈現 -->
    <webflow:flow-builder-services id="flowBuilderServices" view-factory-creator="mvcViewFactoryCreator" />
    <!-- 指明 MVC 框架的 view resolver ,用於通過 view 名查找資源 -->
    <bean id="mvcViewFactoryCreator" class="org.springframework.webflow.mvc.builder.MvcViewFactoryCreator">
        <property name="viewResolvers" ref="viewResolver" />
    </bean>
</beans>
 
        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">
    <!-- view-state中的view對應views文件夾中的jsp頁面,on是觸發事件,to對應state id -->
    <!-- 流程開始前的初始化工作 -->
    <on-start>
        <evaluate expression="initData"></evaluate>
    </on-start>
    <view-state id="hello" view="hello">
        <transition on="viewCart" to="viewCart"></transition>
    </view-state>
    <!-- 根據排在第一位的順序來執行 -->
    <view-state id="viewCart" view="viewCart">
        <transition on="submit" to="viewOrder"></transition>
        <transition on="confirm" to="login"></transition>
    </view-state>
    <action-state id="login" >
        <evaluate expression="loginAction"/>
        <transition on="success" to="orderConfirmed"></transition>
        <transition on="error" to="returnToIndex"></transition>
    </action-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>
        <transition on="dataCheck" to="dataCheck"></transition>
    </view-state>
    <!-- 本流程中的數據流轉 -->
    <action-state id="dataCheck">
        <evaluate expression="dataCheck"></evaluate>
        <transition on="success" to="subflow"></transition>
    </action-state>
    <!-- 創建一個子流程 -->
    <subflow-state id="subflow" subflow="subflow">
        <transition on="returnshopping" to="returnToIndex"></transition>
    </subflow-state>
    <end-state id="returnToIndex" view="index">
    </end-state>
    <!-- 全局流程變量 -->
    <global-transitions>
        <transition on="returnToIndex" to="returnToIndex"></transition>
    </global-transitions>
</flow>
 
        以上配置為我的實驗項目的具體配置,關於(webmvc-config.xml,webflow-config.xml)中的內容已給出相應注釋,只特別說明一點:
<webflow:flow-location path="/WEB-INF/flows/shopping.xml" id="index" />
這個配置中的id為項目的訪問路徑,以上配置的訪問路徑類似:localhost:8080/***/index(項目也將從這個訪問路徑進入webflow流程)
webflow的核心參數:
在開始介紹流程之前我們需要先知道webflow中存在兩大核心參數:
1.execution:此參數用於指定一個唯一的流程實例,在頁面提交時此處的值可以直接通過${flowExecutionKey}獲得
2._eventId:此參數用於確定頁面的跳轉關系,對應shopping.xml中on屬性中的值
3.flowExecutionUrl:在提交的時候可以直接使用此參數作為form表單中action的值:${flowExecutionUrl}
上述的1,2參數是使用webflow框架在頁面提交請求的時候必須帶回的參數
webflow的流程定義:
在介紹完webflow的基礎定義與簡單配置之后,接下來將着重為大家介紹webflow的流程定義(shopping.xml)文件(如上文我配置中引入的其他流程定義與之類似不做重復介紹)
常用標簽:
on-start:此標簽的作用是在流程啟動執行前,先執行的內容(可以用於初始化一些業務所需的數據)
evaluate:
expression:此處的值為對應的bean(該bean需 extends AbstractAction),實現 doExecute 方法(此方法即為初始化方法)
view-state:此標簽用於指定對應的視圖頁面
id:指代當前標簽
view:指代視圖名稱(如不添加veiw屬性,該值默認=id)
transition:
on:對應_eventId的值,表明觸發事件
to:該觸發事件所對應的動作,一般為需要執行的標簽id
action-state:於view-state類似,不同之處在於此標簽對應的是JavaBean(相關屬性參照上文標簽)
subflow-state:用於定義當前流程的子流程
id:指代當前子流程
subflow:指代子流程名字,需對應webflow-config中webflow:flow-location所添加的子流程的id
end-state:流程結束標簽
global-transitions:用於指定全局的流程變量,即:在流程中任意位置觸發當前_eventId,均會進入對應to的位置
最后提醒一點的是:webflow的流程定義文件中的配置為順序執行(哪個標簽配置在最前面,流程會優先進入該標簽,之后的根據流轉規則執行)
webflow的數據:
在webflow中關於數據的業務需要,給出了不同的數據存儲位置,常用儲存位置如下:
1.FlowScope:放在此處的數據僅在當前流程中可見,隨着當前流程的銷毀而銷毀(子流程中不可見)
2.ConversationScope:放在此處的數據為最頂層流程與所有子流程共享數據,在整個業務流程結束后銷毀(子流程可見)
3.RequestScope:放在此處的數據僅存在於當前請求中,隨着當前請求的結束而銷毀。
4.FlashScope:放在此處的數據為當前流程共享,但是會隨着視圖解析而銷毀。
5.ViewScope:放在此處的數據僅在當前視圖狀態可見
數據存儲與取值方式:context.getFlowScope().put() context.getFlowScope().get()
尾聲:
介紹到這里,webflow的基礎知識就已經介紹完畢啦,個人的總結就是webflow在某些特定的場合下確實比MVC的方式,在項目代碼結構看起來更清晰明了,但也存在一些天然缺陷(沒有MVC那么自由),webflow的流程自由是配置時候的流程自由,在配置好之后就是固定的啦。(當然,這本來也是這個框架的定位!)現在webflow的官網中對於webflow的流程定義給出了很多實用的標簽和屬性(如解決頁面彈框等問題)如果對這一塊感興趣的朋友可以參見官網繼續學習~~
最后附上兩個鏈接吧:
1.spring-webflow官網:https://projects.spring.io/spring-webflow/
2.本文檔相關實踐項目:https://github.com/ksuth/Study.git
