隨筆-13  評(píng)論-12  文章-1  trackbacks-0

           

           

           

          Struts教程

           

           

          目錄

           

          概述... 4

          Framework概念... 4

          Struts的概念和體系結(jié)構(gòu)... 5

          Struts的與Web App的關(guān)系... 5

          Struts的體系結(jié)構(gòu)... 5

          從視圖角度(View... 6

          從模型角度(Model... 6

          從控制器角度(Controller... 6

          Struts的基本組件包... 6

          Struts framework的工作原理和組件... 7

          Struts ActionServlet控制器對(duì)象... 8

          Struts Action Classes. 8

          Struts Action Mapping. 9

          使用ActionForward導(dǎo)航... 10

          Struts ActionForm Bean捕獲表單數(shù)據(jù)... 11

          Struts的其他組件... 12

          Validation Framework for Struts. 12

          Struts TagLib. 12

          BeanUtils. 12

          Collections. 13

          Digester 13

          Struts配置文件簡(jiǎn)介... 13

          有關(guān)Struts Controller及其相關(guān)的的配置描述... 13

          有關(guān)struts tag lib的配置描述... 14

          有關(guān)Struts Action Mapping的配置描述... 14

          Form-bean元素... 15

          Action元素... 15

          Struts高級(jí)特性(Struts Advanced Feature... 17

          驗(yàn)證... 17

          使用異常處理聲明... 19

          使用應(yīng)用模塊(Application Modules... 21

          JSP放到WEB-INF后以保護(hù)JSP源代碼... 22

          使用 Prebuilt Action類提升開發(fā)效率... 23

          Struts標(biāo)記庫(kù)... 25

          定制JSP標(biāo)記... 25

          資源束... 26

          Bean標(biāo)記... 27

          Bean復(fù)制標(biāo)記... 27

          定義腳本變量的標(biāo)記... 28

          顯示Bean屬性... 29

          消息標(biāo)記和國(guó)際化... 29

          邏輯標(biāo)記... 30

          條件邏輯... 30

          重復(fù)標(biāo)記... 32

          轉(zhuǎn)發(fā)和重定向標(biāo)記... 33

          HTML標(biāo)記... 34

          顯示表單元素和輸入控件... 34

          顯示錯(cuò)誤信息的標(biāo)記... 38

          其他HTML標(biāo)記... 39

          模板標(biāo)記... 39

          一個(gè)簡(jiǎn)單的示例... 41

          Struts的安裝... 41

          第一個(gè)實(shí)驗(yàn):簡(jiǎn)單的JSP頁(yè)... 41

          第二個(gè)實(shí)驗(yàn):struts的國(guó)際化... 42

          struts中的Forms. 45

          struts:介紹ActionForm.. 49

          分離BookBookForm的一個(gè)好方法... 51

           

          概述

              本文主要講解什么是Struts Framework,它的框架結(jié)構(gòu),組件結(jié)構(gòu),以及簡(jiǎn)單的配置講解。

          文章的包括了如下七大部分:

          Framework的概念和體系簡(jiǎn)介

          Struts的概念和體系結(jié)構(gòu)

          Struts的工作原理和組件

          Struts配置文件簡(jiǎn)介

          Struts高級(jí)特性

          Struts標(biāo)記庫(kù)

          一個(gè)簡(jiǎn)單的示例

          Framework概念

          一直以來我們都說Struts是一個(gè)Web Framework。那么讓我么先來看看什么是Framework

          Framework概念并不是很新了,伴隨著軟件開發(fā)的發(fā)展,在多層的軟件開發(fā)項(xiàng)目中,可重用、易擴(kuò)展的,而且是經(jīng)過良好測(cè)試的軟件組件,越來越為人們所青睞。這意味著人們可以將充裕的時(shí)間用來分析、構(gòu)建業(yè)務(wù)邏輯的應(yīng)用上,而非繁雜的代碼工程。于是人們將相同類型問題的解決途徑進(jìn)行抽象,抽取成一個(gè)應(yīng)用框架。這也就是我們所說的Framework

              Framework的體系提供了一套明確機(jī)制,從而讓開發(fā)人員很容易的擴(kuò)展和控制整個(gè)Framework開發(fā)上的結(jié)構(gòu)。 通常,Framework的結(jié)構(gòu)中都有一個(gè)“命令和控制”組件("command and control" component)——Framework Factory and Manager

          Framework體系

           

                 通過基于請(qǐng)求響應(yīng)(Request-Response)模式的應(yīng)用Framework,基本上有如下幾個(gè)表現(xiàn)邏輯結(jié)構(gòu)組成。

          控制器Controller)——控制整個(gè)Framework中各個(gè)組件的協(xié)調(diào)工作。

          業(yè)務(wù)邏輯層Business Logic)——對(duì)Framwork本身來說,這里僅僅只是概念和幾個(gè)提夠服務(wù)的基礎(chǔ)組件,真正的實(shí)現(xiàn)與客戶的業(yè)務(wù)邏輯接軌,還需要開發(fā)人員在Framework上再次擴(kuò)展。

          數(shù)據(jù)邏輯層Data Logic)——絕大應(yīng)用系統(tǒng)都需要涉及到數(shù)據(jù)交互,這一層次主要包括了數(shù)據(jù)邏輯和數(shù)據(jù)訪問接口。對(duì)于數(shù)據(jù)邏輯來說,如果你了解數(shù)據(jù)建模(Data Modeling)可能就很容易理解。   

           

          Struts的概念和體系結(jié)構(gòu)

          Struts有一組相互協(xié)作的類、Serlvet以及Jsp TagLib組成。基于Struts構(gòu)架的web應(yīng)用程序基本上符合JSP Model2的設(shè)計(jì)標(biāo)準(zhǔn),可以說是MVC設(shè)計(jì)模式的一種變化類型。根據(jù)上面對(duì)framework的描述,我們很容易理解為什么說Struts是一個(gè)web framwork,而不僅僅是一些標(biāo)記庫(kù)的組合。但 Struts 也包含了豐富的標(biāo)記庫(kù)和獨(dú)立于該框架工作的實(shí)用程序類。

          Struts有其自己的控制器(Controller),同時(shí)整合了其他的一些技術(shù)去實(shí)現(xiàn)模型層(Model)和視圖層(View)。在模型層,Struts可以很容易的與數(shù)據(jù)訪問技術(shù)相結(jié)合,包括EJB,JDBCObject Relation Bridge。在視圖層,Struts能夠與JSP, Velocity Templates,XSL等等這些表示層組件想結(jié)合。

          Struts的與Web App的關(guān)系


          既然struts叫做web framework,那么其肯定主要基于web層的應(yīng)用系統(tǒng)開發(fā)。按照J2EE Architecture的標(biāo)準(zhǔn),struts應(yīng)當(dāng)和jsp/servlet一樣,存在于web container一層。

          StrutsWebApp的關(guān)系

           

          Struts的體系結(jié)構(gòu)

              我們說struts frameworkMVC 模式的體現(xiàn),下面我們就從分別從模型、視圖、控制來看看struts的體系結(jié)構(gòu)(Architecture)。下圖顯示了struts framework的體系結(jié)構(gòu)響應(yīng)客戶請(qǐng)求時(shí)候,各個(gè)部分工作的原理。


          Struts體系結(jié)構(gòu)

                從視圖角度(View

          首先,Struts提供了Javaorg. apache.struts.action.ActionFormJava開發(fā)者將該類細(xì)分來創(chuàng)建表單bean。在運(yùn)行時(shí),該bean有兩種用法:

          ― 當(dāng)JSP準(zhǔn)備相關(guān)的HTML,表單以進(jìn)行顯示時(shí),JSP將訪問該

          bean(它保存要放入表單中的值)。那些值是從業(yè)務(wù)邏輯或者是從先前的用戶輸入來提供的。

                    ― 當(dāng)從Web瀏覽器中返回用戶輸入時(shí),該bean將驗(yàn)證并保存該輸入以供業(yè)務(wù)邏輯或(如果驗(yàn)證失敗的話)后續(xù)重新顯示使用。

          其次,Struts提供了許多定制JSP標(biāo)記,它們的使用簡(jiǎn)單,但是它們?cè)陔[藏信息方面功能強(qiáng)大。例如,除了bean名稱和給定bean中每個(gè)段的名稱之外,頁(yè)面設(shè)計(jì)者不需要知道有關(guān)表單bean的更多信息。

          從模型角度(Model

          Struts雖然不直接有助于模型開發(fā)。Struts中,系統(tǒng)模型的狀態(tài)主要由ActiomForm Bean和值對(duì)象體現(xiàn)。

          從控制器角度(Controller

              Struts framework中, Controller主要是ActionServlet,但是對(duì)于業(yè)務(wù)邏輯的操作則主要由ActionActionMappingActionForward這幾個(gè)組件協(xié)調(diào)完成(也許這幾個(gè)組件,應(yīng)該劃分到模型中的業(yè)務(wù)邏輯一塊)。其中,Action扮演了真正的控制邏輯的實(shí)現(xiàn)者,而ActionMappingActionForward則指定了不同業(yè)務(wù)邏輯或流程的運(yùn)行方向。

          Struts的基本組件包

          整個(gè)struts大約有15包,近200個(gè)類所組成,而且數(shù)量還在不斷的擴(kuò)展。在此我們不能一一介紹,只能列舉幾個(gè)主要的簡(jiǎn)要的介紹一下。下表說明了目前struts api中基本的幾個(gè)組件包,包括action,actions,config,util,taglib,validator。下圖則顯現(xiàn)了這幾個(gè)組件包之間的關(guān)系。其中action是整個(gè)struts framework的核心

          org.apache.struts.action

          基本上,控制整個(gè)struts framework的運(yùn)行的核心類、組件都在這個(gè)包中,比如我們上面提到的控制器ActionServlet。已經(jīng)Action,ActionForm,ActionMapping等等。struts1.11.0多了 DynaActionForm 類。增加了動(dòng)態(tài)擴(kuò)展生成FormBean功能

          org.apache.struts.actions

          這個(gè)包是主要作用是提供客戶的http請(qǐng)求和業(yè)務(wù)邏輯處理之間的特定適配器轉(zhuǎn)換功能,而1.0版本中的部分動(dòng)態(tài)增刪FromBean的類,也在struts1.1中被Action包的DynaActionForm組件所取代

          org.apache.struts.config

          提供對(duì)配置文件struts-config.xml元素的映射。這也是sturts1.1中新增的功能

          org.apache.struts.util

          Strtuts為了更好支持web application的應(yīng)用,體統(tǒng)了一個(gè)些常用服務(wù)的支持,比如Connection PoolMessage Source。詳細(xì)信息請(qǐng)參考

          http://jakarta.apache.org/struts/api/org/apache/struts/util/package-summary.html

          org.apache.struts.taglib

          這不是一個(gè)包,而是是一個(gè)客戶標(biāo)簽類的集合。下面包括Bean TagsHTML TagsLogic TagsNested TagsTemplate Tags這幾個(gè)用于構(gòu)建用戶界面的標(biāo)簽類。

          org.apache.struts.validator

          Struts1.1 framework中增加了validator framework,用于動(dòng)態(tài)的配置from表單的驗(yàn)證。詳細(xì)信息請(qǐng)參閱 http://home.earthlink.net/~dwinterfeldt/

           

           

           

          Struts framework的工作原理和組件

          對(duì)于Struts 如何控制、處理客戶請(qǐng)求,讓我們通過對(duì)struts的四個(gè)核心組件介紹來具體說明。這幾個(gè)組件就是:ActionServletAction ClassesAction Mapping(此處包括ActionForward),ActionFrom Bean

          Struts ActionServlet控制器對(duì)象

              ActionServlet繼承自javax.servlet.http.HttpServlet類,其在Struts framework中扮演的角色是中心控制器。它提供一個(gè)中心位置來處理全部的終端請(qǐng)求。控制器ActionServlet主要負(fù)責(zé)將HTTP的客戶請(qǐng)求信息組裝后,根據(jù)配置文件的指定描述,轉(zhuǎn)發(fā)到適當(dāng)?shù)奶幚砥鳌?/span>

              按照Servelt的標(biāo)準(zhǔn),所有得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>

          全部的請(qǐng)求URI*.do的模式存在并映射到這個(gè)servlet,其配置如下:

          <servlet-mapping>

          <servlet-name>action</servlet-name>

          <url-pattern>*.do</url-pattern>

          </servlet-mapping>

          一個(gè)該模式的請(qǐng)求URI符合如下格式:

                        http://www.my_site_name.com/mycontext/actionName.do

           

          中心控制器為所有的表示層請(qǐng)求提供了一個(gè)集中的訪問點(diǎn)。這個(gè)控制器提供的抽象概念減輕了開發(fā)者建立公共應(yīng)用系統(tǒng)服務(wù)的困難,如管理視圖、會(huì)話及表單數(shù)據(jù)。它也提供一個(gè)通用機(jī)制如錯(cuò)誤及異常處理,導(dǎo)航,國(guó)際化,數(shù)據(jù)驗(yàn)證,數(shù)據(jù)轉(zhuǎn)換等。

           

          當(dāng)用戶向服務(wù)器端提交請(qǐng)求的時(shí)候,實(shí)際上信息是首先發(fā)送到控制器ActionServlet,一旦控制器獲得了請(qǐng)求,其就會(huì)將請(qǐng)求信息傳交給一些輔助類(help classes)處理。這些輔助類知道如何去處理與請(qǐng)求信息所對(duì)應(yīng)的業(yè)務(wù)操作。在Struts中,這個(gè)輔助類就是org.apache.struts.action.Action。通常開發(fā)者需要自己繼承Aciton類,從而實(shí)現(xiàn)自己的Action實(shí)例。

          Struts Action Classes

                 ActionServlet全部提交的請(qǐng)求都被控制器委托到RequestProcessor對(duì)象RequestProcessor使用struts-config.xml文件檢查請(qǐng)求URI找到動(dòng)作Action標(biāo)示符。

          一個(gè)Action 類的角色,就像客戶請(qǐng)求動(dòng)作和業(yè)務(wù)邏輯處理之間的一個(gè)適配器(Adaptor),其功能就是將請(qǐng)求與業(yè)務(wù)邏輯分開。這樣的分離,使得客戶請(qǐng)求和Action類之間可以有多個(gè)點(diǎn)對(duì)點(diǎn)的映射。而且Action類通常還提供了其它的輔助功能,比如:認(rèn)證(authorization)、日志(logging)和數(shù)據(jù)驗(yàn)證(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()方法,請(qǐng)參考apidoc,在此不在說明。

              當(dāng)Controller收到客戶的請(qǐng)求的時(shí)候,在將請(qǐng)求轉(zhuǎn)移到一個(gè)Action實(shí)例時(shí),如果這個(gè)實(shí)例不存在,控制器會(huì)首先創(chuàng)建,然后會(huì)調(diào)用這個(gè)Action實(shí)例的execute()方法。Struts Framework為應(yīng)用系統(tǒng)中的每一個(gè)Action類只創(chuàng)建一個(gè)實(shí)例。因?yàn)樗械挠脩舳际褂眠@一個(gè)實(shí)例,所以你必須確定你的Action 類運(yùn)行在一個(gè)多線程的環(huán)境中。下圖顯示了一個(gè)execute()方法如何被訪問:

          Action實(shí)例的execute()方法

             

          注意,客戶自己繼承的Action子類,必須重寫execute()方法,因?yàn)?span>Action類在默認(rèn)情況下是返回null的。

          Struts Action Mapping

          上面講到了一個(gè)客戶請(qǐng)求是如何被控制器轉(zhuǎn)發(fā)和處理的,但是,控制器如何知道什么樣的信息轉(zhuǎn)發(fā)到什么樣的Action類呢?這就需要一些與動(dòng)作和請(qǐng)求信息相對(duì)應(yīng)的映射配置說明。在struts 中,這些配置映射信息是存儲(chǔ)在特定的XML文件(比如struts-config.xml)。 

          這些配置信息在系統(tǒng)啟動(dòng)的時(shí)候被讀入內(nèi)存,供struts framework在運(yùn)行期間使用。在內(nèi)存中,每一個(gè)<action>元素都與org.apache.struts.action.ActionMapping類的一個(gè)實(shí)例對(duì)應(yīng)。下表就顯示了一個(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>


          上面的配置表示:當(dāng)可以通過/logonAction.do(此處假設(shè)配置的控制器映射為*.do)提交請(qǐng)求信息的時(shí)候,控制器將信息委托com.test.LogonAction處理。調(diào)用LogonAction實(shí)例的execute()方法。同時(shí)將Mapping實(shí)例和所對(duì)應(yīng)的LogonForm Bean信息傳入。其中name=LogonForm,使用的form-bean元素所聲明的ActionForm Bean。有關(guān)form-bean的申明如下顯示。

          使用ActionForward導(dǎo)航

          元素<forward>則表示了當(dāng)Action實(shí)例的execute()方法運(yùn)行完畢或,控制器根據(jù)Mapping可將響應(yīng)信息轉(zhuǎn)到適當(dāng)?shù)牡胤健H缟厦娆F(xiàn)實(shí),如果客戶登陸成功,則調(diào)用welcome forward,將成功信息返回到/welcome.jsp頁(yè)面。在你的execute()方法的結(jié)尾可以使用下面的實(shí)例代碼而返回welcome forward。當(dāng)然你的welcome forward必須在action元素屬性中定義,正如上面所聲明的那樣。

          return (mapping.findForward("welcome"));


                 ActionForward對(duì)象是配置對(duì)象。這些配置對(duì)象擁有獨(dú)一無二的標(biāo)識(shí)以允許它們按照有意義的名稱如“success”,“failure”等來檢索。ActionForward對(duì)象封裝了向前進(jìn)的URL路徑且被請(qǐng)求處理器用于識(shí)別目標(biāo)視圖。ActionForward對(duì)象建立自<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>

                 基于執(zhí)行請(qǐng)求處理器的execute(…)方法的結(jié)果,當(dāng)傳遞一個(gè)值匹配指定于<forward>元素中name屬性的值的時(shí)候,下一個(gè)視圖可以在execute(…)方法中被開發(fā)者用方便的方法org.apache.struts.action.ActionMapping.findForward(…)選擇。ActionMapping.findForward(…)方法既從它的本地范圍又從全局范圍提供一個(gè)ActionForward對(duì)象,該對(duì)象返回至RequestProcessorRequestDispatcher.forward(…)response.sendRedirect(…)調(diào)用下一個(gè)視圖。當(dāng)<forward>元素有redirect=false屬性或redirect屬性不存在的時(shí)候,RequestDispatcher.forward(…)被執(zhí)行;當(dāng)redirect=“true”是,將調(diào)用sendRedirect(…)方法。下例舉例說明了redirect屬性的用法:

               <forward name="success" path="/Catalog.jsp" redirect="true"/>

          如果redirect=true, URL建立如/contextPath/path因?yàn)?/span>HttpServletResponse.sendRedirect(…)中解釋URL采用”/”開頭相對(duì)于servlet容器根目錄。

          如果redirect=false, URI建立如/path因?yàn)?/span>ServletContext.getRequestDisptacher(…)采用虛擬目錄相關(guān)URL

           

          在此稍稍說一下有關(guān)global-forwards的概念。其在配置文件中描述了整個(gè)應(yīng)用系統(tǒng)可以使用的ActionForward,而不是僅僅是一個(gè)特定的Action

           <global-forwards>

              <forward name="logout" path="/logout.do"/>

          <forward name="error" path="/error.jsp"/>

           </global-forwards>


          Struts ActionForm Bean捕獲表單數(shù)據(jù)

          在上面講解ActionServletAction ClassesAction Mapping的時(shí)候,我們都提到了ActionForm Bean的概念。一個(gè)應(yīng)用系統(tǒng)的消息轉(zhuǎn)移(或者說狀態(tài)轉(zhuǎn)移)的非持久性數(shù)據(jù)存儲(chǔ),是由ActionForm Bean的負(fù)責(zé)保持的。

                 ActionForm派生的對(duì)象用于保存請(qǐng)求對(duì)象的參數(shù),因此它們和用戶緊密聯(lián)系。

                 一個(gè)ActionForm類被RequestProcessor建立。這是發(fā)生在已完成向前進(jìn)到一個(gè)URL,該URL為映射到控制器servlet而不是JSP和相應(yīng)的動(dòng)作映射指定的表單屬性的。在這個(gè)情況下,如果沒有在指定的活動(dòng)范圍內(nèi)找到,RequestProcessor將嘗試尋找可能導(dǎo)致創(chuàng)建一個(gè)新ActionForm對(duì)象的表單bean。該ActionForm對(duì)象在指定的活動(dòng)范圍內(nèi)被用<action>元素的name屬性找到;

          RequestProcessor將隨后重新安排表單屬性,用請(qǐng)求時(shí)參數(shù)填充表單,隨即調(diào)用表單對(duì)象的validate(…)方法以履行服務(wù)器端用戶輸入驗(yàn)證。僅當(dāng)ActionMapping對(duì)象中validate屬性被設(shè)為true時(shí),validate(…)方法被調(diào)用;這就是默認(rèn)的行為。request.getParameterValues(parameterName)被用于得到一個(gè)String[]對(duì)象,它用來表單填充;驗(yàn)證的結(jié)果應(yīng)該是一個(gè)ActionErrors對(duì)象,用org.apache.struts.taglib.html.ErrorsTag來顯示驗(yàn)證錯(cuò)誤給用戶。ActionForm也可以被用于為當(dāng)前用戶保存即將被一個(gè)視圖引用的中間模型狀態(tài)。

          當(dāng)一個(gè)表單對(duì)象被RequestProcessor找到,它被傳遞到請(qǐng)求處理器的execute(…)方法。一個(gè)ActionForm對(duì)象也可以被請(qǐng)求處理器建立。表單對(duì)象建立目的是提供中間模型狀態(tài)給使用請(qǐng)求范圍JSP;這將確保對(duì)象不會(huì)在有效性過期后仍然存在。默認(rèn)的,所有的表單都被保存為會(huì)話范圍。會(huì)話中表單對(duì)象脫離有效性的存在可能導(dǎo)致浪費(fèi)內(nèi)存,同樣的,請(qǐng)求處理器必須跟蹤保存在會(huì)話中的表單對(duì)象的生命周期。一個(gè)好的捕獲表單數(shù)據(jù)的實(shí)踐是為橫跨多用戶交互的相關(guān)表單用一個(gè)單獨(dú)的表單bean表單bean也可以在反饋的時(shí)候用來儲(chǔ)存能夠被自定義標(biāo)簽改變的中間模型狀態(tài)。在視圖中標(biāo)簽用法避免結(jié)合Java代碼,因此要成一個(gè)好的任務(wù)劃分,web生產(chǎn)組主要處理標(biāo)志,而應(yīng)用開發(fā)組主要處理Java代碼。標(biāo)簽因素退出訪問中間模型狀態(tài)的邏輯;當(dāng)訪問嵌套的對(duì)象或當(dāng)通過聚集列舉時(shí)這個(gè)邏輯可能很復(fù)雜。

          注意:在struts1.1中,ActionForm的校驗(yàn)功能,逐漸被剝離出來(當(dāng)然依然可以使用)。使用了validator framework對(duì)整個(gè)應(yīng)用系統(tǒng)的表單數(shù)據(jù)驗(yàn)證進(jìn)行統(tǒng)一管理。相信信息請(qǐng)參考:http://home.earthlink.net/~dwinterfeldt

          ActionForm的使用中,Struts提倡使用到值對(duì)象(Value Object)。這樣將客戶或開發(fā)人員,對(duì)數(shù)據(jù)狀態(tài)與對(duì)象狀態(tài)能夠更加清晰的理解和使用。

          對(duì)于每一個(gè)客戶請(qǐng)求,Struts framework在處理ActionForm的時(shí)候,一般需要經(jīng)歷如下幾個(gè)步驟:

          (1)檢查Action的映射,確定Action中已經(jīng)配置了對(duì)ActionForm的映射

              (2)根據(jù)name屬性,查找form bean的配置信息

              (3)檢查Actionformbean的使用范圍,確定在此范圍下,是否已經(jīng)有此form bean的實(shí)例。

              (4)假如當(dāng)前范圍下,已經(jīng)存在了此form bean的實(shí)例,而是對(duì)當(dāng)前請(qǐng)求來說,是同一種類型的話,那么就重用。

              (5)否則,就重新構(gòu)建一個(gè)form bean的實(shí)例

              (6)form beanreset()方法備調(diào)用

              (7)調(diào)用對(duì)應(yīng)的setter方法,對(duì)狀態(tài)屬性賦值

              (8)如果validatede的屬性北設(shè)置為true,那么就調(diào)用form beanvalidate()方法。

          9)如果validate()方法沒有返回任何錯(cuò)誤,控制器將ActionForm作為參數(shù),傳給Action實(shí)例的execute()方法并執(zhí)行。

           

          注意:直接從ActionFrom類繼承的reset()validate()方法,并不能實(shí)現(xiàn)什么處理功能,所以有必要自己重新覆蓋。

          Struts的其他組件

              Struts framework本身提供了很多可擴(kuò)展的組件或sub framework,方便的開發(fā)人員在其構(gòu)架上構(gòu)建web層的應(yīng)用系統(tǒng)。比如upload,collections ,logging等等。讓我們來看看兩個(gè)比較重要的組件:validationg frameworkstruts taglib。有關(guān)其他組件請(qǐng)參考Struts用戶手冊(cè)(http://jakarta.apache.org/struts/userGuide)。

             

          Validation Framework for Struts

          struts1.1中,新增了validation framework。增加了對(duì)form數(shù)據(jù)提交的驗(yàn)證。將原本需要在ActionFrom Beanvalidate()進(jìn)行的驗(yàn)證通過配置文件的描述進(jìn)行驗(yàn)證。

          有關(guān)其詳細(xì)信息,請(qǐng)參考http://home.earthlink.net/~dwinterfeldt 。個(gè)人建議對(duì)于小型應(yīng)用系統(tǒng)可以采用這種配置方式,但是對(duì)于應(yīng)用系統(tǒng)中有大量web層表單應(yīng)用的系統(tǒng),并且業(yè)務(wù)需求變動(dòng)比較大的,使用validation framework 可能會(huì)加重開發(fā)難度、系統(tǒng)維護(hù)難度。可以借鑒validation frameworkJavascript Validator Tag

           

          Struts TagLib

              struts提供了一組可擴(kuò)展的自定義標(biāo)簽庫(kù)(TagLib),可以簡(jiǎn)化創(chuàng)建用戶界面的過程。目前包括:Bean TagsHTML TagsLogic TagsNested TagsTemplate Tags 這幾個(gè)Taglib。有關(guān)Struts Taglib的結(jié)構(gòu)和使用,可以參考前面有關(guān)Cutomer Tag Lib的介紹,有關(guān)起詳細(xì)資料,請(qǐng)參考

          BeanUtils

              這個(gè)組件的全稱是Bean Introspection Utilites。是屬于Jakarta Commons項(xiàng)目組的。主要是幫助構(gòu)建javabean的屬性操作的(getter,setter),已經(jīng)提供一種動(dòng)態(tài)定義和訪問bean的屬性。有關(guān)詳細(xì)信息,請(qǐng)參考。

          http://jakarta.apache.org/commons/beanutils.html

              如果各位對(duì)這方面有很興趣,可以參考一些有關(guān)java反射(Reflectio)方面的資料。

          Collections

              這個(gè)組件主要是提供了一些集合或列表對(duì)象,在原有的java collections framework的基礎(chǔ)上進(jìn)行了擴(kuò)展。詳細(xì)資料請(qǐng)參考:

          http://jakarta.apache.org/commons/collections.html 以及

          http://cvs.apache.org/viewcvs/~checkout~/jakarta-commons/collections/STATUS.html?rev=1.13

          Digester

              這個(gè)組件翻譯成中文的意思是“匯編”。其主要功能是根據(jù)xml配置文件,初始化系統(tǒng)的一些java類對(duì)象。Digester幫助你指定XMLjava對(duì)象之間映射模型,而且允許客戶話定制映射規(guī)則(rules)。詳細(xì)資料請(qǐng)參考

          http://jakarta.apache.org/commons/digester.html

          Struts配置文件簡(jiǎn)介

          Struts framework根據(jù)配置文件使得ServletAction,ActionMapping,Action , ActionForm這幾個(gè)不同層次的組件相互交互,協(xié)調(diào)的工作。這些配置文件是在系統(tǒng)啟動(dòng)的時(shí)候,讀入導(dǎo)內(nèi)存中,供控制器使用的。

          Struts framework主要包括三部分的配置描述,一個(gè)是指定有關(guān)Struts Controller及其相關(guān)的的配置描述(Initialization Parameters),一個(gè)對(duì)struts tag lib的描述,一個(gè)是struts組件(ActionMapping,ActionActionForm)之間相互映射協(xié)調(diào)的關(guān)系

           

          有關(guān)Struts Controller及其相關(guān)的的配置描述

              因?yàn)?span>Struts Controller的主要類ActionServlet是繼承自HttpServlet,所以必須像配置一個(gè)Servlet那樣在部署描述符(Web.xml)配置ActionServlet類及其訪問映射。

              當(dāng)您第一次創(chuàng)建基于StrutsWeb應(yīng)用程序時(shí),將為您創(chuàng)建一個(gè)部署描述符,這通常就足夠了。該文件包括下列條目:

          l         <servlet>條目定義用于Web應(yīng)用程序的servlet(在本例中,這是唯一的servlet)

          ― <servlet-name> <servlet-class>指示ActionServlet (標(biāo)識(shí)為“操作”)接收HTTP請(qǐng)求并確定如何響應(yīng)。

          ― <init-param>表示servlet初始化參數(shù).

          -          “config”指示ActionServlet的行為由指定的配置文件來指導(dǎo),該配置文件通常具有以下名稱:

          \WEB-INF\struts-config.xml

          -          “debug”具有整數(shù)值,它指示將有關(guān)處理的詳細(xì)信息寫至控制臺(tái)的程度。

          -          ”detail”具有整數(shù)值,它指示將“映射”詳細(xì)信息(如后面所述)寫至控制臺(tái)的程度。

          ― <load-on-startup>導(dǎo)致在啟動(dòng)應(yīng)用程序時(shí)裝入servlet

          l         <servlet-mapping>元素標(biāo)識(shí)這樣的命名模式:當(dāng)命名模式由URL進(jìn)行匹配時(shí),Web服務(wù)器就將控制權(quán)移交給ActionServlet。考慮下面各種情況:

          ― 訪問了ActionServlet,原因是“操作”(<servlet-mapping>中的<servlet-name>元素的內(nèi)容)與“操作”(<servlet>中的<servlet-name>元素的內(nèi)容)相匹配。

              ― <servlet-mapping>元素指定URL的結(jié)尾的命名模式。每個(gè)URL的開頭都是應(yīng)用程序上下文路徑。按照慣例,ActionServlet調(diào)用對(duì)象以響應(yīng)與命名模式“*do(其中“*”是通配符)一致的URL

          l         <welcome-file-list>元素指示獲得初始控制權(quán)的特定于應(yīng)用程序的代碼;在本例中,Web服務(wù)器直接從Web Content目錄中調(diào)用index.jsp

          l         <error-page>元素指示顯示哪個(gè)JSP來響應(yīng)錯(cuò)誤;在本例中,錯(cuò)誤為如下所示:

          ― 404 (找不到資源)

          ― 500 (Web服務(wù)器內(nèi)部發(fā)生錯(cuò)誤)

          l         每個(gè)<taglib>元素都使相對(duì)URL(相對(duì)于Web.xml)與標(biāo)記庫(kù)描述符(相對(duì)于Web應(yīng)用程序根目錄)相關(guān)聯(lián)。每個(gè)JSP都可以使用同一個(gè)URL來表示給定的標(biāo)記庫(kù),而Web.xml確定引用了哪個(gè)文件。

          有關(guān)struts tag lib的配置描述

              如果你的web application打算使用Strutstaglib,那么你有必要在web.xml中對(duì)struts taglib進(jìn)行配置描述。

          有關(guān)Struts Action Mapping的配置描述

                作為先前描述的web.xml設(shè)置的結(jié)果,Web應(yīng)用程序服務(wù)器將請(qǐng)求的一個(gè)子集按路徑發(fā)送至ActionServlet,它通常調(diào)用一系列操作和JSPActionServlet的響應(yīng)是基于配置文件struts-config.xml的內(nèi)容的。有關(guān)其DTD文檔的描述,請(qǐng)參考http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd

              一般struts-configversion1.1)包含了如下幾個(gè)部分:

          1form-bean

              2global-forwards

              3action-mappings

              4data-sources

           

              我們知道,對(duì)于這樣的一個(gè)請(qǐng)求(例如,表示為“/login.do”),執(zhí)行下列步驟:

          1、 尋找操作類對(duì)象(繼承org. apache.struts.action.Action的類)

          2、 ActionServlet調(diào)用操作類對(duì)象的執(zhí)行方法

          操作類中的執(zhí)行方法的特征符為如下所示:

          public ActionForward execute(

              ActionMapping mapping,

              ActionForm form,

              HttpServletRequest request,

              HttpServletResponse response)

          l         映射對(duì)象(ActionMapping),它包含指示如何響應(yīng)方法的每個(gè)可能結(jié)果的規(guī)則(“映射”)

          l         Struts表單beanActionForm),它保存發(fā)送至HTML表單或接收自HTML表單的數(shù)據(jù)

          l         請(qǐng)求和響應(yīng)對(duì)象(HttpServletReques/ HttpServletResponse

           

          3、 從執(zhí)行方法返回ActionForward對(duì)象,用于指導(dǎo)ActionServlet接著訪問哪個(gè)操作類或JSP

          返回的ActionForward對(duì)象中的信息取決于兩個(gè)值:

          l         方法的結(jié)果(如在“成功”或“故障”等字符串中所述)

          l         映射對(duì)象,它包含從Struts配置文件中讀取的信息

           

           

          要弄明白某些運(yùn)行時(shí)關(guān)系,要明白struts-config.xml該文件包括下面的一組條目:

          l         form-beans>標(biāo)記標(biāo)識(shí)每個(gè)表單bean

          l         action-mappings>標(biāo)記包括用于指導(dǎo)應(yīng)用程序流的信息,每個(gè)<action>子標(biāo)記都使相對(duì)URL與操作類和潛在的后續(xù)操作相關(guān)。

          Form-bean元素

          Struts配置文件中的一個(gè)示例<form-bean>子元素為如下所示:

           <form-bean name=“registerForm” type=“strutscommon.RegisterForm”/>

          每個(gè)<form-bean>子元素都包括下列屬性:

          name

          表單bean的名稱,稍后在配置文件中會(huì)用到。ActionServlet舉例說明了該bean(如果需要的話)并在將對(duì)bean的引用存儲(chǔ)在請(qǐng)求或會(huì)話對(duì)象中時(shí)將該名稱用作鍵。

          type

               類的全限定名稱,它繼承org.apache.struts.action.ActionForm該類必須在類路徑中。接受“Struts貿(mào)易樣本”中的注冊(cè)的表單bean包括HTML注冊(cè)表單中每個(gè)字段的getter setter方法。該bean還包括驗(yàn)證方法,如下節(jié)“驗(yàn)證”中所述。

          Action元素

             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

               將請(qǐng)求指定為非限定URL,不帶文件擴(kuò)展名(例如,“/register”)請(qǐng)求是根據(jù)<action>元素中的其它屬性來處理的,并且是用戶輸入的結(jié)果或者是在differentaction>元素中標(biāo)識(shí)的轉(zhuǎn)發(fā)的結(jié)果。

          type

               指定在發(fā)出請(qǐng)求時(shí)調(diào)用其執(zhí)行方法的操作類的全限定名。該類必須在類路徑中。

             注:不指定要實(shí)例化的類,可以通過使用forward屬性來轉(zhuǎn)發(fā)請(qǐng)求,該屬性在“Struts貿(mào)易樣本”中未使用,并且與后面描述的<forward>子元素不相同。

          name

               用于保存發(fā)送至HTML表單或接收自HTML表單的數(shù)據(jù)表單bean的名稱。

             input

               指定相對(duì)URL(例如,“/register.do”或“/index.jsp”)必須包括后綴,

          如果表單bean的驗(yàn)證方法指示發(fā)生了輸入錯(cuò)誤,則會(huì)調(diào)用URL;有關(guān)詳細(xì)信息,參見下節(jié)的“驗(yàn)證”。

             scope

                   指定將對(duì)表單 bean的引用存儲(chǔ)在哪個(gè)作用域中。其值為“會(huì)話”(缺省值)或“請(qǐng)求”。

               Struts配置文件中的每個(gè)<action>元素還包括子元素<forward>,它指定從方法結(jié)果至后續(xù)調(diào)用的映射。每個(gè)<forward>子元素都包括下列屬性

            name

          指定導(dǎo)致在運(yùn)行時(shí)使用當(dāng)前映射的字符串(例如,“success”),但是

          只限于以下情況:在 type 中引用的操作類的執(zhí)行方法使用完全相同

          的字符串來配置返回至ActionServlet ActionForward對(duì)象。下面

          的執(zhí)行方法不是很重要,但是會(huì)導(dǎo)致使用“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”)必須包括文件擴(kuò)展名,僅當(dāng)使用當(dāng)前映射時(shí)才會(huì)調(diào)用該URL,轉(zhuǎn)發(fā)操作類是根據(jù)different<action>元素中的屬性來處理的,尤其是,在其path屬性標(biāo)識(shí)相同URL<action>元素中。

           

              有必要提一下的是,在struts1.1中,提出了對(duì)Multiple Application Support。在struts的早先版本中,只有一個(gè)struts配置文件,一般叫struts-config.xml。但是,對(duì)于越來越復(fù)雜的應(yīng)用系統(tǒng)的發(fā)展,只有一個(gè)地方存放這個(gè)一個(gè)文件,對(duì)大型項(xiàng)目來說,使用和修改這個(gè)配置文件,使其成為了一個(gè)應(yīng)用的瓶頸問題。在struts1.1中,你可以定義多了配置文件協(xié)同工作。

           

          注:當(dāng)用戶或ActionServlet調(diào)用JSP時(shí),請(qǐng)求是由Web應(yīng)用程序服務(wù)器直接處理的不會(huì)受到ActionServlet的干預(yù)。

          Struts高級(jí)特性(Struts Advanced Feature

          驗(yàn)證

            僅當(dāng)在下列情況下才會(huì)在表單bean中對(duì)用戶輸入進(jìn)行驗(yàn)證:

          l         表單bean覆蓋超類的驗(yàn)證方法

          l         Struts配置文件中的<action>元素的驗(yàn)證屬性顯式地或者缺省設(shè)置為TRUE。表單bean沒有關(guān)于應(yīng)用程序的業(yè)務(wù)邏輯的信息;因此該bean提供的驗(yàn)證僅限于一些相對(duì)簡(jiǎn)單的問題,例如,用戶是否在每個(gè)必填字段中都輸入了數(shù)據(jù)?

          Struts框架的各種部件使得可以進(jìn)行驗(yàn)證

          l         Struts配置文件中的以下<action>子元素將導(dǎo)致使用表單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>

           

          如果缺少驗(yàn)證屬性,則意味著當(dāng)ActionServlet接收到來自HTML表單對(duì)“/register”的請(qǐng)求時(shí),ActionServlet將在接收用戶數(shù)據(jù)的表單bean中調(diào)用驗(yàn)證方法。此驗(yàn)證在ActionServlet訪問操作類之前進(jìn)行。如果丟失了該方法,不會(huì)發(fā)生任何錯(cuò)誤,在該情況下,驗(yàn)證總是會(huì)成功。

          l         如果發(fā)生了錯(cuò)誤,則表單bean的驗(yàn)證方法將舉例說明錯(cuò)誤類并將錯(cuò)誤條目添加至該類。registerForm的驗(yàn)證方法的一個(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è)參數(shù):

           

          property

               用來標(biāo)識(shí)錯(cuò)誤類別的Java字符串。

            如果想要在特定的輸入字段或輸入字段的子集發(fā)生錯(cuò)誤時(shí)

          標(biāo)識(shí)該錯(cuò)誤,則指定屬性值。例如,指定諸如“username

          之類的值的優(yōu)點(diǎn)在于:報(bào)告了錯(cuò)誤的JSP中,可以在屏幕上

          靠近發(fā)生錯(cuò)誤的字段的位置顯示有關(guān)特定HTML字段的錯(cuò)

          誤消息,但是,要指示所有錯(cuò)誤都屬于同一類別,可以對(duì)屬

          性參數(shù)指定以下常量:

            ActionErrors.GLOBAL_ERROR

                        error

                            包含從屬性文件派生的“鍵-字符串”對(duì)的鍵的ActionError 對(duì)象。當(dāng)配置ActionError對(duì)象時(shí),最多可以包括要代入字符串中用來替代{0}、{1}等的四個(gè)值。

           

          l 如果從驗(yàn)證方法返回了錯(cuò)誤,則ActionServlet指導(dǎo)對(duì)在<action>元素的輸入屬性中指定的對(duì)象或JSP進(jìn)行處理;在本例中,將處理register.jsp.

          l JSP register.jsp.     包括用于顯示從驗(yàn)證方法派生的任何錯(cuò)誤消息的以下

          標(biāo)記:

          <html:errors/>

          如果在未發(fā)生輸入錯(cuò)誤的情況下調(diào)用JSP,則該標(biāo)記不顯示任何內(nèi)容,

          而在JSP中將繼續(xù)進(jìn)行處理。但是,如果因發(fā)生驗(yàn)證故障而調(diào)用了JSP

          則為用戶顯示的內(nèi)容將受到屬性文件中是否包括下列鍵的影響:

           errors.header,它導(dǎo)致在所有錯(cuò)誤消息前面顯示一個(gè)字符串;或者

           errors.footer,它導(dǎo)致在所有錯(cuò)誤消息后面顯示一個(gè)字符串;或者

           errors.hiader,和errors.footer兩者

          例如,在ApplicationResources.properties 中,errors.header errors.footer的“鍵-字符串”對(duì)以及先前顯示的這兩個(gè)消息鍵為如下所示,它們各自都在單獨(dú)的一行上(但是分成了多行顯示以便于您復(fù)查):

          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>

           

          如果在注冊(cè)時(shí)用戶對(duì)用戶名輸入了空白,對(duì)余額輸入零,則用戶將接收到一個(gè)包括兩個(gè)錯(cuò)誤的列表的屏幕:

          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.

          可以為標(biāo)記<html:errors/>指定屬性以支持國(guó)際化或者只顯示有關(guān)指定了給定屬性值的錯(cuò)誤的信息。通過使用相異屬性值,可以在相鄰的不同字段中顯示每條錯(cuò)誤消息而不是將所有錯(cuò)誤置于單個(gè)列表中。

          使用異常處理聲明

            要定義應(yīng)用程序的邏輯流程,成熟的經(jīng)驗(yàn)是推薦在代碼之外,用配置的方法來實(shí)現(xiàn),而不是寫死在程序代碼中的。在J2EE中,這樣的例子比比皆是。從實(shí)現(xiàn)EJB的安全性和事務(wù)性行為到描述JMS消息和目的地之間的關(guān)系,很多運(yùn)行時(shí)的處理流程都是可以在程序之外定義的。

            Struts 創(chuàng)建者從一開始就采用這種方法,通過配置Struts的配置文件來定制應(yīng)用系統(tǒng)運(yùn)行時(shí)的各個(gè)方面。這一點(diǎn)在版本1.1的新特性上得到延續(xù),包括新的異常處理功能。在Struts framework以前的版本中,開發(fā)人員不得不自己處理Struts應(yīng)用中發(fā)生的錯(cuò)誤情況。在最新的版本中,情況大大的改觀了,Struts Framework提供了內(nèi)置的一個(gè)稱為 ExceptionHandler 的類, 用于系統(tǒng)缺省處理action類運(yùn)行中產(chǎn)生的錯(cuò)誤。這也是在上一個(gè)技巧中我們提到的framework許多可擴(kuò)展接口之一。

            Struts缺省的 ExceptionHandler類會(huì)生成一個(gè)ActionError對(duì)象并保存在適當(dāng)?shù)姆秶?span>scope)對(duì)象中。這樣就允許JSP頁(yè)面使用錯(cuò)誤類來提醒用戶出現(xiàn)什么問題。如果你認(rèn)為這不能滿足你的需求,那么可以很方便的實(shí)現(xiàn)你自己的ExcepionHandler類。

           

          具體定制異常處理的方法和機(jī)制

           

            要定制自己的異常處理機(jī)制,第一步是繼承org.apache.struts.action.ExceptionHandler類。這個(gè)類有2個(gè)方法可以覆蓋,一個(gè)是excute()另外一個(gè)是storeException(). 在多數(shù)情況下,只需要覆蓋其中的excute()方法。下面是ExceptionHandler類的excute()方法聲明:

           

           

            正如你看到的,該方法有好幾個(gè)參數(shù),其中包括原始的異常。方法返回一個(gè)ActionForward對(duì)象,用于異常處理結(jié)束后將controller類帶到請(qǐng)求必須轉(zhuǎn)發(fā)的地方去。

           

            當(dāng)然您可以實(shí)現(xiàn)任何處理,但一般而言,我們必須檢查拋出的異常,并針對(duì)該類型的異常進(jìn)行特定的處理。缺省的,系統(tǒng)的異常處理功能是創(chuàng)建一個(gè)出錯(cuò)信息,同時(shí)把請(qǐng)求轉(zhuǎn)發(fā)到配置文件中指定的地方去。定制異常處理的一個(gè)常見的例子是處理嵌套異常。假設(shè)該異常包含有嵌套異常,這些嵌套異常又包含了其他異常,因此我們必須覆蓋原來的execute()方法,對(duì)每個(gè)異常編寫出錯(cuò)信息。

           

            一旦你創(chuàng)建了自己的ExceptionHandler 類,就應(yīng)該在Struts配置文件中的部分聲明這個(gè)類,以便讓Struts知道改用你自定義的異常處理取代缺省的異常處理.

           

            可以配置你自己的ExceptionHandler 類是用于Action Mapping特定的部分還是所有的Action對(duì)象。如果是用于Action Mapping特定的部分就在元素中配置。如果想讓這個(gè)類可用于所有的Action對(duì)象,可以在元素中指定。例如,假設(shè)我們創(chuàng)建了異常處理類CustomizedExceptionHandler用于所有的Action, 元素定義如下所示:

           

           

           

            在元素中可以對(duì)很多屬性進(jìn)行設(shè)置。在本文中,最重要的屬性莫過于handler屬性, handler屬性的值就是自定義的繼承了ExceptionHandler類的子類的全名。假如該屬性沒有定義,Struts會(huì)采用自己的缺省值。當(dāng)然,其他的屬性也很重要,但如果想覆蓋缺省的異常處理的話,handler無疑是最重要的屬性。

           

            最后必須指出的一點(diǎn)是,你可以有不同的異常處理類來處理不同的異常。在上面的例子中,CustomizedExceptionHandler用來處理任何java.lang.Exception的子類. 其實(shí),你也可以定義多個(gè)異常處理類,每一個(gè)專門處理不同的異常樹。下面的XML片斷解釋了如何配置以實(shí)現(xiàn)這一點(diǎn)。

           

           

           

            在這里,一旦有異常拋出,struts framework將試圖在配置文件中找到ExceptionHandler,如果沒有找到,那么struts將沿著該異常的父類鏈一層層往上找直到發(fā)現(xiàn)匹配的為止。因此,我們可以定義一個(gè)層次型的異常處理關(guān)系結(jié)構(gòu),在配置文件中已經(jīng)體現(xiàn)了這一點(diǎn)。

          使用應(yīng)用模塊(Application Modules

            Struts 1.1的一個(gè)新特性是應(yīng)用模塊的概念。應(yīng)用模塊允許將單個(gè)Struts應(yīng)用劃分成幾個(gè)模塊,每個(gè)模塊有自己的Struts配置文件,JSP頁(yè)面,Action等等。這個(gè)新特性是為了解決大中型的開發(fā)隊(duì)伍抱怨最多的一個(gè)問題,即為了更好的支持并行開發(fā)允許多個(gè)配置文件而不是單個(gè)配置文件。

            顯然,當(dāng)很多開發(fā)人員一起參加一個(gè)項(xiàng)目時(shí),單個(gè)的Struts配置文件很容易引起資源沖突。應(yīng)用模塊允許Struts按照功能要求進(jìn)行劃分,許多情況已經(jīng)證明這樣更貼近實(shí)際。例如,假設(shè)我們要開發(fā)一個(gè)典型的商店應(yīng)用程序。可以將組成部分劃分成模塊比如catalog(商品目錄), customer(顧客), customer service(顧客服務(wù)), order(訂單)等。每個(gè)模塊可以分布到不同的目錄下,這樣各部分的資源很容易定位,有助于開發(fā)和部署。圖1 顯示了該應(yīng)用的目錄結(jié)構(gòu)。

           

          一個(gè)典型的商店應(yīng)用程序的目錄結(jié)構(gòu) 

           

            注:如果你無需將項(xiàng)目劃分成多個(gè)模塊,Struts框架支持一個(gè)缺省的應(yīng)用模塊。這就使得應(yīng)用程序也可以在1.0版本下創(chuàng)建,具有可移植性,因?yàn)閼?yīng)用程序會(huì)自動(dòng)作為缺省的應(yīng)用模塊。

           

            為了使用多應(yīng)用模塊功能,必須執(zhí)行以下幾個(gè)準(zhǔn)備步驟:

           

            · 為每個(gè)應(yīng)用模塊創(chuàng)建獨(dú)立的Struts配置文件。

           

            · 配置Web 部署描述符 Web.xml文件。

           

            · 使用org.apache.struts.actions.SwitchAction 來實(shí)現(xiàn)程序在模塊之間的跳轉(zhuǎn).

           

            創(chuàng)建獨(dú)立的Struts配置文件

           

            每個(gè)Struts應(yīng)用模塊必須擁有自己的配置文件。允許創(chuàng)建自己的獨(dú)立于其他模塊的ActionActionForm,異常處理甚至更多。

           

            繼續(xù)以上面的商店應(yīng)用程序?yàn)槔覀兛梢詣?chuàng)建以下的配置文件:一個(gè)文件名為struts-config-catalog.xml,包含catalog(商品目錄)、items(商品清單)、和其它與庫(kù)存相關(guān)的功能的配置信息;另一個(gè)文件名為struts- config-order.xml, 包含對(duì)order(訂單)和order tracking(訂單跟蹤)的設(shè)置。第三個(gè)配置文件是struts-config.xml,其中含有屬于缺省的應(yīng)用模塊中的一般性的功能。

            在為每個(gè)應(yīng)用模塊創(chuàng)建獨(dú)立的配置文件之后,我們就有可能需要調(diào)用不同的模塊中Action。為此必須使用Struts框架提供的SwitchAction類。Struts 會(huì)自動(dòng)將應(yīng)用模塊的名字添加到URL,就如Struts 自動(dòng)添加應(yīng)用程序的名字加到URL一樣。應(yīng)用模塊是對(duì)框架的一個(gè)新的擴(kuò)充,有助于進(jìn)行并行的團(tuán)隊(duì)開發(fā)。如果你的團(tuán)隊(duì)很小那就沒必要用到這個(gè)特性,不必進(jìn)行模塊化。當(dāng)然,就算是只有一個(gè)模塊,系統(tǒng)還是一樣的運(yùn)作。

          JSP放到WEB-INF后以保護(hù)JSP源代碼

            為了更好地保護(hù)你的JSP避免未經(jīng)授權(quán)的訪問和窺視,一個(gè)好辦法是將頁(yè)面文件存放在Web應(yīng)用的WEB-INF目錄下。

           

            通常JSP開發(fā)人員會(huì)把他們的頁(yè)面文件存放在Web應(yīng)用相應(yīng)的子目錄下。一個(gè)典型的商店應(yīng)用程序的目錄結(jié)構(gòu)如圖2所示。跟catalog (商品目錄)相關(guān)的JSP被保存在catalog子目錄下。跟customer相關(guān)的JSP,跟訂單相關(guān)的JSP等都按照這種方法存放。

           

          基于不同的功能 JSP 被放置在不同的目錄下 

           

            這種方法的問題是這些頁(yè)面文件容易被偷看到源代碼,或被直接調(diào)用。某些場(chǎng)合下這可能不是個(gè)大問題,可是在特定情形中卻可能構(gòu)成安全隱患。用戶可以繞過Strutscontroller直接調(diào)用JSP同樣也是個(gè)問題。

          為了減少風(fēng)險(xiǎn),可以把這些頁(yè)面文件移到WEB-INF 目錄下。基于Servlet的聲明,WEB-INF不作為Web應(yīng)用的公共文檔樹的一部分。因此,WEB-INF 目錄下的資源不是為客戶直接服務(wù)的。我們?nèi)匀豢梢允褂?span>WEB-INF目錄下的JSP頁(yè)面來提供視圖給客戶,客戶卻不能直接請(qǐng)求訪問JSP

           

            采用前面的例子,圖3顯示將JSP頁(yè)面移到WEB-INF 目錄下后的目錄結(jié)構(gòu)

           

          JSP存放在 WEB-INF 目錄下更為安全 

           

            如果把這些JSP頁(yè)面文件移到WEB-INF 目錄下,在調(diào)用頁(yè)面的時(shí)候就必須把"WEB-INF"添加到URL中。例如,在一個(gè)Struts配置文件中為一個(gè)logoff action寫一個(gè)Action mapping。其中JSP的路徑必須以"WEB-INF"開頭。如下所示:請(qǐng)注意粗體部分.

           

            這個(gè)方法在任何情況下都不失為Struts實(shí)踐中的一個(gè)好方法。是唯一要注意的技巧是你必須把JSP和一個(gè)Struts action聯(lián)系起來。即使該Action只是一個(gè)很基本的很簡(jiǎn)單JSP,也總是要調(diào)用一個(gè)Action,再由它調(diào)用JSP

           

            最后要說明的是,并不是所有的容器都能支持這個(gè)特性。WebLogic早期的版本不能解釋Servlet聲明,因此無法提供支持,據(jù)報(bào)道在新版本中已經(jīng)改進(jìn)了。總之使用之前先檢查一下你的Servlet容器。

          使用 Prebuilt Action類提升開發(fā)效率

            Struts framework帶有好幾個(gè)prebuilt Action類,使用它們可以大大節(jié)省開發(fā)時(shí)間。其中最有用的是org.apache.struts.actions.ForwardAction 和 org.apache.struts.actions.DispatchAction.

           

          使用 ForwardAction

           

            在應(yīng)用程序中,可能會(huì)經(jīng)常出現(xiàn)只要將Action對(duì)象轉(zhuǎn)發(fā)到某個(gè)JSP的情況。在上一點(diǎn)中曾提到總是由Action調(diào)用JSP是個(gè)好習(xí)慣。如果我們不必在Action中執(zhí)行任何業(yè)務(wù)邏輯,卻又想遵循從Action訪問頁(yè)面的話,就可以使用ForwardAction,它可以使你免去創(chuàng)建許多空的Action類。運(yùn)用ForwardAction的好處是不必創(chuàng)建自己的Action類,你需要做的僅僅是在Struts配置文件中配置一個(gè)Action mapping

           

            舉個(gè)例子,假定你有一個(gè)JSP文件index.jsp ,而且不能直接調(diào)用該頁(yè)面,必須讓程序通過一個(gè)Action類調(diào)用,那么,你可以建立以下的Action mapping來實(shí)現(xiàn)這一點(diǎn):

            正如你看到的,當(dāng) /home 被調(diào)用時(shí), 就會(huì)調(diào)用ForwardAction 并把請(qǐng)求轉(zhuǎn)發(fā)到 index.jsp 頁(yè)面.

          再討論一下不通過一個(gè)Action類直接轉(zhuǎn)發(fā)到某個(gè)頁(yè)面的情況,必須注意我們?nèi)匀皇褂迷刂械?span>forward屬性來實(shí)現(xiàn)轉(zhuǎn)發(fā)的目標(biāo)。這時(shí)元素定義如下:

           

           

           

            以上兩種方法都可以節(jié)省你的時(shí)間,并有助于減少一個(gè)應(yīng)用所需的文件數(shù)。

           

          使用 DispatchAction

           

            DispatchAction是Struts包含的另一個(gè)能大量節(jié)省開發(fā)時(shí)間的Action類。與其它Action類僅提供單個(gè)execute()方法實(shí)現(xiàn)單個(gè)業(yè)務(wù)不同,DispatchAction允許你在單個(gè)Action類中編寫多個(gè)與業(yè)務(wù)相關(guān)的方法。這樣可以減少Action類的數(shù)量,并且把相關(guān)的業(yè)務(wù)方法集合在一起使得維護(hù)起來更容易。

           

            要使用DispatchAction的功能,需要自己創(chuàng)建一個(gè)類,通過繼承抽象的DispatchAction得到。對(duì)每個(gè)要提供的業(yè)務(wù)方法必須有特定的方法signature。例如,我們想要提供一個(gè)方法來實(shí)現(xiàn)對(duì)購(gòu)物車添加商品清單,創(chuàng)建了一個(gè)類ShoppingCartDispatchAction提供以下的方法:

           

            那么,這個(gè)類很可能還需要一個(gè)deleteItem()方法從客戶的購(gòu)物車中刪除商品清單,還有clearCart()方法清除購(gòu)物車等等。這時(shí)我們就可以把這些方法集合在單個(gè)Action類,不用為每個(gè)方法都提供一個(gè)Action類。

           

            在調(diào)用ShoppingCartDispatchAction里的某個(gè)方法時(shí),只需在URL中提供方法名作為參數(shù)值。就是說,調(diào)用addItem()方法的 URL看起來可能類似于:

           

            http://myhost/storefront/action/cart?method=addItem

           

            其中method參數(shù)指定ShoppingCartDispatchAction中要調(diào)用的方法。參數(shù)的名稱可以任意配置,這里使用的"method"只是一個(gè)例子。參數(shù)的名稱可以在Struts配置文件中自行設(shè)定。

           

           

           

          Struts標(biāo)記庫(kù)

          定制JSP標(biāo)記

          Struts提供了用來封裝邏輯的各種定制JSP標(biāo)記,因此頁(yè)面設(shè)計(jì)者可以將主要精力花在頁(yè)面的可視特征上,而不必主要考慮Java語(yǔ)法或其它JSP語(yǔ)法,在下列標(biāo)識(shí)庫(kù)描述符中引用了Struts標(biāo)記:

          Struts-bean.tld

              使訪問bean以及新bean的定義更容易,,為了實(shí)現(xiàn)國(guó)際化,應(yīng)使用不同的屬性文件

          struts-html.tld

               提供顯示HTML對(duì)象(例如,表單、按鈕和復(fù)選框)的簡(jiǎn)便方法

          struts-logic.tld

                     支持邏輯構(gòu)造,以便可以有條件地顯示文本或者作為處理循環(huán)的結(jié)果來顯示文本

             struts-template.tld

                     支持使用在運(yùn)行時(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>標(biāo)記中的URL相匹配的URL。另外JSP中的每個(gè) struts標(biāo)記都使用一個(gè)使標(biāo)記與特定標(biāo)記庫(kù)描述符相關(guān)的前綴:

           沒有嵌套內(nèi)容的標(biāo)記可以采用以下格式:

          <prefix:tagName attributesAndValues/>

                    ― 嵌套內(nèi)容是在一對(duì)標(biāo)記之間嵌套的:

                 <prefix:tagName attributesAndValues />

                        </prefix:tagName>

                    

          prefix

                         JSP taglib偽指令中指定的前綴

                tagName

                         標(biāo)記的名稱,如標(biāo)記庫(kù)描述符中所述;描述符條目指定提供標(biāo)記邏輯的Jave

                     attributesAndValues

                        系列屬性與值的配對(duì)(是必需的或者是可選的),每個(gè)配對(duì)都包括一種屬性、一個(gè)等號(hào)(沒有前導(dǎo)或結(jié)尾空白)和一個(gè)引起來的字符串

          文件resource.jsp包含bean:message標(biāo)記的幾個(gè)實(shí)例。以下是標(biāo)記的示例用法:

          <bean:message key=“market. text. title”/>

           

          資源束

          在最簡(jiǎn)單的情況下,bean:message標(biāo)記解析為存儲(chǔ)在根據(jù)屬性文件創(chuàng)建的資源束中的字符串:

           屬性文件的名稱是用來調(diào)用ActoinServletweb.xml “application”參數(shù)的值。如:

          \WEB-INF\classes\ApplicationResources.properties

           消息標(biāo)記中的key屬性指向?qū)傩晕募械?#8220;鍵-字符串”對(duì);在本例中,指向下面的“鍵-字符串”對(duì):

           market. text.title=Current Market Conditions

          可以采用各種方法來定制bean:message標(biāo)記,以便(例如)JSP在運(yùn)行時(shí)引用不同的屬性文件。標(biāo)記提供了一種方法來支持多種語(yǔ)言以及最多將四個(gè)替代值插入到字符串中來代替{0}、{1}等等。

          l         僅當(dāng)指定的對(duì)象或值存在時(shí),logic:present 標(biāo)記才會(huì)導(dǎo)致顯示嵌套的文本。在register.jsp中,僅當(dāng)操作類創(chuàng)建了作為 tickerBean引用(在任何作用域中)的 Java bean 時(shí)才為用戶提供HTML表行。 Struts標(biāo)記為如下所示:

              <logic:present name=“tickerBean”>

                     -->nested content for presentation<--

                  </logic:present>

          l         Struts標(biāo)記允許很方便地訪問Java bean內(nèi)容。例如,以下標(biāo)記將解析為存儲(chǔ)在 tickerBean中的值:

             <bean:write name=  “tickerBean”property=“DJChange”/>

           

          tickerBean的源代碼在以下目錄中:

          Trade\Java Source\tradeCommon\tickerBean.java

          l         HTML表單與表單bean之間的數(shù)據(jù)傳送是通過使用html:form html:text標(biāo)記來完成的。 register.jsp中的輸入表單是按如下所示構(gòu)建的:

             <html:form action= “/register”>

                 -->nested form content with html: text tags<--

                </html:form action>

           

              html:form 標(biāo)記解析為HTML FORM 標(biāo)記并導(dǎo)致html: text 標(biāo)記引用適當(dāng)?shù)谋韱?/span>bean;特別是在 path=“/register” Struts配置文件的 <action>標(biāo)記中標(biāo)識(shí)的表單 bean

           

            html:text標(biāo)記建立HTML輸入字段。例如,以下標(biāo)記確保在HTML輸入字段與表單bean的用戶名字段之間傳送信息:

              <html:text property=“username”size=“40”/>

             

           

          JSP視窗組件所使用的 struts標(biāo)記庫(kù)由四類標(biāo)記組成:

          l         Bean標(biāo)記:用來在JSP頁(yè)中管理bean

          l         邏輯標(biāo)記:用來在JSP頁(yè)中控制流程

          l         HTML標(biāo)記:用來生成HTML標(biāo)記,在表單中顯示數(shù)據(jù),使用會(huì)話ID對(duì)URL進(jìn)行編程

          l         模板標(biāo)記:使用動(dòng)態(tài)模板構(gòu)造普通格式的頁(yè)

          Bean標(biāo)記

          這個(gè)標(biāo)記庫(kù)中包含用于定義新bean、訪問bean及其屬性的標(biāo)記。Struts框架提供了多種自定義標(biāo)記用來在JSP頁(yè)中處理JavaBean。這些標(biāo)記被封裝在一個(gè)普通的標(biāo)記庫(kù)中,在文件struts-bean.tld中定義了它的標(biāo)記庫(kù)描述器。Bean標(biāo)記庫(kù)將標(biāo)記定義在四個(gè)子類別中:

          l         創(chuàng)建和復(fù)制bean的標(biāo)記

          l         腳本變量定義標(biāo)記

          l         bean翻譯標(biāo)記

          l         消息國(guó)際化標(biāo)記

          Bean復(fù)制標(biāo)記

          可定義新bean,可復(fù)制現(xiàn)有bean,還可從現(xiàn)有bean復(fù)制屬性。

          <bean:define>標(biāo)記用來:

          l         定義新字符串常數(shù)

          l         將現(xiàn)有的bean復(fù)制到新定義的bean對(duì)象

          l         復(fù)制現(xiàn)有bean的屬性來創(chuàng)建新的bean

           <bean:define>標(biāo)記屬性:

           

          屬性

          描述

          Id

          新定義的bean腳本變量名稱,必須設(shè)置

          Type

          定義引入腳本變量的類

          Value

          id屬性定義的腳本變量分配一個(gè)新的對(duì)象

          Name

          目標(biāo)bean的名稱。若value屬性沒有設(shè)置,這個(gè)屬性就必須設(shè)置

          property

          Name屬性定義的bean的屬性名稱,用來定義新的bean

          Scope

          bean的作用域。若沒有設(shè)置,搜索范圍是從頁(yè)作用域到應(yīng)用程序作用域

          toScope

          目標(biāo)bean的作用域。若沒有設(shè)置,默認(rèn)值是頁(yè)作用域

          例如:定義一個(gè)bean:

          <bean:define id=”test” value=”this is a test”/>

          bean在頁(yè)作用域中被拷貝大哦請(qǐng)求作用域中的另一個(gè)bean:

          <bean:define id=”targetBean” name=”sourceBean”

          scope=”page” toScope=”request”/>

          定義腳本變量的標(biāo)記

          從多種資源中定義和生成腳本變量,這些資源包括cookie,請(qǐng)求參數(shù),HTTP標(biāo)頭等等。屬性如下:

          屬性

          描述

          Id

          腳本變量和要定義的頁(yè)作用域?qū)傩缘拿Q

          Name

          cookie/標(biāo)頭/參數(shù)的名稱

          multiple

          如果這個(gè)屬性設(shè)置了任意一個(gè)數(shù)值,所有匹配的cookie都會(huì)被積累并存儲(chǔ)到一個(gè)Cookie[](一個(gè)數(shù)組)類型的bean里。若無設(shè)置,指定cookie的第一個(gè)值將作為Cookie類型的值

          Value

          如果沒有匹配的cookie或數(shù)值,就返回這個(gè)屬性指定的默認(rèn)值

          例如:

          <bean:cookie id=”myCookie” name=”userName”/>

          腳本變量名稱是myCookie,用來創(chuàng)建這個(gè)屬性的cookie的名稱是userName

          <bean:header id=”myHeader” name=”Accept-Language”/>

          腳本變量名稱是myHeader,請(qǐng)求標(biāo)頭的名稱是Accept-Language.

          <bean:parameter id=”myParameter” name=”myParameter”>

          腳本變量名稱是myPatameter,它保存的請(qǐng)求參數(shù)的名稱也是myParameter.

          <bean:include>標(biāo)記將對(duì)一個(gè)資源的響應(yīng)進(jìn)行檢索,并引入一個(gè)腳本變量和字符串類型的頁(yè)作用域?qū)傩浴_@個(gè)資源可以是一個(gè)頁(yè),一個(gè)ActionForward或一個(gè)外部URL。與<jsp:include>的不同是資源的響應(yīng)被存儲(chǔ)到一個(gè)頁(yè)作用域的bean中,而不是寫入到輸出流。屬性如下:

          屬性

          描述

          Id

          腳本變量和要定義的頁(yè)作用域?qū)傩缘拿Q

          Page

          一個(gè)內(nèi)部資源

          forward

          一個(gè)ActionForward

          Href

          要包含的資源的完整URL

          例如:

          <bean:include id=”myInclude” page=”MyJsp?x=1”/>

          腳本變量的名稱是myInclude,要檢索的響應(yīng)來自資源MyJsp?x=1

           

          <bean:resource>標(biāo)記將檢索web應(yīng)用中的資源,并引入一個(gè)腳本變量和InputStream或字符串類型的頁(yè)作用域?qū)傩浴H绻跈z索資源時(shí)發(fā)生問題,就會(huì)產(chǎn)生一個(gè)請(qǐng)求時(shí)間異常。屬性如下:

          屬性

          描述

          Id

          腳本變量和要定義的頁(yè)作用域?qū)傩缘拿Q

          Name

          資源的相對(duì)路徑

          Input

          如果這個(gè)屬性不存在,資源的類型就是字符串

          例如:

          <bean:resource id=”myResource” name=”/WEB-INF/images/myResource.xml”/>

          腳本變量的名稱是myResource,要檢索的資源的名稱是myResource.xml

           

          顯示Bean屬性

           標(biāo)記庫(kù)中定義了<bean:write>標(biāo)記,用來將bean的屬性輸送到封裝的JSP頁(yè)寫入器。這個(gè)標(biāo)記與<jsp:getProperty>類似,屬性如下:

          屬性

          描述

          Name

          要進(jìn)行屬性顯示的bean的名稱

          property

          要顯示的屬性的名稱。如果這個(gè)屬性類有java.beans.PropertyEditor,getAsText()toString 方法會(huì)被調(diào)用

          Scope

          Bean的作用域,若沒有設(shè)置,搜索范圍是從頁(yè)到應(yīng)用程序作用域

          Filter

          如果設(shè)置true,屬性中的所有特殊HTML字符都將被轉(zhuǎn)化為相應(yīng)的實(shí)體引用

          Ignore

          如果設(shè)置false,當(dāng)發(fā)現(xiàn)屬性時(shí)會(huì)產(chǎn)生一個(gè)請(qǐng)求時(shí)間異常,否則返回null

          例如:

          <bean:write name=”myBean” property=”myProperty” scope=”request”

           filter=”true”/>

          myBean的屬性myProperty將會(huì)被顯示,作用域?yàn)檎?qǐng)求,如果發(fā)現(xiàn)任何HTML特殊字符都將被轉(zhuǎn)化為相應(yīng)的實(shí)體引用。

           

          消息標(biāo)記和國(guó)際化

          strtus框架支持國(guó)際化和本地化。用戶在他們的計(jì)算機(jī)中定義自己所在的區(qū)域,當(dāng)web應(yīng)用程序需要輸出一條消息時(shí),它將引用一個(gè)資源文件,在這個(gè)文件中所有的消息都使用了適當(dāng)?shù)恼Z(yǔ)言。一個(gè)應(yīng)用程序可能提供了很多資源文件,每個(gè)文件提供了用不同語(yǔ)言編寫的消息。如果沒有找到所選語(yǔ)言的資源文件,就將使用默認(rèn)的資源文件。

          struts框架對(duì)國(guó)際化的支持是使用<bean:message>標(biāo)記,以及使用java.util數(shù)據(jù)包中定義的LocaleResourceBundle類來實(shí)現(xiàn)Java2平臺(tái)對(duì)這些任務(wù)的支持。Java.text.MessageFormat類定義的技術(shù)可以支持消息的格式。利用此功能,開發(fā)人員不需了解這些類的細(xì)節(jié)就可進(jìn)行國(guó)際化和設(shè)置消息的格式。

          strtus實(shí)現(xiàn)國(guó)際化和本地化:

          第一步要定義資源文件的名稱,這個(gè)文件會(huì)包含用默認(rèn)語(yǔ)言編寫的在程序中會(huì)出現(xiàn)的所有消息。這些消息以“關(guān)鍵字-值”的形式存儲(chǔ),如下:

          error.validation.location = The entered location is invalid

          這個(gè)文件需要存儲(chǔ)在類的路徑下,而且它的路徑要作為初始化參數(shù)傳送給ActionServlet作為參數(shù)進(jìn)行傳遞時(shí),路徑的格式要符合完整Java類的標(biāo)準(zhǔn)命名規(guī)范。比如,如果資源文件存儲(chǔ)在WEB-INF\classes目錄中,文件名是ApplicationResources.properties,那么需要傳遞的參數(shù)值是ApplicationResources。如果文件在WEB-INF\classes\com\test中,那么參數(shù)值就應(yīng)該是com.test. ApplicationResources.

          為了實(shí)現(xiàn)國(guó)際化,所有的資源文件必須都存儲(chǔ)在基本資源文件所在的目錄中。基本資源文件包含的是用默認(rèn)地區(qū)語(yǔ)言-本地語(yǔ)言編寫的消息。如果基本資源文件的名稱是ApplicationResources.properties,那么用其他特定語(yǔ)言編寫的資源文件的名稱就應(yīng)該是ApplicationResources_xx.properties(xxISO編碼,如英語(yǔ)是en)。因此這些文件應(yīng)包含相同的關(guān)鍵字,但關(guān)鍵字的值是用特定語(yǔ)言編寫的。

          ActionServlet的區(qū)域初始化參數(shù)必須與一個(gè)true值一起傳送,這樣ActionServlet就會(huì)在用戶會(huì)話中的Action.LOCALE_KEY關(guān)鍵字下存儲(chǔ)一個(gè)特定用戶計(jì)算機(jī)的區(qū)域?qū)ο蟆,F(xiàn)在可以運(yùn)行一個(gè)國(guó)際化的web站點(diǎn),它可以根據(jù)用戶計(jì)算機(jī)上的設(shè)置的區(qū)域自動(dòng)以相應(yīng)的語(yǔ)言顯示。

          我們還可以使用特定的字符串來替換部分消息,就象用java.text.MessageFormat的方法一樣:

          error.invalid.number = The number {0} is valid

          我們可以把字符串{0}替換成任何我們需要的數(shù)字。<bean:message>標(biāo)簽屬性如下:

          屬性

          描述

          Key

          資源文件中定義消息關(guān)鍵字

          Locale

          用戶會(huì)話中存儲(chǔ)的區(qū)域?qū)ο蟮膶傩悦Q。若沒有設(shè)置,默認(rèn)值是Action.LOCALE_KEY

          Bundle

          在應(yīng)用程序上下文中,存儲(chǔ)資源對(duì)象的屬性的名稱。如果沒有設(shè)置這個(gè)屬性,默認(rèn)值是Action.MESSAGE_KEY

          arg0

          第一個(gè)替換參數(shù)值

          arg1

          第二個(gè)替換參數(shù)值

          arg2

          第三個(gè)替換參數(shù)值

          arg3

          第四個(gè)替換參數(shù)值

          例如:資源文件中定義了一個(gè)消息:

          info.myKey = The numbers entered are {0},{1},{2},{3}

          我們可使用下面的消息標(biāo)記:

          <bean:message key=”info.myKey” arg0=”5” arg1=”6” arg2=”7” arg3=”8”/>

           這個(gè)信息標(biāo)記輸出到JSP頁(yè)會(huì)顯示為:The numbers entered are 5,6,7,8

          邏輯標(biāo)記

          邏輯庫(kù)的標(biāo)記能夠用來處理外觀邏輯而不需要使用scriptletStruts邏輯標(biāo)簽庫(kù)包含的標(biāo)記能夠有條件地產(chǎn)生輸出文本,在對(duì)象集合中循環(huán)從而重復(fù)地產(chǎn)生輸出文本,以及應(yīng)用程序流程控制。它也提供了一組在JSP頁(yè)中處理流程控制的標(biāo)記。這些標(biāo)記封裝在文件名為struts-logic.tld的標(biāo)記包中。邏輯標(biāo)記庫(kù)定義的標(biāo)記能夠執(zhí)行下列三個(gè)功能:

          l         條件邏輯

          l         重復(fù)

          l         轉(zhuǎn)發(fā)/重定向響應(yīng)

          條件邏輯

          struts有三類條件邏輯。第一類可以比較下列實(shí)體與一個(gè)常數(shù)的大小:

          l         cookie

          l         請(qǐng)求參數(shù)

          l         beanbean的參數(shù)

          l         請(qǐng)求標(biāo)頭

           以下列出了這一類標(biāo)記:

          標(biāo)記

          功能

          <equal>

          如果常數(shù)與被定義的實(shí)體相等,返回true

          <notEqual>

          如果常數(shù)與被定義的實(shí)體不相等,返回true

          <greaterEqual>

          如果常數(shù)大于等于被定義的實(shí)體,返回true

          <lessEqual>

          如果常數(shù)小于等于被定義的實(shí)體,返回true

          <lessThan>

          如果常數(shù)小于被定義的實(shí)體,返回true

          <greaterThan>

          如果常數(shù)大于被定義的實(shí)體,返回true

           

          這一類的所有標(biāo)記有相同的屬性

          屬性

          描述

          Value

          要進(jìn)行比較的常數(shù)值

          Cookie

          要進(jìn)行比較的HTTP cookie的名稱

          Header

          要進(jìn)行比較的HTTP請(qǐng)求標(biāo)頭的名稱

          parameter

          要進(jìn)行比較的HTTP請(qǐng)求參數(shù)的名稱

          Name

          如果要進(jìn)行比較的是beanbean的屬性,則這個(gè)屬性代表bean的名稱

          property

          要進(jìn)行比較的bean屬性的名稱

          Scope

          Bean的作用域,如果沒有指定作用域,則它的搜索范圍是從頁(yè)到應(yīng)用程序

          例如:

          <logic:equal parameter=”name” value=”SomeName”>

                  The entered name is SomeName

          </logic:equal>

          判斷名為”name”的請(qǐng)求參數(shù)的值是否是”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è)屬性能夠轉(zhuǎn)化為數(shù)值,就進(jìn)行數(shù)值比較,否則就進(jìn)行字符串比較。

          第二類條件標(biāo)記定義了兩個(gè)標(biāo)記:

          l         <logic:present>

          l         <logic:notPresent>

          它們的功能是在計(jì)算標(biāo)記體之前判斷特定的項(xiàng)目是否存在。標(biāo)記的屬性和屬性值決定了要進(jìn)行檢查的項(xiàng)目。

          屬性

          描述

          Cookie

          由這個(gè)屬性指定的cookie將被檢查是否存在

          Header

          由這個(gè)屬性指定的請(qǐng)求標(biāo)頭將被檢查是否存在

          parameter

          由這個(gè)屬性指定的請(qǐng)求參數(shù)將被檢查是否存在

          Name

          如果沒有設(shè)置property屬性,那么有這個(gè)屬性指定的bean將被檢查是否存在。如果設(shè)置了,那么beanbean屬性都將被檢查是否存在。

          property

          檢查有name屬性指定的bean中是否存在指定的屬性

          Scope

          如果指定了bean的名稱,這就是bean的作用域。如果沒有指定作用域,搜索的范圍從頁(yè)到應(yīng)用程序作用域。

          Role

          檢查當(dāng)前已經(jīng)確認(rèn)的用戶是否屬于特殊的角色

          User

          檢查當(dāng)前已經(jīng)確認(rèn)的用戶是否有特定的名稱

          例如:

          <logic:notPresent name=”bean” property=”prop” scope=”page”>

          The bean property bean.prop is present

          </logic:notPresent>

          標(biāo)記判斷在頁(yè)作用域中是否存在一個(gè)名為”bean”bean,這個(gè)bean有一個(gè)prop屬性。

          第三類條件標(biāo)記比較復(fù)雜,這些標(biāo)記根據(jù)模板匹配的結(jié)果檢查標(biāo)記體的內(nèi)容。換句話說,這些標(biāo)記判斷一個(gè)指定項(xiàng)目的值是否是一個(gè)特定常數(shù)的子字符串:

          l         <logic:match>

          l         <logic:notMatch>

          這些標(biāo)記允許JSP引擎在發(fā)現(xiàn)了匹配或是沒有發(fā)現(xiàn)時(shí)計(jì)算標(biāo)記主體。屬性如下:

          屬性

          描述

          Cookie

          要進(jìn)行比較的HTTP cookie的名稱

          Header

          要進(jìn)行比較的的HTTP標(biāo)頭 的名稱

          parameter

          要進(jìn)行比較的的HTTP請(qǐng)求參數(shù)的名稱

          Name

          若要對(duì)beanbean的屬性進(jìn)行比較,這個(gè)屬性是用戶指定bean的名稱

          location

          如果設(shè)置了這個(gè)屬性的值,將會(huì)在這個(gè)指定的位置(索引值)進(jìn)行匹配

          scope

          如果對(duì)bean進(jìn)行比較,這個(gè)屬性指定了bean的作用域。如果沒有設(shè)置這個(gè)參數(shù),搜索范圍是從頁(yè)到應(yīng)用程序作用域

          property

          要進(jìn)行比較的bean的屬性名稱

          value

          要進(jìn)行比較的常數(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>

          標(biāo)記檢查名為”name”的請(qǐng)求參數(shù)是否是”xyz”的子字符串,但是子字符串必須從”xyz”的索引位置1開始(也就是說子字符串必須是”y””yz”)。

          重復(fù)標(biāo)記

          在邏輯標(biāo)記庫(kù)中定義了<logic:iterate>標(biāo)記,它能夠根據(jù)特定集合中元素的數(shù)目對(duì)標(biāo)記體的內(nèi)容進(jìn)行重復(fù)的檢查。集合的類型可以是java.util.Iterator,java.util.Collection

          ,java.util.Map或是一個(gè)數(shù)組。有三種方法可以定義這個(gè)集合:

          l         使用運(yùn)行時(shí)間表達(dá)式來返回一個(gè)屬性集合的集合

          l         將集合定義為bean,并且使用name屬性指定存儲(chǔ)屬性的名稱。

          l         使用name屬性定義一個(gè)bean,并且使用property屬性定義一個(gè)返回集合的bean屬性。

          當(dāng)前元素的集合會(huì)被定義為一個(gè)頁(yè)作用域的bean。屬性如下,所有這些屬性都能使用運(yùn)行時(shí)表達(dá)式。

          屬性

          描述

          collection

          如果沒有設(shè)置name屬性,它就指定了要進(jìn)行重復(fù)的集合

          Id

          頁(yè)作用域bean和腳本變量的名稱,它保存著集合中當(dāng)前元素的句柄

          indexed

          頁(yè)作用域JSP bean的名稱,它包含著每次重復(fù)完成后集合的當(dāng)前索引

          Length

          重復(fù)的最大次數(shù)

          Name

          作為集合的bean的名稱,或是一個(gè)bean名稱,它由property屬性定義的屬性,是個(gè)集合

          Offset

          重復(fù)開始位置的索引

          property

          作為集合的Bean屬性的名稱

          Scope

          如果指定了bean名稱,這個(gè)屬性設(shè)置bean的作用域。若沒有設(shè)置,搜索范圍從頁(yè)到應(yīng)用程序作用域

          Type

          為當(dāng)前定義的頁(yè)作用域bean的類型

          例如:

          <logic:iterate id=”currentInt”

          collection=”<% =myList %>”

          type=”java.lang.Integer”

          offset=”1”

          length=”2”>

              <% =currentint %>

              </logic:iterate>

          代碼將從列表中的第一個(gè)元素開始重復(fù)兩個(gè)元素并且能夠讓當(dāng)前元素作為頁(yè)作用域和java.lang.Integer類型的腳本變量來使用。也就是說,如果myList包含元素1234等,代碼將會(huì)打印12

          轉(zhuǎn)發(fā)和重定向標(biāo)記

          轉(zhuǎn)發(fā)標(biāo)記

          <logic:forward>標(biāo)記能夠?qū)㈨憫?yīng)轉(zhuǎn)發(fā)給重定向到特定的全局ActionForward上。ActionForward的類型決定了是使用PageContext轉(zhuǎn)發(fā)響應(yīng),還是使用sendRedirect將響應(yīng)進(jìn)行重定向。此標(biāo)記只有一個(gè)”name”屬性,用來指定全局ActionForward的名稱,例如:

          <logic:forward name=”myGlobalForward”/>

          重定向標(biāo)記

          <logic:redirect>標(biāo)記是一個(gè)能夠執(zhí)行HTTP重定向的強(qiáng)大工具。根據(jù)指定的不同屬性,它能夠通過不同的方式實(shí)現(xiàn)重定向。它還允許開發(fā)人員指定重定向URL的查詢參數(shù)。屬性如下:

          屬性

          描述

          Forward

          映射了資源相對(duì)路徑的ActionForward

          Href

          資源的完整URL

          Page

          資源的相對(duì)路徑

          Name

          Map類型的頁(yè)名稱,請(qǐng)求,會(huì)話或程序?qū)傩缘拿Q,其中包含要附加大哦重定向URL(如果沒有設(shè)置 property屬性)上的“名稱-值”參數(shù)。或是具有Map類型屬性的bean名稱,其中包含相同的信息(沒有設(shè)置property屬性)

          Property

          Map類型的bean屬性的名稱。Bean的名稱由name屬性指定。

          Scope

          如果指定了bean的名稱,這個(gè)屬性指定搜索bean的范圍。如果沒有設(shè)置,搜索范圍從頁(yè)到應(yīng)用程序作用域

          ParamID

          定義特定查詢參數(shù)的名稱

          ParamName

          字符串類型的bean的名稱,其中包含查詢參數(shù)的值(如果沒有設(shè)置paramProperty屬性);或是一個(gè)bean的名稱,它的屬性(paramProperty屬性中指定)包含了查詢參數(shù)值

          paramProperty

          字符串bean屬性的名稱,其中包含著查詢參數(shù)的值

          ParamScope

          ParamName定義的bean的搜索范圍

          使用這個(gè)標(biāo)記時(shí)至少要指定forward,hrefpage中的一個(gè)屬性,以便標(biāo)明將響應(yīng)重定向到哪個(gè)資源。

          HTML標(biāo)記

          Struts HTML標(biāo)記可以大致地分為以下幾個(gè)功能:

          l         顯示表單元素和輸入控件

          l         顯示錯(cuò)誤信息

          l         顯示其他HTML元素

          顯示表單元素和輸入控件

          strutsHTML表單與為表單操作而定義的ActionForm bean緊密聯(lián)系在一起。表單輸入字段的名稱與ActionForm bean里定義的屬性名稱是對(duì)應(yīng)的。當(dāng)?shù)谝淮物@示表單時(shí),表單的輸入字段是從ActionForm bean中移植過來的,當(dāng)表單被提交時(shí),請(qǐng)求參數(shù)將移植到ActionForm bean實(shí)例。

          所有可以在<form>標(biāo)記中使用的用來顯示HTML輸入控件的內(nèi)嵌標(biāo)記都使用下列屬性來定義JavaScript事件處理器。

          屬性

          描述

          Onblur

          字段失去了焦點(diǎn)

          Onchange

          字段失去了焦點(diǎn)并且數(shù)值被更改了

          Onclick

          字段被鼠標(biāo)點(diǎn)擊

          Ondblclick

          字段被鼠標(biāo)雙擊

          Onfocus

          字段接收到輸入焦點(diǎn)

          Onkeydown

          字段擁有焦點(diǎn)并且有鍵按下

          onkeypress

          字段擁有焦點(diǎn)并且有鍵按下并釋放

          Onkeyup

          字段擁有焦點(diǎn)并且有鍵被釋放

          onmousedown

          鼠標(biāo)指針指向字段并且點(diǎn)擊

          onmousemove

          鼠標(biāo)指針指向字段并且在字段內(nèi)移動(dòng)

          onmouseout

          鼠標(biāo)指針指向控件,但是指針在元素外圍移動(dòng)

          onmouseover

          鼠標(biāo)指針沒有指向字段,但是指針在元素內(nèi)部移動(dòng)

          Onmouseup

          鼠標(biāo)指針指向字段,并且釋放了鼠標(biāo)按鍵

          <form>元素中能夠被定義的其他一般屬性有:

          屬性

          描述

          Accesskey

          定義訪問輸入字段的快捷鍵

          Style

          定義輸入字段的樣式

          styleClass

          定義輸入字段的樣式表類

          Tabindex

          輸入字段的tab順序

          表單標(biāo)記

          <html:form>標(biāo)記用來顯示HTML標(biāo)記,可以指定AcitonForm bean的名稱和它的類名。如果沒有設(shè)置這些屬性,就需要有配置文件來指定ActionMapping以表明當(dāng)前輸入的是哪個(gè)JSP頁(yè),以及從映射中檢索的bean名和類。如果在ActionMapping指定的作用域中沒有找到指定的名稱,就會(huì)創(chuàng)建并存儲(chǔ)一個(gè)新的bean,否則將使用找到的bean

          <form>標(biāo)記能夠包含與各種HTML輸入字段相對(duì)應(yīng)的子標(biāo)記。

          <html:form>標(biāo)記屬性如下:

          屬性

          描述

          Action

          與表單相關(guān)的操作。在配置中,這個(gè)操作也用來標(biāo)識(shí)與表單相關(guān)的ActionForm bean

          Enctype

          表單HTTP方法的編碼類型

          Focus

          表單中需要初始化焦點(diǎn)的字段

          Method

          表單使用的HTTP方法

          Name

          與表單相關(guān)的ActionForm bean的名稱。如果沒有設(shè)置這個(gè)屬性,bean的名稱將會(huì)從配置信息中獲得

          Onreset

          表單復(fù)位時(shí)的JavaScript事件句柄

          Onsubmit

          表單提交時(shí)的JavaScript事件句柄

          Scope

          搜索ActionForm bean的范圍。如果沒有設(shè)置,將從配置文件中獲取

          Style

          使用的格式

          styleClass

          這個(gè)元素的格式表類

          Type

          ActionForm bean的完整名稱。如果沒有設(shè)置,將從配置文件獲得

          例如:

          <html:form action=”validateEmploee.do” method=”post”>

          </html:form>

          與表單相關(guān)的操作路徑是validateEmployee,而表單數(shù)據(jù)是通過POST傳遞的。對(duì)于這個(gè)表單來說,ActionForm bean的其他信息,如bean名稱類型,作用域,都是從表單指定操作的ActionMapping中檢索得到的:

          <form-beans>

          <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>

          如果配置文件中包含上述信息,并且請(qǐng)求URI*.do被映射到ActionServlet,與表單相關(guān)的ActionForm bean的名稱,類型和作用域分別是empForm,com.example.EmployeeFormrequest.這些屬性也可以使用<html:form>標(biāo)記屬性進(jìn)行顯示的定義。

          以下標(biāo)記必須嵌套在<html:form>標(biāo)記里

          按鈕和取消標(biāo)記

          <html:button>標(biāo)記顯示一個(gè)按鈕控件;<html:cancel>標(biāo)記顯示一個(gè)取消按鈕。屬性如下:

          屬性

          描述

          Property

          定義在表單被提交時(shí)返回到服務(wù)器的請(qǐng)求參數(shù)的名稱

          Value

          按鈕上的標(biāo)記

          復(fù)位和提交標(biāo)記

          <html:reset><html:submit>標(biāo)記分別能夠顯示HTML復(fù)位按鈕和提交按鈕。

          文本和文本區(qū)標(biāo)記

          <html:text><html:textarea>標(biāo)記分別HTML文本框和文本區(qū),屬性如下:

          屬性

          描述

          Property

          定義當(dāng)表單被提交時(shí)送回到服務(wù)器的請(qǐng)求參數(shù)的名稱,或用來確定文本元素當(dāng)前值的bean的屬性名稱

          Name

          屬性被查詢的bean的名稱,它決定了文本框和文本區(qū)的值。如果沒有設(shè)置,將使用與這個(gè)內(nèi)嵌表單相關(guān)的ActionForm的名稱

          <html:text>標(biāo)記還有以下屬性:

          屬性

          描述

          Maxlength

          能夠輸入的最大字符數(shù)

          Size

          文本框的大小(字符數(shù))

          <html:textarea>標(biāo)記特有的屬性如下:

          屬性

          描述

          Rows

          文本區(qū)的行數(shù)

          Cols

          文本區(qū)的列數(shù)

          檢查框和復(fù)選框標(biāo)記

          <html:checkbox>標(biāo)記能夠顯示檢查框控件。<html:multibox>標(biāo)記能夠顯示HTML復(fù)選框控件,請(qǐng)求對(duì)象在傳遞檢查框名稱時(shí)使用的getParameterValues()調(diào)用將返回一個(gè)字符串?dāng)?shù)組。屬性如下:

          屬性

          描述

          Name

          Bean的名稱,其屬性會(huì)被用來確定檢查是否以選中的狀態(tài)顯示。如果沒有設(shè)置,將使用與這個(gè)內(nèi)嵌表單相關(guān)的ActionFrom bean的名稱。

          Property

          檢查框的名稱,也是決定檢查框是否以選中的狀態(tài)顯示的bean屬性名稱。在復(fù)選框的情況下,這個(gè)屬性必須是一個(gè)數(shù)組。

          Value

          當(dāng)檢查框被選中時(shí)返回到服務(wù)器的請(qǐng)求參數(shù)的值

          例如:

          <html:checkbox property=”married” value=”Y”/>

          一個(gè)名為married的檢查框,在表單提交時(shí)會(huì)返回一個(gè)”Y”.

          文件標(biāo)記

          <html:file>標(biāo)記可以顯示HTML文件控件。屬性如下:

          屬性

          描述

          Name

          Bean的名稱,它的屬性將確定文件控件中顯示的內(nèi)容。如果沒設(shè)置,將使用與內(nèi)嵌表單相關(guān)的ActionForm bean的名稱

          property

          這個(gè)屬性定義了當(dāng)表單被提交時(shí)送回到服務(wù)器的請(qǐng)求參數(shù)的名稱,以及用來確定文件控件中顯示內(nèi)容的bean屬性名稱

          Accept

          服務(wù)器能夠處理的內(nèi)容類型集。它也將對(duì)客戶瀏覽器對(duì)話框中的可選文件類型進(jìn)行過濾

          Value

          按鈕上的標(biāo)記,這個(gè)按鈕能夠在本地文件系統(tǒng)中瀏覽文件

          單選鈕標(biāo)記

          <html:radio>標(biāo)記用來顯示HTML單選鈕控件,屬性如下:

          屬性

          描述

          Name

          Bean的名稱,其屬性會(huì)被用來確定單選鈕是否以選中的狀態(tài)顯示。如果沒有設(shè)置,將使用與這個(gè)內(nèi)嵌表單相關(guān)的ActionFrom bean的名稱。

          property

          當(dāng)表單被提交時(shí)送回到服務(wù)器的請(qǐng)求參數(shù)的名稱,以及用來確定單選鈕是否以被選中狀態(tài)進(jìn)行顯示的bean屬性的名稱

          Value

          當(dāng)單選鈕被選中時(shí)返回到服務(wù)器的值

          隱藏標(biāo)記

          <html:hidden>標(biāo)記能夠顯示HTML隱藏輸入元素,屬性如下:

          屬性

          描述

          Name

          Bean的名稱,其屬性會(huì)被用來確定隱藏元素的當(dāng)前值。如果沒有設(shè)置,將使用與這個(gè)內(nèi)嵌表單相關(guān)的ActionFrom bean的名稱。

          property

          定義了當(dāng)表單被提交時(shí)送回到服務(wù)器的請(qǐng)求參數(shù)的名稱,以及用來確定隱藏元素當(dāng)前值的bean屬性的名稱

          Value

          用來初始化隱藏輸入元素的值

          密碼標(biāo)記

          <html:password>標(biāo)記能夠顯示HTML密碼控件,屬性如下:

          屬性

          描述

          maxlength

          能夠輸入的最大字符數(shù)

          Name

          Bean的名稱,它的屬性將用來確定密碼元素的當(dāng)前值。如果沒有設(shè)置,將使用與這個(gè)內(nèi)嵌表單相關(guān)的ActionFrom bean的名稱。

          property

          定義了當(dāng)表單被提交時(shí)送回到服務(wù)器的請(qǐng)求參數(shù)的名稱,以及用來確定密碼元素當(dāng)前值的bean屬性的名稱

          redisplay

          在顯示這個(gè)字段時(shí),如果相應(yīng)的bean屬性已經(jīng)被設(shè)置了數(shù)據(jù),這個(gè)屬性決定了是否顯示密碼的內(nèi)容

          Size

          字段的大小

          選擇標(biāo)記

          <html:select>標(biāo)記能夠顯示HTML選擇控件,屬性如下:

          屬性

          描述

          multiple

          表明這個(gè)選擇控件是否允許進(jìn)行多選

          Name

          Bean的名稱,它的屬性確定了哪個(gè)。如果沒有設(shè)置,將使用與這個(gè)內(nèi)嵌表單相關(guān)的ActionFrom bean的名稱。

          property

          定義了當(dāng)表單被提交時(shí)送回到服務(wù)器的請(qǐng)求參數(shù)的名稱,以及用來確定哪個(gè)選項(xiàng)需要被選中的bean屬性的名稱

          Size

          能夠同時(shí)顯示的選項(xiàng)數(shù)目

          Value

          用來表明需要被選中的選項(xiàng)

          選項(xiàng)標(biāo)記(這個(gè)元素需要嵌套在<html:select>標(biāo)記里)

          <html:option>標(biāo)記用來顯示HTML選項(xiàng)元素集合,屬性如下:

          屬性

          描述

          collection

          Bean集合的名稱,這個(gè)集合存儲(chǔ)在某個(gè)作用域的屬性中。選項(xiàng)的數(shù)目與集合中元素的數(shù)目相同。Property屬性能夠定義選項(xiàng)值所使用的bean屬性,而labelProperty屬性定義選項(xiàng)標(biāo)記所使用的bean的屬性

          labelName

          用來指定存儲(chǔ)于某個(gè)作用域的bean,這個(gè)bean是一個(gè)字符串的集合,能夠定義<html:option>元素的標(biāo)記(如果標(biāo)志與值不相同)

          labelProperty

          collection屬性共同使用時(shí),用來定義了存儲(chǔ)于某個(gè)作用域的bean,這個(gè)bean將返回一個(gè)字符串集合,能夠用來寫入<html:option>元素的value屬性

          Name

          如果這是唯一被指定的屬性,它就定義了存儲(chǔ)于某個(gè)作用域的bean,這個(gè)bean將返回一個(gè)字符串集合,能夠用來寫入<html:option>元素的value屬性

          property

          這個(gè)屬性在與collection屬性共同使用時(shí),定義了每個(gè)要顯示選項(xiàng)值的獨(dú)立beanname屬性。如果不是與collection屬性共同使用,這個(gè)屬性定義了由name屬性指定的bean的屬性名稱(如果有name屬性),或是定義了一個(gè)ActionForm bean,這個(gè)bean將返回一個(gè)集合來寫入選項(xiàng)的值

          我們看一下這個(gè)標(biāo)記的一些例子:

          <html:option collection=”optionCollection” property=”optionValue”

          labelProperty=”optionLabel”/>

          標(biāo)記假設(shè)在某個(gè)作用域中有一個(gè)名為optionCollection的集合,它包含了一些具有optionValue屬性的獨(dú)立的bean,每個(gè)屬性將作為一個(gè)選項(xiàng)的值。每個(gè)選項(xiàng)的標(biāo)志由beanoptionLabel屬性屬性進(jìn)行定義。

          <html:option name=”optionValues” labelName=”optionLabels”/>

          標(biāo)記中optionValues代表一個(gè)存儲(chǔ)在某個(gè)作用域中的bean,它是一個(gè)字符串集合,能夠用來寫入選項(xiàng)的值,而optionLabels代表一個(gè)存儲(chǔ)在某個(gè)作用域中的bean,它也是一個(gè)字符串集合,能夠用來寫入選項(xiàng)的標(biāo)志。

          顯示錯(cuò)誤信息的標(biāo)記

          <html:errors>標(biāo)記能夠與ActionErrors結(jié)合在一起來顯示錯(cuò)誤信息。這個(gè)標(biāo)記首先要從當(dāng)前區(qū)域的資源文件中讀取消息關(guān)鍵字errors.header,然后顯示消息的文本。接下去它會(huì)在ActionErrors對(duì)象(通常作為請(qǐng)求參數(shù)而存儲(chǔ)在Action.ERROR_KEY關(guān)鍵字下)中循環(huán),讀取單個(gè)ActionError對(duì)象的消息關(guān)鍵字,從當(dāng)前區(qū)域的資源文件中讀取并格式化相應(yīng)的消息,并且顯示它們。然后它讀取與errors.footer關(guān)鍵字相對(duì)應(yīng)的消息并且顯示出來。

          通過定義property屬性能夠過濾要顯示的消息,這個(gè)屬性的值應(yīng)該與ActionErrors對(duì)象中存儲(chǔ)ActionError對(duì)象的關(guān)鍵字對(duì)應(yīng)。屬性如下:

          屬性

          描述

          Bundle

          表示應(yīng)用程序作用域?qū)傩缘拿Q,它包含著消息資源,其默認(rèn)值Acion.MESSAGE_KEY

          Locale

          表示會(huì)話作用域?qū)傩缘拿Q,它存儲(chǔ)著用戶當(dāng)前登錄的區(qū)域信息。其默認(rèn)值是Action.ERROR_KEY

          Name

          表示請(qǐng)求屬性的名稱,它存儲(chǔ)著ActionErrors對(duì)象。其默認(rèn)值是Action.ERROR_KEY

          property

          這個(gè)屬性指定了ActionErrors對(duì)象中存儲(chǔ)每個(gè)獨(dú)立ActionError對(duì)象的關(guān)鍵字,它可以過濾消息

          例子:

          <html:errors/>

          顯示集合中所有的錯(cuò)誤。

          <html:errors property=”missing.name”/>

          顯示存儲(chǔ)在missing.name關(guān)鍵字的錯(cuò)誤。

          其他HTML標(biāo)記

          struts HTML標(biāo)記還定義了下列標(biāo)記來顯示其他HTML元素:

          l         <html:html> : 顯示HTML元素

          l         <html:img> : 顯示圖象標(biāo)記

          l         <html:link> : 顯示HTML鏈接或錨點(diǎn)

          l         <html:rewrite> : 創(chuàng)建沒有錨點(diǎn)標(biāo)記的URI

          這些標(biāo)記的詳細(xì)內(nèi)容請(qǐng)參照struts文檔。

          模板標(biāo)記

          動(dòng)態(tài)模板是模塊化WEB頁(yè)布局設(shè)計(jì)的強(qiáng)大手段。Struts模板標(biāo)記庫(kù)定義了自定義標(biāo)記來實(shí)現(xiàn)動(dòng)態(tài)模板。

          插入標(biāo)記

          <template:insert>標(biāo)記能夠在應(yīng)用程序的JSP頁(yè)中插入動(dòng)態(tài)模板。這個(gè)標(biāo)記只有一個(gè)template屬性,用來定義模板JSP頁(yè)。要插入到模板的頁(yè)是有多個(gè)<template:put>標(biāo)記來指定的,而這些標(biāo)記被定義為<template:insert>標(biāo)記的主體內(nèi)容。

          放置標(biāo)記

          <template:put>標(biāo)記是<template:insert>標(biāo)記內(nèi)部使用的,用來指定插入到模板的資源。屬性如下:

          屬性

          描述

          content

          定義要插入的內(nèi)容,比如一個(gè)JSP文件或一個(gè)HTML文件

          direct

          如果這個(gè)設(shè)置為true,由content屬性指定的內(nèi)容將直接顯示在JSP上而不是作為包含文件

          Name

          要插入的內(nèi)容的名稱

          Role

          如果設(shè)置了這個(gè)屬性,只有在當(dāng)前合法用戶具有特定角色時(shí)才能進(jìn)行內(nèi)容的插入。

          獲得標(biāo)記

          在模板JSP頁(yè)中使用<template:get>標(biāo)記能夠檢索由<template:put>標(biāo)記插入到JSP頁(yè)的資源。屬性如下:

          屬性

          描述

          Name

          <template:put>標(biāo)記插入的內(nèi)容的名稱

          Role

          如果設(shè)置了這個(gè)屬性,只有在當(dāng)前合法用戶具有特定角色時(shí)才能進(jìn)行內(nèi)容的檢索

          使用模板標(biāo)記

          首先編寫一個(gè)模板JSP頁(yè),它將被所有的web頁(yè)使用:

          <html>

           <%@ taglib uri=”/template” prefix=”template” %>

           <head>

          <title></title>

           </head>

           <body>

          <table width=”100%” height=”100%” >

           <tr height=”10%”>

              <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>

          </table>

           </body>

          </html>

          我們將這個(gè)文件命名為template.jsp。這個(gè)文件使用<template:get>標(biāo)記來獲得由JSP頁(yè)使用<template:put>標(biāo)記提供的內(nèi)容,并且將內(nèi)容在一個(gè)HTML表格中顯示出來。這三個(gè)內(nèi)容是標(biāo)題,內(nèi)容和頁(yè)腳。典型的內(nèi)容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”/>

          </template:insert>

          這個(gè)應(yīng)用程序JSP頁(yè)使用<template:insert標(biāo)記來定義模板,然后使用<template:put>標(biāo)記將特定內(nèi)容名稱指定的資源放到模板JSP頁(yè)中。如果我們有上百個(gè)布局相同的頁(yè),但突然想改變這個(gè)模板,我們只需要改變template.jsp文件。

          一個(gè)簡(jiǎn)單的示例

           在這個(gè)指導(dǎo)中我們將step by step開發(fā)一個(gè)小的應(yīng)用程序。你應(yīng)該有一些JSPXML的經(jīng)驗(yàn),并且有一個(gè)可以運(yùn)行的應(yīng)用服務(wù)器。

          Struts的安裝

           請(qǐng)先將Struts.jar和所有相關(guān)common拷貝到你應(yīng)用程序的lib目錄中,不用刪除你的struts目錄中的其他文件。結(jié)果如1所示。

           

          第一個(gè)實(shí)驗(yàn):簡(jiǎn)單的JSP頁(yè)

           現(xiàn)在我們要做一個(gè)簡(jiǎn)單的JSP頁(yè),用來確認(rèn)至此我們的操作是正確的。

           strutsShop里建一個(gè)BookView.jsp的文件。內(nèi)容如下,按圖2所示在瀏覽器中運(yùn)行:

           

          第二個(gè)實(shí)驗(yàn):struts的國(guó)際化

           我們將使用戶能用本國(guó)的語(yǔ)言瀏覽預(yù)定義的文本,進(jìn)而接觸一些struts的功能。首先你要按照?qǐng)D3拷貝一些文件到WEB-INF目錄下。在struts-html.tld文件里有我們要用的標(biāo)簽。這些我們?cè)谏辖右呀?jīng)介紹了,你可以簡(jiǎn)短的回顧一下。

          struts-config.xml的配置清單如下,這是一個(gè)標(biāo)準(zhǔn)的清單,你以后的程序都可以以此為基礎(chǔ)進(jìn)行擴(kuò)展:

          web.xml的配置清單如下,這是一個(gè)標(biāo)準(zhǔn)的清單,你以后的程序都可以以此為基礎(chǔ)進(jìn)行擴(kuò)展:

           

           

          classes目錄下創(chuàng)建一個(gè)ApplicationResources.properties的文件(此文件名在web.xml中定義),打開它,輸入一行:index.title=Struts Tutorial。然后在創(chuàng)建一個(gè)ApplicationResources_de.properties文件,也輸入一行:index.title=Struts Einführung。其實(shí)這兩個(gè)文件就是當(dāng)加載時(shí)會(huì)根據(jù)當(dāng)前的瀏覽器而選擇英文或德文,這里我們只能了解國(guó)際化過程來測(cè)試前者了。我們還需編寫BookView.jsp文件,如下:

           

          可在瀏覽器中瀏覽,你可能需要重啟你的tomcat

           

           其實(shí)我們可以將國(guó)際化寫在一個(gè)文件中,就是將參數(shù)寫在一個(gè)屬性文件中。(這是作者的意圖,但我沒有各種版本的IE進(jìn)行實(shí)驗(yàn))

           

          struts中的Forms

           在這一章我們將創(chuàng)建一個(gè)簡(jiǎn)單的Bean(Book.java)和兩個(gè)JSP頁(yè)面,一個(gè)是創(chuàng)建新書的,另一個(gè)是顯示它的,我們也會(huì)第一次使用struts-config.xml文件。

           我們先在你的classes目錄下創(chuàng)建如下Book.java文件。

           

           我們還需要?jiǎng)?chuàng)建新書的JSP頁(yè)。我們將使用title,authernumber of pages三個(gè)字段,在此之前我們先要做一些工作,對(duì)于一個(gè)初學(xué)者這將有些難度。在你的BookView中加上以下內(nèi)容:

           

          再次運(yùn)行,你將得到圖5所示內(nèi)容,如果沒有錯(cuò),那你需要重啟tomcat;如果錯(cuò)誤不一樣,沒關(guān)系,因?yàn)樗际菦]有在配置文件中找到mapping路徑。

           

          接下來我們需要第二個(gè)JSP頁(yè)面CreateBook.jsp,代碼如下:

           

          classes目錄下創(chuàng)建一個(gè)BookAction文件:

           

          它沒按照struts要求編寫僅僅創(chuàng)建一本書并給它標(biāo)題。然后編寫你的struts-config.xml

           

           我們希望在struts中在bookFormBook間建立連接。而且我們還用bookCreated定義了一個(gè)到BookView.jsp的轉(zhuǎn)發(fā)。最后我們用action=createBook.do屬性定義了我們的form做什么。關(guān)于do:與接受CreateBook.jsp輸入信息的bookForm相關(guān)的bean,由createBook命令創(chuàng)建。

              按圖6編譯你的類。由于我是初手,在這里遇見很多問題,所以耽誤了很久,不過它讓你學(xué)到很多東東。比如:javax.servlet要用到servlet.jar包;javac后跟a.java, java后跟a;還有我遇見了很原文提到的問題,很多都是由于自己編寫(沒有copy)而造成的馬虎。希望大家也能引起注意,到此除了ActionForm我們都已用到了。

           

           編譯成功后,在你的classes目錄下會(huì)增加兩個(gè)文件:Book.classBookAction.class.

           重啟你的tomcat(每次改動(dòng)config文件你都需要重啟,改動(dòng)注冊(cè)表需要重啟機(jī)器)。現(xiàn)在在你的瀏覽器里登陸CreateBook.jsp,如圖7:

           

           當(dāng)你填寫后提交,另你失望的是什么也沒有得到。這是由于我們并沒有ActionForm bean.

          struts:介紹ActionForm

           這節(jié)我們繼續(xù)做ActionForm bean來完成我們的例子。我們將用ActionForm得到合法的book的信息,并進(jìn)行一些檢驗(yàn),例如沒有輸入標(biāo)題等,向用戶提供錯(cuò)誤或成功的信息。我們還將得到book的屬性并且能夠更改它。

           為此我們需要一個(gè)ActionForm:它僅是一個(gè)簡(jiǎn)單的容器,沒有應(yīng)用程序邏輯,只有兩個(gè)方法:reset(),validate().struts1.1里,validate()方法被單獨(dú)作為一個(gè)validate.xml文件。詳見參考資料二。

           現(xiàn)在我們做另一個(gè)類:BookForm.java。它將包含book的實(shí)例,并且有一些getXXXsetXXX的方法來訪問它。關(guān)于內(nèi)部的方法可看struts架構(gòu)介紹。

           

           我們還要做一些額外的工作。去看struts-config.xml文件,我們需要用這個(gè)新類與Form關(guān)聯(lián),從而替代Book.java。因此我們必須改變form-beans: <form-bean name="bookForm" type="BookForm"/>.

           另外我們還有定義一下當(dāng)錯(cuò)誤發(fā)生時(shí)的信息,在你的配置文件中輸入:error.book.title=Error

           現(xiàn)在編譯你的類,重新啟動(dòng)tomcat,重新登陸CreateBook.jsp.,輸入onebook,你將在tomcatdos窗口看見如下圖所示:

           你也可以在重輸入其他的title,看看tomcatdos窗口有什么變化。

           

           分離BookBookForm的一個(gè)好方法

           上一節(jié)我們使用一個(gè)新類BookForm.java去訪問Book.java,而不用struts直接連接到Book.java。接下來,我們要解決在這兩個(gè)類中重復(fù)輸入getXXXsetXXXStruts允許我們直接訪問實(shí)例的方法。這很容易,但需要理解。我們給出改變的CreateBook.jsp的代碼:

           

           正如你看到的,除了將title改為book.title,我們什么也沒做。現(xiàn)在你可以去掉BookForm.java中的getXXXsetXXX方法了,如下圖:(別忘記了也更改BookView.jsp,否則在你的tomcat窗口下After creation of book : null

           

           

           你還應(yīng)該改動(dòng)BookAction.java,把String title = req.getParameter("title");中的title改為book.title,然后重新編譯,這樣你的tomcat下的After creation of book :none中的none就會(huì)出現(xiàn)你輸入的名了。

           

          posted on 2007-04-13 11:57 白杰 閱讀(790) 評(píng)論(0)  編輯  收藏 所屬分類: java

          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 海口市| 安泽县| 澄城县| 云阳县| 灵武市| 鄂伦春自治旗| 嵊泗县| 临漳县| 晋江市| 麻栗坡县| 柏乡县| 永年县| 宁城县| 青龙| 城市| 清水县| 南部县| 阿坝县| 光山县| 溧水县| 尼勒克县| 香格里拉县| 阜宁县| 额敏县| 邻水| 承德市| 广州市| 呼伦贝尔市| 治多县| 万安县| 库车县| 兖州市| 和龙市| 清新县| 横山县| 馆陶县| 延寿县| 大安市| 阿荣旗| 介休市| 灵宝市|