使用 WebFlowEditor 開發SWF應用
http://blog.csdn.net/zmxj/archive/2005/05/31/384946.aspx
轉自:http://www.nirvanastudio.org/nicholas/SWFEditor.htm
如果你還不了解Spring Web Flow,請參考Spring Web Flow這篇文章。
如果你已經開始對Spring Web Flow感興趣了,那么我們開始著手了解如何獨自開發SWF應用了。
首先,一個好的開發環境能夠節省很多時間,這里我介紹一下如何使用Eclipse + WebFlowEditor開發SWF應用。
安裝:
- 下載Eclipse,我用的是3.1 M6版本。
- 下載Spring Framework和Spring Web Flow
- 安裝plug-in,首先要裝一個Spring IDE,之后要裝Eclipse GEF,最后裝Spring WebFlowEditor。
安裝插件可以通過Help->Software Updates->Find and Install->Search for new festures to install->New Remote Site的辦法,添加插件下載頁的方式直接通過eclipse下載安裝。
Spring IDE: http://springide.org/updatesite/
WebFlowEditor: http://springide.org/updatesite_dev
GET: 通過默認的Eclipse.org update site安裝,或者直接從eclipse網站下載安裝
配置:
- 新建一個Java Project,在Package Explorer選中項目點右鍵選擇Add Spring Project Nature
- 我認為是很重要的一點,很多朋友都很疑惑Spring IDE在哪里,其實默認情況下這個View并沒有顯示出來,我們在Window->Show View->Other里面添加它到開發界面上。其實Spring IDE和Spring WebFlow的最大特點也就是能夠以圖形的方式直觀的給人一個大體的映像,這樣一來就能很好的看清Beans之間的聯系。
- 在Spring Beans和Spring WebFlow里面添加配置信息,主要就是設定applicationContext.xml和xxxFlow.xml(Web Flow 定義),一切配置好后,就可以Show Graph和Show WebFlow Editor的方式顯示出圖形界面。有圖形界面做起來就方便多啦:-)
圖1 - Spring IDE 視圖
第一個應用:
這個例子來源于Spring Web Flow發行包內的例子 - fileupload,這是一個很簡單的例子,流程也很簡單。它采用了Spring MVC,最后我嘗試著將它轉換成Struts MVC。
在WEB-INF下的upload-flow.xml如下:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE webflow PUBLIC "-//SPRING//DTD WEBFLOW//EN" "http://www.springframework.org/dtd/spring-webflow.dtd"> <webflow id="upload" start-state="selectFile.view"> <view-state id="selectFile.view" view="selectFile.view"> <transition on="submit" to="bindAndValidate"/> </view-state> <action-state id="bindAndValidate"> <action bean="upload.process"/> <transition on="success" to="confirmation.view"/> <transition on="error" to="selectFile.view"/> </action-state> <view-state id="confirmation.view" view="confirmation.view"> <transition on="back" to="selectFile.view"/> </view-state> </webflow>通過Spring Web Flow Editor生成的流程圖如下:
圖2- fileupload 流程
在這個應用里,所有的view都放在了WEB-INF/jsp里面,每個標單里面必須有這樣一個隱藏域:
<INPUT type="hidden" name="_flowExecutionId" value="<%=request.getAttribute("flowExecutionId") %>">
用于SWF判斷流程執行位置。
SelectFile.view ==> WEB-INF/jsp/selectFile.view.jsp,在這個View里面還有一個隱藏域:
<INPUT type="hidden" name="_eventId" value="submit">
這個用于表示事件ID,就是transition的on屬性,這樣標示就能讓spring知道執行哪個transitioin了。
與Struts集成:
Spring提供的例子是與Spring MVC集成的,我嘗試將它換成了Struts。
1、在struts-config.xml里面加入Spring Plugin,并且定義SWF入口:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN" "http://jakarta.apache.org/struts/dtds/struts-config_1_2.dtd"> <struts-config> <form-beans> <form-bean name="actionForm" type="org.springframework.web.struts.BindingActionForm"/> </form-beans> <global-forwards> <forward name="confirmation.view" path="/WEB-INF/jsp/confirmation.view.jsp" /> <forward name="selectFile.view" path="/WEB-INF/jsp/selectFile.view.jsp" /> </global-forwards> <action-mappings> <action path="/upload" type="org.springframework.web.flow.struts.FlowAction" name="actionForm" scope="request" className="org.springframework.web.flow.struts.FlowActionMapping"> <set-property property="flowId" value="upload" /> </action> </action-mappings> <plug-in className="org.springframework.web.struts.ContextLoaderPlugIn"> <set-property property="contextConfigLocation" value="/WEB-INF/applicationContext.xml"/> </plug-in> </struts-config>
關于view的映射需要使用action forwards,典型的做法是定義成全局的(SWF JavaDocs上介紹)。
定義SWF入口是最重要的,如果不定義,SWF是無法啟動的。同時要啟動一個Web流程,你需要傳遞一個flowId給控制器,這里FlowAction包含了一個全局的控制器(詳細內容查SWF JavaDocs)。upload這個屬性值很重要,他是你的webflow的id號,你可能有多個webflow,用它標示你需要啟動的那個。當然還有其他的啟動辦法,另外的例子上有介紹。
3、編寫完整的applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <bean id="upload" class="org.springframework.web.flow.config.FlowFactoryBean"> <property name="flowBuilder"> <bean class="org.springframework.web.flow.config.XmlFlowBuilder"> <property name="resource" value="/WEB-INF/upload-flow.xml"/> </bean> </property> </bean> <bean id="upload.process" class="org.springframework.samples.fileupload.web.flow.ProcessUploadAction"> <property name="formObjectName" value="file"/> <property name="formObjectClass" value="org.springframework.samples.fileupload.web.flow.FileUploadBean"/> </bean> </beans>
4、編寫web.xml以加載Struts和Spring:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app id="WebApp"> <servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<init-param>
<param-name>debug</param-name>
<param-value>2</param-value>
</init-param>
<init-param>
<param-name>detail</param-name>
<param-value>2</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet> <servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping> <servlet>
<servlet-name>context</servlet-name>
<servlet-class>
org.springframework.web.context.ContextLoaderServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
結論:
由于沒有細看SWF提供的例子,birthdate就是一個Struts + Spring的例子,害得我捉摸了半天......
birthday的例子中提供了Spring MVC和Struts的配置的對比,就是沒有講解,也讓人看得很郁悶。
SWF與Struts是兩個獨立的模塊,SWF設計者的初衷是實現最大程度的重用,也就是說SWF開發和Struts開發是相對獨立的。不僅是Struts,包括Spring MVC和Spring Portlet MVC都是與之獨立的。使用Struts僅僅是作為一個啟動WebFlow的入口,就像Spring MVC一樣,與之不同的是Struts使用struts-config.xml配合applicationContext配置啟動WebFlow入口,而Spring MVC只需要直接定義在applicationContext配置里面,因為Spring都是一家子的東西嘛。
從前一篇翻譯的文章里可以看到,Action State的實現是繼承org.springframework.web.flow.action包里面的類,而不是針對特定的MVC框架,那么他們是如何通訊的呢。那就是Context對象模式(Context Object Pattern),屬于J2EE的表現層模式,可以參考J2EE Core Pattern這個書,上面介紹的詳細。這個Context對象提供了在一個全局應用中使用的與協議無關的封裝后的對象。這樣就為了把SWF和MVC框架分開。
作者:
2005-5-28