免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
Struts教程
本文主要講解什么是Struts Framework,它的框架結(jié)構(gòu),組件結(jié)構(gòu),以及簡單的配置講解。
文章的包括了如下七大部分:
Framework的概念和體系簡介
Struts的概念和體系結(jié)構(gòu)
Struts的工作原理和組件
Struts配置文件簡介
Struts高級特性
Struts標記庫
一個簡單的示例
概念
一直以來我們都說Struts是一個Web Framework。那么讓我么先來看看什么是Framework。
Framework概念并不是很新了,伴隨著軟件開發(fā)的發(fā)展,在多層的軟件開發(fā)項目中,可重用、易擴展的,而且是經(jīng)過良好測試的軟件組件,越來越為人們所青睞。這意味著人們可以將充裕的時間用來分析、構(gòu)建業(yè)務邏輯的應用上,而非繁雜的代碼工程。于是人們將相同類型問題的解決途徑進行抽象,抽取成一個應用框架。這也就是我們所說的Framework。
Framework的體系提供了一套明確機制,從而讓開發(fā)人員很容易的擴展和控制整個Framework開發(fā)上的結(jié)構(gòu)。 通常,F(xiàn)ramework的結(jié)構(gòu)中都有一個“命令和控制”組件("command and control" component)——Framework Factory and Manager。
Framework體系
通過基于請求響應(Request-Response)模式的應用Framework,基本上有如下幾個表現(xiàn)邏輯結(jié)構(gòu)組成。
控制器(Controller)——控制整個Framework中各個組件的協(xié)調(diào)工作。
業(yè)務邏輯層(Business Logic)——對Framwork本身來說,這里僅僅只是概念和幾個提夠服務的基礎組件,真正的實現(xiàn)與客戶的業(yè)務邏輯接軌,還需要開發(fā)人員在Framework上再次擴展。
數(shù)據(jù)邏輯層(Data Logic)——絕大應用系統(tǒng)都需要涉及到數(shù)據(jù)交互,這一層次主要包括了數(shù)據(jù)邏輯和數(shù)據(jù)訪問接口。對于數(shù)據(jù)邏輯來說,如果你了解數(shù)據(jù)建模(Data Modeling)可能就很容易理解。
的概念和體系結(jié)構(gòu)
Struts有一組相互協(xié)作的類、Serlvet以及Jsp TagLib組成。基于Struts構(gòu)架的web應用程序基本上符合JSP Model2的設計標準,可以說是MVC設計模式的一種變化類型。根據(jù)上面對framework的描述,我們很容易理解為什么說Struts是一個web framwork,而不僅僅是一些標記庫的組合。但 Struts 也包含了豐富的標記庫和獨立于該框架工作的實用程序類。
Struts有其自己的控制器(Controller),同時整合了其他的一些技術(shù)去實現(xiàn)模型層(Model)和視圖層(View)。在模型層,Struts可以很容易的與數(shù)據(jù)訪問技術(shù)相結(jié)合,包括EJB,JDBC和Object Relation Bridge。在視圖層,Struts能夠與JSP, Velocity Templates,XSL等等這些表示層組件想結(jié)合。
的與Web App的關系
既然struts叫做web framework,那么其肯定主要基于web層的應用系統(tǒng)開發(fā)。按照J2EE Architecture的標準,struts應當和jsp/servlet一樣,存在于web container一層。
Struts與WebApp的關系
的體系結(jié)構(gòu)
我們說struts framework是MVC 模式的體現(xiàn),下面我們就從分別從模型、視圖、控制來看看struts的體系結(jié)構(gòu)(Architecture)。下圖顯示了struts framework的體系結(jié)構(gòu)響應客戶請求時候,各個部分工作的原理。
Struts體系結(jié)構(gòu)
首先,Struts提供了Java類org. apache.struts.action.ActionForm,Java開發(fā)者將該類細分來創(chuàng)建表單bean。在運行時,該bean有兩種用法:
― 當JSP準備相關的HTML,表單以進行顯示時,JSP將訪問該
bean(它保存要放入表單中的值)。那些值是從業(yè)務邏輯或者是從先前的用戶輸入來提供的。
― 當從Web瀏覽器中返回用戶輸入時,該bean將驗證并保存該輸入以供業(yè)務邏輯或(如果驗證失敗的話)后續(xù)重新顯示使用。
其次,Struts提供了許多定制JSP標記,它們的使用簡單,但是它們在隱藏信息方面功能強大。例如,除了bean名稱和給定bean中每個段的名稱之外,頁面設計者不需要知道有關表單bean的更多信息。
Struts雖然不直接有助于模型開發(fā)。在Struts中,系統(tǒng)模型的狀態(tài)主要由ActiomForm Bean和值對象體現(xiàn)。
在Struts framework中, Controller主要是ActionServlet,但是對于業(yè)務邏輯的操作則主要由Action、ActionMapping、ActionForward這幾個組件協(xié)調(diào)完成(也許這幾個組件,應該劃分到模型中的業(yè)務邏輯一塊)。其中,Action扮演了真正的控制邏輯的實現(xiàn)者,而ActionMapping和ActionForward則指定了不同業(yè)務邏輯或流程的運行方向。
的基本組件包
整個struts大約有15包,近200個類所組成,而且數(shù)量還在不斷的擴展。在此我們不能一一介紹,只能列舉幾個主要的簡要的介紹一下。下表說明了目前struts api中基本的幾個組件包,包括action,actions,config,util,taglib,validator。下圖則顯現(xiàn)了這幾個組件包之間的關系。其中action是整個struts framework的核心
org.apache.struts.action
基本上,控制整個struts framework的運行的核心類、組件都在這個包中,比如我們上面提到的控制器ActionServlet。已經(jīng)Action,ActionForm,ActionMapping等等。struts1.1比1.0多了 DynaActionForm 類。增加了動態(tài)擴展生成FormBean功能
org.apache.struts.actions
這個包是主要作用是提供客戶的http請求和業(yè)務邏輯處理之間的特定適配器轉(zhuǎn)換功能,而1.0版本中的部分動態(tài)增刪FromBean的類,也在struts1.1中被Action包的DynaActionForm組件所取代
org.apache.struts.config
提供對配置文件struts-config.xml元素的映射。這也是sturts1.1中新增的功能
org.apache.struts.util
Strtuts為了更好支持web application的應用,體統(tǒng)了一個些常用服務的支持,比如Connection Pool和Message Source。詳細信息請參考
http://jakarta.apache.org/struts/api/org/apache/struts/util/package-summary.html
org.apache.struts.taglib
這不是一個包,而是是一個客戶標簽類的集合。下面包括Bean Tags,HTML Tags,Logic Tags,Nested Tags,Template Tags這幾個用于構(gòu)建用戶界面的標簽類。
org.apache.struts.validator
Struts1.1 framework中增加了validator framework,用于動態(tài)的配置from表單的驗證。詳細信息請參閱 http://home.earthlink.net/~dwinterfeldt/
Struts的基本組件關系圖
的工作原理和組件
對于Struts 如何控制、處理客戶請求,讓我們通過對struts的四個核心組件介紹來具體說明。這幾個組件就是:ActionServlet。Action Classes,Action Mapping(此處包括ActionForward),ActionFrom Bean。
控制器對象
ActionServlet繼承自javax.servlet.http.HttpServlet類,其在Struts framework中扮演的角色是中心控制器。它提供一個中心位置來處理全部的終端請求??刂破鰽ctionServlet主要負責將HTTP的客戶請求信息組裝后,根據(jù)配置文件的指定描述,轉(zhuǎn)發(fā)到適當?shù)奶幚砥鳌?div style="height:15px;">
按照Servelt的標準,所有得Servlet必須在web配置文件(web.xml)聲明。同樣,ActoinServlet必須在Web Application配置文件(web.xml)中描述,有關配置信息如下。
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
</servlet>
全部的請求URI以*.do的模式存在并映射到這個servlet,其配置如下:
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
一個該模式的請求URI符合如下格式:
http://www.my_site_name.com/mycontext/actionName.do
中心控制器為所有的表示層請求提供了一個集中的訪問點。這個控制器提供的抽象概念減輕了開發(fā)者建立公共應用系統(tǒng)服務的困難,如管理視圖、會話及表單數(shù)據(jù)。它也提供一個通用機制如錯誤及異常處理,導航,國際化,數(shù)據(jù)驗證,數(shù)據(jù)轉(zhuǎn)換等。
當用戶向服務器端提交請求的時候,實際上信息是首先發(fā)送到控制器ActionServlet,一旦控制器獲得了請求,其就會將請求信息傳交給一些輔助類(help classes)處理。這些輔助類知道如何去處理與請求信息所對應的業(yè)務操作。在Struts中,這個輔助類就是org.apache.struts.action.Action。通常開發(fā)者需要自己繼承Aciton類,從而實現(xiàn)自己的Action實例。
ActionServlet把全部提交的請求都被控制器委托到RequestProcessor對象。RequestProcessor使用struts-config.xml文件檢查請求URI找到動作Action標示符。
一個Action 類的角色,就像客戶請求動作和業(yè)務邏輯處理之間的一個適配器(Adaptor),其功能就是將請求與業(yè)務邏輯分開。這樣的分離,使得客戶請求和Action類之間可以有多個點對點的映射。而且Action類通常還提供了其它的輔助功能,比如:認證(authorization)、日志(logging)和數(shù)據(jù)驗證(validation)。
public ActionForward execute(ActionMapping mapping,                              ActionForm form,                              javax.servlet.ServletRequest request,                              javax.servlet.ServletResponse response)                       throws java.io.IOException,javax.servlet.ServletException
Action最為常用的是execute()方法。(注意,以前的perform方法在struts1.1中已經(jīng)不再支持),還有一個execute()方法,請參考apidoc,在此不在說明。
當Controller收到客戶的請求的時候,在將請求轉(zhuǎn)移到一個Action實例時,如果這個實例不存在,控制器會首先創(chuàng)建,然后會調(diào)用這個Action實例的execute()方法。Struts Framework為應用系統(tǒng)中的每一個Action類只創(chuàng)建一個實例。因為所有的用戶都使用這一個實例,所以你必須確定你的Action 類運行在一個多線程的環(huán)境中。下圖顯示了一個execute()方法如何被訪問:
Action實例的execute()方法
注意,客戶自己繼承的Action子類,必須重寫execute()方法,因為Action類在默認情況下是返回null的。
上面講到了一個客戶請求是如何被控制器轉(zhuǎn)發(fā)和處理的,但是,控制器如何知道什么樣的信息轉(zhuǎn)發(fā)到什么樣的Action類呢?這就需要一些與動作和請求信息相對應的映射配置說明。在struts 中,這些配置映射信息是存儲在特定的XML文件(比如struts-config.xml)。
這些配置信息在系統(tǒng)啟動的時候被讀入內(nèi)存,供struts framework在運行期間使用。在內(nèi)存中,每一個<action>元素都與org.apache.struts.action.ActionMapping類的一個實例對應。下表就顯示了一個登陸的配置映射。
<action-mappings>
<action path="/logonAction"
type="com.test.LogonAction"
name="LogonForm"
scope="request"
input="logoncheck.jsp"
validate="false">
<forward name="welcome" path="/welcome.jsp"/>
<forward name="failure" path="/logon_failure.jsp "/>
</action>
</action-mappings>
<form-beans>
<form-bean  name="LoginForm"
type="com.test.LoginForm"/>
</form-beans>
上面的配置表示:當可以通過/logonAction.do(此處假設配置的控制器映射為*.do)提交請求信息的時候,控制器將信息委托com.test.LogonAction處理。調(diào)用LogonAction實例的execute()方法。同時將Mapping實例和所對應的LogonForm Bean信息傳入。其中name=LogonForm,使用的form-bean元素所聲明的ActionForm Bean。有關form-bean的申明如下顯示。
ActionForward導航
元素<forward>則表示了當Action實例的execute()方法運行完畢或,控制器根據(jù)Mapping可將響應信息轉(zhuǎn)到適當?shù)牡胤?。如上面現(xiàn)實,如果客戶登陸成功,則調(diào)用welcome forward,將成功信息返回到/welcome.jsp頁面。在你的execute()方法的結(jié)尾可以使用下面的實例代碼而返回welcome forward。當然你的welcome forward必須在action元素屬性中定義,正如上面所聲明的那樣。
return (mapping.findForward("welcome"));
ActionForward對象是配置對象。這些配置對象擁有獨一無二的標識以允許它們按照有意義的名稱如“success”,“failure”等來檢索。ActionForward對象封裝了向前進的URL路徑且被請求處理器用于識別目標視圖。ActionForward對象建立自<forward>元素位于struts-config.xml。下面是一個Struts中<forward>元素例子,屬于<action>元素范圍。
<action path="/editCustomerProfile"
type="packageName.EditCustomerProfileAction"
name="customerProfileForm" scope="request">
<forward name="success" path="/MainMenu.jsp"/>
<forward name="failure" path="/CustomerService.jsp"/>
</action>
基于執(zhí)行請求處理器的execute(…)方法的結(jié)果,當傳遞一個值匹配指定于<forward>元素中name屬性的值的時候,下一個視圖可以在execute(…)方法中被開發(fā)者用方便的方法org.apache.struts.action.ActionMapping.findForward(…)選擇。ActionMapping.findForward(…)方法既從它的本地范圍又從全局范圍提供一個ActionForward對象,該對象返回至RequestProcessor以RequestDispatcher.forward(…)或response.sendRedirect(…)調(diào)用下一個視圖。當<forward>元素有redirect=“false”屬性或redirect屬性不存在的時候,RequestDispatcher.forward(…)被執(zhí)行;當redirect=“true”是,將調(diào)用sendRedirect(…)方法。下例舉例說明了redirect屬性的用法:
<forward name="success" path="/Catalog.jsp" redirect="true"/>
如果redirect=true, URL建立如/contextPath/path因為HttpServletResponse.sendRedirect(…)中解釋URL采用”/”開頭相對于servlet容器根目錄。
如果redirect=false, URI建立如/path因為ServletContext.getRequestDisptacher(…)采用虛擬目錄相關URL。
在此稍稍說一下有關global-forwards的概念。其在配置文件中描述了整個應用系統(tǒng)可以使用的ActionForward,而不是僅僅是一個特定的Action。
<global-forwards>
<forward name="logout" path="/logout.do"/>
<forward name="error" path="/error.jsp"/>
</global-forwards>
捕獲表單數(shù)據(jù)
在上面講解ActionServlet,Action Classes和Action Mapping的時候,我們都提到了ActionForm Bean的概念。一個應用系統(tǒng)的消息轉(zhuǎn)移(或者說狀態(tài)轉(zhuǎn)移)的非持久性數(shù)據(jù)存儲,是由ActionForm Bean的負責保持的。
ActionForm派生的對象用于保存請求對象的參數(shù),因此它們和用戶緊密聯(lián)系。
一個ActionForm類被RequestProcessor建立。這是發(fā)生在已完成向前進到一個URL,該URL為映射到控制器servlet而不是JSP和相應的動作映射指定的表單屬性的。在這個情況下,如果沒有在指定的活動范圍內(nèi)找到,RequestProcessor將嘗試尋找可能導致創(chuàng)建一個新ActionForm對象的表單bean。該ActionForm對象在指定的活動范圍內(nèi)被用<action>元素的name屬性找到;
RequestProcessor將隨后重新安排表單屬性,用請求時參數(shù)填充表單,隨即調(diào)用表單對象的validate(…)方法以履行服務器端用戶輸入驗證。僅當ActionMapping對象中validate屬性被設為true時,validate(…)方法被調(diào)用;這就是默認的行為。request.getParameterValues(parameterName)被用于得到一個String[]對象,它用來表單填充;驗證的結(jié)果應該是一個ActionErrors對象,用org.apache.struts.taglib.html.ErrorsTag來顯示驗證錯誤給用戶。ActionForm也可以被用于為當前用戶保存即將被一個視圖引用的中間模型狀態(tài)。
當一個表單對象被RequestProcessor找到,它被傳遞到請求處理器的execute(…)方法。一個ActionForm對象也可以被請求處理器建立。表單對象建立目的是提供中間模型狀態(tài)給使用請求范圍JSP;這將確保對象不會在有效性過期后仍然存在。默認的,所有的表單都被保存為會話范圍。會話中表單對象脫離有效性的存在可能導致浪費內(nèi)存,同樣的,請求處理器必須跟蹤保存在會話中的表單對象的生命周期。一個好的捕獲表單數(shù)據(jù)的實踐是為橫跨多用戶交互的相關表單用一個單獨的表單bean。表單bean也可以在反饋的時候用來儲存能夠被自定義標簽改變的中間模型狀態(tài)。在視圖中標簽用法避免結(jié)合Java代碼,因此要成一個好的任務劃分,web生產(chǎn)組主要處理標志,而應用開發(fā)組主要處理Java代碼。標簽因素退出訪問中間模型狀態(tài)的邏輯;當訪問嵌套的對象或當通過聚集列舉時這個邏輯可能很復雜。
注意:在struts1.1中,ActionForm的校驗功能,逐漸被剝離出來(當然依然可以使用)。使用了validator framework對整個應用系統(tǒng)的表單數(shù)據(jù)驗證進行統(tǒng)一管理。相信信息請參考:http://home.earthlink.net/~dwinterfeldt
在ActionForm的使用中,Struts提倡使用到值對象(Value Object)。這樣將客戶或開發(fā)人員,對數(shù)據(jù)狀態(tài)與對象狀態(tài)能夠更加清晰的理解和使用。
對于每一個客戶請求,Struts framework在處理ActionForm的時候,一般需要經(jīng)歷如下幾個步驟:
(1)檢查Action的映射,確定Action中已經(jīng)配置了對ActionForm的映射
(2)根據(jù)name屬性,查找form bean的配置信息
(3)檢查Action的formbean的使用范圍,確定在此范圍下,是否已經(jīng)有此form bean的實例。
(4)假如當前范圍下,已經(jīng)存在了此form bean的實例,而是對當前請求來說,是同一種類型的話,那么就重用。
(5)否則,就重新構(gòu)建一個form bean的實例
(6)form bean的reset()方法備調(diào)用
(7)調(diào)用對應的setter方法,對狀態(tài)屬性賦值
(8)如果validatede的屬性北設置為true,那么就調(diào)用form bean的validate()方法。
(9)如果validate()方法沒有返回任何錯誤,控制器將ActionForm作為參數(shù),傳給Action實例的execute()方法并執(zhí)行。
注意:直接從ActionFrom類繼承的reset()和validate()方法,并不能實現(xiàn)什么處理功能,所以有必要自己重新覆蓋。
的其他組件
Struts framework本身提供了很多可擴展的組件或sub framework,方便的開發(fā)人員在其構(gòu)架上構(gòu)建web層的應用系統(tǒng)。比如upload,collections ,logging等等。讓我們來看看兩個比較重要的組件:validationg framework和struts taglib。有關其他組件請參考Struts用戶手冊(http://jakarta.apache.org/struts/userGuide)。
在struts1.1中,新增了validation framework。增加了對form數(shù)據(jù)提交的驗證。將原本需要在ActionFrom Bean的validate()進行的驗證通過配置文件的描述進行驗證。
有關其詳細信息,請參考http://home.earthlink.net/~dwinterfeldt 。個人建議對于小型應用系統(tǒng)可以采用這種配置方式,但是對于應用系統(tǒng)中有大量web層表單應用的系統(tǒng),并且業(yè)務需求變動比較大的,使用validation framework 可能會加重開發(fā)難度、系統(tǒng)維護難度。可以借鑒validation framework的Javascript Validator Tag。
struts提供了一組可擴展的自定義標簽庫(TagLib),可以簡化創(chuàng)建用戶界面的過程。目前包括:Bean Tags,HTML Tags,Logic Tags,Nested Tags,Template Tags 這幾個Taglib。有關Struts Taglib的結(jié)構(gòu)和使用,可以參考前面有關Cutomer Tag Lib的介紹,有關起詳細資料,請參考
這個組件的全稱是Bean Introspection Utilites。是屬于Jakarta Commons項目組的。主要是幫助構(gòu)建javabean的屬性操作的(getter,setter),已經(jīng)提供一種動態(tài)定義和訪問bean的屬性。有關詳細信息,請參考。
http://jakarta.apache.org/commons/beanutils.html
如果各位對這方面有很興趣,可以參考一些有關java反射(Reflectio)方面的資料。
這個組件主要是提供了一些集合或列表對象,在原有的java collections framework的基礎上進行了擴展。詳細資料請參考:
http://jakarta.apache.org/commons/collections.html 以及
http://cvs.apache.org/viewcvs/~checkout~/jakarta-commons/collections/STATUS.html?rev=1.13
這個組件翻譯成中文的意思是“匯編”。其主要功能是根據(jù)xml配置文件,初始化系統(tǒng)的一些java類對象。Digester幫助你指定XML與java對象之間映射模型,而且允許客戶話定制映射規(guī)則(rules)。詳細資料請參考
http://jakarta.apache.org/commons/digester.html
配置文件簡介
Struts framework根據(jù)配置文件使得ServletAction,ActionMapping,Action , ActionForm這幾個不同層次的組件相互交互,協(xié)調(diào)的工作。這些配置文件是在系統(tǒng)啟動的時候,讀入導內(nèi)存中,供控制器使用的。
Struts framework主要包括三部分的配置描述,一個是指定有關Struts Controller及其相關的的配置描述(Initialization Parameters),一個對struts tag lib的描述,一個是struts組件(ActionMapping,Action,ActionForm)之間相互映射協(xié)調(diào)的關系
及其相關的的配置描述
因為Struts Controller的主要類ActionServlet是繼承自HttpServlet,所以必須像配置一個Servlet那樣在部署描述符(Web.xml)中配置ActionServlet類及其訪問映射。
當您第一次創(chuàng)建基于Struts的Web應用程序時,將為您創(chuàng)建一個部署描述符,這通常就足夠了。該文件包括下列條目:
l         <servlet>條目定義用于Web應用程序的servlet(在本例中,這是唯一的servlet):
― <servlet-name> 和<servlet-class>指示ActionServlet (標識為“操作”)接收HTTP請求并確定如何響應。
― <init-param>表示servlet初始化參數(shù).
-          “config”指示ActionServlet的行為由指定的配置文件來指導,該配置文件通常具有以下名稱:
\WEB-INF\struts-config.xml
-          “debug”具有整數(shù)值,它指示將有關處理的詳細信息寫至控制臺的程度。
-          ”detail”具有整數(shù)值,它指示將“映射”詳細信息(如后面所述)寫至控制臺的程度。
― <load-on-startup>導致在啟動應用程序時裝入servlet。
l         <servlet-mapping>元素標識這樣的命名模式:當命名模式由URL進行匹配時,Web服務器就將控制權(quán)移交給ActionServlet??紤]下面各種情況:
― 訪問了ActionServlet,原因是“操作”(<servlet-mapping>中的<servlet-name>元素的內(nèi)容)與“操作”(<servlet>中的<servlet-name>元素的內(nèi)容)相匹配。
― <servlet-mapping>元素指定URL的結(jié)尾的命名模式。每個URL的開頭都是應用程序上下文路徑。按照慣例,ActionServlet調(diào)用對象以響應與命名模式“*do”(其中“*”是通配符)一致的URL。
l         <welcome-file-list>元素指示獲得初始控制權(quán)的特定于應用程序的代碼;在本例中,Web服務器直接從Web Content目錄中調(diào)用index.jsp。
l         <error-page>元素指示顯示哪個JSP來響應錯誤;在本例中,錯誤為如下所示:
― 404 (找不到資源)
― 500 (Web服務器內(nèi)部發(fā)生錯誤)
l         每個<taglib>元素都使相對URL(相對于Web.xml)與標記庫描述符(相對于Web應用程序根目錄)相關聯(lián)。每個JSP都可以使用同一個URL來表示給定的標記庫,而Web.xml確定引用了哪個文件。
的配置描述
如果你的web application打算使用Struts的taglib,那么你有必要在web.xml中對struts taglib進行配置描述。
的配置描述
作為先前描述的web.xml設置的結(jié)果,Web應用程序服務器將請求的一個子集按路徑發(fā)送至ActionServlet,它通常調(diào)用一系列操作和JSP。ActionServlet的響應是基于配置文件struts-config.xml的內(nèi)容的。有關其DTD文檔的描述,請參考http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd
一般struts-config(version1.1)包含了如下幾個部分:
(1)form-bean
(2)global-forwards
(3)action-mappings
(4)data-sources
我們知道,對于這樣的一個請求(例如,表示為“/login.do”),執(zhí)行下列步驟:
1、 尋找操作類對象(繼承org. apache.struts.action.Action的類)
2、 ActionServlet調(diào)用操作類對象的執(zhí)行方法
操作類中的執(zhí)行方法的特征符為如下所示:
public ActionForward execute(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
l         映射對象(ActionMapping),它包含指示如何響應方法的每個可能結(jié)果的規(guī)則(“映射”)
l         Struts表單bean(ActionForm),它保存發(fā)送至HTML表單或接收自HTML表單的數(shù)據(jù)
l         請求和響應對象(HttpServletReques/ HttpServletResponse)
3、 從執(zhí)行方法返回ActionForward對象,用于指導ActionServlet接著訪問哪個操作類或JSP
返回的ActionForward對象中的信息取決于兩個值:
l         方法的結(jié)果(如在“成功”或“故障”等字符串中所述)
l         映射對象,它包含從Struts配置文件中讀取的信息
要弄明白某些運行時關系,要明白struts-config.xml該文件包括下面的一組條目:
l         <form-beans>標記標識每個表單bean
l         <action-mappings>標記包括用于指導應用程序流的信息,每個<action>子標記都使相對URL與操作類和潛在的后續(xù)操作相關。
元素
Struts配置文件中的一個示例<form-bean>子元素為如下所示:
<form-bean name=“registerForm” type=“strutscommon.RegisterForm”/>
每個<form-bean>子元素都包括下列屬性:
name
表單bean的名稱,稍后在配置文件中會用到。ActionServlet舉例說明了該bean(如果需要的話)并在將對bean的引用存儲在請求或會話對象中時將該名稱用作鍵。
type
類的全限定名稱,它繼承org.apache.struts.action.ActionForm該類必須在類路徑中。接受“Struts貿(mào)易樣本”中的注冊的表單bean包括HTML注冊表單中每個字段的getter 和setter方法。該bean還包括驗證方法,如下節(jié)“驗證”中所述。
元素
Struts配置文件中的一個示例<action>元素為如下所示:
<action path=“/register”
type=“strutsEGL.RegisterAction”
name=“registerForm”
input=“/register.jsp”
scope=“request”
<forward name=“success”path=“/home.do”/>
< forward name=“failure”path=“/register.jsp”/>
</action>
每個<action>元素都包括下列屬性中的某些屬性或所有屬性:
path
將請求指定為非限定URL,不帶文件擴展名(例如,“/register”)請求是根據(jù)<action>元素中的其它屬性來處理的,并且是用戶輸入的結(jié)果或者是在different<action>元素中標識的轉(zhuǎn)發(fā)的結(jié)果。
type
指定在發(fā)出請求時調(diào)用其執(zhí)行方法的操作類的全限定名。該類必須在類路徑中。
注:不指定要實例化的類,可以通過使用forward屬性來轉(zhuǎn)發(fā)請求,該屬性在“Struts貿(mào)易樣本”中未使用,并且與后面描述的<forward>子元素不相同。
name
用于保存發(fā)送至HTML表單或接收自HTML表單的數(shù)據(jù)表單bean的名稱。
input
指定相對URL(例如,“/register.do”或“/index.jsp”)必須包括后綴,
如果表單bean的驗證方法指示發(fā)生了輸入錯誤,則會調(diào)用URL;有關詳細信息,參見下節(jié)的“驗證”。
scope
指定將對表單 bean的引用存儲在哪個作用域中。其值為“會話”(缺省值)或“請求”。
Struts配置文件中的每個<action>元素還包括子元素<forward>,它指定從方法結(jié)果至后續(xù)調(diào)用的映射。每個<forward>子元素都包括下列屬性
name
指定導致在運行時使用當前映射的字符串(例如,“success”),但是
只限于以下情況:在 type 中引用的操作類的執(zhí)行方法使用完全相同
的字符串來配置返回至ActionServlet的 ActionForward對象。下面
的執(zhí)行方法不是很重要,但是會導致使用“success”映射:
public ActionForward exectue(
ActionMapping mapping,
ActoinForm form,
HttpServletRequest request,
HttpServletResponse response)
Throws IOException,ServletException
ActionForward forward=new ActionForward();
Forward=mapping,findForward(“success”);
return(forward);
path
指定非限定URL(例如,“/home.do” 或“/index.jsp”)必須包括文件擴展名,僅當使用當前映射時才會調(diào)用該URL,轉(zhuǎn)發(fā)操作類是根據(jù)different<action>元素中的屬性來處理的,尤其是,在其path屬性標識相同URL的<action>元素中。
有必要提一下的是,在struts1.1中,提出了對Multiple Application Support。在struts的早先版本中,只有一個struts配置文件,一般叫struts-config.xml。但是,對于越來越復雜的應用系統(tǒng)的發(fā)展,只有一個地方存放這個一個文件,對大型項目來說,使用和修改這個配置文件,使其成為了一個應用的瓶頸問題。在struts1.1中,你可以定義多了配置文件協(xié)同工作。
注:當用戶或ActionServlet調(diào)用JSP時,請求是由Web應用程序服務器直接處理的不會受到ActionServlet的干預。
高級特性(Struts Advanced Feature)
僅當在下列情況下才會在表單bean中對用戶輸入進行驗證:
l         表單bean覆蓋超類的驗證方法
l         Struts配置文件中的<action>元素的驗證屬性顯式地或者缺省設置為TRUE。表單bean沒有關于應用程序的業(yè)務邏輯的信息;因此該bean提供的驗證僅限于一些相對簡單的問題,例如,用戶是否在每個必填字段中都輸入了數(shù)據(jù)?
Struts框架的各種部件使得可以進行驗證
l         Struts配置文件中的以下<action>子元素將導致使用表單bean registerForm:
<action path=“/register”
type=“strutsEGL.RegisterAction”
name=“registerForm”
input=“/register.jsp”
scope=“request”
<forward name=“success” path=“/home.do”/>
<forward name=“failure”path=“/register.jsp”/>
</action>
如果缺少驗證屬性,則意味著當ActionServlet接收到來自HTML表單對“/register”的請求時,ActionServlet將在接收用戶數(shù)據(jù)的表單bean中調(diào)用驗證方法。此驗證在ActionServlet訪問操作類之前進行。如果丟失了該方法,不會發(fā)生任何錯誤,在該情況下,驗證總是會成功。
l         如果發(fā)生了錯誤,則表單bean的驗證方法將舉例說明錯誤類并將錯誤條目添加至該類。registerForm的驗證方法的一個子集為如下所示:
ActionErrors errors=new ActionErrors();
If (username= =unll║username.equals(“”))
{
errors.add(“register”,
new ActionError(“error. Register.username”));
}
if (openingBalance<0.01)
{
errors.add(“register”,
new ActionError(“error. register. balance”));
}
return errors;
errors.add方法包括兩個參數(shù):
property
用來標識錯誤類別的Java字符串。
如果想要在特定的輸入字段或輸入字段的子集發(fā)生錯誤時
標識該錯誤,則指定屬性值。例如,指定諸如“username”
之類的值的優(yōu)點在于:報告了錯誤的JSP中,可以在屏幕上
靠近發(fā)生錯誤的字段的位置顯示有關特定HTML字段的錯
誤消息,但是,要指示所有錯誤都屬于同一類別,可以對屬
性參數(shù)指定以下常量:
ActionErrors.GLOBAL_ERROR
error
包含從屬性文件派生的“鍵-字符串”對的鍵的ActionError 對象。當配置ActionError對象時,最多可以包括要代入字符串中用來替代{0}、{1}等的四個值。
l 如果從驗證方法返回了錯誤,則ActionServlet指導對在<action>元素的輸入屬性中指定的對象或JSP進行處理;在本例中,將處理register.jsp.
l JSP register.jsp.     包括用于顯示從驗證方法派生的任何錯誤消息的以下
標記:
<html:errors/>
如果在未發(fā)生輸入錯誤的情況下調(diào)用JSP,則該標記不顯示任何內(nèi)容,
而在JSP中將繼續(xù)進行處理。但是,如果因發(fā)生驗證故障而調(diào)用了JSP,
則為用戶顯示的內(nèi)容將受到屬性文件中是否包括下列鍵的影響:
― errors.header,它導致在所有錯誤消息前面顯示一個字符串;或者
― errors.footer,它導致在所有錯誤消息后面顯示一個字符串;或者
― errors.hiader,和errors.footer兩者
例如,在ApplicationResources.properties 中,errors.header和 errors.footer的“鍵-字符串”對以及先前顯示的這兩個消息鍵為如下所示,它們各自都在單獨的一行上(但是分成了多行顯示以便于您復查):
errors.header=
<p class=“errors”>
The Action failed because of the following reason(s):
<ul class=“errors”>
error.register.username=<li>you must enter a User ID.
error.register.balance=
<li>Your account must start with a positive balance.
Errors.footer=</ul></p>
如果在注冊時用戶對用戶名輸入了空白,對余額輸入零,則用戶將接收到一個包括兩個錯誤的列表的屏幕:
The Action failed because of the following reason(s):
o You must enter a User ID.
o Your account must start with a positive balance.
可以為標記<html:errors/>指定屬性以支持國際化或者只顯示有關指定了給定屬性值的錯誤的信息。通過使用相異屬性值,可以在相鄰的不同字段中顯示每條錯誤消息而不是將所有錯誤置于單個列表中。
要定義應用程序的邏輯流程,成熟的經(jīng)驗是推薦在代碼之外,用配置的方法來實現(xiàn),而不是寫死在程序代碼中的。在J2EE中,這樣的例子比比皆是。從實現(xiàn)EJB的安全性和事務性行為到描述JMS消息和目的地之間的關系,很多運行時的處理流程都是可以在程序之外定義的。
Struts 創(chuàng)建者從一開始就采用這種方法,通過配置Struts的配置文件來定制應用系統(tǒng)運行時的各個方面。這一點在版本1.1的新特性上得到延續(xù),包括新的異常處理功能。在Struts framework以前的版本中,開發(fā)人員不得不自己處理Struts應用中發(fā)生的錯誤情況。在最新的版本中,情況大大的改觀了,Struts Framework提供了內(nèi)置的一個稱為 ExceptionHandler 的類,用于系統(tǒng)缺省處理action類運行中產(chǎn)生的錯誤。這也是在上一個技巧中我們提到的framework許多可擴展接口之一。
Struts缺省的 ExceptionHandler類會生成一個ActionError對象并保存在適當?shù)姆秶╯cope)對象中。這樣就允許JSP頁面使用錯誤類來提醒用戶出現(xiàn)什么問題。如果你認為這不能滿足你的需求,那么可以很方便的實現(xiàn)你自己的ExcepionHandler類。
具體定制異常處理的方法和機制
要定制自己的異常處理機制,第一步是繼承org.apache.struts.action.ExceptionHandler類。這個類有2個方法可以覆蓋,一個是excute()另外一個是storeException(). 在多數(shù)情況下,只需要覆蓋其中的excute()方法。下面是ExceptionHandler類的excute()方法聲明:
正如你看到的,該方法有好幾個參數(shù),其中包括原始的異常。方法返回一個ActionForward對象,用于異常處理結(jié)束后將controller類帶到請求必須轉(zhuǎn)發(fā)的地方去。
當然您可以實現(xiàn)任何處理,但一般而言,我們必須檢查拋出的異常,并針對該類型的異常進行特定的處理。缺省的,系統(tǒng)的異常處理功能是創(chuàng)建一個出錯信息,同時把請求轉(zhuǎn)發(fā)到配置文件中指定的地方去。定制異常處理的一個常見的例子是處理嵌套異常。假設該異常包含有嵌套異常,這些嵌套異常又包含了其他異常,因此我們必須覆蓋原來的execute()方法,對每個異常編寫出錯信息。
一旦你創(chuàng)建了自己的ExceptionHandler 類,就應該在Struts配置文件中的部分聲明這個類,以便讓Struts知道改用你自定義的異常處理取代缺省的異常處理.
可以配置你自己的ExceptionHandler 類是用于Action Mapping特定的部分還是所有的Action對象。如果是用于Action Mapping特定的部分就在元素中配置。如果想讓這個類可用于所有的Action對象,可以在 元素中指定。例如,假設我們創(chuàng)建了異常處理類CustomizedExceptionHandler用于所有的Action類, 元素定義如下所示:
在元素中可以對很多屬性進行設置。在本文中,最重要的屬性莫過于handler屬性, handler屬性的值就是自定義的繼承了ExceptionHandler類的子類的全名。假如該屬性沒有定義,Struts會采用自己的缺省值。當然,其他的屬性也很重要,但如果想覆蓋缺省的異常處理的話,handler無疑是最重要的屬性。
最后必須指出的一點是,你可以有不同的異常處理類來處理不同的異常。在上面的例子中,CustomizedExceptionHandler用來處理任何java.lang.Exception的子類. 其實,你也可以定義多個異常處理類,每一個專門處理不同的異常樹。下面的XML片斷解釋了如何配置以實現(xiàn)這一點。
在這里,一旦有異常拋出,struts framework將試圖在配置文件中找到ExceptionHandler,如果沒有找到,那么struts將沿著該異常的父類鏈一層層往上找直到發(fā)現(xiàn)匹配的為止。因此,我們可以定義一個層次型的異常處理關系結(jié)構(gòu),在配置文件中已經(jīng)體現(xiàn)了這一點。
Application Modules)
Struts 1.1的一個新特性是應用模塊的概念。應用模塊允許將單個Struts應用劃分成幾個模塊,每個模塊有自己的Struts配置文件,JSP頁面,Action等等。這個新特性是為了解決大中型的開發(fā)隊伍抱怨最多的一個問題,即為了更好的支持并行開發(fā)允許多個配置文件而不是單個配置文件。
顯然,當很多開發(fā)人員一起參加一個項目時,單個的Struts配置文件很容易引起資源沖突。應用模塊允許Struts按照功能要求進行劃分,許多情況已經(jīng)證明這樣更貼近實際。例如,假設我們要開發(fā)一個典型的商店應用程序??梢詫⒔M成部分劃分成模塊比如catalog(商品目錄), customer(顧客), customer service(顧客服務), order(訂單)等。每個模塊可以分布到不同的目錄下,這樣各部分的資源很容易定位,有助于開發(fā)和部署。圖1 顯示了該應用的目錄結(jié)構(gòu)。
一個典型的商店應用程序的目錄結(jié)構(gòu)
注:如果你無需將項目劃分成多個模塊,Struts框架支持一個缺省的應用模塊。這就使得應用程序也可以在1.0版本下創(chuàng)建,具有可移植性,因為應用程序會自動作為缺省的應用模塊。
為了使用多應用模塊功能,必須執(zhí)行以下幾個準備步驟:
· 為每個應用模塊創(chuàng)建獨立的Struts配置文件。
· 配置Web 部署描述符 Web.xml文件。
· 使用org.apache.struts.actions.SwitchAction 來實現(xiàn)程序在模塊之間的跳轉(zhuǎn).
創(chuàng)建獨立的Struts配置文件
每個Struts應用模塊必須擁有自己的配置文件。允許創(chuàng)建自己的獨立于其他模塊的Action,ActionForm,異常處理甚至更多。
繼續(xù)以上面的商店應用程序為例,我們可以創(chuàng)建以下的配置文件:一個文件名為struts-config-catalog.xml,包含catalog(商品目錄)、items(商品清單)、和其它與庫存相關的功能的配置信息;另一個文件名為struts- config-order.xml, 包含對order(訂單)和order tracking(訂單跟蹤)的設置。第三個配置文件是struts-config.xml,其中含有屬于缺省的應用模塊中的一般性的功能。
在為每個應用模塊創(chuàng)建獨立的配置文件之后,我們就有可能需要調(diào)用不同的模塊中Action。為此必須使用Struts框架提供的SwitchAction類。Struts 會自動將應用模塊的名字添加到URL,就如Struts 自動添加應用程序的名字加到URL一樣。應用模塊是對框架的一個新的擴充,有助于進行并行的團隊開發(fā)。如果你的團隊很小那就沒必要用到這個特性,不必進行模塊化。當然,就算是只有一個模塊,系統(tǒng)還是一樣的運作。
JSP放到WEB-INF后以保護JSP源代碼
為了更好地保護你的JSP避免未經(jīng)授權(quán)的訪問和窺視, 一個好辦法是將頁面文件存放在Web應用的WEB-INF目錄下。
通常JSP開發(fā)人員會把他們的頁面文件存放在Web應用相應的子目錄下。一個典型的商店應用程序的目錄結(jié)構(gòu)如圖2所示。跟catalog (商品目錄)相關的JSP被保存在catalog子目錄下。跟customer相關的JSP,跟訂單相關的JSP等都按照這種方法存放。
基于不同的功能 JSP 被放置在不同的目錄下
這種方法的問題是這些頁面文件容易被偷看到源代碼,或被直接調(diào)用。某些場合下這可能不是個大問題,可是在特定情形中卻可能構(gòu)成安全隱患。用戶可以繞過Struts的controller直接調(diào)用JSP同樣也是個問題。
為了減少風險,可以把這些頁面文件移到WEB-INF 目錄下。基于Servlet的聲明,WEB-INF不作為Web應用的公共文檔樹的一部分。因此,WEB-INF 目錄下的資源不是為客戶直接服務的。我們?nèi)匀豢梢允褂肳EB-INF目錄下的JSP頁面來提供視圖給客戶,客戶卻不能直接請求訪問JSP。
采用前面的例子,圖3顯示將JSP頁面移到WEB-INF 目錄下后的目錄結(jié)構(gòu)
JSP存放在 WEB-INF 目錄下更為安全
如果把這些JSP頁面文件移到WEB-INF 目錄下,在調(diào)用頁面的時候就必須把"WEB-INF"添加到URL中。例如,在一個Struts配置文件中為一個logoff action寫一個Action mapping。其中JSP的路徑必須以"WEB-INF"開頭。如下所示:請注意粗體部分.
這個方法在任何情況下都不失為Struts實踐中的一個好方法。是唯一要注意的技巧是你必須把JSP和一個Struts action聯(lián)系起來。即使該Action只是一個很基本的很簡單JSP,也總是要調(diào)用一個Action,再由它調(diào)用JSP。
最后要說明的是,并不是所有的容器都能支持這個特性。WebLogic早期的版本不能解釋Servlet聲明,因此無法提供支持,據(jù)報道在新版本中已經(jīng)改進了??傊褂弥跋葯z查一下你的Servlet容器。
Prebuilt Action類提升開發(fā)效率
Struts framework帶有好幾個prebuilt Action類,使用它們可以大大節(jié)省開發(fā)時間。其中最有用的是org.apache.struts.actions.ForwardAction 和 org.apache.struts.actions.DispatchAction.
使用 ForwardAction
在應用程序中,可能會經(jīng)常出現(xiàn)只要將Action對象轉(zhuǎn)發(fā)到某個JSP的情況。在上一點中曾提到總是由Action調(diào)用JSP是個好習慣。如果我們不必在Action中執(zhí)行任何業(yè)務邏輯,卻又想遵循從Action訪問頁面的話,就可以使用ForwardAction,它可以使你免去創(chuàng)建許多空的Action類。運用ForwardAction的好處是不必創(chuàng)建自己的Action類,你需要做的僅僅是在Struts配置文件中配置一個Action mapping。
舉個例子,假定你有一個JSP文件index.jsp ,而且不能直接調(diào)用該頁面,必須讓程序通過一個Action類調(diào)用,那么,你可以建立以下的Action mapping來實現(xiàn)這一點:
正如你看到的,當 /home 被調(diào)用時, 就會調(diào)用ForwardAction 并把請求轉(zhuǎn)發(fā)到 index.jsp 頁面.
再討論一下不通過一個Action類直接轉(zhuǎn)發(fā)到某個頁面的情況,必須注意我們?nèi)匀皇褂迷刂械膄orward屬性來實現(xiàn)轉(zhuǎn)發(fā)的目標。這時元素定義如下:
以上兩種方法都可以節(jié)省你的時間,并有助于減少一個應用所需的文件數(shù)。
使用 DispatchAction
DispatchAction是Struts包含的另一個能大量節(jié)省開發(fā)時間的Action類。與其它Action類僅提供單個execute()方法實現(xiàn)單個業(yè)務不同,DispatchAction允許你在單個Action類中編寫多個與業(yè)務相關的方法。這樣可以減少Action類的數(shù)量,并且把相關的業(yè)務方法集合在一起使得維護起來更容易。
要使用DispatchAction的功能,需要自己創(chuàng)建一個類,通過繼承抽象的DispatchAction得到。對每個要提供的業(yè)務方法必須有特定的方法signature。例如,我們想要提供一個方法來實現(xiàn)對購物車添加商品清單,創(chuàng)建了一個類ShoppingCartDispatchAction提供以下的方法:
那么,這個類很可能還需要一個deleteItem()方法從客戶的購物車中刪除商品清單,還有clearCart()方法清除購物車等等。這時我們就可以把這些方法集合在單個Action類,不用為每個方法都提供一個Action類。
在調(diào)用ShoppingCartDispatchAction里的某個方法時,只需在URL中提供方法名作為參數(shù)值。就是說,調(diào)用addItem()方法的 URL看起來可能類似于:
http://myhost/storefront/action/cart?method=addItem
其中method參數(shù)指定ShoppingCartDispatchAction中要調(diào)用的方法。參數(shù)的名稱可以任意配置,這里使用的"method"只是一個例子。參數(shù)的名稱可以在Struts配置文件中自行設定。
標記庫
標記
Struts提供了用來封裝邏輯的各種定制JSP標記,因此頁面設計者可以將主要精力花在頁面的可視特征上,而不必主要考慮Java語法或其它JSP語法,在下列標識庫描述符中引用了Struts標記:
Struts-bean.tld
使訪問bean以及新bean的定義更容易,,為了實現(xiàn)國際化,應使用不同的屬性文件
struts-html.tld
提供顯示HTML對象(例如,表單、按鈕和復選框)的簡便方法
struts-logic.tld
支持邏輯構(gòu)造,以便可以有條件地顯示文本或者作為處理循環(huán)的結(jié)果來顯示文本
struts-template.tld
支持使用在運行時可以修改的JSP模板
要在JSP文件頂部的<taglib>偽指令如下所示:
<%@ taglib uri=“struts-html. tld” prefix=“html”%>
<%@ taglib uri=“struts-bean.tld”prefix=“bean”%>
<%@ taglib uri=“struts-logic.tld”prefix=“logic”%>
每個<taglib>偽指令都具有與基于 web.xml的< taglib>標記中的URL相匹配的URL。另外JSP中的每個 struts標記都使用一個使標記與特定標記庫描述符相關的前綴:
― 沒有嵌套內(nèi)容的標記可以采用以下格式:
<prefix:tagName attributesAndValues/>
― 嵌套內(nèi)容是在一對標記之間嵌套的:
<prefix:tagName attributesAndValues />
</prefix:tagName>
prefix
在JSP taglib偽指令中指定的前綴
tagName
標記的名稱,如標記庫描述符中所述;描述符條目指定提供標記邏輯的Jave類
attributesAndValues
― 系列屬性與值的配對(是必需的或者是可選的),每個配對都包括一種屬性、一個等號(沒有前導或結(jié)尾空白)和一個引起來的字符串
文件resource.jsp包含bean:message標記的幾個實例。以下是標記的示例用法:
<bean:message key=“market. text. title”/>
在最簡單的情況下,bean:message標記解析為存儲在根據(jù)屬性文件創(chuàng)建的資源束中的字符串:
― 屬性文件的名稱是用來調(diào)用ActoinServlet的web.xml “application”參數(shù)的值。如:
\WEB-INF\classes\ApplicationResources.properties
― 消息標記中的key屬性指向?qū)傩晕募械?#8220;鍵-字符串”對;在本例中,指向下面的“鍵-字符串”對:
market. text.title=Current Market Conditions
可以采用各種方法來定制bean:message標記,以便(例如)JSP在運行時引用不同的屬性文件。標記提供了一種方法來支持多種語言以及最多將四個替代值插入到字符串中來代替{0}、{1}等等。
l         僅當指定的對象或值存在時,logic:present 標記才會導致顯示嵌套的文本。在register.jsp中,僅當操作類創(chuàng)建了作為 tickerBean引用(在任何作用域中)的 Java bean 時才為用戶提供HTML表行。 Struts標記為如下所示:
<logic:present name=“tickerBean”>
-->nested content for presentation<--
</logic:present>
l         Struts標記允許很方便地訪問Java bean內(nèi)容。例如,以下標記將解析為存儲在 tickerBean中的值:
<bean:write name=  “tickerBean”property=“DJChange”/>
tickerBean的源代碼在以下目錄中:
Trade\Java Source\tradeCommon\tickerBean.java
l         HTML表單與表單bean之間的數(shù)據(jù)傳送是通過使用html:form 和html:text標記來完成的。 register.jsp中的輸入表單是按如下所示構(gòu)建的:
<html:form action= “/register”>
-->nested form content with html: text tags<--
</html:form action>
html:form 標記解析為HTML FORM 標記并導致html: text 標記引用適當?shù)谋韱蝏ean;特別是在 path=“/register”的 Struts配置文件的 <action>標記中標識的表單 bean。
html:text標記建立HTML輸入字段。例如,以下標記確保在HTML輸入字段與表單bean的用戶名字段之間傳送信息:
<html:text property=“username”size=“40”/>
JSP視窗組件所使用的 struts標記庫由四類標記組成:
l         Bean標記:用來在JSP頁中管理bean
l         邏輯標記:用來在JSP頁中控制流程
l         HTML標記:用來生成HTML標記,在表單中顯示數(shù)據(jù),使用會話ID對URL進行編程
l         模板標記:使用動態(tài)模板構(gòu)造普通格式的頁
標記
這個標記庫中包含用于定義新bean、訪問bean及其屬性的標記。Struts框架提供了多種自定義標記用來在JSP頁中處理JavaBean。這些標記被封裝在一個普通的標記庫中,在文件struts-bean.tld中定義了它的標記庫描述器。Bean標記庫將標記定義在四個子類別中:
l         創(chuàng)建和復制bean的標記
l         腳本變量定義標記
l         bean翻譯標記
l         消息國際化標記
復制標記
可定義新bean,可復制現(xiàn)有bean,還可從現(xiàn)有bean復制屬性。
<bean:define>標記用來:
l         定義新字符串常數(shù)
l         將現(xiàn)有的bean復制到新定義的bean對象
l         復制現(xiàn)有bean的屬性來創(chuàng)建新的bean
<bean:define>標記屬性:
屬性
描述
Id
新定義的bean腳本變量名稱,必須設置
Type
定義引入腳本變量的類
Value
為id屬性定義的腳本變量分配一個新的對象
Name
目標bean的名稱。若value屬性沒有設置,這個屬性就必須設置
property
Name屬性定義的bean的屬性名稱,用來定義新的bean
Scope
源bean的作用域。若沒有設置,搜索范圍是從頁作用域到應用程序作用域
toScope
目標bean的作用域。若沒有設置,默認值是頁作用域
例如:定義一個bean:
<bean:define id=”test” value=”this is a test”/>
源bean在頁作用域中被拷貝大哦請求作用域中的另一個bean:
<bean:define id=”targetBean” name=”sourceBean”
scope=”page” toScope=”request”/>
從多種資源中定義和生成腳本變量,這些資源包括cookie,請求參數(shù),HTTP標頭等等。屬性如下:
屬性
描述
Id
腳本變量和要定義的頁作用域?qū)傩缘拿Q
Name
cookie/標頭/參數(shù)的名稱
multiple
如果這個屬性設置了任意一個數(shù)值,所有匹配的cookie都會被積累并存儲到一個Cookie[](一個數(shù)組)類型的bean里。若無設置,指定cookie的第一個值將作為Cookie類型的值
Value
如果沒有匹配的cookie或數(shù)值,就返回這個屬性指定的默認值
例如:
<bean:cookie id=”myCookie” name=”userName”/>
腳本變量名稱是myCookie,用來創(chuàng)建這個屬性的cookie的名稱是userName。
<bean:header id=”myHeader” name=”Accept-Language”/>
腳本變量名稱是myHeader,請求標頭的名稱是Accept-Language.
<bean:parameter id=”myParameter” name=”myParameter”>
腳本變量名稱是myPatameter,它保存的請求參數(shù)的名稱也是myParameter.
<bean:include>標記將對一個資源的響應進行檢索,并引入一個腳本變量和字符串類型的頁作用域?qū)傩?。這個資源可以是一個頁,一個ActionForward或一個外部URL。與<jsp:include>的不同是資源的響應被存儲到一個頁作用域的bean中,而不是寫入到輸出流。屬性如下:
屬性
描述
Id
腳本變量和要定義的頁作用域?qū)傩缘拿Q
Page
一個內(nèi)部資源
forward
一個ActionForward
Href
要包含的資源的完整URL
例如:
<bean:include id=”myInclude” page=”MyJsp?x=1”/>
腳本變量的名稱是myInclude,要檢索的響應來自資源MyJsp?x=1。
<bean:resource>標記將檢索web應用中的資源,并引入一個腳本變量和InputStream或字符串類型的頁作用域?qū)傩?。如果在檢索資源時發(fā)生問題,就會產(chǎn)生一個請求時間異常。屬性如下:
屬性
描述
Id
腳本變量和要定義的頁作用域?qū)傩缘拿Q
Name
資源的相對路徑
Input
如果這個屬性不存在,資源的類型就是字符串
例如:
<bean:resource id=”myResource” name=”/WEB-INF/images/myResource.xml”/>
腳本變量的名稱是myResource,要檢索的資源的名稱是myResource.xml。
屬性
標記庫中定義了<bean:write>標記,用來將bean的屬性輸送到封裝的JSP頁寫入器。這個標記與<jsp:getProperty>類似,屬性如下:
屬性
描述
Name
要進行屬性顯示的bean的名稱
property
要顯示的屬性的名稱。如果這個屬性類有java.beans.PropertyEditor,getAsText()或toString 方法會被調(diào)用
Scope
Bean的作用域,若沒有設置,搜索范圍是從頁到應用程序作用域
Filter
如果設置true,屬性中的所有特殊HTML字符都將被轉(zhuǎn)化為相應的實體引用
Ignore
如果設置false,當發(fā)現(xiàn)屬性時會產(chǎn)生一個請求時間異常,否則返回null
例如:
<bean:write name=”myBean” property=”myProperty” scope=”request”
filter=”true”/>
myBean的屬性myProperty將會被顯示,作用域為請求,如果發(fā)現(xiàn)任何HTML特殊字符都將被轉(zhuǎn)化為相應的實體引用。
strtus框架支持國際化和本地化。用戶在他們的計算機中定義自己所在的區(qū)域,當web應用程序需要輸出一條消息時,它將引用一個資源文件,在這個文件中所有的消息都使用了適當?shù)恼Z言。一個應用程序可能提供了很多資源文件,每個文件提供了用不同語言編寫的消息。如果沒有找到所選語言的資源文件,就將使用默認的資源文件。
struts框架對國際化的支持是使用<bean:message>標記,以及使用java.util數(shù)據(jù)包中定義的Locale和ResourceBundle類來實現(xiàn)Java2平臺對這些任務的支持。Java.text.MessageFormat類定義的技術(shù)可以支持消息的格式。利用此功能,開發(fā)人員不需了解這些類的細節(jié)就可進行國際化和設置消息的格式。
用strtus實現(xiàn)國際化和本地化:
第一步要定義資源文件的名稱,這個文件會包含用默認語言編寫的在程序中會出現(xiàn)的所有消息。這些消息以“關鍵字-值”的形式存儲,如下:
error.validation.location = The entered location is invalid
這個文件需要存儲在類的路徑下,而且它的路徑要作為初始化參數(shù)傳送給ActionServlet作為參數(shù)進行傳遞時,路徑的格式要符合完整Java類的標準命名規(guī)范。比如,如果資源文件存儲在WEB-INF\classes目錄中,文件名是ApplicationResources.properties,那么需要傳遞的參數(shù)值是ApplicationResources。如果文件在WEB-INF\classes\com\test中,那么參數(shù)值就應該是com.test. ApplicationResources.
為了實現(xiàn)國際化,所有的資源文件必須都存儲在基本資源文件所在的目錄中。基本資源文件包含的是用默認地區(qū)語言-本地語言編寫的消息。如果基本資源文件的名稱是ApplicationResources.properties,那么用其他特定語言編寫的資源文件的名稱就應該是ApplicationResources_xx.properties(xx為ISO編碼,如英語是en)。因此這些文件應包含相同的關鍵字,但關鍵字的值是用特定語言編寫的。
ActionServlet的區(qū)域初始化參數(shù)必須與一個true值一起傳送,這樣ActionServlet就會在用戶會話中的Action.LOCALE_KEY關鍵字下存儲一個特定用戶計算機的區(qū)域?qū)ο蟆,F(xiàn)在可以運行一個國際化的web站點,它可以根據(jù)用戶計算機上的設置的區(qū)域自動以相應的語言顯示。
我們還可以使用特定的字符串來替換部分消息,就象用java.text.MessageFormat的方法一樣:
error.invalid.number = The number {0} is valid
我們可以把字符串{0}替換成任何我們需要的數(shù)字。<bean:message>標簽屬性如下:
屬性
描述
Key
資源文件中定義消息關鍵字
Locale
用戶會話中存儲的區(qū)域?qū)ο蟮膶傩悦Q。若沒有設置,默認值是Action.LOCALE_KEY
Bundle
在應用程序上下文中,存儲資源對象的屬性的名稱。如果沒有設置這個屬性,默認值是Action.MESSAGE_KEY
arg0
第一個替換參數(shù)值
arg1
第二個替換參數(shù)值
arg2
第三個替換參數(shù)值
arg3
第四個替換參數(shù)值
例如:資源文件中定義了一個消息:
info.myKey = The numbers entered are {0},{1},{2},{3}
我們可使用下面的消息標記:
這個信息標記輸出到JSP頁會顯示為:The numbers entered are 5,6,7,8
邏輯庫的標記能夠用來處理外觀邏輯而不需要使用scriptlet。Struts邏輯標簽庫包含的標記能夠有條件地產(chǎn)生輸出文本,在對象集合中循環(huán)從而重復地產(chǎn)生輸出文本,以及應用程序流程控制。它也提供了一組在JSP頁中處理流程控制的標記。這些標記封裝在文件名為struts-logic.tld的標記包中。邏輯標記庫定義的標記能夠執(zhí)行下列三個功能:
l         條件邏輯
l         重復
l         轉(zhuǎn)發(fā)/重定向響應
struts有三類條件邏輯。第一類可以比較下列實體與一個常數(shù)的大?。?div style="height:15px;">
l         cookie
l         請求參數(shù)
l         bean或bean的參數(shù)
l         請求標頭
以下列出了這一類標記:
標記
功能
<equal>
如果常數(shù)與被定義的實體相等,返回true
<notEqual>
如果常數(shù)與被定義的實體不相等,返回true
<greaterEqual>
如果常數(shù)大于等于被定義的實體,返回true
<lessEqual>
如果常數(shù)小于等于被定義的實體,返回true
<lessThan>
如果常數(shù)小于被定義的實體,返回true
<greaterThan>
如果常數(shù)大于被定義的實體,返回true
這一類的所有標記有相同的屬性
屬性
描述
Value
要進行比較的常數(shù)值
Cookie
要進行比較的HTTP cookie的名稱
Header
要進行比較的HTTP請求標頭的名稱
parameter
要進行比較的HTTP請求參數(shù)的名稱
Name
如果要進行比較的是bean或bean的屬性,則這個屬性代表bean的名稱
property
要進行比較的bean屬性的名稱
Scope
Bean的作用域,如果沒有指定作用域,則它的搜索范圍是從頁到應用程序
例如:
<logic:equal parameter=”name” value=”SomeName”>
The entered name is SomeName
</logic:equal>
判斷名為”name”的請求參數(shù)的值是否是”SomeName”。
<logic:greaterThan name=”bean” property=”prop” scope=”page” value=”7”>
The value of bean.Prop is greater than 7
</logic:greaterThan>
判斷在頁的作用域中是否有一個名為”bean”的bean,它有一個prop屬性,這個屬性的值是否大于7。如果這個屬性能夠轉(zhuǎn)化為數(shù)值,就進行數(shù)值比較,否則就進行字符串比較。
第二類條件標記定義了兩個標記:
l         <logic:present>
l         <logic:notPresent>
它們的功能是在計算標記體之前判斷特定的項目是否存在。標記的屬性和屬性值決定了要進行檢查的項目。
屬性
描述
Cookie
由這個屬性指定的cookie將被檢查是否存在
Header
由這個屬性指定的請求標頭將被檢查是否存在
parameter
由這個屬性指定的請求參數(shù)將被檢查是否存在
Name
如果沒有設置property屬性,那么有這個屬性指定的bean將被檢查是否存在。如果設置了,那么bean和bean屬性都將被檢查是否存在。
property
檢查有name屬性指定的bean中是否存在指定的屬性
Scope
如果指定了bean的名稱,這就是bean的作用域。如果沒有指定作用域,搜索的范圍從頁到應用程序作用域。
Role
檢查當前已經(jīng)確認的用戶是否屬于特殊的角色
User
檢查當前已經(jīng)確認的用戶是否有特定的名稱
例如:
<logic:notPresent name=”bean” property=”prop” scope=”page”>
The bean property bean.prop is present
</logic:notPresent>
標記判斷在頁作用域中是否存在一個名為”bean”的bean,這個bean有一個prop屬性。
第三類條件標記比較復雜,這些標記根據(jù)模板匹配的結(jié)果檢查標記體的內(nèi)容。換句話說,這些標記判斷一個指定項目的值是否是一個特定常數(shù)的子字符串:
l         <logic:match>
l         <logic:notMatch>
這些標記允許JSP引擎在發(fā)現(xiàn)了匹配或是沒有發(fā)現(xiàn)時計算標記主體。屬性如下:
屬性
描述
Cookie
要進行比較的HTTP cookie的名稱
Header
要進行比較的的HTTP標頭 的名稱
parameter
要進行比較的的HTTP請求參數(shù)的名稱
Name
若要對bean或bean的屬性進行比較,這個屬性是用戶指定bean的名稱
location
如果設置了這個屬性的值,將會在這個指定的位置(索引值)進行匹配
scope
如果對bean進行比較,這個屬性指定了bean的作用域。如果沒有設置這個參數(shù),搜索范圍是從頁到應用程序作用域
property
要進行比較的bean的屬性名稱
value
要進行比較的常數(shù)值
例如:
<logic:match parameter=”name” value=”xyz” location=”1”>
The parameter name is a sub-string of the string xyz from index 1
</logic:match>
標記檢查名為”name”的請求參數(shù)是否是”xyz”的子字符串,但是子字符串必須從”xyz”的索引位置1開始(也就是說子字符串必須是”y”或”yz”)。
在邏輯標記庫中定義了<logic:iterate>標記,它能夠根據(jù)特定集合中元素的數(shù)目對標記體的內(nèi)容進行重復的檢查。集合的類型可以是java.util.Iterator,java.util.Collection
,java.util.Map或是一個數(shù)組。有三種方法可以定義這個集合:
l         使用運行時間表達式來返回一個屬性集合的集合
l         將集合定義為bean,并且使用name屬性指定存儲屬性的名稱。
l         使用name屬性定義一個bean,并且使用property屬性定義一個返回集合的bean屬性。
當前元素的集合會被定義為一個頁作用域的bean。屬性如下,所有這些屬性都能使用運行時表達式。
屬性
描述
collection
如果沒有設置name屬性,它就指定了要進行重復的集合
Id
頁作用域bean和腳本變量的名稱,它保存著集合中當前元素的句柄
indexed
頁作用域JSP bean的名稱,它包含著每次重復完成后集合的當前索引
Length
重復的最大次數(shù)
Name
作為集合的bean的名稱,或是一個bean名稱,它由property屬性定義的屬性,是個集合
Offset
重復開始位置的索引
property
作為集合的Bean屬性的名稱
Scope
如果指定了bean名稱,這個屬性設置bean的作用域。若沒有設置,搜索范圍從頁到應用程序作用域
Type
為當前定義的頁作用域bean的類型
例如:
<logic:iterate id=”currentInt”
collection=”<% =myList %>”
type=”java.lang.Integer”
offset=”1”
length=”2”>
<% =currentint %>
</logic:iterate>
代碼將從列表中的第一個元素開始重復兩個元素并且能夠讓當前元素作為頁作用域和java.lang.Integer類型的腳本變量來使用。也就是說,如果myList包含元素1,2,3,4等,代碼將會打印1和2。
轉(zhuǎn)發(fā)標記
<logic:forward>標記能夠?qū)㈨憫D(zhuǎn)發(fā)給重定向到特定的全局ActionForward上。ActionForward的類型決定了是使用PageContext轉(zhuǎn)發(fā)響應,還是使用sendRedirect將響應進行重定向。此標記只有一個”name”屬性,用來指定全局ActionForward的名稱,例如:
<logic:forward name=”myGlobalForward”/>
重定向標記
<logic:redirect>標記是一個能夠執(zhí)行HTTP重定向的強大工具。根據(jù)指定的不同屬性,它能夠通過不同的方式實現(xiàn)重定向。它還允許開發(fā)人員指定重定向URL的查詢參數(shù)。屬性如下:
屬性
描述
Forward
映射了資源相對路徑的ActionForward
Href
資源的完整URL
Page
資源的相對路徑
Name
Map類型的頁名稱,請求,會話或程序?qū)傩缘拿Q,其中包含要附加大哦重定向URL(如果沒有設置 property屬性)上的“名稱-值”參數(shù)。或是具有Map類型屬性的bean名稱,其中包含相同的信息(沒有設置property屬性)
Property
Map類型的bean屬性的名稱。Bean的名稱由name屬性指定。
Scope
如果指定了bean的名稱,這個屬性指定搜索bean的范圍。如果沒有設置,搜索范圍從頁到應用程序作用域
ParamID
定義特定查詢參數(shù)的名稱
ParamName
字符串類型的bean的名稱,其中包含查詢參數(shù)的值(如果沒有設置paramProperty屬性);或是一個bean的名稱,它的屬性(在paramProperty屬性中指定)包含了查詢參數(shù)值
paramProperty
字符串bean屬性的名稱,其中包含著查詢參數(shù)的值
ParamScope
ParamName定義的bean的搜索范圍
使用這個標記時至少要指定forward,href或page中的一個屬性,以便標明將響應重定向到哪個資源。
標記
Struts HTML標記可以大致地分為以下幾個功能:
l         顯示表單元素和輸入控件
l         顯示錯誤信息
l         顯示其他HTML元素
struts將HTML表單與為表單操作而定義的ActionForm bean緊密聯(lián)系在一起。表單輸入字段的名稱與ActionForm bean里定義的屬性名稱是對應的。當?shù)谝淮物@示表單時,表單的輸入字段是從ActionForm bean中移植過來的,當表單被提交時,請求參數(shù)將移植到ActionForm bean實例。
所有可以在<form>標記中使用的用來顯示HTML輸入控件的內(nèi)嵌標記都使用下列屬性來定義JavaScript事件處理器。
屬性
描述
Onblur
字段失去了焦點
Onchange
字段失去了焦點并且數(shù)值被更改了
Onclick
字段被鼠標點擊
Ondblclick
字段被鼠標雙擊
Onfocus
字段接收到輸入焦點
Onkeydown
字段擁有焦點并且有鍵按下
onkeypress
字段擁有焦點并且有鍵按下并釋放
Onkeyup
字段擁有焦點并且有鍵被釋放
onmousedown
鼠標指針指向字段并且點擊
onmousemove
鼠標指針指向字段并且在字段內(nèi)移動
onmouseout
鼠標指針指向控件,但是指針在元素外圍移動
onmouseover
鼠標指針沒有指向字段,但是指針在元素內(nèi)部移動
Onmouseup
鼠標指針指向字段,并且釋放了鼠標按鍵
<form>元素中能夠被定義的其他一般屬性有:
屬性
描述
Accesskey
定義訪問輸入字段的快捷鍵
Style
定義輸入字段的樣式
styleClass
定義輸入字段的樣式表類
Tabindex
輸入字段的tab順序
表單標記
<html:form>標記用來顯示HTML標記,可以指定AcitonForm bean的名稱和它的類名。如果沒有設置這些屬性,就需要有配置文件來指定ActionMapping以表明當前輸入的是哪個JSP頁,以及從映射中檢索的bean名和類。如果在ActionMapping指定的作用域中沒有找到指定的名稱,就會創(chuàng)建并存儲一個新的bean,否則將使用找到的bean。
<form>標記能夠包含與各種HTML輸入字段相對應的子標記。
<html:form>標記屬性如下:
屬性
描述
Action
與表單相關的操作。在配置中,這個操作也用來標識與表單相關的ActionForm bean
Enctype
表單HTTP方法的編碼類型
Focus
表單中需要初始化焦點的字段
Method
表單使用的HTTP方法
Name
與表單相關的ActionForm bean的名稱。如果沒有設置這個屬性,bean的名稱將會從配置信息中獲得
Onreset
表單復位時的JavaScript事件句柄
Onsubmit
表單提交時的JavaScript事件句柄
Scope
搜索ActionForm bean的范圍。如果沒有設置,將從配置文件中獲取
Style
使用的格式
styleClass
這個元素的格式表類
Type
ActionForm bean的完整名稱。如果沒有設置,將從配置文件獲得
例如:
<html:form action=”validateEmploee.do” method=”post”>
</html:form>
與表單相關的操作路徑是validateEmployee,而表單數(shù)據(jù)是通過POST傳遞的。對于這個表單來說,ActionForm bean的其他信息,如bean名稱類型,作用域,都是從表單指定操作的ActionMapping中檢索得到的:
<form-bean name=”empForm” type=”com.example.EmployeeForm”/>
</form-beans>
<action-mappings>
<action path=”/validateEmployee”
type=”com.example.ValidateExampleAction”
name=”empForm”
scope=”request”
input=”/employeeInput.jsp”>
<forward name=”success” path=”/employeeOutput.jsp”>
</action>
</action-mapping>
如果配置文件中包含上述信息,并且請求URI的*.do被映射到ActionServlet,與表單相關的ActionForm bean的名稱,類型和作用域分別是empForm,com.example.EmployeeForm和request.這些屬性也可以使用<html:form>標記屬性進行顯示的定義。
以下標記必須嵌套在<html:form>標記里
按鈕和取消標記
<html:button>標記顯示一個按鈕控件;<html:cancel>標記顯示一個取消按鈕。屬性如下:
屬性
描述
Property
定義在表單被提交時返回到服務器的請求參數(shù)的名稱
Value
按鈕上的標記
復位和提交標記
<html:reset>和<html:submit>標記分別能夠顯示HTML復位按鈕和提交按鈕。
文本和文本區(qū)標記
<html:text>和<html:textarea>標記分別HTML文本框和文本區(qū),屬性如下:
屬性
描述
Property
定義當表單被提交時送回到服務器的請求參數(shù)的名稱,或用來確定文本元素當前值的bean的屬性名稱
Name
屬性被查詢的bean的名稱,它決定了文本框和文本區(qū)的值。如果沒有設置,將使用與這個內(nèi)嵌表單相關的ActionForm的名稱
<html:text>標記還有以下屬性:
屬性
描述
Maxlength
能夠輸入的最大字符數(shù)
Size
文本框的大?。ㄗ址麛?shù))
<html:textarea>標記特有的屬性如下:
屬性
描述
Rows
文本區(qū)的行數(shù)
Cols
文本區(qū)的列數(shù)
檢查框和復選框標記
<html:checkbox>標記能夠顯示檢查框控件。<html:multibox>標記能夠顯示HTML復選框控件,請求對象在傳遞檢查框名稱時使用的getParameterValues()調(diào)用將返回一個字符串數(shù)組。屬性如下:
屬性
描述
Name
Bean的名稱,其屬性會被用來確定檢查是否以選中的狀態(tài)顯示。如果沒有設置,將使用與這個內(nèi)嵌表單相關的ActionFrom bean的名稱。
Property
檢查框的名稱,也是決定檢查框是否以選中的狀態(tài)顯示的bean屬性名稱。在復選框的情況下,這個屬性必須是一個數(shù)組。
Value
當檢查框被選中時返回到服務器的請求參數(shù)的值
例如:
<html:checkbox property=”married” value=”Y”/>
一個名為married的檢查框,在表單提交時會返回一個”Y”.
文件標記
<html:file>標記可以顯示HTML文件控件。屬性如下:
屬性
描述
Name
Bean的名稱,它的屬性將確定文件控件中顯示的內(nèi)容。如果沒設置,將使用與內(nèi)嵌表單相關的ActionForm bean的名稱
property
這個屬性定義了當表單被提交時送回到服務器的請求參數(shù)的名稱,以及用來確定文件控件中顯示內(nèi)容的bean屬性名稱
Accept
服務器能夠處理的內(nèi)容類型集。它也將對客戶瀏覽器對話框中的可選文件類型進行過濾
Value
按鈕上的標記,這個按鈕能夠在本地文件系統(tǒng)中瀏覽文件
單選鈕標記
<html:radio>標記用來顯示HTML單選鈕控件,屬性如下:
屬性
描述
Name
Bean的名稱,其屬性會被用來確定單選鈕是否以選中的狀態(tài)顯示。如果沒有設置,將使用與這個內(nèi)嵌表單相關的ActionFrom bean的名稱。
property
當表單被提交時送回到服務器的請求參數(shù)的名稱,以及用來確定單選鈕是否以被選中狀態(tài)進行顯示的bean屬性的名稱
Value
當單選鈕被選中時返回到服務器的值
隱藏標記
<html:hidden>標記能夠顯示HTML隱藏輸入元素,屬性如下:
屬性
描述
Name
Bean的名稱,其屬性會被用來確定隱藏元素的當前值。如果沒有設置,將使用與這個內(nèi)嵌表單相關的ActionFrom bean的名稱。
property
定義了當表單被提交時送回到服務器的請求參數(shù)的名稱,以及用來確定隱藏元素當前值的bean屬性的名稱
Value
用來初始化隱藏輸入元素的值
密碼標記
<html:password>標記能夠顯示HTML密碼控件,屬性如下:
屬性
描述
maxlength
能夠輸入的最大字符數(shù)
Name
Bean的名稱,它的屬性將用來確定密碼元素的當前值。如果沒有設置,將使用與這個內(nèi)嵌表單相關的ActionFrom bean的名稱。
property
定義了當表單被提交時送回到服務器的請求參數(shù)的名稱,以及用來確定密碼元素當前值的bean屬性的名稱
redisplay
在顯示這個字段時,如果相應的bean屬性已經(jīng)被設置了數(shù)據(jù),這個屬性決定了是否顯示密碼的內(nèi)容
Size
字段的大小
選擇標記
<html:select>標記能夠顯示HTML選擇控件,屬性如下:
屬性
描述
multiple
表明這個選擇控件是否允許進行多選
Name
Bean的名稱,它的屬性確定了哪個。如果沒有設置,將使用與這個內(nèi)嵌表單相關的ActionFrom bean的名稱。
property
定義了當表單被提交時送回到服務器的請求參數(shù)的名稱,以及用來確定哪個選項需要被選中的bean屬性的名稱
Size
能夠同時顯示的選項數(shù)目
Value
用來表明需要被選中的選項
選項標記(這個元素需要嵌套在<html:select>標記里)
<html:option>標記用來顯示HTML選項元素集合,屬性如下:
屬性
描述
collection
Bean集合的名稱,這個集合存儲在某個作用域的屬性中。選項的數(shù)目與集合中元素的數(shù)目相同。Property屬性能夠定義選項值所使用的bean屬性,而labelProperty屬性定義選項標記所使用的bean的屬性
labelName
用來指定存儲于某個作用域的bean,這個bean是一個字符串的集合,能夠定義<html:option>元素的標記(如果標志與值不相同)
labelProperty
與collection屬性共同使用時,用來定義了存儲于某個作用域的bean,這個bean將返回一個字符串集合,能夠用來寫入<html:option>元素的value屬性
Name
如果這是唯一被指定的屬性,它就定義了存儲于某個作用域的bean,這個bean將返回一個字符串集合,能夠用來寫入<html:option>元素的value屬性
property
這個屬性在與collection屬性共同使用時,定義了每個要顯示選項值的獨立bean的name屬性。如果不是與collection屬性共同使用,這個屬性定義了由name屬性指定的bean的屬性名稱(如果有name屬性),或是定義了一個ActionForm bean,這個bean將返回一個集合來寫入選項的值
我們看一下這個標記的一些例子:
<html:option collection=”optionCollection” property=”optionValue”
labelProperty=”optionLabel”/>
標記假設在某個作用域中有一個名為optionCollection的集合,它包含了一些具有optionValue屬性的獨立的bean,每個屬性將作為一個選項的值。每個選項的標志由bean的optionLabel屬性屬性進行定義。
標記中optionValues代表一個存儲在某個作用域中的bean,它是一個字符串集合,能夠用來寫入選項的值,而optionLabels代表一個存儲在某個作用域中的bean,它也是一個字符串集合,能夠用來寫入選項的標志。
<html:errors>標記能夠與ActionErrors結(jié)合在一起來顯示錯誤信息。這個標記首先要從當前區(qū)域的資源文件中讀取消息關鍵字errors.header,然后顯示消息的文本。接下去它會在ActionErrors對象(通常作為請求參數(shù)而存儲在Action.ERROR_KEY關鍵字下)中循環(huán),讀取單個ActionError對象的消息關鍵字,從當前區(qū)域的資源文件中讀取并格式化相應的消息,并且顯示它們。然后它讀取與errors.footer關鍵字相對應的消息并且顯示出來。
通過定義property屬性能夠過濾要顯示的消息,這個屬性的值應該與ActionErrors對象中存儲ActionError對象的關鍵字對應。屬性如下:
屬性
描述
Bundle
表示應用程序作用域?qū)傩缘拿Q,它包含著消息資源,其默認值Acion.MESSAGE_KEY
Locale
表示會話作用域?qū)傩缘拿Q,它存儲著用戶當前登錄的區(qū)域信息。其默認值是Action.ERROR_KEY
Name
表示請求屬性的名稱,它存儲著ActionErrors對象。其默認值是Action.ERROR_KEY
property
這個屬性指定了ActionErrors對象中存儲每個獨立ActionError對象的關鍵字,它可以過濾消息
例子:
<html:errors/>
顯示集合中所有的錯誤。
<html:errors property=”missing.name”/>
顯示存儲在missing.name關鍵字的錯誤。
標記
struts HTML標記還定義了下列標記來顯示其他HTML元素:
l         <html:html> : 顯示HTML元素
l         <html:img> : 顯示圖象標記
l         <html:link> : 顯示HTML鏈接或錨點
l         <html:rewrite> : 創(chuàng)建沒有錨點標記的URI
這些標記的詳細內(nèi)容請參照struts文檔。
動態(tài)模板是模塊化WEB頁布局設計的強大手段。Struts模板標記庫定義了自定義標記來實現(xiàn)動態(tài)模板。
插入標記
<template:insert>標記能夠在應用程序的JSP頁中插入動態(tài)模板。這個標記只有一個template屬性,用來定義模板JSP頁。要插入到模板的頁是有多個<template:put>標記來指定的,而這些標記被定義為<template:insert>標記的主體內(nèi)容。
放置標記
<template:put>標記是<template:insert>標記內(nèi)部使用的,用來指定插入到模板的資源。屬性如下:
屬性
描述
content
定義要插入的內(nèi)容,比如一個JSP文件或一個HTML文件
direct
如果這個設置為true,由content屬性指定的內(nèi)容將直接顯示在JSP上而不是作為包含文件
Name
要插入的內(nèi)容的名稱
Role
如果設置了這個屬性,只有在當前合法用戶具有特定角色時才能進行內(nèi)容的插入。
獲得標記
在模板JSP頁中使用<template:get>標記能夠檢索由<template:put>標記插入到JSP頁的資源。屬性如下:
屬性
描述
Name
由<template:put>標記插入的內(nèi)容的名稱
Role
如果設置了這個屬性,只有在當前合法用戶具有特定角色時才能進行內(nèi)容的檢索
使用模板標記
首先編寫一個模板JSP頁,它將被所有的web頁使用:
<%@ taglib uri=”/template” prefix=”template” %>
<head>
<title></title>
</head>
<body>
<table width=”100%” height=”100%” >
<td>
<template:get name=”header”/>
</td>
</tr>
<tr height=”80%”>
<td>
<template:get name=”content”/>
</td>
</tr>
<tr height=”10%”>
<td>
<template:get name=”footer”/>
</td>
</tr>
</body>
我們將這個文件命名為template.jsp。這個文件使用<template:get>標記來獲得由JSP頁使用<template:put>標記提供的內(nèi)容,并且將內(nèi)容在一個HTML表格中顯示出來。這三個內(nèi)容是標題,內(nèi)容和頁腳。典型的內(nèi)容JSP會是這樣:
<%@ taglib uri=”/template” prefix=”/template” %>
<template:insert template=”template.jsp”>
<template:put name=”header” content=”header.html”/>
<template:put name=”content” content=”employeeList.jsp”/>
<template:put name=”footer” content=”footer.html”/>
這個應用程序JSP頁使用<template:insert標記來定義模板,然后使用<template:put>標記將特定內(nèi)容名稱指定的資源放到模板JSP頁中。如果我們有上百個布局相同的頁,但突然想改變這個模板,我們只需要改變template.jsp文件。
在這個指導中我們將step by step開發(fā)一個小的應用程序。你應該有一些JSP和XML的經(jīng)驗,并且有一個可以運行的應用服務器。
的安裝
請先將Struts.jar和所有相關common拷貝到你應用程序的lib目錄中,不用刪除你的struts目錄中的其他文件。結(jié)果如圖1所示。
現(xiàn)在我們要做一個簡單的JSP頁,用來確認至此我們的操作是正確的。
在strutsShop里建一個BookView.jsp的文件。內(nèi)容如下,按圖2所示在瀏覽器中運行:
的國際化
我們將使用戶能用本國的語言瀏覽預定義的文本,進而接觸一些struts的功能。首先你要按照圖3拷貝一些文件到WEB-INF目錄下。在struts-html.tld文件里有我們要用的標簽。這些我們在上接已經(jīng)介紹了,你可以簡短的回顧一下。
struts-config.xml的配置清單如下,這是一個標準的清單,你以后的程序都可以以此為基礎進行擴展:
web.xml的配置清單如下,這是一個標準的清單,你以后的程序都可以以此為基礎進行擴展:
在classes目錄下創(chuàng)建一個ApplicationResources.properties的文件(此文件名在web.xml中定義),打開它,輸入一行:index.title=Struts Tutorial。然后在創(chuàng)建一個ApplicationResources_de.properties文件,也輸入一行:index.title=Struts Einführung。其實這兩個文件就是當加載時會根據(jù)當前的瀏覽器而選擇英文或德文,這里我們只能了解國際化過程來測試前者了。我們還需編寫B(tài)ookView.jsp文件,如下:
可在瀏覽器中瀏覽,你可能需要重啟你的tomcat:
其實我們可以將國際化寫在一個文件中,就是將參數(shù)寫在一個屬性文件中。(這是作者的意圖,但我沒有各種版本的IE進行實驗)
中的Forms
在這一章我們將創(chuàng)建一個簡單的Bean(Book.java)和兩個JSP頁面,一個是創(chuàng)建新書的,另一個是顯示它的,我們也會第一次使用struts-config.xml文件。
我們先在你的classes目錄下創(chuàng)建如下Book.java文件。
我們還需要創(chuàng)建新書的JSP頁。我們將使用title,auther和number of pages三個字段,在此之前我們先要做一些工作,對于一個初學者這將有些難度。在你的BookView中加上以下內(nèi)容:
再次運行,你將得到圖5所示內(nèi)容,如果沒有錯,那你需要重啟tomcat;如果錯誤不一樣,沒關系,因為他都是沒有在配置文件中找到mapping路徑。
接下來我們需要第二個JSP頁面CreateBook.jsp,代碼如下:
在classes目錄下創(chuàng)建一個BookAction文件:
它沒按照struts要求編寫僅僅創(chuàng)建一本書并給它標題。然后編寫你的struts-config.xml:
我們希望在struts中在bookForm和Book間建立連接。而且我們還用bookCreated定義了一個到BookView.jsp的轉(zhuǎn)發(fā)。最后我們用action=createBook.do屬性定義了我們的form做什么。關于do:與接受CreateBook.jsp輸入信息的bookForm相關的bean,由createBook命令創(chuàng)建。
按圖6編譯你的類。由于我是初手,在這里遇見很多問題,所以耽誤了很久,不過它讓你學到很多東東。比如:javax.servlet要用到servlet.jar包;javac后跟a.java, 而java后跟a;還有我遇見了很原文提到的問題,很多都是由于自己編寫(沒有copy)而造成的馬虎。希望大家也能引起注意,到此除了ActionForm我們都已用到了。
編譯成功后,在你的classes目錄下會增加兩個文件:Book.class和BookAction.class.
重啟你的tomcat(每次改動config文件你都需要重啟,改動注冊表需要重啟機器)?,F(xiàn)在在你的瀏覽器里登陸CreateBook.jsp,如圖7:
當你填寫后提交,另你失望的是什么也沒有得到。這是由于我們并沒有ActionForm bean.
介紹ActionForm
這節(jié)我們繼續(xù)做ActionForm bean來完成我們的例子。我們將用ActionForm得到合法的book的信息,并進行一些檢驗,例如沒有輸入標題等,向用戶提供錯誤或成功的信息。我們還將得到book的屬性并且能夠更改它。
為此我們需要一個ActionForm:它僅是一個簡單的容器,沒有應用程序邏輯,只有兩個方法:reset(),validate().在struts1.1里,validate()方法被單獨作為一個validate.xml文件。詳見參考資料二。
現(xiàn)在我們做另一個類:BookForm.java。它將包含book的實例,并且有一些getXXX和setXXX的方法來訪問它。關于內(nèi)部的方法可看struts架構(gòu)介紹。
我們還要做一些額外的工作。去看struts-config.xml文件,我們需要用這個新類與Form關聯(lián),從而替代Book.java。因此我們必須改變form-beans: <form-bean name="bookForm" type="BookForm"/>.
另外我們還有定義一下當錯誤發(fā)生時的信息,在你的配置文件中輸入:error.book.title=Error
現(xiàn)在編譯你的類,重新啟動tomcat,重新登陸CreateBook.jsp.,輸入onebook,你將在tomcat的dos窗口看見如下圖所示:
你也可以在重輸入其他的title,看看tomcat的dos窗口有什么變化。
和BookForm的一個好方法
上一節(jié)我們使用一個新類BookForm.java去訪問Book.java,而不用struts直接連接到Book.java。接下來,我們要解決在這兩個類中重復輸入getXXX和setXXX。Struts允許我們直接訪問實例的方法。這很容易,但需要理解。我們給出改變的CreateBook.jsp的代碼:
正如你看到的,除了將title改為book.title,我們什么也沒做?,F(xiàn)在你可以去掉BookForm.java中的getXXX和setXXX方法了,如下圖:(別忘記了也更改BookView.jsp,否則在你的tomcat窗口下After creation of book : null)
你還應該改動BookAction.java,把String title = req.getParameter("title");中的title改為book.title,然后重新編譯,這樣你的tomcat下的After creation of book :none中的none就會出現(xiàn)你輸入的名了。
本站僅提供存儲服務,所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Struts標記庫
java面試-ssh-1
創(chuàng)建JSP文件和ActionForm Bean
【轉(zhuǎn)】struts1標簽庫
Struts用戶手冊翻譯(1)
【使用 struts portlet 在門戶應用程序中實現(xiàn)頁面導航】
更多類似文章 >>
生活服務
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服