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

          Struts 的底層機制是MVC,下面是Struts 1.1中的MVC實現示意圖:



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

          控制器接收HTTP請求,并從ActionConfig中找出對應于該請求的Action子類,如果沒有對應的Action,控制器直接將請求轉發給JSP或者靜態頁面。否則控制器將請求分發至具體Action類進行處理。

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

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

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

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

          下圖給出了客戶端從發出請求到獲得響應整個過程的圖解說明。



          ActionServlet

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

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

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

          ActionForm

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

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

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

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

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

          DynaActionForm類

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

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

          Action

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

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

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

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


          網站導航:
           
          主站蜘蛛池模板: 咸阳市| 六盘水市| 武邑县| 瓦房店市| 甘谷县| 教育| 凤城市| 兴安盟| 吉首市| 改则县| 长宁县| 双鸭山市| 塔河县| 盐池县| 腾冲县| 三门县| 宁海县| 普兰县| 北票市| 秭归县| 台南市| 农安县| 德阳市| 昌江| 张北县| 长葛市| 宜川县| 双城市| 安徽省| 湖口县| 武城县| 巨野县| 苍溪县| 廉江市| 凌云县| 枣阳市| 孙吴县| 宣化县| 雷山县| 温州市| 贵阳市|