Spring Web Flow (SWF)是Spring Framework的一個脫離模塊。這個模塊是Spring Web應用開發模塊棧的一部分,Spring Web包含Spring MVC。
Spring Web Flow的目標是成爲管理Web應用頁面流程的最佳方案。當你的應用需要複雜的導航控制,例如嚮導,在一個比較大的事務過程中去指導用戶經過一連串的步驟的時候,SWF將會是一個功能強大的控制器。
下面我們還是從一個簡單的demo開始瞭解它:
這個例子是結合Springmvc來實現,項目結構:
Web.xml配置:
- <?xml version="1.0" encoding="UTF-8"?>
- <web-app xmlns: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">
- <display-name>CartApp</display-name>
- <!-- 配置springmvc需要的servlet -->
- <servlet>
- <servlet-name>CartServlet</servlet-name>
- <servlet-class>
- org.springframework.web.servlet.DispatcherServlet
- </servlet-class>
- <init-param>
- <param-name>contextConfigLocation</param-name>
- <param-value>
- /WEB-INF/config/web-application-config.xml
- </param-value>
- </init-param>
- <load-on-startup>1</load-on-startup>
- </servlet>
- <servlet-mapping>
- <servlet-name>CartServlet</servlet-name>
- <url-pattern>/spring/*</url-pattern>
- </servlet-mapping>
- <welcome-file-list>
- <welcome-file>index.jsp</welcome-file>
- </welcome-file-list>
- </web-app>
對應的SpringMVC的配置文件:web-application-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: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">
- <!-- SpringMVC的配置文件-2015年6月14日15:45:54 -->
- <!-- 搜索 samples.webflow 包裏的 @Component 註解,並將其部署到容器中 -->
- <context:component-scan base-package="samples.webflow" />
- <!-- 啓用基於註解的配置 -->
- <context:annotation-config />
- <import resource="webmvc-config.xml" />
- <import resource="webflow-config.xml" />
- </beans>
其中引入的兩個配置文件: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">
- <!-- SpringMVC的配置文件-2015年6月14日15:45:54 -->
- <!-- 對轉向頁面的路徑解析。prefix:前綴, suffix:後綴 -->
- <bean id="viewResolver"
- class="org.springframework.web.servlet.view.InternalResourceViewResolver">
- <property name="viewClass"
- value="org.springframework.web.servlet.view.JstlView">
- </property>
- <property name="prefix" value="/WEB-INF/jsp/">
- </property>
- <property name="suffix" value=".jsp">
- </property>
- </bean>
- <!-- 如何根據http請求選擇合適的controller是MVC中一項十分關鍵的功能,在Spring MVC中,HandlerMapping接口是這一活動的抽象 -->
- <!-- SimpleUrlHandlerMapping 通過配置文件,把一個URL映射到Controller -->
- <bean id="viewMappings"
- class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
- <!-- /shopping.do 請求由 flowController 來處理 -->
- <!-- 不管設成 /shopping.do 還是設成 /shopping ,或者 /shopping.htm ,效果都是一樣的, flowController 都會去找 id 爲 shopping的flow來執行 -->
- <property name="mappings">
- <value> /shopping.do=flowController </value>
- </property>
- <property name="defaultHandler">
- <!-- UrlFilenameViewController 會將 "/index" 這樣的請求映射成名爲 "index" 的視圖 -->
- <bean class="org.springframework.web.servlet.mvc.UrlFilenameViewController" />
- </property>
- </bean>
- <!-- 我們只要明白 FlowController 可根據客戶端請求的結尾部分,找出相應的 flow 來執行。配置 FlowController只需指定FlowExecutor即可 -->
- <bean id="flowController" class="org.springframework.webflow.mvc.servlet.FlowController">
- <property name="flowExecutor" ref="flowExecutor" />
- </bean>
- </beans>
對於UrlFilenameViewController類,此處理解爲由於我們並不是通過訪問controller來返回頁面的形式,那麼我們如何可以訪問Web-INF下的保護類資源呢,就是通過這個類的作用來實現。此處的理解有什麼偏差還請各位提出寶貴意見!
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">
- <!-- 流程的配置文件-2015年6月14日15:45:46 -->
- <!-- FlowExecutor 是 Spring Web Flow 的一個核心接口,啓動某個 flow ,都要通過這個接口來進行。
- 從配置角度來說,只要保證有個 FlowExecutor 就可以了, Spring Web Flow 的默認行爲已經足夠 -->
- <!-- FlowExecutor 就是通過 id 來找出要執行的 flow 。至於這個 id ,則是要由用戶來指定的。
- 在默認配置情況下,如果客戶端發送瞭如下URL請求:http://localhost:8080/CartApp/spring/shopping。
- 則從 Spring Web Flow 的角度來看,這個 URL 就表示客戶想要執行一個 id 爲“ shopping ”的 flow ,
- 於是就會在 FlowRegistry 中查找名爲“ shopping ”的 flow,由FlowExecutor負責執行。 -->
- <webflow:flow-executor id="flowExecutor" />
- <!-- 所有 flow的定義文件它的位置在這裏進行配置, flow-builder-services 用於配置 flow 的特性 -->
- <!-- FlowRegistry 是存放 flow 的倉庫,每個定義 flow 的 XML 文檔被解析後,都會被分配一個唯一的 id ,並以 FlowDefinition 對象的形式存放在 FlowResigtry 中 -->
- <!-- 每個 flow 都必須要有 id 來標識,如果在配置中省略,那麼該 flow 默認的 id 將是該定義文件(xml文件)的文件名去掉後綴所得的字符串
- (例如本例中如果去掉id="shopping",那麼flow的id就是shopping.xml去掉後綴名.xml後的shopping作爲id) -->
- <!-- flow-builder-services 屬性的配置指明瞭在這個 flow-registry “倉庫”裏的 flow 的一些基本特性,
- 例如,是用 Unified EL 還是 OGNL 、 model (模型)對象中的數據在顯示之前是否需要先作轉換,等等 -->
- <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>
- <!--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對應jsp文件夾中的jsp頁面,on是觸發事件,to對應state id -->
- <!-- 流程文件-2015年6月14日15:51:56 -->
- <!-- 根據排在第一位的順序來執行 -->
- <view-state id="viewCart" view="viewCart">
- <transition on="submit" to="viewOrder">
- </transition>
- </view-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>
對應的頁面:
index.jsp
- <?xml version="1.0" encoding="utf-8" ?>
- <!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>Cart Application</title>
- </head>
- <body>
- <h1>Hello!</h1>
- <br />
- <a href="shopping.do">View Cart</a>
- </body>
- </html><span style="font-family:Arial, Helvetica, sans-serif;background-color:rgb(255,255,255);"> </span>
viewCart.jsp
- <body>
- <h1>View Cart</h1>
- <a href="${flowExecutionUrl}&_eventId=submit">Submit</a>
- </body>
viewOrder.jsp
- <body>
- <h1>Order</h1>
- <a href="${flowExecutionUrl}&_eventId=confirm">Confirm</a>
- </body>
orderConfirmed.jsp
- <body>
- <h1>Order Confirmed</h1>
- <a href="${flowExecutionUrl}&_eventId=returnToIndex">Return to
- index</a>
- </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 的請求,要解決以下幾個問題:
- 需要在某個 HandlerMapping 中配置負責處理 flow 請求的 handler (或 controller )--配置controller(flowController)
- 該handler (或 controller )要負責啓動指定的 flow--該controller負責啓動flow(flowExecutor)
- flow 執行過程中以及執行完成後所涉及的視圖應呈現給客戶端--配置解析返回視圖方式(viewResolvers)
所有這些配置的目的無非是兩個:一是要讓客戶端的請求轉變成flow 的執行,二是要讓 flow 執行過程中、或執行結束後得到的視圖能返還給客戶端。
Spring Web Flow (SWF)是Spring Framework的一個脫離模塊。這個模塊是Spring Web應用開發模塊棧的一部分,Spring Web包含Spring MVC。
Spring Web Flow的目標是成爲管理Web應用頁面流程的最佳方案。當你的應用需要複雜的導航控制,例如嚮導,在一個比較大的事務過程中去指導用戶經過一連串的步驟的時候,SWF將會是一個功能強大的控制器。
下面我們還是從一個簡單的demo開始瞭解它:
這個例子是結合Springmvc來實現,項目結構:
Web.xml配置:
- <?xml version="1.0" encoding="UTF-8"?>
- <web-app xmlns: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">
- <display-name>CartApp</display-name>
- <!-- 配置springmvc需要的servlet -->
- <servlet>
- <servlet-name>CartServlet</servlet-name>
- <servlet-class>
- org.springframework.web.servlet.DispatcherServlet
- </servlet-class>
- <init-param>
- <param-name>contextConfigLocation</param-name>
- <param-value>
- /WEB-INF/config/web-application-config.xml
- </param-value>
- </init-param>
- <load-on-startup>1</load-on-startup>
- </servlet>
- <servlet-mapping>
- <servlet-name>CartServlet</servlet-name>
- <url-pattern>/spring/*</url-pattern>
- </servlet-mapping>
- <welcome-file-list>
- <welcome-file>index.jsp</welcome-file>
- </welcome-file-list>
- </web-app>
對應的SpringMVC的配置文件:web-application-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: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">
- <!-- SpringMVC的配置文件-2015年6月14日15:45:54 -->
- <!-- 搜索 samples.webflow 包裏的 @Component 註解,並將其部署到容器中 -->
- <context:component-scan base-package="samples.webflow" />
- <!-- 啓用基於註解的配置 -->
- <context:annotation-config />
- <import resource="webmvc-config.xml" />
- <import resource="webflow-config.xml" />
- </beans>
其中引入的兩個配置文件: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">
- <!-- SpringMVC的配置文件-2015年6月14日15:45:54 -->
- <!-- 對轉向頁面的路徑解析。prefix:前綴, suffix:後綴 -->
- <bean id="viewResolver"
- class="org.springframework.web.servlet.view.InternalResourceViewResolver">
- <property name="viewClass"
- value="org.springframework.web.servlet.view.JstlView">
- </property>
- <property name="prefix" value="/WEB-INF/jsp/">
- </property>
- <property name="suffix" value=".jsp">
- </property>
- </bean>
- <!-- 如何根據http請求選擇合適的controller是MVC中一項十分關鍵的功能,在Spring MVC中,HandlerMapping接口是這一活動的抽象 -->
- <!-- SimpleUrlHandlerMapping 通過配置文件,把一個URL映射到Controller -->
- <bean id="viewMappings"
- class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
- <!-- /shopping.do 請求由 flowController 來處理 -->
- <!-- 不管設成 /shopping.do 還是設成 /shopping ,或者 /shopping.htm ,效果都是一樣的, flowController 都會去找 id 爲 shopping的flow來執行 -->
- <property name="mappings">
- <value> /shopping.do=flowController </value>
- </property>
- <property name="defaultHandler">
- <!-- UrlFilenameViewController 會將 "/index" 這樣的請求映射成名爲 "index" 的視圖 -->
- <bean class="org.springframework.web.servlet.mvc.UrlFilenameViewController" />
- </property>
- </bean>
- <!-- 我們只要明白 FlowController 可根據客戶端請求的結尾部分,找出相應的 flow 來執行。配置 FlowController只需指定FlowExecutor即可 -->
- <bean id="flowController" class="org.springframework.webflow.mvc.servlet.FlowController">
- <property name="flowExecutor" ref="flowExecutor" />
- </bean>
- </beans>
對於UrlFilenameViewController類,此處理解爲由於我們並不是通過訪問controller來返回頁面的形式,那麼我們如何可以訪問Web-INF下的保護類資源呢,就是通過這個類的作用來實現。此處的理解有什麼偏差還請各位提出寶貴意見!
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">
- <!-- 流程的配置文件-2015年6月14日15:45:46 -->
- <!-- FlowExecutor 是 Spring Web Flow 的一個核心接口,啓動某個 flow ,都要通過這個接口來進行。
- 從配置角度來說,只要保證有個 FlowExecutor 就可以了, Spring Web Flow 的默認行爲已經足夠 -->
- <!-- FlowExecutor 就是通過 id 來找出要執行的 flow 。至於這個 id ,則是要由用戶來指定的。
- 在默認配置情況下,如果客戶端發送瞭如下URL請求:http://localhost:8080/CartApp/spring/shopping。
- 則從 Spring Web Flow 的角度來看,這個 URL 就表示客戶想要執行一個 id 爲“ shopping ”的 flow ,
- 於是就會在 FlowRegistry 中查找名爲“ shopping ”的 flow,由FlowExecutor負責執行。 -->
- <webflow:flow-executor id="flowExecutor" />
- <!-- 所有 flow的定義文件它的位置在這裏進行配置, flow-builder-services 用於配置 flow 的特性 -->
- <!-- FlowRegistry 是存放 flow 的倉庫,每個定義 flow 的 XML 文檔被解析後,都會被分配一個唯一的 id ,並以 FlowDefinition 對象的形式存放在 FlowResigtry 中 -->
- <!-- 每個 flow 都必須要有 id 來標識,如果在配置中省略,那麼該 flow 默認的 id 將是該定義文件(xml文件)的文件名去掉後綴所得的字符串
- (例如本例中如果去掉id="shopping",那麼flow的id就是shopping.xml去掉後綴名.xml後的shopping作爲id) -->
- <!-- flow-builder-services 屬性的配置指明瞭在這個 flow-registry “倉庫”裏的 flow 的一些基本特性,
- 例如,是用 Unified EL 還是 OGNL 、 model (模型)對象中的數據在顯示之前是否需要先作轉換,等等 -->
- <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>
- <!--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對應jsp文件夾中的jsp頁面,on是觸發事件,to對應state id -->
- <!-- 流程文件-2015年6月14日15:51:56 -->
- <!-- 根據排在第一位的順序來執行 -->
- <view-state id="viewCart" view="viewCart">
- <transition on="submit" to="viewOrder">
- </transition>
- </view-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>
對應的頁面:
index.jsp
- <?xml version="1.0" encoding="utf-8" ?>
- <!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>Cart Application</title>
- </head>
- <body>
- <h1>Hello!</h1>
- <br />
- <a href="shopping.do">View Cart</a>
- </body>
- </html><span style="font-family:Arial, Helvetica, sans-serif;background-color:rgb(255,255,255);"> </span>
viewCart.jsp
- <body>
- <h1>View Cart</h1>
- <a href="${flowExecutionUrl}&_eventId=submit">Submit</a>
- </body>
viewOrder.jsp
- <body>
- <h1>Order</h1>
- <a href="${flowExecutionUrl}&_eventId=confirm">Confirm</a>
- </body>
orderConfirmed.jsp
- <body>
- <h1>Order Confirmed</h1>
- <a href="${flowExecutionUrl}&_eventId=returnToIndex">Return to
- index</a>
- </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 的請求,要解決以下幾個問題:
- 需要在某個 HandlerMapping 中配置負責處理 flow 請求的 handler (或 controller )--配置controller(flowController)
- 該handler (或 controller )要負責啓動指定的 flow--該controller負責啓動flow(flowExecutor)
- flow 執行過程中以及執行完成後所涉及的視圖應呈現給客戶端--配置解析返回視圖方式(viewResolvers)
所有這些配置的目的無非是兩個:一是要讓客戶端的請求轉變成flow 的執行,二是要讓 flow 執行過程中、或執行結束後得到的視圖能返還給客戶端。