欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

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

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久