1. 程式人生 > >Spring Web Flow 入門demo(一)簡單頁面跳轉 附原始碼

Spring Web Flow 入門demo(一)簡單頁面跳轉 附原始碼

轉載地址

http://blog.csdn.net/hejingyuan6/article/details/46508821

spring Web Flow (SWF)是Spring Framework的一個脫離模組。這個模組是Spring Web應用開發模組棧的一部分,Spring Web包含Spring MVC。

Spring Web Flow的目標是成為管理Web應用頁面流程的最佳方案。當你的應用需要複雜的導航控制,例如嚮導,在一個比較大的事務過程中去指導使用者經過一連串的步驟的時候,SWF將會是一個功能強大的控制器。

下面我們還是從一個簡單的demo開始瞭解它:

這個例子是結合Springmvc

來實現,專案結構:

Web.xml配置:

[html] view plain copy print?
  1. <?xmlversion="1.0"encoding="UTF-8"?>
  2. <web-appxmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns="http://java.sun.com/xml/ns/javaee"xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="WebApp_ID"version="2.5">
  3.   <display-name>CartApp</display-name>
  4. <!-- 配置springmvc需要的servlet -->
  5. <servlet>
  6.   <servlet-name>CartServlet</servlet-name>
  7.   <servlet-class>
  8.   org.springframework.web.servlet.DispatcherServlet  
  9.   </servlet-class>
  10.   <init-param>
  11.     <param-name>contextConfigLocation</param-name>
  12.     <param-value>
  13.     /WEB-INF/config/web-application-config.xml   
  14.     </param-value>
  15.   </init-param>
  16.   <load-on-startup>1</load-on-startup>
  17. </servlet>
  18.     <servlet-mapping>
  19.         <servlet-name>CartServlet</servlet-name>
  20.         <url-pattern>/spring/*</url-pattern>
  21.     </servlet-mapping>
  22.   <welcome-file-list>
  23.     <welcome-file>index.jsp</welcome-file>
  24.   </welcome-file-list>
  25. </web-app>

對應的SpringMVC的配置檔案:web-application-config.xml

[html] view plain copy print?
  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <beansxmlns="http://www.springframework.org/schema/beans"
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"
  4.     xsi:schemaLocation="http://www.springframework.org/schema/beans   
  5.     http://www.springframework.org/schema/beans/spring-beans-2.5.xsd   
  6.     http://www.springframework.org/schema/context   
  7.     http://www.springframework.org/schema/context/spring-context-2.5.xsd">
  8.     <!-- SpringMVC的配置檔案-2015年6月14日15:45:54 -->
  9.     <!-- 搜尋 samples.webflow 包裡的 @Component 註解,並將其部署到容器中 -->
  10.     <context:component-scanbase-package="samples.webflow"/>
  11.     <!-- 啟用基於註解的配置 -->
  12.     <context:annotation-config/>
  13.     <importresource="webmvc-config.xml"/>
  14.     <importresource="webflow-config.xml"/>
  15. </beans>

其中引入的兩個配置檔案:webmvc-config.xml

[html] view plain copy print?
  1. <?xmlversion="1.0"encoding="UTF-8"?>
  2. <beansxmlns="http://www.springframework.org/schema/beans"
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.     xsi:schemaLocation="http://www.springframework.org/schema/beans   
  5.     http://www.springframework.org/schema/beans/spring-beans.xsd">
  6.     <!-- SpringMVC的配置檔案-2015年6月14日15:45:54 -->
  7.     <!-- 對轉向頁面的路徑解析。prefix:字首, suffix:字尾 -->
  8.     <beanid="viewResolver"
  9.         class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  10.         <propertyname="viewClass"
  11.             value="org.springframework.web.servlet.view.JstlView">
  12.         </property>
  13.         <propertyname="prefix"value="/WEB-INF/jsp/">
  14.         </property>
  15.         <propertyname="suffix"value=".jsp">
  16.         </property>
  17.     </bean>
  18.     <!--  如何根據http請求選擇合適的controller是MVC中一項十分關鍵的功能,在Spring MVC中,HandlerMapping介面是這一活動的抽象 -->
  19.     <!-- SimpleUrlHandlerMapping  通過配置檔案,把一個URL對映到Controller -->
  20.     <beanid="viewMappings"
  21.         class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
  22.         <!-- /shopping.do 請求由 flowController 來處理 -->
  23.         <!-- 不管設成 /shopping.do 還是設成 /shopping ,或者 /shopping.htm ,效果都是一樣的, flowController 都會去找 id 為 shopping的flow來執行 -->
  24.         <propertyname="mappings">
  25.             <value> /shopping.do=flowController</value>
  26.         </property>
  27.          <propertyname="defaultHandler">
  28.             <!-- UrlFilenameViewController 會將 "/index" 這樣的請求對映成名為 "index" 的檢視 -->
  29.             <beanclass="org.springframework.web.servlet.mvc.UrlFilenameViewController"/>
  30.         </property>
  31.     </bean>
  32.     <!-- 我們只要明白 FlowController 可根據客戶端請求的結尾部分,找出相應的 flow 來執行。配置 FlowController只需指定FlowExecutor即可 -->
  33.     <beanid="flowController"class="org.springframework.webflow.mvc.servlet.FlowController">
  34.         <propertyname="flowExecutor"ref="flowExecutor"/>
  35.     </bean>
  36. </beans>

對於UrlFilenameViewController類,此處理解為由於我們並不是通過訪問controller來返回頁面的形式,那麼我們如何可以訪問Web-INF下的保護類資源呢,就是通過這個類的作用來實現。此處的理解有什麼偏差還請各位提出寶貴意見!

webflow-config.xml:

[html] view plain copy print?
  1. <?xmlversion="1.0"encoding="UTF-8"?>
  2. <beansxmlns="http://www.springframework.org/schema/beans"
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:webflow="http://www.springframework.org/schema/webflow-config"
  4.     xsi:schemaLocation=" http://www.springframework.org/schema/beans   
  5.     http://www.springframework.org/schema/beans/spring-beans-2.5.xsd   
  6.     http://www.springframework.org/schema/webflow-config   
  7.     http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.0.xsd">
  8.     <!-- 流程的配置檔案-2015年6月14日15:45:46 -->
  9.     <!-- FlowExecutor 是 Spring Web Flow 的一個核心介面,啟動某個 flow ,都要通過這個介面來進行。  
  10.         從配置角度來說,只要保證有個 FlowExecutor 就可以了, Spring Web Flow 的預設行為已經足夠 -->
  11.     <!-- FlowExecutor 就是通過 id 來找出要執行的 flow 。至於這個 id ,則是要由使用者來指定的。  
  12.         在預設配置情況下,如果客戶端傳送瞭如下URL請求:http://localhost:8080/CartApp/spring/shopping。  
  13.         則從 Spring Web Flow 的角度來看,這個 URL 就表示客戶想要執行一個 id 為“ shopping ”的 flow ,  
  14.         於是就會在 FlowRegistry 中查詢名為“ shopping ”的 flow,由FlowExecutor負責執行。 -->
  15.     <webflow:flow-executorid="flowExecutor"/>
  16.     <!-- 所有 flow的定義檔案它的位置在這裡進行配置, flow-builder-services 用於配置 flow 的特性 -->
  17.     <!-- FlowRegistry 是存放 flow 的倉庫,每個定義 flow 的 XML 文件被解析後,都會被分配一個唯一的 id ,並以 FlowDefinition 物件的形式存放在 FlowResigtry 中 -->
  18.     <!-- 每個 flow 都必須要有 id 來標識,如果在配置中省略,那麼該 flow 預設的 id 將是該定義檔案(xml檔案)的檔名去掉字尾所得的字串  
  19.     (例如本例中如果去掉id="shopping",那麼flow的id就是shopping.xml去掉字尾名.xml後的shopping作為id) -->
  20.     <!--  flow-builder-services 屬性的配置指明瞭在這個 flow-registry “倉庫”裡的 flow 的一些基本特性,  
  21.         例如,是用 Unified EL 還是 OGNL 、 model (模型)物件中的資料在顯示之前是否需要先作轉換,等等 -->
  22.     <webflow:flow-registryid="flowRegistry"flow-builder-services="flowBuilderServices">
  23.         <webflow:flow-locationpath="/WEB-INF/flows/shopping.xml"id="shopping"/>
  24.         <webflow:flow-locationpath="/WEB-INF/flows/addToCart.xml"id="addToCart"/>
  25.     </webflow:flow-registry>
  26.     <!--Web Flow 中的檢視通過 MVC 框架的檢視技術來呈現 -->
  27.     <webflow:flow-builder-servicesid="flowBuilderServices"view-factory-creator="mvcViewFactoryCreator"/>
  28.     <!-- 指明 MVC 框架的 view resolver ,用於通過 view 名查詢資源 -->
  29.     <beanid="mvcViewFactoryCreator"class="org.springframework.webflow.mvc.builder.MvcViewFactoryCreator">
  30.         <propertyname="viewResolvers"ref="viewResolver"/>
  31.     </bean>
  32. </beans>

使用的流程檔案:shopping.xml


[html] view plain copy print?
  1. <?xmlversion="1.0"encoding="UTF-8"?>
  2. <flowxmlns="http://www.springframework.org/schema/webflow"
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.     xsi:schemaLocation="http://www.springframework.org/schema/webflow  
  5.  http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">
  6.  <!-- view-state中的view對應jsp資料夾中的jsp頁面,on是觸發事件,to對應state id -->
  7.     <!-- 流程檔案-2015年6月14日15:51:56 -->
  8.     <!-- 根據排在第一位的順序來執行 -->
  9.     <view-stateid="viewCart"view="viewCart">
  10.         <transitionon="submit"to="viewOrder">
  11.         </transition>
  12.     </view-state>
  13.     <view-stateid="viewOrder"view="viewOrder">
  14.         <transitionon="confirm"to="orderConfirmed">
  15.         </transition>
  16.     </view-state>
  17.     <view-stateid="orderConfirmed"view="orderConfirmed">
  18.         <transitionon="returnToIndex"to="returnToIndex">
  19.         </transition>
  20.     </view-state>
  21.     <end-stateid="returnToIndex"view="externalRedirect:servletRelative:/index.jsp">
  22.     </end-state>
  23. </flow>

對應的頁面:

index.jsp

[html] view plain copy print?
  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"   
  3.   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  4. <htmlxmlns="http://www.w3.org/1999/xhtml">
  5. <head>
  6. <metahttp-equiv="Content-Type"content="text/html; charset=utf-8"/>
  7. <title>Cart Application</title>
  8. </head>
  9. <body>
  10.     <h1>Hello!</h1>
  11.     <br/>
  12.     <ahref="shopping.do">View Cart</a>
  13. </body>
  14. </html><spanstyle="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"></span>

viewCart.jsp


[html] view plain copy print?
  1. <body>
  2.     <h1>View Cart</h1>
  3.     <ahref="${flowExecutionUrl}&_eventId=submit">Submit</a>
  4. </body>

viewOrder.jsp

[html] view plain copy print?
  1. <body>
  2.     <h1>Order</h1>
  3.     <ahref="${flowExecutionUrl}&_eventId=confirm">Confirm</a>
  4. </body>

orderConfirmed.jsp

[html] view plain copy print?
  1. <body>
  2.     <h1>Order Confirmed</h1>
  3.     <ahref="${flowExecutionUrl}&_eventId=returnToIndex">Return to  
  4.         index</a>
  5. </body>

這幾個頁面都使用了變數 flowExecutionUrl ,表示 flow 執行到當前狀態時的 URL 。 flowExecutionUrl 的值已經由 Spring Web Flow 2.0 框架的程式碼進行賦值,並放入相應的 model 中供 view 訪問。 flowExecutionUrl 的值包含 flow 在執行過程中會為每一狀態生成的唯一的 key ,因此不可用其他手段來獲取。請求引數中 _eventId 的值與shoppting.xml中 transition 元素的 on 屬性的值是對應的,在接收到_eventId引數後,相應transition會被執行。


測試使用方式:

訪問地址:http://localhost:8080/CartApp3/spring/index.jsp

總的來說,為什麼要配置這麼多內容呢?原因如下:

SpringWeb Flow 如何與 Spring Web MVC 整合在一起?

客戶端傳送的請求,先會由 servlet 容器(Tomcat)接收, servlet容器會找到相應的應用程式(CartApp3),再根據 web.xml 的配置找到出符合對映條件的 servlet 來處理。Spring Web MVC 中處理請求的 servlet 是 DispatcherServlet ,如果請求的路徑滿足 DispatcherServlet的對映條件,則 DispatcherServlet 會找出 Spring IoC 容器中所有的 HandlerMapping ,根據這些HandlerMapping 中匹配最好的 handler (一般情況下都是 controller ,即控制器)來處理請求。當 Controller處理完畢,一般都會返回一個 view (檢視)的名字,DispatcherServlet再根據這個view的名字找到相應的檢視資源返回給客戶端。

弄清楚Spring Web MVC 處理請求的流程後,基本上就可以明白要整合 Spring Web MVC 與 Spring Web Flow所需要的配置了。為了讓客戶端的請求變成執行某個 flow 的請求,要解決以下幾個問題:

  1. 需要在某個 HandlerMapping 中配置負責處理 flow 請求的 handler (或 controller )--配置controller(flowController)
  2. 該handler (或 controller )要負責啟動指定的 flow--controller負責啟動flow(flowExecutor)
  3. flow 執行過程中以及執行完成後所涉及的檢視應呈現給客戶端--配置解析返回檢視方式(viewResolvers)

所有這些配置的目的無非是兩個:一是要讓客戶端的請求轉變成flow 的執行,二是要讓 flow 執行過程中、或執行結束後得到的檢視能返還給客戶端。

 原始碼下載