struts2 xml配置/struts.xml檔案結構
轉載注明出處:http://write.blog.csdn.net/postedit/8896764
1.struts.xml檔案
struts.xml檔案是整個Struts2架構的核心。
struts.xml檔案内定義了Struts2的系列Action,定義Action時,指定該Action的實作類,并定義該Action處理結果與視圖資源之間的映射關系。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="example" namespace="/example" extends="struts-default">
<!-- 定義一個Action名稱為HelloWorld,實作類為example.HelloWorld.java-->
<action name="HelloWorld" class="example.HelloWorld">
<!-- 任何情況下都轉入到/example/HelloWorld.jsp -->
<result>/example/HelloWorld.jsp</result>
</action>
<action name="Login_*" method="{1}" class="example.Login">
<!-- 傳回input時,轉入到/example/login.jsp -->
<result name="input">/example/Login.jsp</result>
<!-- 重定向到Menu的Action -->
<result type="redirect-action">Menu</result>
</action>
<action name="*" class="example.ExampleSupport">
<result>/example/{1}.jsp</result>
</action>
</package>
</struts>
關于<result name="input">/example/Login.jsp</result>
以上表示當execute方法傳回input的字元串時,跳轉到/example/Login.jsp。定義rusult元素時,可以指定兩個屬性:type和name。其中name指定了execute方法傳回的字元串,而type指定轉向的資源類型,此處轉向的資源可以是JSP,也可以是FreeMarker等,甚至是另一個Action。
2.加載子配置檔案
Struts2架構的核心配置檔案就是struts.xml配置檔案,該檔案主要負責管理Struts2架構的業務控制器Action。在預設情況下,Struts2架構将自動加載放在WEB-INF/classes路徑下的struts.xml檔案。為了避免随着應用規模的增加,而導緻的struts.xml檔案過于龐大,臃腫,進而是該檔案的可讀性下降。我們可以将一個struts.xml配置檔案分解成多個配置檔案 ,然後在struts.xml檔案中包含其他配置檔案。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
<constant name="struts.devMode" value="false" />
<!--通過include元素導入其他元素-->
<include file="myStruts.xml"/>
</struts>
通過這種方式,Struts2提供了一種子產品化的方式來管理struts.xml配置檔案。
3.package配置
package元素用于定義包配置,每個package元素定義了一個包配置。Struts2架構使用包來管理Action和攔截器等。每個包就是多個Action、多個攔截器、多個攔截器引用的集合。使用package可以将邏輯上相關的一組Action,Result,Intercepter等元件分為一組,package有些像對象,可以繼承其他的package,也可以被其他package繼承,甚至可以定義抽象的package。
package的可以使用的屬性: 屬性 是否必須 說明
name 是 package的表示,指定包的名字,該名字是該包(package)被其他包引用的key。
extends 否 指定該包繼承其他包。繼承其他包,可以繼承其他包中的Action定義、攔截器定義等。
namespace 否 定義該包的命名空間。
abstract 否 可選,它指定該包是否是一個抽象包。抽象包不能包含Action定義。
由于struts.xml檔案是自上而下解析的,是以被繼承的package要放在繼承package的前邊。
4.namespace配置(命名空間配置)
Struts2以命名空間的方式來管理Action,同一個命名空間裡不能有同名的Action,不同的命名空間裡可以有同名的Action。Struts2不支援為單獨的Action設定命名空間,而是通過為包指定namespace屬性來為包下面的所有Action指定共同的命名空間。
namespace将action分成邏輯上的不同子產品,每一個子產品有自己獨立的字首。使用namespace可以有效的避免action重名的沖突,例如每一個package都可以有自己獨立的Menu和Help action,但是實作方式各有不同。Struts2标簽帶有namespace選項,可以根據namespace的不同向伺服器送出不同的package的action的請求。
“/”表示根namespace,所有直接在應用程式上下文環境下的請求(Context)都在這個package中查找。
“”表示預設namespace,當所有的namespace中都找不到的時候就在這個namespace中尋找.
例如,有如下配置:
<package name="default">
<action name="foo" class="mypackage.simpleAction>
<result name="success" type="dispatcher">greeting.jsp</result>
</action>
<action name="bar" class="mypackage.simpleAction">
<result name="success" type="dispatcher">bar1.jsp</result>
</action>
</package>
<package name="mypackage1" namespace="/">
<action name="moo" class="mypackage.simpleAction">
<result name="success" type="dispatcher">moo.jsp</result>
</action>
</package>
<package name="mypackage2" namespace="/barspace">
<action name="bar" class="mypackage.simpleAction">
<result name="success" type="dispatcher">bar2.jsp</result>
</action>
</package>
1)如果請求為/barspace/bar.action
查找namespace('/barspace'),如果找到bar則執行對應的action,否則将會查找預設的namespace,在上面的例子中,在 barspace中存在名字為bar的action,是以這個action将會被執行,如果傳回結果為success,則頁面将定為到bar2.jsp
2)如果請求為/moo.action
根namespace('/')被查找,如果moo.action存在則執行否則查詢預設的namespace,上面的例子中,根namespace中存在moo.action,是以該action被調用,傳回success的情況下頁面将定位到moo.jsp。
又例:
<struts>
<constant name="struts.custom.i18n.resources" value="messageResource"/>
<package name="lee" extends="struts-default">
<action name="login" class="lee.LoginAction">
<result name="input">/login.jsp</result>
<result name="error">/error.jsp</result>
<result name="success">/welcome.jsp</result>
</action>
</package>
<package name="get" extends="struts-default" namespace="/book">
<action name="getBooks" class="lee.GetBooksAction">
<result name="login">/login.jsp</result>
<result name="success">/showBook.jsp</result>
</action>
</package>
</struts>
以上代碼配置了兩個包:lee和get,配置get包時,指定了該包的命名空間為/book。對于名為lee的包而言,沒有指定namespace屬性。如果某個包沒有指定namespace屬性,即該包使用預設的命名空間,則預設的命名空間總是""。
需要注意的問題有兩個:
1)預設命名空間裡的Action可以處理任何子產品下的Action請求。
即:如果存在URL為/book/GetBooks.action的請求,并且/book的命名空間沒有名為GetBooks的Action,則預設命名空間下名為GetBooks的Action也會處理使用者請求。
2)當某個包指定了命名空間後,該包下所有的Action處理的URL應該是: 命名空間+Action名。
以上面的get包為例,該包下包含了名為getBooks的Action,則該Action處理的URL為:
http://localhost:8080/AppName/book/getBooks.action
*AppName是應用名,book是該Action所有包對應的命名空間,getBooks是Action名。
5.Action配置
配置Action就是讓Struts2容器知道該Action的存在,并且能調用該Action來處理使用者請求。是以,我們認為:Action是Struts2的基本“程式機關”。即,在struts2架構中每一個Action是一個工作單元。Action負責将一個請求對應到一個Action處理上去,每當一個Action類比對一個請求的時候,這個Action類就會被Struts2架構調用。Action隻是一個控制器,它并不直接對浏覽器生成任何響應,是以,Action處理完使用者請求後,Action需要将指定的視圖資源呈現給使用者. 是以,配置Action時,應該配置邏輯視圖和實體視圖資源之間的映射。
Struts2使用包來組織Action,是以,将Action的定義是放在包定義下完成的,定義Action通過使用package下的action子元素來完成。至少需要指定該Action的name屬性,該name屬性既是該Action的名字,也是該Action需要處理的URL的前半部分。除此之外,通常還需要為action元素指定一個class屬性,其中class屬性指定了該Action的實作類。
一個簡單的例子:
<package name="lee" extends="struts-default">
<action name="login" class="lee.LoginAction">
<result name="input">/login.jsp</result>
<result name="error">/error.jsp</result>
<result name="success">/welcome.jsp</result>
</action>
</package>
一個較全面的Action配置示例:
<action name="logon" class="tutorial.Logon">
<result type="redirect-action">Menu</result>
<result name="input">/tutorial/logon.jsp</result>
</action>
每一個Action可以配置多個result,多個ExceptionHandler,多個Intercepter,但是隻能有一個name,這個name和package的namespace來唯一差別一個Action。
每當struts2架構接受到一個請求的時候,他會去掉Host,Application和字尾等資訊,得到Action的名字,例如如下的請求将得到Welcome這個Action: http://www.planetstruts.org/struts2-mailreader/Welcome.action
在一個Struts2應用程式中,一個指向Action的連結通常有Struts Tag産生,這個Tag隻需要指定Action的名字,Struts架構會自動添加諸如字尾等的擴充,例如:
<s:form action="Hello">
<s:textfield label="Please enter your name" name="name"/>
<s:submit/>
</s:form>
将産生一個如下的連結的請求:
http://Hostname:post/appname/Hello.action
在定義Action的名字的時候不要使用.和/來命名,最好使用英文字母和下劃線。
5.1.Action中的方法
Action的預設入口方法由xwork2的Action接口來定義,代碼清單為:
public interface Action {
public String execute() throws Exception;
}
有些時候我們想指定一個Action的多個方法,我們可以做如下兩步:
1)建立一些execute簽名相同的方法,例如:
Public String forward() throws Exception
2)在Action配置的時候使用method屬性,例如:
<action name="delete" class="example.CrudAction" method="delete">
5.2.Action中的方法通配符
有些時候對Action中方法的調用滿足一定的規律,例如editAction對應edit方法,deleteAction對應delete方法,這個時候我們可以使用方法通配符,例如:
<action name="*Crud" class="example.Crud" method="{1}">
這時,editCrudAction的引用将調用edit方法,同理,deleteCrudAction的引用将調用delete 方法。
另外一種比較常用的方式是使用下劃線分割,例如:
<action name="Crud_*" class="example.Crud" method="{1}">
這樣當遇到如下調用的時候可以找到對應的方法。
"action=Crud_input" => input方法
"action=Crud_delete"=> delete方法 預設通配符
<action name="*" >
<result>/{1}.jsp</result>
</action>
每個Action将會被映射到以自己名字命名的JSP上。
通配符和普通的配置具有相同的地位,可以結合使用架構的所有其他功能。
5.3.預設的Action
當我們沒有指定Action的class屬性的時候,例如:<action name="Hello"> 我們預設使用com.opensymphony.xwork.ActionSupport.ActionSupport有兩個方法input和execute,每個方法都是簡單的傳回SUCCESS。 通常情況下,請求的Action不存在的情況下,Struts2架構會傳回一個Error畫面:“404 - Page not found”,有些時候或許我們不想出現一個控制之外的錯誤畫面,我們可以指定一個預設的Action,在請求的Action不存在的情況下,調用預設的Action,通過如下配置可以達到要求:
<package name="Hello" extends="action-default">
<default-action-ref name="UnderConstruction">
<action name="UnderConstruction">
<result>/UnderConstruction.jsp</result>
</action>
</package>
5.4.Post-Back Action
可以使用如下畫面達到字畫面重新整理的效果
<s:form>
<s:textfield label="Please enter your name" name="name"/>
<s:submit/>
</s:form>