目前見到的最傻瓜全面的STRUTS入門教程^_^ 一 Jakarta Struts學習之新手上路 Web 應用開發早期曾經是那麼的「簡單」,那個時候還只是純HTML頁面和瀏覽器特效而已。因爲還涉及不到動態數據操做和商業應用,也就省去了不少麻煩。可是這 樣的「簡單」只是過眼雲煙,現在咱們不得不爲複雜的基於Web的商業應用開發採用諸多技術。 本文將介紹如何利用Struts進行應用開發的前臺整合的開發過程。Struts是一個爲開發基於模型(Model)-視圖(View)-控制器 (Controller)(MVC)模式的應用架構的開源框架,是利用Java Servlet和JSP構建Web應用的一項很是有用的技術。 閱 讀本文須要讀者具備如下幾方面的開發經驗:JSP、Servlet、自定義標籤庫(custom tag library)和XML。若是讀者想補一補自定義標籤庫的知識,能夠參考做者之前關於這方面的文章。而本文也是關於介紹如何使用Struts系列文章的 上半部分,本系列暫定分爲上下兩部分。 新手上路注意事項 Struts是一個基於Sun J2EE平臺的MVC框架,主要是採用Servlet和JSP技術來實現的。其最初萌芽於Craig McClanahan的構思,誕生至今也一年有餘了(譯註2)。如今,Struts是Apache軟件基金會旗下Jakarta項目組的一部分,其官方網 站是[url]http://jakarta.apache.org/struts[/url]。因爲Struts能充分知足應用開發的需求,簡單易用, 敏捷迅速,在過去的一年中頗受關注。Struts把Servlet、JSP、自定義標籤和信息資源(message resources)整合到一個統一的框架中,開發人員利用其進行開發時不用再本身編碼實現全套MVC模式,極大的節省了時間,因此說Struts是一個 很是不錯的應用框架。 目前的Struts 1.0修正版包括完整的文檔,既能夠說是用戶文檔又是開發指導文檔。若是讀者是JSP新手,或者對MVC設計模式不是太熟的話,可能剛上路時會比較慢,不過不用擔憂,要相信本身會盡快遇上的:) 此 外,應該注意到儘管當前Struts只是1.0版,但已經至關穩定了,做者從Struts 0.9版就在一個大規模的項目中應用了(最近升級到1.0版),至今尚未遇到什麼麻煩問題。實際上,Struts在這個要開發複雜用戶界面的項目中,爲 咱們團隊大大的縮短了開發時間,在此衷心的感謝Struts項目團隊的全部開發人員。 哦,還有,若是讀者開始上路了,要知道Struts的郵件列表但是有至關份量的,在這裏混混纔可保證能及時跟上Jakarta項目的最新動態哦 [url]http://jakarta.apache.org/site/mail.html[/url]。 開始上路! Struts 框架可分爲如下四個主要部分,其中三個就和MVC模式緊密相關: 一、模型(Model),本質上來講在Struts中Model是一個Action類(這個會在後面詳細討論),開發者經過其實現商業邏輯,同時用戶請求 經過控制器(Controller)向Action的轉發過程是基於由struts-config.xml文件描述的配置信息的。 二、視圖(View),View是由與控制器Servlet配合工做的一整套JSP定製標籤庫構成,利用她們咱們能夠快速創建應用系統的界面。 三、控制器(Controller),本質上是一個Servlet,將客戶端請求轉發到相應的Action類。 四、一堆用來作XML文件解析的工具包,Struts是用XML來描述如何自動產生一些JavaBean的屬性的,此外Struts還利用XML來描述在國際化應用中的用戶提示信息的(這樣一來就實現了應用系統的多語言支持)。 好,下一步我們來看看構成這個框架的各個部分以及相互之間是怎樣運做的吧! 搞定配置 在 使用Struts以前,我們必先設置好JSP服務器,以便讓服務器在用戶請求時,知道該如何將指定後綴的請求轉到相應的 Controller-Struts ActionServlet處理,固然,這些配置信息都通常在服務器啓動時經過web.xml文件讀入的。咱們能夠在web.xml定義多個 Controlloer,爲每個應用定義一個。一個典型的web.xml文件配置以下,其中有相應的註釋,很好懂的,在後面討論Action的時候,我 們將主要分析strutc-config.xml。 <web-app> <servlet> <!-- 以 下配置信息聲明瞭Struts中的ActionServlet,即一個名爲OreillyAction的Servlet,其具體實現爲 org.apache.struts.action.ActionServlet。在這個配置中還有這個Servlet的兩個參數:debug level和detail,此處這兩個參數的值都設爲了2,此外還設置了在啓動載入時建立兩個實例。 --> <servlet-name>OreillyActionServlet</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> <!-- 設置全部後綴爲.action的請求,都轉發到OreillyActionServlet --> <servlet-mapping> <servlet-name> OreillyActionServlet </servlet-name> <url-pattern>*.action</url-pattern> </servlet-mapping> <!-- 將初始請求頁面設置爲login.jsp --> <welcome-file-list><welcome-file>login.jsp</welcome-file></welcome-file-list> <!-- 設置Struts的JSP頁面要用到的標籤庫和她們的路徑 --> <taglib> <taglib-uri>/WEB-INF/struts-bean.tld</taglib-uri> <taglib-location>/WEB-INF/struts-bean.tld</taglib-location> </taglib> <taglib> <taglib-uri>/WEB-INF/struts-html.tld</taglib-uri> <taglib-location>/WEB-INF/struts-html.tld</taglib-location> </taglib> <taglib> <taglib-uri>/WEB-INF/struts-logic.tld</taglib-uri> <taglib-location>/WEB-INF/struts-logic.tld</taglib-location> </taglib> </web-app> 控制器(Controller) Controller是這個框架中扮演「交通警察」的角色,當客戶端與服務器有交互動做時,都由她來控制。Controller將HTTP請求封包並轉發到框架中相應的對象,這些對象多是一個JSP頁面或一個Action。 Controller 在web.xml中設置爲org.apache.struts.action.ActionServlet的一個實例,在本例中,這個實例就是 OreillyActionServlet。在一個完整的控制過程當中,也就是處理一個HTTP請求時,在控制過程之初,這個Servlet會從一個配置文 件struts-config.xml中獲取請求與控制動做向對應的配置信息,這個咱們會在後面詳細討論,Controller經過這些配置信息來決定 HTTP請求該往何處轉發,而這些Action在接收到轉發來的請求後,實現真正的商業邏輯。咱們要注意的很是重要的一點是Action對象要可以調用這 個ActionServlet的若干方法,經過這個有力的特性,當Action對象在控制過程當中將請求再向別的Action對象轉發時(最初的請求是由 ActionServlet獲取,向Action對象轉發,而Action對象還能夠再轉發到別的對象),咱們能夠將一些須要共享的數據對象經過調用一些 方法放入這個Servlet相關的一些標準容器中捎帶過去。 模型(Model) 所謂Model就是在對用戶請求的整 個控制過程當中,真正處理用戶請求並保存處理結果的對象,在整個過程當中,咱們通常利用JavaBean來把一些信息保存起來以便在各個對象之間傳遞。由於在 框架中,Model對象是真正處理商業邏輯功能的對象,所以也就是框架中應用需求實現相關性最大的部分。在Struts的實現裏,Model的具體表現形 式就是ActionForm對象和與其對應的Action對象了。對用戶提交表單的數據進行校驗,甚至對數據進行預處理都能在ActionForm中完 成。一般的應用中,通常是一個Model對象和一個請求頁面對應的關係,但也能夠一個Model對象對應多個頁面請求。若是struts- config.xml配置文件沒有指定一個Model對象對應的Action,那麼控制器將直接把(經過Model對象完成數據封裝的)請求轉到一個 View對象。 struts-config.xml 前面屢次提到的struts-config.xml配置文件是整 個框架的主心骨。web.xml文件定義了一個請求到來應向何處轉發後,後面的工做就全權由struts-config.xml管理控制了。能夠說 struts-config.xml就是整個Struts框架的「扛把子」,只有這位「老大」清楚全部請求與動做的映射關係,要是他那裏沒有搞定或不爽的 話,整個「社團」就什麼也擺不平了:)現在的應用系統,XML形式的配置文件愈來愈多,若是整個系統只使用一個這樣的配置文件的話,那麼保持整個系統的模 塊化和可維護性都很是的輕鬆。使用配置文件來描述請求-動做的控制過程和相互關係,而不是在代碼中將對象之間的調用關係寫死,那麼都應用系統有變更時,我 們只用修改配置文件就好了,而不是再從新編譯發佈程序了。 Controller經過struts-config.xml文件的配置信息 肯定當有請求時應該調用那個對象來處理,從效率的角度出發,這些信息都是在系統啓動時讀入並存在內存中的。下面咱們將講解一個極短小的struts- config.xml文件,文件中定義了一個與登陸請求對應的登陸動做,請求到達後將被轉發到 com.oreilly.ui.authentication.actions.LoginAction這個Action對象,該對象處理的結果決定向用 戶返回的頁面。這個例子同時還示範了一個Action對象將請求轉發到別的Action對象,而例子中另外一個返回的對象則是一個View對象,即咱們看到 的login.jsp頁面。 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.0//EN" "http://jakarta.apache.org/struts/dtds/struts-config_1_0.dtd";> <struts-config> <!-- ========== Action 映射定義 =================== --> <action-mappings> <!-- <action> 屬性的說明 --> <!- type - 完整的Action實現類名 name - 該Action要用到的ActionForm名 path - 請求該Action的URI unknown – 若是將該屬性設置爲true,那麼就是聲明這個Action將處理整個應用中全部未找到相應處理Action的請求,固然,一個應用系統中也只會有一個Action的unknown屬性能夠設爲true了 validate - 若是本屬性爲true則在Action動做以前其對應的ActionForm的validate方法會自動被調用,通常用以校驗用戶輸入的數據 --> <!-- ~~~~~~~~~~~~~~~~~~~~~ --> <!-- O‘Reilly Main Actions --> <!-- ~~~~~~~~~~~~~~~~~~~~~ --> <action path="/Login" type="com.oreilly.ui.authentication.actions.LoginAction"> <forward name="success" path="/DisplayMainPage.action"/> <forward name="failure" path="/login.jsp"/> </action> </action-mappings> </struts-config> 視圖(View) View 對象一般來講都是指的JSP頁面。Struts框架實際上並無真正的JSP的要求規範,而是提供了大量的標籤庫來爲開發者更簡便的將JSP整合到 Struts框架中。在Struts中經過標籤訂義方式的JSP頁面可以將用戶經過表單輸入的數據存入一個JavaBean中,也就是咱們前面提到的 ActionForm bean。經過Action類調用(自動或手動)ActionForm的校驗方法來檢查用戶輸入的數據,若是發現不合法的數據,再經過Struts的一個 通用機制將錯誤信息返回給用戶顯示。 Struts框架提供了若干個標籤庫,它們有各自不一樣的用途。因爲這些庫還能夠脫離Struts框架單獨使用,這樣咱們也能夠在其餘系統中嘗試使用這些標籤庫,它們包括: * struts-html - 這個標籤庫用來建立動態的HTML頁面和表單。 * struts-bean - 提供了相似甚至更強於中的功能。 * struts-logic - 用於在頁面輸出文本信息時的條件、循環等流程的控制。 * struts-template - 用於產生有共同風格的動態JSP頁面模板。 此外,可定製標籤庫在Struts中還有一大用處是,經過資源文件的方式來實現應用系統的多語言特性,應用Struts的系統若想將系統中的用戶交互信息換一種語言的會很簡單,更換一個不一樣的資源文件就能夠了。 你們都開始應用Struts吧! Struts框架可能對於大多數開發人員來講,是一門比較新的技術。但咱們如今已經能夠在很多的應用系統中看到Struts的身影了,而咱們大可在新的應用或正在開發的JSP項目中使用Struts框架。 例 如,在做者如今正在爲客戶開發的一個大型數據庫應用系統中,商業邏輯都是經過EJB來實現的,用戶界面則是JSP頁面。在struts- config.xml文件中定義了用戶輸入表單和對應的Action類,當一個請求發生時,即用戶數據以ActionForm的形式封裝提交到 Action時,Action先調用ActionForm的校驗方法,數據檢查校驗經過後,Action再調用相應的EJB中的方法來完成數據操做,操做 的結果以XML的形式返回,XML解析後再放入咱們數據的封裝傳遞JavaBean - ActionForm中顯示到JSP頁面裏返回用戶。 整個的控制流程(包括Action調用後的不一樣的返回結果)都盡在struts-config.xml中所掌握,這種「中央集權」的方式很是便於應用流程的調整。而無論是Servlet仍是JSP頁面中(甚至在一些n層的應用架構)都無需撰寫如何獲取顯示數據的代碼。 由 於目前做者所開發的是一個較大型的系統,有不少的JSP頁面和用戶要提交的ActionForm類型,所以發現Struts的一個麻煩的地方,那就是:我 們要爲如此多頁面和ActionForm開發對應的Action類來完成控制,由於咱們目前JSP和ActionForm與Action是一對一的關係。 不過我認爲若是在項目前期分析和設計時多下些功夫,作出更完美一些的設計方案的話,這樣的狀況是能夠避免的,固然,在新產品的開發過程當中,想一步就把全部 需求弄清楚明白那也是不可能的。咱們不是都有這樣的經歷嗎?在開發中的應用系統正一步一步走向成熟的時候,更新和更明確的需求才會被提出來。不過,像咱們 手裏這個利用Struts開發了六個月的系統也確實少見了,呵呵。除去這些非技術因素不談,Struts框架爲咱們實現MVC模式節省了大量的時間,而且 開發出的系統至關的穩定,能夠說是很成熟的產品了。 在本系列文章的第二部分,咱們將把各小段代碼集成起來,完成一個完整的Struts應用的實例,但願你們繼續和做者一塊兒學習Struts! |
|
||
Jakarta Struts學習之應用實踐 接上一篇:Jakarta Struts學習之新手上路 本 文是三篇學習Struts框架系列文章的第二篇。在本系列的的第一篇中,咱們大體瀏覽了Struts框架,框架的功能以及框架中應用到的各個模塊。而本 文,我將利用Struts 1.0爲你們演示創建一個簡單的應用;在第三篇文章中將介紹如何利用Struts的標籤在JSP中訪問ApplicationResource文件中的信 息。 咱們在這篇文章將會一步一步的講解Struts的應用,以這樣的形式打開Struts一道道神祕的大門,經過這樣的過程,相信也能激起你在應用開發中如何 應用Struts的靈感。若是你對Struts的一些術語不是很清楚的話,能夠參考本系列前一篇對Struts做大致介紹的文章。 再次 重複一遍,本文須要讀者有以下幾方面的知識和經驗:JSP,Servlets,自定義標籤庫(Custom Tag libraries)和XML。此外,在本文中,我還會用到Jakarta項目組其餘一些好東東,好比 Tomcathttp://jakarta.apache.org/tomcat/index.html(實現Java Servlet和JSP官方標準的Servlet容器,通俗的講就是一個JSP的Web Server啦)和Anthttp://jakarta.apache.org/ant/index.html(基於Java的自動編譯發佈工具,這但是 好東東啊)。 做爲一名一直使用前沿技術開發了諸多應用的技術人員,我一直堅信掌握新技術,理解該技術開發的邏輯是相當重要的。但這每每 就是陷住咱們學習步伐的泥潭,正因如此,我打算將利用Struts開發的一套完整流程做爲咱們教學的案例。該流程的這個案例可謂「麻雀雖小、五臟據全」, 你徹底能夠將這個流程應用到你手頭那些複雜龐大的項目中,至少在咱們的大項目中應用這個流程效果不錯。 有開發複雜商業應用的開發人員都知道,客戶的需求老是在不停變幻,因此若是有一套規範的開發流程來遵循,當客戶提出新的需求時,咱們至少能夠明確哪些「無理」需求實際上是合理可行的。好,接下里我將在個人這個例子中向各位展現和應用整個流程。 本 文中的示例代碼是StrutsSample應用中的一部分,包括build.xml的完整代碼能夠到此處 [url]http://www.onjava.com/onjava/2001/10/31/examples /StrutsPartII.jar[/url]下載。 Struts開發過程 從Struts發佈的版本號能夠看出,Struts是個新玩意,她有好幾個部分組成,明智的你若是搞清楚了什麼時候該開發完成合適的部分,那將會更好的利用咱們的開發時間。從我所開發的幾個利用Struts應用中,我大體總結出以下這個比較有效的開發步驟: 1,明確應用需求; 2,由用戶輸入和獲取數據的角度出發,明確和設計出每個用戶界面; 3,肯定用戶界面的進入路徑; 4,由應用邏輯信息肯定動做映射表(ActionMapping); 5,由設計完成的用戶界面開發其所用到的類和應用函數; 6,由用戶界面中的數據信息開發ActionForm和相應的數據校驗方法; 7,ActionMapping中將會被調用相應的Action或轉到相應的JSP頁面,這一步咱們先開發這些Action; 8,開發商業應用邏輯,就是相應的JavaBean、EJB或其餘東東; 9,開發由ActionMapping定義的系統工做流程完成對應的JSP頁面; 10,完成系統配置文件:struts-config.xml和web.xml; 11,編譯/測試/發佈。 明確應用需求 開發任何應用系統的第一步就是收集用戶需求信息。無論一個用戶邏輯初看上去多麼合理,但總有可能在開發時才發現它比看上去要可貴多。因此,建議擬一份明確的用戶需求列表,這不僅是出於開發的目的,還能經過該表分析用戶需求以肯定哪些地方可能須要花更多的精力。 在咱們這個StrutsSample項目中,應用需求就是: 做爲一個展現Struts框架應用的完整例子,本示例完成的功能是用戶登陸。目的只爲明確Struts的應用,本示例將不會涉及到通常複雜應用系統中可能應用的安全、數據庫、EJB開發等等相關技術。 設計用戶界面 這個應用中,包括以下三個用戶界面: 1)登陸界面,用於用戶名和密碼輸入; 2)當登陸用戶爲合法用戶時的歡迎界面; 3)當登陸失敗時的錯誤提示界面。 肯定用戶界面的進入路徑 1)登陸界面做爲這個應用的默認頁面; 2)歡迎界面只有當成功登陸後才能進入; 3)任何可能發生錯誤的頁面能能夠進入錯誤提示界面; 由 應用邏輯信息肯定ActionMapping ActionMapping爲整個應用肯定的「線路圖」,在配置文件struts-config.xml對ActionMapping進行定義,經過轉發 請求(forward)來理順應用的處理流程,肯定應用中每一個用戶請求對應的動做。 一般咱們在開發過程當中就逐步肯定了ActionMapping所需的信息,開發代碼的過程就是在由草稿開始一步步完善struts-config.xml 的過程。當Action類處理完用戶請求後,其返回的的forward就是在ActionMapping中定義的一個。一個Action返回的 forward徹底有多種可能,儘管一個Action通常只定義其相關的幾個forward。那麼,若是有多個Action均可能返回的同一個 forward,那麼就能夠將其定義爲全局轉發(global forward)。這相似於C中的頭文件中全局變量,若是在struts-config.xml描述信息中,某一個forward並非在當前 Action描述中定義的而是全局定義的,那麼這個全局的將起做用,一樣,一個Action中當前定義的forward將覆蓋全局定義。在咱們所給的這個 簡單實例中,咱們定義了全局forward D D「error」,當某Action返回的forward是「error」這個映射,那麼Errorpage.jsp頁面將會顯示給用戶,儘管當前 Action並無對其定義。 咱們繼續不斷的開發,項目日漸完善,項目相關的配置文件也會愈來愈詳細。在下面的例子中,咱們將以StrutsSample中用到的struts- confug.xml文件爲例,學習global forward和一個Action中相關映射的定義。下面定義了一個名爲「login」的Action,其爲 com.oreilly.actions.LoginAction的實例,當Action處理用戶登陸成功後將一個名爲"success"的 forward返回,用戶也就會看到Welcome.jsp頁面,若是登陸失敗,Action將返回對應的forward以再顯示Login.jsp給用 戶,而若是處理過程當中發生其餘錯誤,Action將返回全局定義的forward D D「error」,用戶也就會看到錯誤提示頁面Errorpage.jsp。 <!-- ========== Global Forward 定義 --> <global-forwards> <forward name="login" path="/Login.jsp"/> <forward name="error" path="/Errorpage.jsp"/> </global-forwards> <!-- ========== Action Mapping 定義 --> <action-mappings> <!-- <action>元素的相關屬性 --> <!-- 如下只列出經常使用屬性,其餘請參考org.apache.struts.action.ActionMapping的相關文檔 path - 當前Action對應的用戶請求URI路徑 type - 實現當前Action的Java class的完整名字 name - 當前Action中用到的ActionForm的名字,其具體信息在配置文件其餘地方另有詳細定義 unknown - 若是將該屬性設置爲true,那麼就是聲明這個Action將處理整個應用中全部未找到相應處理Action的請求,固然,一個應用系統中也只會有一個Action的unknown屬性能夠設爲true scope - Action中所用到的ActionForm的生存期,能夠爲「request」或「session」,隨着生存期的設置,該Action也會在相應的時間被建立 input - 該Action中相關ActionForm獲取用戶輸入的輸入頁面,當將ActionForm設爲自動驗證輸入數據,發現不合法數據返回錯誤時,將返回該頁面 validate - 若是本屬性爲true則在Action動做以前其對應的ActionForm的validate方法會自動被調用,通常用以驗證用戶輸入的數據 forward 元素 - 定義當前Action相關的ActionForward --> <!-- =================== --> <!-- O‘Reilly Struts Sample Main Actions --> <!-- =================== --> <action path="/login" type="com.oreilly.actions.LoginAction" name="loginForm" scope="request" input="/Login.jsp"> <forward name="success" path="/Welcome.jsp"/> <forward name="failure" path="/Login.jsp"/> </action> </action-mappings> 在 前一篇文章中,咱們曾說過,struts-config.xml就是MVC模式的的Controller。在肯定struts-config.xml中的 配置信息時,應該多花些時間精力在上面,以保證每個Action定義及其相關定義是符合應用的需求的。若是在項目開始沒有詳細的設計其定義,當將全部代 碼和配置集成到一塊兒的時候,咱們將不可避免的將各部分的代碼和配置徹底從新組織一遍。 咱們當前的例子StrusSample由於只是處理用戶登陸,因此只須要一個Action。一個應用系統中所要用到的Action的多少徹底依應用的大小 而定。一旦整套Action的映射徹底的定義出來後,咱們就能夠一個一個開發其具體實現的Action和ActionForm類,並逐漸將完成的部分一點 一點集成起來。 由設計完成的用戶界面開發其所用到的類和應用函數 全部ActionForm的實現類都是org.apache.struts.ActionForm的子類。一個ActionForm是與頁面上的輸入表單 相關聯的,並且ActionForm的實現還能夠對用戶輸入數據的合法性進行驗證。做爲一個Java Bean,ActionForm有Set和Get方法,當一個頁面中表單被提交時,系統將自動調用Set方法將數據放入ActionForm中,而Get 方法將爲在Action中操做這些數據所提供。通常來講,處理表單中的全部數據,並進行合法性驗證都徹底能夠交由ActionForm來完成。在應用中, 就我我的而言,傾向於將ActionForm和Action劃分到不一樣的包中,由於當一個頁面中要用到幾對ActionFrom和Action時,都放在 一個包內會混淆的。下面的代碼,就是實例中登陸頁面用到的ActionForm的代碼。 /* * LoginForm.java */ package com.oreilly.forms; import javax.servlet.http.HttpServletRequest; import org.apache.struts.action.ActionError; import org.apache.struts.action.ActionErrors; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionMapping; /** * 驗證用戶要用到的兩個數據 * * username - 登陸用戶名 * password - 用戶密碼 * */ public final class LoginForm extends ActionForm { private String userName = null; private String password = null; /** * userName的Get方法 * @return String */ public String getUserName() { return (userName); } /** * userName的Set方法 * @param userName */ public void setUserName(String newUserName) { userName = newUserName; } /** * password的Get方法 * @return String */ public String getPassword() { return (password); } /** * password的Set方法 * @param password */ public void setPassword(String newPassword) { password = newPassword; } /** * 重置全部數據 * * @param mapping 當前的ActionMapping * @param request 當前Server正在處理的HttpServletRequest */ public void reset(ActionMapping mapping, HttpServletRequest request) { userName = null; password = null; } /** * 驗證當前HTTP請求提交上來的數據 * 若是數據驗證發現不合法數據,將返回一個封裝 * 全部驗證錯誤的ActionErrors對象 * 若是數據驗證經過,該方法返回null或者一個 * 沒有封裝任何驗證錯誤的ActionErrors對象 * * @param mapping 當前的ActionMapping * @param request 當前Server正在處理的HttpServletRequest */ public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) { ActionErrors errors = new ActionErrors(); // 當前ActionForm中,只須要檢查用戶輸入的用戶名數據 if( userName == null || userName.length()==0 ){ errors.add("userName",new ActionError("error.userName.required")); } return (errors); } } 以 上的代碼,只有兩點和通常的Java Bean有所不一樣。其一是reset方法,方法中設置的值將在表單被reset時反應到其對應的表單項上,即將表單項的數據恢復到默認值。其二是 validate方法,是用來驗證用戶在表單中所輸入數據的方法。在當前這個例子中,咱們只驗證用戶輸入的用戶名。由於一個用戶名其對應的密碼可能爲空, 因此咱們的邏輯就是驗證時不去檢查密碼。驗證用戶名,當發現輸入的用戶名爲空時,方法就會產生一個錯誤對象(ActionError)。 在 Struts中用ActionErrors來裝載多個錯誤,從ActionErrors結尾的那個「s」就能夠知道她是一個ActionError對象的 集合。在驗證用戶輸入時,能夠驗證完表單中全部數據後,再將可能發現的多個錯誤經過ActionErrors返回給用戶,這樣的邏輯應該是想固然的啦,不 可能用戶有五個不一樣的輸入錯誤,卻要分五次提示,讓用戶修改提交五遍吧,呵呵。 同時,要知道在咱們這個例子中,咱們將錯誤信息提示給用 戶是經過ApplicationResource.properties文件。這個文件在Tomcat啓動時經過web.xml中的定義爲這個應用所使 用。一般每個應用都在其WEB-INF目錄下都有web.xml文件來描述系統,而關於部署應用時具體的結構信息,請參考 Tomcathttp://jakarta.apache.org/tomcat/index.html等Server相關的用戶手冊。 ApplicationResource.properties 文件中能夠定義應用中所要用到的提示信息的字符串,字符串都經過一個鍵值來惟一肯定其位置。在咱們這個例子中,鍵值 error.userName.required所對應的字符串信息是「A username is required」,在給用戶顯示錯誤信息時,也就經過鍵值肯定的錯誤提示顯示該字符串。經過這樣的機制,爲咱們在系統中實現多語言提供了便利,將該文件 中的這些字符串翻譯成相應的語言,咱們的系統就能夠實現西班牙語、德語、法語和漢語等等語言的版本了。 下面這些ApplicationResource.properties中的信息對於咱們這個簡單的示例中已經夠用了: login.title=Login Struts Sample error.userName.required=A username is required error.login.authenticate=Invalid username/password errors.footer=</ul><hr> errors.header=<h3><font color="red">Page Validation</font></h3>Please correct the following error(s) before contiuing:<ul> applicationResources=Cannot load application resources bundle {0} 頁面的標題,按鈕或其餘什麼須要文本提示的地方均可以經過這個文件來定義顯示用字符串。咱們將在該系列的最後一篇文章,也就是後續幾個開發步驟中講解如何經過Struts的標籤從這個文件中獲取顯示用字符串。 待續 |
|
||
Jakarta Struts學習之實戰演示 本 文是三篇學習Struts框架系列文章的最後一篇。在第一篇文章《Jakarta Struts簡介》中,我大體分析了Struts框架,討論了它所能完成的功能,還瀏覽了組成Struts的各個組成部分。在第二篇文章《學習 Jakarta Struts》中,我開始詳細描述如何利用Struts來構建一個簡單應用的過程步驟。而本篇文章將會向你們演示如何將 ApplicationResource文件中的文本信息,經過Struts標籤在JSP頁面中顯示出來。 Action類是鏈接Struts架 構和應用中業務邏輯代碼的橋樑。因此你應該儘量讓Action類小巧簡單,由於真實應用中的邏輯處理應該是由單獨分離出來的邏輯層來完成的。若是你正在 從事n層應用的開發,你固然但願層與層之間的接口越簡單越好。而事實上,Action類中的主要方法"perform()"(1.1中爲 execute())卻有點暗示應該在本方法中作點什麼的意思。咱們知道,每一個Action類都須要從 org.apache.struts.action.Action 繼承而來。在小型應用中,咱們的Action類極可能就只要繼承org.apache.struts.action.Action就足夠了;而在某些特定 的複雜應用中,我就從咱們所實現的Action類中總結出來了一些通用特性。所以,在我看來,構造一個基類將這些通用特性的代碼實現出來,讓應用中所用到 的全部Action類不直接繼承org.apache.struts.action.Action,而繼承這個完成了一些通用特性的基類以實現代碼重用, 是一個至關不錯的設計。我在StrutsSample中就應用了這種方法,構造了這樣的一個基類,該基類的方法在完成複雜邏輯的和簡單轉發請求的 Action類中均可以使用。 package com.oreilly.actions; import java.io.IOException; import java.util.Properties; import java.util.ResourceBundle; import java.util.MissingResourceException; import java.util.Enumeration; import java.util.Properties; import java.rmi.RemoteException; import javax.ejb.EJBHome; import javax.ejb.CreateException; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts.action.Action; import org.apache.struts.action.ActionServlet; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; 這 個類就是使用Struts開發時,全部Action類都要繼承的基類。它把一些一般在實際應用中最有可能被用到的東西都考慮進來了。就這篇文章而言, 類中一些與Struts並非太緊密相關的方法將只作註釋而不會完整的實現,而從事開發工做的你,有興趣的話,請完成這些方法並應用這個類,將爲你在實際 項目中的開發馬不停蹄。注意,由於全部的Action類都要從org.apache.struts.action.Action 繼承而來,因此咱們的這個類一樣。 public abstract class AbstStrutsActionBase extends Action { / * 定義一些在struts-config.xml中記錄在案的 * 全局應用中皆可可通用的forward標識*/ protected static final String SUCCESS = "success"; protected static final String FAILURE = "failure"; protected static final String ERROR = "error"; protected static final String LOGIN = "login"; protected static final String CONFIRM = "confirm"; protected Context jndiContext = null; /** * 默認構造方法 */ public AbstStrutsActionBase() { } /** 下面這個查找EJB實例的方法將不會完整實現。 一 般來講,Action類應該調用實現了應用的商務邏輯的EJB會話bean(或僅僅普通JavaBean)。在大型項目中,開發人員必須劃清層與層之間的 界限。在Action類中,咱們應該拿到獲取含有JNDI信息的環境的實例,而後經過EJB的JNDI名字去查詢獲取它的home接口。過程並不簡單,所 如下面這個代碼片段只是個給出了必要實現的小例子。 參數類型String,傳入的要查詢JNDI的名字 返回類型Object,即查找到的home接口 若是查找失敗,拋出NamingException異常 若是獲取資源信息失敗,拋出MissingResourceException異常 */ public Object lookup(String jndiName) throws NamingException, MissingResourceException { // 爲調用EJB對象,經過構建記錄JNDI信息的Properties對象 // 來得到初始環境信息 if (jndiContext == null) { ResourceBundle resource = ResourceBundle.getBundle("strutssample.properties"); Properties properties = new Properties(); properties.setProperty( Context.INITIAL_CONTEXT_FACTORY, resource.getString(Context.INITIAL_CONTEXT_FACTORY)); properties.setProperty( Context.PROVIDER_URL, resource.getString(Context.PROVIDER_URL)); properties.setProperty( Context.SECURITY_PRINCIPAL, resource.getString(Context.SECURITY_PRINCIPAL)); properties.setProperty( Context.SECURITY_CREDENTIALS, resource.getString(Context.SECURITY_CREDENTIALS)); jndiContext = new InitialContext(properties); } 注意:在真正的產品中,咱們應該在此處考慮代碼的健壯性,將代碼加入到try/catch塊內,並記錄全部錯誤或重要信息到系統log中。而本例中,咱們僅僅把異常往外拋,並假定必定會找到EJB對象的home接口並返回。 return (jndiContext.lookup(jndiName)); } 因爲Action類將是由Struts來調用的。因此它的主要方法應該是一個抽象方法,而由每一個繼承的子類來具體實現,或者在其中作一些全部Action都會作的通用機制,例如記錄log信息。在本例中,咱們一切從簡,將其抽象之。 參數mapping:其類型爲ActionMapping,將在本Action作跳轉選擇用 參數actionForm:由Struts根據本次HTTP請求數據填充完成的ActionForm對象(可選,若是存在請求數據的話) 參數request:此Action全部處理的本次HTTP請求(對象) 參數response:此Action輸出數據所要用到的HTTP響應(對象) 若是有I/O錯誤出現,則本方法拋出IOException異常 若是處理時發生servlet異常,則本方法拋出ServletException異常 本方法處理完請求後按照處理邏輯返回相應的頁面導向(對象) public abstract ActionForward perform( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException; } 或者讓這個抽象方法更有用一點,那就在裏面乾點什麼吧,好比像下面這樣在其中記錄log。 { ActionForward forward = null; // 只是簡單的記錄一些提示信息到servlet log getServlet().log( "AbstStrutsActionBase.perform() [Action Class: " + this.getClass().getName() + " ]"); getServlet().log( "AbstStrutsActionBase.perform() [Form Class : " + (form == null ? "null" : form.getClass().getName()) + " ]"); } 而後,咱們再編寫的每一個Action類都應該從AbstStrutsActionBase繼承,並依照處理邏輯編寫各自的perform方法。讓咱們用LoginAction爲例,看看具體應該怎麼應用吧。 package com.oreilly.actions; import java.io.IOException; import java.rmi.RemoteException; import javax.ejb.CreateException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts.action.ActionError; import org.apache.struts.action.ActionErrors; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionMapping; import org.apache.struts.action.ActionForward; import com.oreilly.forms.LoginForm; /* LoginAction 將演示一個Action將如何被Struts架構所調用 在這個例子中,咱們只是簡單的演示perform方法是如何調用、執行並返回的 */ public class LoginAction extends AbstStrutsActionBase { 接下來這個是驗證用戶的方法,本例中沒有具體實現。但一個典型的應用方案是調用JavaBean或者EJB來完成。用來查找EJB的lookup方法(在基類中完成的)應該在本方法中被調用,其返回一個依據後臺數據庫驗證用戶的接口。 參數類型String,要驗證的用戶名 參數類型String,密碼 返回類型boolean,若是驗證經過爲true,不然爲false public boolean authenticate(String username, String password) { /* 本方法將先作一個查找動做,得到驗證用戶的EJB對象的接口並調用 * 因爲本例只演示Action與商務邏輯層是如何交互的 * 因此具體實現代碼本例中就不提供了:) */ return (true); } 接下來咱們在LoginAction中重載基類的perform方法。 參數mapping:其類型爲ActionMapping,將在本Action作跳轉選擇用 參數actionForm:由Struts根據本次HTTP請求數據填充完成的ActionForm對象(可選,若是存在請求數據的話) 參數request:此Action全部處理的本次HTTP請求(對象) 參數response:此Action輸出數據所要用到的HTTP響應(對象) 若是有I/O錯誤出現,則本方法拋出IOException異常 若是處理時發生servlet異常,則本方法拋出ServletException異常 本方法處理完請求後按照處理邏輯返回相應的頁面導向(對象) public ActionForward perform( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { // 先假定驗證失敗,那麼要導向的forward固然是LOGIN了(見基類定義的全局變量) boolean validLogin = false; ActionForward actionForward = mapping.findForward(LOGIN); // 構造出承載ActionError對象的容器——errors,以備錯誤出現時可用 ActionErrors errors = new ActionErrors(); // 從由本次請求構造的ActionForm中提取出所須要的數據 LoginForm loginForm = (LoginForm)form; String userName = null; String password = null; if (loginForm != null) { userName = loginForm.getUserName(); password = loginForm.getPassword(); validLogin = authenticate(userName, password); } if (validLogin) { // 驗證成功了,導向到struts-config.xml中定義的SUCCESS actionForward = mapping.findForward(SUCCESS); // 存點必要的東東到session,以備後用 request.getSession(true).setAttribute("USERNAME", userName); } else { errors.add("login", new ActionError("error.login.authenticate")); } // 系統若是用戶界面友好一點,咱們就應該將錯誤信息存入request對象中 // 而後到頁面,經過在Struts的標籤顯示出來 if (!errors.empty()) { saveErrors(request, errors); } // 本Action處理完成,導向到合適的forward return (actionForward); } } 注意,這個LoginAction類就是在struts-config.xml中定義的用來處理登陸事務的一個具體實現。當這個類被載入並有一個對象實例化後,Struts架構就會調用它的perform方法。這個方法是這樣聲明的: public ActionForward perform( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException 其中,mapping是一個記錄與此Action對應的forward導向的對象,form對象封裝由客戶端提交的此Action要處理的數據,還有標準的HttpServletRequest對象和HttpServletResponse對象。 有 了這些對象的輔助,此Action就能夠拿到須要的東東順利開工了。咱們的例子中,要處理的數據主要是用戶名和密碼,這些都由form對象提供。實現驗證 功能是本應用的主要業務邏輯,在方法中的具體實現應該是去取EJB的相應接口來操做或者直接去拿數據庫數據來驗證。前面那個 AbstStrutsActionBase類中已經實現了一個簡單的EJB接口查找動做,因此若是咱們是在開發一個基於EJB實現的系統,它的可重用性就 很是強了。 由驗證方法(authenticate())的返回值,Action要接着作出合理的動做。若是驗證經過,就要讓用戶進入正 確的頁面,那麼咱們就將一些後面可能會用到的信息存入request對象(譯註:準確的講,代碼中是存到了session對象裏,固然session對象 是和當前request相關的),並向Struts返回success這個forward。這個forward是在struts-config.xml中 定義的,而後由ActionMapping封裝起來,在Action處理中能夠從中拿出合適的forward作爲返回值。若是回頭去看看struts- config.xml中的定義,就會知道success這個forward會將用戶導向至Welcome.jsp這個頁面的。若是驗證失敗,則將一個錯誤 信息存起來,而後導向到一個錯誤提示頁面顯示出來。 開發應用的業務邏輯 在一個真實的應用系統中,咱們應該將業務邏輯 層整合進來了。在咱們這個例子裏,咱們就應該去開發LoginAction中的authenticae方法所調用到的EJB了。可是正如你所見的,咱們完 全能夠把這一層暫時屏蔽掉,而利用Struts把前端部分構建並可以讓它跑起來的。我其實至關推崇的是方法是先將應用框架搭建並運行起來,而後在開發後臺 實際的業務邏輯層。在應用框架徹底恰當的構建起來的時候,後臺的開發工做全部作的debug工做也少的多了。並且,業務邏輯的開發也不是本文所要函概的範 圍,因此此處咱們略過,不過我相信你如今必定對應用的全局有了整體的把握了吧! 開發由ActionMapping定義的系統工做流程,完成對應的JSP頁面 終 於能夠將全部這些東東整合在一塊兒了。在struts-config.xml配置文件中定義的那些ActionMapping,咱們要完成這些 ActionMapping定義用到的JSP頁面。本例中,包括Login.jsp、Welcome.jsp和Errorpage.jsp。還有,儘管我 們在本例中都是將Action處理完成forward到JSP頁面,這在這個簡單的例子中是再恰當不過的邏輯流程了,而在實際利用Struts開發應用中 呢,固然能夠從Action forward到其餘的Action。咱們這個簡單的Login.jsp頁面內容是這樣的: <%@ page language="java" %> <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %> <%@ taglib uri="/WEB-INF/struts-form.tld" prefix="form" %> <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %> <html> <head> <title><bean:message key="login.title"/></title> </head> <body> <html:errors/> <h3>Enter your username and password to login:</h3> <html:form action="login.action" focus="userName" > <html:text property="userName" size="30" maxlength="30"/> <html:password property="password" size="16" maxlength="16" redisplay="false"/> <html:submit property="submit" value="Submit"/> <html:reset/> </html:form> </body> </html> Struts在JSP自定義標籤庫的基礎上提供了一套綜合各類功能的標籤庫。利用這些標籤庫很容易的構建用戶界面了。使用這些標籤庫的好處之一就是能夠利用其提供的不少附加功能。好比在通常的JSP頁面的表單裏咱們能夠看到這樣常見的HTML片段: <input type="text" name="userName" value=""> 若是咱們使用Struts的標籤庫的話,就能夠改爲這樣子: <html:text property ="userName"> 不過咱們得如今頁面中先聲明Struts標籤庫的定義。 <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %> 在 這個例子中,咱們會用到一些Struts標籤,但我不許備在此詳細講解Struts各類標籤庫的用法。相信在你不斷使用Struts搭建功能複雜的JSP 頁面的過程當中,你將會對所使用過的標籤愈來愈熟悉的。到那時,你也將更能體會到Struts標籤的益處,利用它們大大的縮短你的開發時間。目前,你能夠從 Struts Developers Guides瞭解到更多的細節。 在咱們這個簡單例子中,有兩個重點。其一: <title><bean:message key="login.title"/></title> 這就是在利用咱們前面提到的資源文件ApplicationResource來在頁面顯示信息,而不是將信息文本硬編碼到咱們的應用中。 其二: <html:errors/> 這就是在頁面中顯示出ActionErrors的信息,也就是咱們在LoginForm的驗證方法和LoginAction中產生的報錯信息的集合對象。 頁面中的表單,利用Struts,咱們將用以下的標籤來定義: <html:form action="login.action" focus="userName"> 這 裏的login.action,是和struts-config.xml中定義ActionMapping相匹配的。在頁面標籤中這樣的定義,就將相關的 Action、ActionForm和ActionForward完整的串了起來。當這個用標籤訂義的表單提交的時候,Struts中的 ActionServlet就會將其交由login.action來處理。具體的過程咱們下面慢慢深刻。 在Welcome.jsp中,咱們只演示如何將Action中的信息傳遞到頁面加以利用的通常機制: <html> <title>Welcome to Struts</title> <body> <p>Welcome <%= (String)request.getSession().getAttribute("USERNAME") %></p> </p>You have logged in successfully!</p> </body> </html> 還記得嗎?咱們在LoginAction中的perform()方法中將USERNAME放到了session中哦。 完成系統配置文件 我 們已經就struts-config.xml談了好多了。一般,這個文件中的信息會在開發過程當中逐漸完善。可是到了開發過程的最後一部,咱們更應該回頭去 檢查這個相當重要的配置文件,以保證萬無一失:Action、JSP頁面還有ActionForm都應該在文件中正確的定義。此外,咱們還不得不說到 web.xml。這個文件是JSP容器(例如Tomcat)獲取應用相關配置的重要文件。咱們這個StrutsSample例子所用到的web.xml大 致是這樣的: <?xml version="1.0" encoding="ISO-8859-1"?> <!-- This is the web-app configuration that allow the strutsSample to work under Apache Tomcat. --> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN" "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd";;> <web-app> <servlet> <servlet-name>oreilly</servlet-name> <servlet-class>org.apache.struts.action.ActionServlet</servlet-class> <init-param> <param-name>application</param-name> <param-value>com.oreilly.ApplicationResources</param-value> </init-param> <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> <init-param> <param-name>validate</param-name> <param-value>true</param-value> </init-param> <load-on-startup>2</load-on-startup> </servlet> <servlet-mapping> <servlet-name>oreilly</servlet-name> <url-pattern>*.action</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>Login.jsp</welcome-file> </welcome-file-list> <!-- Struts Tag Library Descriptors --> <taglib> <taglib-uri>/WEB-INF/struts.tld</taglib-uri> <taglib-location>/WEB-INF/struts.tld</taglib-location> </taglib> <taglib> <taglib-uri>/WEB-INF/struts-bean.tld</taglib-uri> <taglib-location>/WEB-INF/struts-bean.tld</taglib-location> </taglib> <taglib> <taglib-uri>/WEB-INF/struts-html.tld</taglib-uri> <taglib-location>/WEB-INF/struts-html.tld</taglib-location> </taglib> <taglib> <taglib-uri>/WEB-INF/struts-logic.tld</taglib-uri> <taglib-location>/WEB-INF/struts-logic.tld</taglib-location> </taglib> <taglib> <taglib-uri>/WEB-INF/struts-form.tld</taglib-uri> <taglib-location>/WEB-INF/struts-form.tld</taglib-location> </taglib> </web-app> 這 裏的標籤訂義了org.apache.struts.action.ActionServlet,並且在本例中,咱們把這個定義的servlet叫做 「oreilly」,並傳了兩個初始化參數給它:其一是咱們爲這個應用所需的顯示字符串定義的資源文件,其二是指明struts-config.xml文 件的位置。相信你也注意到了,在中爲這個Servlet指明的相應請求處理串是*.action,這是和咱們在頁面中的表單定義的提交的URL是吻合的。 也就是說,咱們經過標籤告訴Tomcat,全部後綴爲.action的請求都交給「oreilly」這個Servlet來處理。你固然能夠指定你喜歡的後 綴。在Struts附帶的例子中,你可能會看到一般以.do作爲後綴,不過我認爲.action更明確一些。標籤中定義了本應用初始顯示頁面。最後呢,我 們還要把會用到的Struts標籤庫列在後面。 編譯/測試/發佈 到此爲止,編譯/測試/發佈應用以前的全部工做都完 成了。用Ant來編譯整個應用是至關容易的。若是你之前沒有接觸過Ant,那最好把這個研究一下。其實學習和應用Ant來管理一個應用編譯環境並不難。我 把這個編譯應用所要用到的build.xml和例子放到了一塊兒,這篇文章所要用到的全部東東,你均可以點此下載,到時候你到build.xml所在目錄簡 單執行ant命令就能夠完成編譯,並打包成strutsSample.war包。固然要執行ant,你得先去下載Ant。將Ant下載回來並搭建好環境可 能得花十幾分鐘的時間哦。 本應用的目錄結構以下: StrutsSample根目錄 *.jsp WEB-INF目錄 Struts配置文件(struts-config.xml, web.xml) classes目錄(仍是以Java程序文件包結構爲路徑) lib目錄(struts.jar) 拿 到了應用的war包,咱們就將它放到Tomcat的webapps路徑下,而後啓動Tomcat。war包會被自動展開,此應用的上下文環境也會由 Tomcat自動創建起來。咱們經過web.xml告知Tomcat這個應用所需的其餘資源在哪裏。如今,咱們能夠經過 [url]http://localhost:8080/strutsSample[/url]來訪問咱們的應用了。若是沒有特別指定的話,Tomcat 默認的端口是8080,咱們定義的默認初始頁面Login.jsp也將顯示出來,如今咱們來試試吧。 結論 經過本系列 的文章,咱們利用Struts從應用需求開始,一步步將整個應用搭建起來。和普通的JSP技術相比,經過Struts開發的應用涉及到更多的與之相關的各 類文件,也正是依靠各種文件,咱們纔可能構建一個適合開發複雜應用的MVC架構。咱們的第一個Struts應用花了如此多的時間,是爲了要弄清楚 Struts的各個部分究竟是如何工做的。 但願本系列Struts文章,可以幫助你瞭解Struts是由哪些部分構成的,它們可以完成什麼,也但願介紹一個比較好的開發流程可供你參考。Struts才誕生不久,我有信心它將成爲咱們構建J2EE應用的優秀工具。 做者簡介: Sue Spielman是ONJava.com的副編輯,主要擅長於JSP和Servlet技術,她仍是Switchback Software LLC公司的總裁和高級技術諮詢專家。 |
|
||
這東西,國外早就淘汰了的 |
|
||
[quote]原帖由 [i]風雲孤獨[/i] 於 2006-8-27 18:06 發表 這東西,國外早就淘汰了的 [/quote] ........ |
|
||
[quote]原帖由 [i]風雲孤獨[/i] 於 2006-8-27 18:06 發表 這東西,國外早就淘汰了的 [/quote] 不至於吧,如今咱們給鬼子作東西都還用這個啊 也許如今有新技術了,可是struts仍是挺不錯的 |
|
||
[quote]原帖由 [i]風雲孤獨[/i] 於 2006-8-27 18:06 發表 這東西,國外早就淘汰了的 [/quote] 好像目前最流行的三個是struts,webwork,spring mvc. struts的下一代框架還不成熟吧. 估計還會流行一段時間. |
|
||
如今就國內有市場,學這個建議開始時別抱着書啃,多看看標籤,logic html bean之類的,學點javascript、實用的sql之類的東西 最基礎的東西了 還有多作項目纔是硬道理 剛開始不要急着學hibernate和spring 雖然那個東西很方便,但屁事兒也多 只是建議~ |
|
||
俺決定不學J2EE了,作了一段時間就煩了 |