全方位解析:Struts2配置文件

1.1.1 web.xml配置

任何MVC框架都須要與Web應用整合,就不得不依賴於web.xml文件,只有配置在web.xml文件中的Servlet、Filter纔會被應用加載。web

1. 核心控制器及參數配置編程

全部MVC框架都須要Web應用加載一個核心控制器,對於Struts2框架而言,其須要加載FilterDispatcher,只要Web應用負責加載FilterDispatcher,FilterDispatcher將會加載應用的Struts2框架。安全

FilterDispatcher實質是一個過濾器,它負責初始化整個Struts2框架而且處理全部的請求。這個過濾器能夠包括一些初始化參數,有的參數指定了要加載哪些額外的xml配置文件,還有的會影響Struts2框架的行爲。除了FilterDispatcher外,Struts2還提供了一個ActionContexCleanUp過濾器,它的主要任務是當有其它一些過濾器要訪問一個初始化好了的Struts2框架的時候,負責處理一些特殊的清除任務。ActionContexCleanUp過濾器主要配合其餘插件過濾器使用。詳細配置,以下圖所示:服務器

clip_image002

clip_image004

其中有3個初始化參數有特殊意義: session

config:該參數的值是一個以英文逗號(,)隔開的字符串,每一個字符串都是一個XML配置文件的位置。Struts 2框架將自動加載該屬性指定的系列配置文件。 多線程

actionPackages:該參數的值也是一個以英文逗號(,)隔開的字符串,每一個字符串都是一個包空間,Struts 2框架將掃描這些包空間下的Action類。 app

configProviders:若是用戶須要實現本身的ConfigurationProvider類,用戶能夠提供一個或多個實現了ConfigurationProvider接口的類,而後將這些類的類名設置成該屬性的值,多個類名之間以英文逗號(,)隔開。框架

loggerFactory:指定LoggerFactory實現類的類名。jsp

除此以外,還可在此處配置Struts 2常量,每一個<init-param>元素配置一個Struts2常量,其中<param-name>子元素指定了常量name,而<param-value>子元素指定了常量value。ide

至於filter-mapping屬性是過濾器(Filter)必須的一個屬性,用於過濾請求的路徑,此處通常就設爲/*形式,對全部請求uri進行攔截(過濾),除非你要作一些特殊的處理。

2. 標籤庫配置

若是web容器是J2EE1.3(servlet2.3)及之前的規範,因爲不會自動加載Struts2的標籤庫,因此須要在web.xml文件中手動加載Struts2的標籤庫,將struts-tags.tld文件,通常複製放在WEB-INF下面,能夠本身指定,在web.xml中配置的加載標籤訂義文件以下:

clip_image006

但若是web容器是J2EE1.4(servlet2.4),那麼web容器會自動加載標籤庫,Struts 2的標籤庫定義文件包含在struts2-core-2.1.6.jar文件裏,在struts2-core-2.1.6.jar文件的META-INF路徑下,包含了一個struts-tag.tld文件, 這個文件就是Struts 2的標籤庫定義文件,Servlet 2.4規範會自動加載該標籤庫文件,避免了在web.xml文件中從新定義Struts2標籤庫文件的URI。其中struts-tags.tld文件裏包含了加載信息的片段,以下:

clip_image008

1.1.2 struts.properties配置

struts.properties文件定義了Struts 2框架的大量屬性(也稱爲Struts2常量),開發者能夠經過改變這些屬性來知足應用的需求。

struts.properties文件是一個標準的Properties文件,該文件包含了系列的key-value對象,每一個key就是一個Struts 2屬性,該key對應的value就是一個Struts2屬性值。

struts.properties文件一般放在Web應用的WEB-INF/classes路徑下。實際上,只

要將該文件放在Web應用的CLASSPATH路徑下,Struts 2框架就能夠加載該文件。

其實,配置Struts2常量有3個地方:

a) 在struts.properties文件中配置常量;

b) 在web.xml文件中配置FilterDispatcher指定初始化參數來配置常量;

c) 在struts.xml文件中使用<constant …/>元素來配置常量;

下面將該文件必須知道的配置參數詳細列舉出來,以下圖所示:

clip_image010

clip_image012

其餘詳細配置參數,請參考:http://www.javashuo.com/tag/struts.properties

1.1.3 struts.xml配置

struts.xml文件主要負責管理應用中的業務控制器Action映射,以及該Action包含的Result定義等。在默認狀況下,Struts2框架將自動加載放在WEB-INF/classes路徑下的struts.xml文件。

另外,struts-default.xml文件是Struts2框架的默認配置文件,Struts2框架每次都會自動加載該文件。

不只如此,Struts2框架提供了一種相似Eclipse的擴展方式,容許以一種「可插拔」的方式來安裝插件。如:Spring插件、JSF插件等,它們都提供了一個相似的struts2-xxx-plugin.jar的文件,只要將該文件放在WEB-INF/lib路徑下,Struts2框架會自動加載該插件。在struts2-xxx-plugin.jar文件中,包含struts-plugin.xml文件,Struts2框架同時也會加載該文件。經過這種方式,Struts2框架容許使用可插拔的方式管理Struts2框架。

上面介紹的struts.xml、struts-default.xml、struts-plugin.xml,所配置的內容沒有任何區別,只是加載時順序有前後(struts-default.xml、struts-plugin.xml、struts.xml),若三個文件中存在相同的配置,後加載的配置會覆蓋先加載的配置。

1.struts.xml文件結構

<!-- struts是Struts 2配置文件的根元素 -->

<struts>

<!-- 常量配置元素能夠出現零次,也能夠出現無數次 -->

<constant name="" value="" />

<!-- Bean配置元素能夠出現零次,也能夠出現無數次 -->

<bean type="" name="" class="" scope="" static="" optional="" />

<!-- 配置文件包含元素能夠出現零次,也能夠出現無數次 -->

<include file="" />

<!-- 包元素是Struts配置文件的核心,該元素能夠出現零次,或者無數次 -->

<package name="必填的包名" extends="" namespace="" abstract="" externalReferenceResolver>

<!-- 返回結果類型集合元素能夠出現,也能夠不出現,最多出現一次 -->

<result-types>

<!-- 返回結果類型元素必須出現,能夠出現無數次 -->

<result-type name="" class="" default="true|false">

<!-- 返回結果類型參數元素能夠出現零次,也能夠無數次 -->

<param name="參數名">參數值</param>*

</result-type>

</result-types>

<!-- 攔截器集合元素能夠出現,也能夠不出現,最多出現一次 -->

<interceptors>

<!-- 攔截器集合元素的interceptor元素和interceptor-stack至少出現其中之一, 也能夠兩者都出現 -->

<!-- 攔截器元素能夠出現零次,也能夠無數次 -->

<interceptor name="" class="">

<!-- 攔截器參數元素能夠出現零次,也能夠無數次 -->

<param name="參數名">參數值</param>*

</interceptor>

<!-- 攔截器棧元素能夠出現零次,也能夠無數次 -->

<interceptor-stack name="">

<!-- 引用攔截器元素必須出現,能夠出現無數次 -->

<interceptor-ref name="">

<!-- 引用攔截器參數元素能夠出現零次,也能夠無數次 -->

<param name="參數名">參數值</param>*

</interceptor-ref>

</interceptor-stack>

</interceptors>

<!-- 默認攔截器(棧)引用元素能夠出現零次,也能夠無數次 -->

<default-interceptor-ref name="">

<!-- 默認攔截器(棧)引用參數元素能夠出現零次,也能夠無數次 -->

<param name="參數名">參數值</param>

</default-interceptor-ref>

<!-- 默認Action引用元素能夠出現零次,也能夠無數次 -->

<default-action-ref name="">

<!-- 默認Action引用參數元素能夠出現零次,也能夠無數次 -->

<param name="參數名">參數值</param>*

</default-action-ref>?

<!-- 全局返回結果集合元素能夠出現零次,也能夠無數次 -->

<global-results>

<!-- 返回結果元素必須出現,能夠出現無數次 -->

<result name="" type="">

<!-- 該字符串內容能夠出現零次或屢次 -->

映射資源

<!-- 返回結果參數元素能夠出現零次,也能夠無數次 -->

<param name="參數名">參數值</param>*

</result>

</global-results>

<!-- 全局異常映射集合元素能夠出現零次,也能夠無數次 -->

<global-exception-mappings>

<!-- 異常映射元素必須出現,能夠出現無數次 -->

<exception-mapping name="" exception="" result="">

異常處理資源

<!-- 異常映射參數元素能夠出現零次,也能夠無數次 -->

<param name="參數名">參數值</param>*

</exception-mapping>

</global-exception-mappings>

<!-- Action元素能夠出現零次,也能夠無數次 -->

<action name="" class="" method="" converter="">

<!-- Action參數元素能夠出現零次,也能夠無數次 -->

<param name="參數名">參數值</param>*

<!-- 返回結果元素能夠出現零次,也能夠無數次 -->

<result name="" type="">

映射資源

<!-- 結果參數元素能夠出現零次,也能夠無數次 -->

<param name="參數名">參數值</param>*

</result>

<!-- 攔截器(棧)引用元素能夠出現零次,也能夠無數次 -->

<interceptor-ref name="">

<!-- 攔截器(棧)引用參數元素能夠出現零次,也能夠無數次 -->

<param name="參數名">參數值</param>*

</interceptor-ref>

<!-- 異常映射元素能夠出現零次,也能夠無數次 -->

<exception-mapping name="" exception="" result="">

異常處理資源

<!—異常映射參數元素能夠出現零次,也能夠無數次 -->

<param name="參數名">參數值</param>*

</exception-mapping>

</action>

</package>*

<!-- 未知處理器棧元素可出現零次或1次 -->

<unknown-handler-stack>

<!-- 未知處理器元素可出現零次或屢次 -->

<unknown-handler-ref name=" ">...</unknown-handler-ref>*

</unknown-handler-stack>?

<struts>

2.struts.xml標籤使用介紹

a) 使用<include>標籤重用配置文件

在Struts2中提供了一個默認的struts.xml文件,但若是package、action、

interceptors等配置比較多時,都放到一個struts.xml文件不太容易維護。所以,就須要將struts.xml文件分紅多個配置文件,而後在struts.xml文件中使用<include>標籤引用這些配置文件。這樣作優勢以下:

1) 結構更清晰,更容易維護配置信息;

2) 配置文件能夠複用。若是在多個Web程序中都使用相似或相同的配置文件,那麼可使用<include>標籤來引用這些配置文件,這樣能夠減小工做量。

clip_image014

小提示:

用<include>引用的xml文件也必須是完整的struts2配置,如:必須包括頭部信息等。實際上<include>在引用時是單獨解析的xml文件,而不是將被引用的文件插入到struts.xml文件中。

一般,將Struts2的全部配置文件都放在Web應用的WEB-INF/classes路徑下,struts.xml文件包含了其餘的配置文件,Struts2框架自動加載struts.xml文件時,完成加載全部配置信息。

b) 使用<constant>標籤進行常量配置

在以前提到struts.properties配置文件的介紹中,咱們曾經提到全部在struts.properties文件中定義的屬性,均可以配置在struts.xml文件中。而在struts.xml中,是經過<constant>標籤來進行配置的。

clip_image016

小提示:

一般推薦在struts.xml文件中配置Struts2常量,而不是在struts.properties文件中配置常量。之因此保留使用struts.properties文件配置Struts2常量的方式,主要是爲了保持與WebWork之間的兼容性。

統一塊兒來看,Struts2的常量配置能夠在struts-plugin.xml、struts.xml、struts.properties、web.xml中配置,則Struts2框架會按以下搜索順序加載Struts2常量:default.properties、struts-default.xml、struts-plugin.xml、struts.xml、struts.properties、web.xml,若是在多個文件中配置了同一個Struts2常量,則後面文件中配置的常量值會覆蓋前面文件中配置的常量值。

一般推薦將Struts2常量集中在struts.xml文件中進行管理。

c) 使用<bean>標籤配置Bean組件

Struts2框架是一個高度可擴展性的框架,框架大部分核心組件,Struts2並非以硬編碼的方式寫在代碼中的,而是以本身的IOC容器來管理框架的核心組件。

Struts2框架以可配置的方式來管理Struts2的核心組件,從而容許開發者能夠很方便地擴展該框架的核心組件。當開發者須要擴展,或者替換Struts2的核心組件時,只須要提供本身的組件實現類,並將該組件實現類配置在Struts2的IOC容器中便可。

在strus.xml文件中定義Bean時,一般有兩個做用:

1) 建立該Bean的實例,將該實例做爲Struts2框架的核心組件使用;

2) Bean包含的靜態方法須要注入一個值;

在第一種用法下,由於Bean實例每每是做爲一個核心組件使用的,所以須要告訴Struts2容器該實例的做用-就是該實例實現了哪一個接口,這個接口每每定義了該組件作必須遵照的規範,配置以下圖所示:

clip_image018

在第二種用法下,則能夠很方便容許不建立某個類的實例,卻能夠接受框架常量,一般須要設置static=true。

clip_image020

小提示:

對於絕大部分Struts2應用而言,咱們無需從新定義Struts2框架的核心組件,也就無需在Struts.xml文件中定義Bean。

在使用<bean/>元素在struts.xml文件中定義Bean,bean元素有如下幾個屬性:

class:必填屬性,它指定了Bean實例的實現類。

type:可選屬性,它指定了Bean實例實現的Struts2的規範,該規範

一般是經過某個接口或者在此前定義過的Bean,所以該屬性值一般是個接口或者此前定義過的Bean的name屬性值。若是須要將Bean的實例做爲Strut2組件使用,則應該指定該屬性的值。

name:可選屬性,它指定的Bean實例的名字,對於有相同type的多個Bean。則它們的name屬性不能相同。

scope:可選屬性,它指定Bean實例的做用域,該屬性的值只能是default、singleton、request、session或thread之一。

static:可選屬性,它指定Bean是否使用靜態方法注入。一般而言,當指定了type屬性時,該屬性就不該該指定爲true。

optional:可選屬性,它指定Bean是不是一個可選Bean。

d) 使用<package>標籤配置包

Struts2框架中核心組件就是Action、Interceptor、Result等,Struts2使用包來管理。每一個包就是多個Action、多個Interceptor、多個Result、多個Interceptor引用的集合。

屬性

必需

描述

name

包名,做爲其它包應用本包的標記

extends

設置本包繼承其它包

namespace

設置包的命名空間

abstract

設置爲抽象包

1. name屬性:必填屬性,指定包的名字,該名字是該包被其餘包引用的key;

2. abstract屬性:該屬性爲true時,該包爲抽象包,抽象包不能包含Action定義;

2. extends屬性:當一個包經過配置extends屬性繼承了另外一個包時,該包將會繼承父包中全部的配置,包括action、result、interceptor等;因爲包信息的獲取是按照配置文件的前後順序進行的,且Struts2配置文件是從上到下處理的,因此父包應該在子包前面定義;一般咱們配置struts.xml時,都繼承一個名爲「struts-defaul」

的包,該包是struts2內置的包。

3. namespace屬性:該屬性針對大型項目中Action的管理,更重要的是解決Action重名問題,同一個命名空間裏不能有同名的Action,不一樣的命名空間能夠有同名的Action。

<package>標籤具體配置,以下圖所示:

clip_image022

4. Struts2若是沒有爲某個包指定命名空間,該包使用默認的命名空間,默認的命名空間老是"";

5. Struts2還能夠顯示指定根命名空間,經過設置包的namespace="/"來指定根命名空間;

6. Struts2會按順序在命名空間中搜索請求的Action,以下:命名空間只有一個級別。若是請求的URL是/bookservice/search/get.action,系統將先在/bookservice/search的命名空間下查找名爲get的Action,若是查找到,則有該Action處理;若是未查找到,系統直接進入默認的命名空間查找名爲get的Action,而不會在/bookservice的命名空間下查找名爲get的Action;

小提示:

查找Action會根據URL對應的命名空間(可能會是根命名空間)查找Action,若沒有,則會在默認命名空間裏查找。

7. Struts2默認命名空間和根命名空間二者區別:

默認的命名空間namespace="",根命名空間namespace="/";

clip_image024

若是未指定命名空間,則命名空間默認爲namespace=""。默認命

名空間裏的Action能夠處理任何命名空間下的Action請求,而根命名空間裏的Action只處理根命名空間下的Action請求。

Struts2查找對應的Action時,會根據URL首先在對應的命名空間下查找,若未查找到,則繼續會在默認命名空間下查找。

e) 使用<interceptor-stack>、<interceptors>、<interceptor>標籤配置攔截器

攔截器其實就是AOP的編程思想。攔截器容許在Action處理以前,或者Action處理以後,插入開發者自定義的代碼。

一般,使用攔截器能夠完成以下操做:進行權限控制、跟蹤日誌、跟蹤系統的性能瓶頸。

Struts2容許多個攔截器組合在一塊兒,造成一個攔截器棧。一個攔截器棧能夠包含多個攔截器,多個攔截器組成一個攔截器棧。對於Struts2系統而言,多個攔截器組成的攔截器棧對外也表現成一個攔截器。

能夠認爲多個攔截器組成攔截器棧是一個大的攔截器。Struts2推薦定義多個小粒度的攔截器,而後組合成攔截器棧來完成複雜的功能,而不是直接定義大粒度攔截器。同一個小粒度的攔截器,能夠與其餘不一樣的攔截器組成不一樣的攔截器棧,從而提供更好的複用性。

定義攔截器棧以前,必須先定義組成攔截器棧的多個攔截器,相關配置以下圖所示:

clip_image026

在package元素節點下,設置Action默認攔截器引用:

clip_image028

小提示:

使用<default-interceptor-ref>標籤能夠爲其所在的Action添加默認攔截器功能。當爲某個Action單獨添加攔截器功能後,<default-interceptor-ref>中所指定的默認攔截器將再也不對這個Action起做用,須要再次手動添加默認攔截器引用。

f) 使用<action>標籤配置業務控制器Action

1. 實現Action處理類

相對於Struts1而言,Struts2採用了低侵入式的設計,Struts2不要求Action類繼承任何的Struts2基類,甚至不要求實現任何Struts2接口,在這種設計方式下,Struts2的Action類是一個普通POJO類(一般應該包含一個無參數的execute方法),Struts2會默認執行該類的execute方法,從而有很好的代碼複用性。這正如HelloWord應用中的Action實現類。

Struts2一般直接使用Action來封裝Http請求參數,以下圖所示:

clip_image030

小提示:

即便Action須要處理的請求包含username和password兩個HTTP參數,Action類也能夠不包含username和password屬性。由於系統是經過對應的getter和setter方法來處理請求參數的,而不是經過屬性名來處理請求參數的。也就是說,若是包含username的HTTP請求參數,Action類裏是否包含username屬性並不重要,重要的是需要包含setter和getter兩個方法。

Action類裏的屬性,不只用於封裝請求參數,還能夠用於封裝處理結果。對系統而言,封裝請求參數的屬性和封裝處理結果的屬性是徹底平等的。

若是HTTP請求裏包含了名爲username的請求參數,系統會調用Action類的setUsername方法,經過這種方法,名爲username的請求參數就能夠傳遞給Action實例;若是Action類裏沒有包含對應的set方法,則請求參數沒法傳入該Action。

一樣,在jsp頁面中輸出Action屬性username時,系統會調用Action類的getUsername方法,系統不會區分該屬性是用於封裝請求參數的屬性仍是用於封裝處理結果的屬性。所以,使用Struts2的標籤既能夠輸出Action的處理結果,也能夠輸出HTTP請求參數值。

2. Action接口與ActionSupport類

雖然Struts2沒有要求Action必須實現特定接口或繼承特定類,但爲了讓用戶開發的Action類規範,Struts2提供了一個Action接口,這個接口定義了Struts2的Action處理類應該實現的規範,開發者的Action類能夠實現該接口。下面是標準Action接口的代碼:

clip_image032

Struts2還爲Action接口提供了一個實現類:ActionSupport,下面是該ActionSupport實現類的代碼:

clip_image034

clip_image036

小提示:

ActionSupport是一個默認的Action類,該類已經提供了許多默認的方法,這些默認方法包括獲取國際化信息的方法、數據校驗的方法、默認的處理用戶請求的方法等。實際上,ActionSupport類徹底能夠做爲Struts2應用的Action處理類(由於它已經實現了execute方法),若是讓開發者的Action類繼承該ActionSupport類,則會大大簡化Action的開發。

因爲ActionSupport徹底可做爲Struts2應用的Action處理類,所以當用戶配置Action類沒有指定class屬性時,系統會自動使用ActionSupport類做爲Action默認的處理類。此時,該Action老是返回「success」字符竄做爲邏輯視圖名。配置Action默認的處理類,以下圖所示:

clip_image038

3. Action訪問Servlet API

Struts2的Action並未直接與任何Servlet API耦合,這是Struts2的一個改良之處,由於Action類再也不與Servlet API耦合,從而能更輕鬆地測試該Action。

但對於Struts2應用中控制器而言,除了將請求參數自動設置到Action的字段中,不訪問Servlet API幾乎是不可能的。Struts2應用中一般須要訪問的Servlet API就是HttpServletRequest、HttpSession和ServletContext,這3個類分別表明JSP內置對象中的request、session和application。Struts2一般會如下面兩種方式,訪問Servlet API:

非IOC方式

經過以非IOC的方式訪問上述對象,關鍵是要經過Struts 2中com.opensymphony.xwork2.ActionContext類的方法得到Struts2封裝的Servlet API的Map對象。

ActionContext是一個Action的上下文對象,Action運行期間所用到的數據都保存在ActionContext中(如Session,客戶端提交的參數等信息)。上下文能夠看做是一個容器(其實咱們這裏的容器就是一個Map而已),它存放的是Action在執行時須要用到的對象,好比:在使用WebWork時,咱們的上下文放有請求的參數(Parameter)、會話(Session)、Servlet上下文(ServletContext)、本地化(Locale)信息等。在Action中能夠經過下面的代碼來建立和使用ActionContext類,關於該類的方法介紹以下所示:

ActionContext ac=ActionContext.getContext();//獲取ActionContext對象

1.Object get(Object key) :經過參數key來查找當前ActionContext中的對應的value。該方法可獲取HttpServletRequest屬性。
2.Map getApplication() :返回一個Application級的Map對象,該對象模擬了該應用的ServletContext實例。
3.Static ActionContext getContext() :靜態方法,得到當前線程的ActionContext對象。
4.Map getParameters() :返回一個包含全部HttpServletRequest參數信息的Map對象 。
5.Map getSession() :返回一個Map類型的HttpSession對象,該對象模擬了HttpSession實例。
6.Void put(Object key,Object value) :向當前ActionContext對象中存入鍵值對信息,該方法可用於向HttpServletRequest裏存入屬性。
7.Void setApplication(Map application) :直接傳入一個Map實例,將該Map實例裏的key-value對轉換成application的屬性名、屬性值,以設置Application上下文對象。
8.Void setSession(Map session) :直接傳入一個Map實例,將該Map實例裏的key-value對轉換成session的屬性名、屬性值。

小提示:

1.WebWork框架將與Web相關的不少對象從新進行了包裝,好比這裏就將HttpSession對象從新包裝成了一個Map對象,供咱們的Action使用,而不用直接和底層的HttpSession打交道。也正是框架的包裝,讓咱們的Actoion能夠徹底的和Web層解藕。

2.ActionContext有一個內置的map,全部的參數都保存在這個map中,其中就有valuestack;

3.在每次執行Action以前都會建立新的ActionContext,ActionContext是線程安全的,也就是說在同一個線程裏ActionContext裏的屬性是惟一的,這樣個人Action就能夠在多線程中使用。ActionContext中有個靜態的ThreadLocal變量,用來存放每一個Action的actionContext。以下圖所示:

clip_image040

ActionContextThreadLocal是實現ThreadLocal的一個內部類。ThreadLocal能夠命名爲「線程局部變量」,它爲每個使用該變量的線程都提供一個變量值的副本,使每個線程均可以獨立地改變本身的副本,而不會和其它線程的副本衝突。這樣,咱們ActionContext裏的屬性只會在對應的當前請求線程中可見,從而保證它是線程安全的。

非IOC方式實現Action,如圖所示:

clip_image042

顯然,相比Struts1中直接訪問Servlet API,Struts2經過ActionContext訪問Servlet API更加優雅。讓Action完全從Servlet API中分離出來,從而能夠容許該Action脫離Web容器運行。最大的好處:能夠脫離Web容器測試。

另外,爲了直接訪問Servlet API,Struts2提供了一個ServletActionContext,這個類包含了幾個靜態方法:

PageContext getPageContext():取得Web應用Http頁面的PageContext對象。

HttpServletRequest getRequest():取得Web應用HttpServletRequest

對象。

HttpServletResponse getResponse():取得Web應用的

HttpServletResponse對象。

ServletContext getServletContext():取得Web應用的ServletContext對象。

具體使用,相關代碼如圖所示:

clip_image044

小提示:

藉助ServletActionContext類的幫助,開發者也能夠在Action中直接訪問Servlet API,避免Action類須要實現XXXAware接口,雖然如此,此種方式仍不被推薦,該Action依然與Servlet API直接耦合,同樣不利於程序解耦。

IOC方式

要使用IOC方式,一般首先要告訴IOC容器想取得某個對象的意願,經過實現對應的接口能夠作到這點。

ServletContextAware:實現了該接口的Action能夠直接訪問web應用的ServletContext實例。

SerlvetRequestAware:實現了該接口的Action能夠直接訪問webDe HttpSerlvetRequest實例。

ServletResponseAware:實現了該接口的Action能夠直接訪問服務器的相應的HttpServletResponse對象。

若是實現了ServletResponseAware只須要實現之中的public void setServletResponse(HttpServletResponse response)方法便可,而後就可使用httpServletResponse對象進行操做。ServletRequestAware對象也是這樣的。

相關代碼如圖所示:

clip_image046

小提示:

必須指出,雖然能夠在Action類中獲取HttpServletResponse,但若是但願經過HttpServletResponse來生成服務器響應是不可能的,由於Action只是控制器。即若是在Action中書寫以下代碼:

response.getWrite().println("Hello World");

上面代碼在標準Servlet中會生成對客戶端的輸,但在Struts2的Action中,沒有任何實際意義。

因此即便咱們在Struts2的Action類中得到了HttpServletRequest對象,也不要嘗試直接在Action中生成對客戶端的輸出。由於那很沒意義。

4. 配置Action

一旦提供了Action的實現類後,就能夠在struts.xml文件中配置該Action。配置Action就是讓Struts2容器知道該Action的存在,而且可以調用該Action來處理用戶請求。所以,Action是Struts2的基本「程序單位」。

<action>屬性介紹

屬性名稱

是否必須

功能描述

name

請求的Action名稱

class

Action處理類對應具體路徑

method

指定Action中的方法名

converter

指定Action使用的類型轉換器

1. name屬性:必選屬性,指定該Action的名字,也同時指定該Action須要處理的URL的後半部分,如:URL爲/bookservice/search/get.action,則name應該爲get;等同於Struts1中Action的path屬性。

若是須要在name屬性中使用斜線(/),則須要指定Struts2框架容許Action name中出現斜線。配置如圖所示:

clip_image048

若是咱們但願Struts2應用能夠列出Web應用根路徑下的全部頁面,則能夠在struts.xml文件中配置一個name=」」的Action,該Action就能夠處理列出Web應用根路徑下的全部文件請求。配置以下圖所示:

clip_image050

此外,還須要保證Web容器自己能夠列出根路徑下全部文件。好比Tomcat 5.五、6.0,它默認是不會列出的。因此要修改Tomcat的conf/web.xml文件98行的listings參數,將其修改成true。

2. class屬性:可選屬性,指定該Action的實現類。若未指定class屬性,系統則默認使用系統的ActionSupport類。

3. method屬性:可選屬性,指定Action處理請求的方法名。若未指定method屬性,則Action處理請求默認執行execute方法。

4. 動態方法調用:能夠採用DMI調用來處理這種請求。動態方法調用是指表單元素的action並非直接等於某個Action的名字。而是以以下來指定Form的action屬性:

action=」action!methodName.action」(若以/開始,則爲絕對路徑;不然爲相對路徑。)

使用動態方法調用前必須設置Struts2容許動態方法調用。配置以下:

clip_image052

5. 使用通配符:在配置<action>元素時,須要指定name、class和method屬性,其中name屬性可支持通配符,而後能夠在class、method屬性中使用表達式。這種使用通配符的方式是另外一種形式的動態方法調用。

clip_image054

實際上,Struts2不只容許在class、name、method屬性中使用表達式,還能夠在<result>元素中使用表達式。

使用通配符模式配置Action時,URL與 Action的匹配規則以下:由於除非請求的URL與Action的name屬性絕對相同,不然,將按前後順序來決定由哪一個Action來處理用戶請求。所以,咱們應該將名爲星號「*」的Action配置在最後,不然Struts2將使用該Action來處理全部但願使用通配符匹配的請求。

6. 配置默認Action

對於使用Struts2框架的應用而言,儘可能不要讓超連接直接連接到某個視圖資源,由於這種方式增長了額外的風險。推薦將全部請求都發送給Struts2框架,讓該框架來處理用戶請求,即便只是簡單的超連接。

對於只是簡單的超連接的請求,能夠經過定義name爲*的Action(該Action應該放在最後位置定義)實現。除此以外,Struts2還容許在容器中定義一個默認的Action,當用戶請求的URL在容器中找不到對應的Action時,系統將使用默認Action來處理用戶請求。相關配置如圖所示:

clip_image056

<action>具體配置

clip_image058

小提示:

Action只是一個控制器,它並不會像Servlet那樣直接對瀏覽者生成任何響應。因此,在Action中,任何的response輸出都是無效的,非法的,所以,Action處理完用戶請求後,Action須要將指定的視圖資源呈現給用戶,所以,配置Action時,應該配置邏輯視圖資源和物理視圖資源之間的映射。

j) 使用<result>標籤配置返回結果

配置邏輯視圖資源和物理視圖資源之間的映射關係是經過<result>元素來定義的,每一個<result>元素定義邏輯視圖和物理視圖之間的一次映射。

Action處理完用戶請求後,並未直接將請求轉發給任何具體的視圖資源,而是返回一個邏輯視圖,Struts2框架收到這個邏輯視圖後,把請求轉發到對應的視圖資源,視圖資源將處理結果呈現給用戶。

簡單的說,結果是告訴Struts2框架,當Action處理結束時,系統下一步作什麼。當Action返回一個普通字符串時,系統下一步將作什麼。

局部結果:將<result>做爲<action>元素的子元素配置;

全局結果:將<result>做爲<global-results>元素的子元素配置;

<result>屬性介紹

屬性名稱

是否必須

功能描述

name

對應Action返回邏輯視圖名稱,默認爲success

type

返回結果類型,默認爲dispatcher

parse

指定是否容許在實際視圖名字中使用OGNL表達式,默認爲true。

小提示:

1. Struts2默認的結果類型是dispatcher,但咱們能夠經過修改配置文件,改變默認的結果類型。一旦改變了默認的結果類型,若是配置<result>元素時省略type元素時,則意味着使用默認的結果類型。

2. 若是配置<result>元素時沒有指定location參數,系統將會把<result>…</result>中間的字符串當成實際視圖資源;

若是沒有指定name屬性,則name屬性採用默認值:success;

若是沒有指定type屬性,則採用Struts2的默認結果類型;

3. 全局結果的做用範圍是對全部的Action都有效;局部結果的做用範圍僅是當前Action有效。

4. 若是一個Action裏包含了與全局結果裏同名的結果,則Action裏的局部Action會覆蓋全局Action。也就是說,當Action處理用戶請求結束後,會首先在本Action裏的局部結果裏搜索邏輯視圖對應的結果,只有在Action裏的局部結果裏找不到邏輯視圖對應的結果,纔會到全局結果裏搜索。

<result>具體配置

1. 全局結果配置

clip_image060

2. 局部結果配置

clip_image062

h) 使用<result-type>標籤配置返回結果類型

Struts2支持使用多種視圖技術,如:JSP、Velocity和FreeMarker等。當一個Action處理用戶請求結束後,僅僅返回一個字符串,這個字符串只是邏輯視圖名,該邏輯視圖並未與任何的視圖技術及任何的視圖資源關聯,直到咱們在struts.xml文件中爲該邏輯視圖指定實際的視圖資源。

結果類型決定了Action處理結束後,下一步將執行哪一種類型的動做。

Struts2的結果類型要求實現com.opensymphony.xwork.Result接口,是全部Action執行結果的通用接口。若是咱們須要本身的結果類型,咱們應該提供一個實現該接口的類,而且在struts.xml文件中配置該結果類型。

如下列出Struts2框架自帶的幾種結果類型配置,並作了簡要說明,如圖所示:

clip_image064

k) 使用<global-exception-mapping>、<exception-mapping>標籤配置異常映射

clip_image066

l) 使用<unknown-handler-stack>與<unknown-handler-ref>標籤配置未知處理器

clip_image068

相關文章
相關標籤/搜索