<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Gay Bird

    登高者必自卑,行遠者必自邇,在這個世界上,重要的不是你正站在那里,而是你正朝什么方向移動......

    編程經驗系列-Java學習雜談(九)--Struts

     J2ee的開源框架很多,筆者只能介紹自己熟悉的幾個,其他的目前在中國IT行業應用得不是很多。希望大家對新出的框架不要盲目的推崇,首先一定要熟悉它比舊的到底好在哪里,新的理念和特性是什么?然后再決定是否要使用它。

        這期的主題是Struts,直譯過來是支架。Struts的第一個版本是在2001年5月發布的,它提供了一個Web應用的解決方案,如何讓Jsp和 servlet共存去提供清晰的分離視圖和業務應用邏輯的架構。在Struts之前,通常的做法是在Jsp中加入業務邏輯,或者在Servlet中生成視圖轉發到前臺去。Struts帶著MVC的新理念當時退出幾乎成為業界公認的Web應用標準,于是當代IT市場上也出現了眾多熟悉Struts的程序員。即使有新的框架再出來不用,而繼續用Struts的理由也加上了一條低風險,因為中途如果開發人員變動,很容易的招進新的會Struts的IT民工啊, ^_^!

        筆者之前說的都是Struts-1,因為新出了Struts-2,使得每次談到Struts都必須注明它是Struts-1還是2.筆者先談比較熟悉的 Struts-1,下次再介紹一下與Struts-2的區別:

        1.   Struts框架整體結構

        Struts-1的核心功能是前端控制器,程序員需要關注的是后端控制器。前端控制器是是一個Servlet,在Web.xml中間配置所有 Request都必須經過前端控制器,它的名字是ActionServlet,由框架來實現和管理。所有的視圖和業務邏輯隔離都是應為這個 ActionServlet,       它就像一個交通警察,所有過往的車輛必須經過它的法眼,然后被送往特定的通道。所有,對它的理解就是分發器,我們也可以叫做Dispatcher,其實了解Servlet編程的人自己也可以寫一個分發器,加上攔截request的Filter,其實自己實現一個struts框架并不是很困難。主要目的就是讓編寫視圖的和后臺邏輯的可以脫離緊耦合,各自同步的完成自己的工作。

        那么有了ActionServlet在中間負責轉發,前端的視圖比如說是Jsp,只需要把所有的數據Submit,這些數據就會到達適合處理它的后端控制器Action,然后在里面進行處理,處理完畢之后轉發到前臺的同一個或者不同的視圖Jsp中間,返回前臺利用的也是Servlet里面的forward 和redirect兩種方式。所以到目前為止,一切都只是借用了Servlet的API搭建起了一個方便的框架而已。這也是Struts最顯著的特性?? 控制器。

        那么另外一個特性,可以說也是Struts-1帶來的一個比較成功的理念,就是以xml配置代替硬編碼配置信息。以往決定Jsp往哪個servlet提交,是要寫進Jsp代碼中的,也就是說一旦這個提交路徑要改,我們必須改寫代碼再重新編譯。而Struts提出來的思路是,編碼的只是一個邏輯名字,它對應哪個class文件寫進了xml配置文件中,這個配置文件記錄著所有的映射關系,一旦需要改變路徑,改變xml文件比改變代碼要容易得多。這個理念可以說相當成功,以致于后來的框架都延續著這個思路,xml所起的作用也越來越大。

        大致上來說Struts當初給我們帶來的新鮮感就這么多了,其他的所有特性都是基于方便的控制轉發和可擴展的xml配置的基礎之上來完成它們的功能的。

        下面將分別介紹Action和FormBean,       這兩個是Struts中最核心的兩個組件。
    2.   后端控制器Action

        Action就是我們說的后端控制器,它必須繼承自一個Action父類,Struts設計了很多種Action,例如DispatchAction、 DynaValidationAction.它們都有一個處理業務邏輯的方法execute(),傳入的request,       response,       formBean和actionMapping四個對象,返回actionForward對象。到達Action之前先會經過一個 RequestProcessor來初始化配置文件的映射關系,這里需要大家注意幾點:

        1)   為了確保線程安全,在一個應用的生命周期中,Struts框架只會為每個Action類創建一個Action實例,所有的客戶請求共享同一個Action 實例,并且所有線程可以同時執行它的execute()方法。所以當你繼承父類Action,并添加了private成員變量的時候,請記住這個變量可以被多個線程訪問,它的同步必須由程序員負責。(所有我們不推薦這樣做)。在使用Action的時候,保證線程安全的重要原則是在Action類中僅僅使用局部變量,謹慎的使用實例變量。局部變量是對每個線程來說私有的,execute方法結束就被銷毀,而實例變量相當于被所有線程共享。

        2)   當ActionServlet實例接收到Http請求后,在doGet()或者doPost()方法中都會調用process()方法來處理請求。 RequestProcessor類包含一個HashMap,作為存放所有Action實例的緩存,每個Action實例在緩存中存放的屬性key為 Action類名。在RequestProcessor類的processActionCreate()方法中,首先檢查在HashMap中是否存在 Action實例。創建Action實例的代碼位于同步代碼塊中,以保證只有一個線程創建Action實例。一旦線程創建了Action實例并把它存放到 HashMap中,以后所有的線程會直接使用這個緩存中的實例。

        3)   <action>       元素的   <roles>   屬性指定訪問這個Action用戶必須具備的安全角色,多個角色之間逗號隔開。RequestProcessor類在預處理請求時會調用自身的 processRoles()方法,檢查配置文件中是否為Action配置了安全角色,如果有,就調用HttpServletRequest的 isUserInRole()方法來判斷用戶是否具備了必要的安全性角色,如果不具備,就直接向客戶端返回錯誤。(返回的視圖通過   <input>   屬性來指定)

        3.   數據傳輸對象FormBean

        Struts并沒有把模型層的業務對象直接傳遞到視圖層,而是采用DTO(Data       Transfer       Object)來傳輸數據,這樣可以減少傳輸數據的冗余,提高傳輸效率;還有助于實現各層之間的獨立,使每個層分工明確。Struts的DTO就是 ActionForm,即formBean.由于模型層應該和Web應用層保持獨立。由于ActionForm類中使用了Servlet       API,       因此不提倡把ActionForm傳遞給模型層,       而應該在控制層把ActionForm       Bean的數據重新組裝到自定義的DTO中,       再把它傳遞給模型層。它只有兩個scope,分別是session和request.(默認是session)一個ActionForm標準的生命周期是:1)   控制器收到請求       -> 2)   從request或session中取出ActionForm實例,如不存在就創建一個       -> 3)   調用ActionForm的reset()方法       -> 4)   把實例放入session或者request中       -> 5)   將用戶輸入表達數據組裝到ActionForm中       -> 6)   如眼張方法配置了就調用validate()方法           -> 7)   如驗證錯誤就轉發給   <input>   屬性指定的地方,否則調用execute()方法

        validate()方法調用必須滿足兩個條件:1)   ActionForm       配置了Action映射而且name屬性匹配2)   <aciton>       元素的validate屬性為true

        如果ActionForm在request范圍內,那么對于每個新的請求都會創建新的ActionForm實例,屬性被初始化為默認值,那么reset ()方法就顯得沒有必要;但如果ActionForm在session范圍內,同一個ActionForm實例會被多個請求共享,reset()方法在這種情況下極為有用。

    4.   驗證框架和國際化

        Struts有許多自己的特性,但是基本上大家還是不太常用,說白了它們也是基于JDK中間的很多Java基礎包來完成工作。例如國際化、驗證框架、插件自擴展功能、與其他框架的集成、因為各大框架基本都有提供這樣的特性,Struts也并不是做得最好的一個,這里也不想多說。Struts的驗證框架,是通過一個validator.xml的配置文件讀入驗證規則,然后在validation-rules.xml里面找到驗證實現通過自動為Jsp插入 Javascript來實現,可以說做得相當簡陋。彈出來的JavaScript框不但難看還很多冗余信息,筆者寧愿用formBean驗證或者 Action的saveErrors(),驗證邏輯雖然要自己寫,但頁面隱藏/浮現的警告提示更加人性化和美觀一些。

        至于Struts的國際化,其實無論哪個框架的國際化,java.util.Locale類是最重要的Java       I18N類。在Java語言中,幾乎所有的對國際化和本地化的支持都依賴于這個類。如果Java類庫中的某個類在運行的時候需要根據Locale對象來調整其功能,那么就稱這個類是本地敏感的(Locale-Sensitive),       例如java.text.DateFormat類就是,依賴于特定Locale.

        創建Locale對象的時候,需要明確的指定其語言和國家的代碼,語言代碼遵從的是ISO-639規范,國家代碼遵從ISO-3166規范,可以從http://www.unicode.org/unicode/onlinedat/languages.html http://www.unicode.org/unicode/onlinedat/countries.htm

        Struts的國際化是基于properties的message/key對應來實現的,筆者曾寫過一個程序,所有Jsp頁面上沒有任何Text文本串,全部都用的是   <bean:message>   去Properties文件里面讀,這個時候其實只要指定不同的語言區域讀不同的Properties文件就實現了國際化。需要注意的是不同語言的字符寫進Properties文件的時候需要轉化成Unicode碼,JDK已經帶有轉換的功能。JDK的bin目錄中有native2ascii這個命令,可以完成對*.txt和*.properties的Unicode碼轉換。

    posted on 2008-09-12 17:26 Sky Yi 閱讀(168) 評論(0)  編輯  收藏 所屬分類: 編程經驗系列-Java學習雜談(轉)

    主站蜘蛛池模板: 99蜜桃在线观看免费视频网站| 一级成人生活片免费看| 一个人免费视频观看在线www | 激情小说亚洲图片| 免费网站看v片在线香蕉| 456亚洲人成影院在线观| a级毛片无码免费真人| 香蕉大伊亚洲人在线观看| 欧美日韩国产免费一区二区三区| 亚洲w码欧洲s码免费| 精品久久免费视频| 成a人片亚洲日本久久| 亚洲AV网站在线观看| 一本到卡二卡三卡免费高| 国产精品亚洲w码日韩中文| a级毛片免费网站| 亚洲av永久无码精品网站| 99re这里有免费视频精品| 亚洲国产精品人久久电影| 精品国产麻豆免费网站| 精品在线视频免费| 狠狠亚洲婷婷综合色香五月排名 | 久久伊人免费视频| 亚洲国产成人综合| 成全高清视频免费观看| 免费福利在线观看| 久久精品夜色国产亚洲av| 国产在线jyzzjyzz免费麻豆| 中文字幕在线观看亚洲日韩| 亚洲阿v天堂在线2017免费| 久久99精品免费视频| 亚洲精品一二三区| 在线亚洲精品自拍| 2021在线永久免费视频| 亚洲人AV在线无码影院观看| 亚洲一区日韩高清中文字幕亚洲 | 99久久综合国产精品免费| 美女被艹免费视频| 亚洲国产精品久久久久久| 午夜视频免费观看| 久久九九全国免费|