posts - 7,comments - 5,trackbacks - 0
          Struts1.1機(jī)制[摘錄]

          Struts 的底層機(jī)制是MVC,下面是Struts 1.1中的MVC實現(xiàn)示意圖:



          首先,控制器(ActionServlet)進(jìn)行初始化工作,讀取配置文件(struts-config.xml),為不同的Struts模塊初始化相應(yīng)的ModuleConfig對象。比如配置文件中的Action映射定義都保存在ActionConfig集合中。相應(yīng)地有ControlConfig集合、FormBeanConfig集合、ForwardConfig集合和MessageResourcesConfig集合等。

          控制器接收HTTP請求,并從ActionConfig中找出對應(yīng)于該請求的Action子類,如果沒有對應(yīng)的Action,控制器直接將請求轉(zhuǎn)發(fā)給JSP或者靜態(tài)頁面。否則控制器將請求分發(fā)至具體Action類進(jìn)行處理。

          在控制器調(diào)用具體Action的execute方法之前,ActionForm對象將利用HTTP請求中的參數(shù)來填充自己(可選步驟,需要在配置文件中指定)。具體的ActionForm對象應(yīng)該是ActionForm的子類對象,它其實就是一個JavaBean。此外,還可以在ActionForm類中調(diào)用validate方法來檢查請求參數(shù)的合法性,并且可以返回一個包含所有錯誤信息的ActionErrors對象。如果執(zhí)行成功,ActionForm自動將這些參數(shù)信息以JavaBean(一般稱之為form bean)的方式保存在Servlet Context中,這樣它們就可以被其它Action對象或者JSP調(diào)用。

          Struts將這些ActionForm的配置信息都放在FormBeanConfig集合中,通過它們Struts能夠知道針對某個客戶請求是否需要創(chuàng)建相應(yīng)的ActionForm實例。

          Action很簡單,一般只包含一個execute方法,它負(fù)責(zé)執(zhí)行相應(yīng)的業(yè)務(wù)邏輯,如果需要,它也進(jìn)行相應(yīng)的數(shù)據(jù)檢查。執(zhí)行完成之后,返回一個ActionForward對象,控制器通過該ActionForward對象來進(jìn)行轉(zhuǎn)發(fā)工作。我們主張將獲取數(shù)據(jù)和執(zhí)行業(yè)務(wù)邏輯的功能放到具體的JavaBean當(dāng)中,而Action只負(fù)責(zé)完成與控制有關(guān)的功能。遵循該原則,所以在上圖中我將Action對象歸為控制器部分。

          提示:其實在Struts 1.1中,ActionMapping的作用完全可以由ActionConfig來替代,只不過由于它是公共API的一部分以及兼容性的問題得以保留。ActionMapping通過繼承ActionConfig來獲得與其一致的功能,你可以等同地看待它們。同理,其它例如ActionForward與ForwardConfig的關(guān)系也是如此。

          下圖給出了客戶端從發(fā)出請求到獲得響應(yīng)整個過程的圖解說明。



          ActionServlet

          首先來了解MVC中的控制器。在Struts 1.1中缺省采用ActionServlet類來充當(dāng)控制器,當(dāng)然如果ActionServlet不能滿足需求,也可以通過繼承它來實現(xiàn)自己的類。可以在/WEB-INF/web.xml中來具體指定。

          要掌握ActionServlet,就必須了解它所扮演的角色。首先,ActionServlet表示MVC結(jié)構(gòu)中的控制器部分,它需要完成控制器所需的前端控制及轉(zhuǎn)發(fā)請求等職責(zé)。其次,ActionServlet被實現(xiàn)為一個專門處理HTTP請求的Servlet,它同時具有servlet的特點(diǎn)。在Struts 1.1中它主要完成以下功能:
          接收客戶端請求;
          根據(jù)客戶端的URI將請求映射到一個相應(yīng)的Action類;
          從請求中獲取數(shù)據(jù)填充Form Bean(如果需要);
          調(diào)用Action類的execute()方法獲取數(shù)據(jù)或者執(zhí)行業(yè)務(wù)邏輯;
          選擇正確的視圖響應(yīng)客戶。
          此外,ActionServlet還負(fù)責(zé)初始化和清除應(yīng)用配置信息的任務(wù)。ActionServlet的初始化工作在init方法中完成,它可以分為兩個部分:初始化ActionServlet自身的一些信息以及每個模塊的配置信息。前者主要通過initInternal、initOther和initServlet三個方法來完成。

          我們可以在/WEB-INF/web.xml中指定具體的控制器以及初始參數(shù)。

          ActionForm

          對于ActionForm你可以從以下幾個方面來理解:
          1、ActionForm表示HTTP窗體中的數(shù)據(jù),可以將其看作是模型和視圖的中介,它負(fù)責(zé)保存視圖中的數(shù)據(jù)供模型或者視圖使用。Struts 1.1文檔中把它比作HTTP和Action之間的防火墻,這體現(xiàn)了ActionForm具有的過濾保護(hù)的作用,只有通過ActionForm驗證的數(shù)據(jù)才能夠發(fā)送到Action處理。
           
          2、ActionForm是與一個或多個ActionConfig關(guān)聯(lián)的JavaBean,在相應(yīng)的action的execute方法被調(diào)用之前,ActionForm會自動利用請求參數(shù)來填充自己(初始化屬性)。
           
          3、ActionForm是一個抽象類,必須通過繼承來實現(xiàn)自己的類。

          4、ActionForm首先利用屬性的getter和setter方法來實現(xiàn)初始化,初始化完畢后,ActionForm的validate方法被調(diào)用,可以檢查請求參數(shù)的正確性和有效性,并且可以將錯誤信息以ActionErrors的形式返回到輸入窗體。否則,ActionForm將被作為參數(shù)傳給action的execute方法以供使用。

          5、ActionForm bean的生命周期可以設(shè)置為session(缺省)和request,當(dāng)設(shè)置為session時,記得在reset方法中將所有的屬性重新設(shè)置為初始值。

          6、由于ActionForm對應(yīng)于HTTP窗體,所以隨著頁面的增多,ActionForm將會急速增加。而且可能同一類型頁面字段將會在不同的ActionForm中出現(xiàn),并且在每個ActionForm中都存在相同的驗證代碼。為了解決這個問題,可以為整個應(yīng)用實現(xiàn)一個ActionForm或者至少一個模塊對應(yīng)于一個ActionForm。

          但是,聚合的代價就是復(fù)用性很差,而且難維護(hù)。針對這個問題,在Struts 1.1中提出了DynaActionForm的概念。

          DynaActionForm類

          DynaActionForm的目的就是減少ActionForm的數(shù)目,利用DynaActionForm不必創(chuàng)建一個個具體的ActionForm類,而是在配置文件中配置出所需的虛擬ActionForm。例如,在下表中通過指定<form-bean>的type為"org.apache.struts.action.DynaActionForm"來創(chuàng)建一個動態(tài)的ActionForm--loginForm。
          <form-beans>
              <form-bean name="loginForm" type="org.apache.struts.action.DynaActionForm">  
                  <form-property name="actionClass" type="java.lang.String"/>
                  <form-property name="username" type="java.lang.String"/>
                  <form-property name="password" type="java.lang.String"/> 
              </form-bean> 
          </form-beans>
          動態(tài)的ActionForm的使用方法跟普通的ActionForm相同,但是要注意一點(diǎn):普通的ActionForm對象需要為每個屬性提供getter和setter方法,如果使用DynaActionForm,它將屬性保存在一個HashMap類對象中,同時提供相應(yīng)的get(name) 和 set(name)方法,其中參數(shù)name是要訪問的屬性名。例如要訪問DynaActionForm中username的值,可以采用類似的代碼:
          String username = (String)form.get("username");

          由于值存放于一個HashMap對象,所以要記得對get()方法返回的Object對象做強(qiáng)制性類型轉(zhuǎn)換。正是由于這點(diǎn)區(qū)別,如果在Action中非常頻繁地使用ActionForm對象,建議還是使用普通的ActionForm對象。

          Action

          我們通過繼承Action類來實現(xiàn)具體的執(zhí)行類。具體Action類的功能一般都在execute(以前是perform方法)方法中完成,其中主要涉及到以下幾個方面:
          a、輔助ActionForm進(jìn)行一些表單數(shù)據(jù)的檢查; 
          b、執(zhí)行必要的業(yè)務(wù)邏輯,比如存取數(shù)據(jù)庫,調(diào)用實體bean等; 
          c、更新服務(wù)器端的bean數(shù)據(jù),后續(xù)對象中可能會用到這些數(shù)據(jù),比如在JSP中利用bean:write來獲得這些數(shù)據(jù); 
          d、根據(jù)處理結(jié)果決定程序的去處,并以ActionForward對象的形式返回給ActionServlet。 

          提示:由于在Action和ActionForm中都可以實現(xiàn)驗證方法,那么如何來安排它們之間的分工呢?一般來說,我們秉著MVC分離的原則,也就是視圖級的驗證工作放在ActionForm來完成,比如輸入不能為空,email格式是否正確,利用ValidatorForm可以很輕松地完成這些工作。而與具體業(yè)務(wù)相關(guān)的驗證則放入Action中,這樣就可以獲得最大ActionForm重用性的可能。

          前面提到過,我們主張將業(yè)務(wù)邏輯執(zhí)行分離到單獨(dú)的JavaBean中,而Action只負(fù)責(zé)錯誤處理和流程控制。而且考慮到重用性的原因,在執(zhí)行業(yè)務(wù)邏輯的JavaBean中不要引用任何與Web應(yīng)用相關(guān)的對象,比如HttpServletRequest,HttpServletResponse等對象,而應(yīng)該將其轉(zhuǎn)化為普通的Java對象。
          posted on 2009-03-06 15:14 心路 閱讀(614) 評論(0)  編輯  收藏

          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 永修县| 连平县| 罗甸县| 信宜市| 苏州市| 乐至县| 罗江县| 潼南县| 保山市| 信宜市| 修武县| 武强县| 手游| 铜山县| 钦州市| 河南省| 北碚区| 宜丰县| 马公市| 象山县| 桃源县| 镇赉县| 许昌县| 玉溪市| 澄城县| 禄劝| 沁源县| 宿松县| 沙洋县| 龙州县| 治县。| 新化县| 衡东县| 绍兴市| 溧阳市| 白银市| 织金县| 瓮安县| 海伦市| 朔州市| 玉门市|