?????上一篇 Struts2框架的基本使用 我們限于篇幅证鸥,最后簡(jiǎn)單介紹了Action的配置問題失息,本篇接著介紹有關(guān)框架的一些其他基本用法,主要內(nèi)容如下:
- Action的基本配置
- result的基本配置
- Struts的異常處理機(jī)制
- Convention插件于“約定”的支持
一、Action的基本配置
?????上篇文章我們簡(jiǎn)單的看了Struts.xml中的package包元素的一些屬性的使用情況杂数,接下來我們看看Action的元素的一些屬性及其使用情況。依然是上篇的Struts.xml文件瘸洛。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<package name="walker" extends="struts-default">
<action name="login" class="MyPackage.LoginAction">
<result name="error">/error.jsp</result>
<result name="success">/index.jsp</result>
</action>
</package>
</struts>
我們這里的action元素就對(duì)應(yīng)于一個(gè)xxxAction揍移,它的name屬性指定了他所處理的URL,也就是我們請(qǐng)求/login的時(shí)候核心攔截器會(huì)匹配到此Action反肋。class屬性指定了該Action對(duì)應(yīng)的物理路徑那伐。此外action元素還可以有method屬性,該屬性的默認(rèn)值是execute石蔗,也就是當(dāng)核心攔截器匹配到一個(gè)xxxAction的時(shí)候罕邀,會(huì)默認(rèn)調(diào)用它的execute方法,當(dāng)然我們也是可以使用method屬性來顯式指定某個(gè)方法作為默認(rèn)方法調(diào)用养距。
<struts>
<package name="walker" extends="struts-default">
<action name="login" class="MyPackage.LoginAction" method="myMehod">
<result name="error">/error.jsp</result>
<result name="success">/index.jsp</result>
</action>
</package>
</struts>
public class LoginAction extends ActionSupport {
private String username;
private String password;
public String getUsername(){
return this.username;
}
public void setUsername(String s){
this.username = s;
}
public String getPassword(){
return this.password;
}
public void setPassword(String s){
this.password = s;
}
public String execute() throws Exception{
if(getUsername().equals("walker")&&getPassword().equals("yam")){
ActionContext ac = ActionContext.getContext();
ac.put("login","hello 123");
return SUCCESS;
}
return ERROR;
}
public String myMehod(){
ActionContext ac = ActionContext.getContext();
ac.put("login","hello walker");
return SUCCESS;
}
}
我們?cè)赟truts.xml中指定了默認(rèn)調(diào)用的方法是myMethod诉探,從結(jié)果圖中我們可以看出來,框架執(zhí)行了我們的myMethod方法而不是默認(rèn)的execute方法棍厌。
?????在配置action元素的時(shí)候肾胯,Struts框架允許我們?cè)趎ame屬性字段使用通配符。即使用 * 代表一個(gè)或多個(gè)字符耘纱,然后我們可以在class屬性或者子元素中使用{n}來獲取 * 所代表的內(nèi)容敬肚。例如:
<struts>
<package name="walker" extends="struts-default">
<action name="*" class="MyPackage.LoginAction" method="{1}">
<result name="error">/error.jsp</result>
<result name="success">/index.jsp</result>
</action>
</package>
</struts>
當(dāng)我們請(qǐng)求login這個(gè)URL時(shí)候,核心攔截器獲取到這個(gè)URL束析,然后在struts.xml中查找艳馒,哪個(gè)Action能匹配這個(gè)URL呢?當(dāng)它看到一個(gè)action的name值為 * 的時(shí)候畸陡,就決定用此action來響應(yīng)此次請(qǐng)求鹰溜,此時(shí) * 的值為login虽填,{1}表示name中的第一個(gè) * 的值,此處自然也是login曹动,于是顯式調(diào)用LoginAction中的login方法斋日。這就是統(tǒng)配符的簡(jiǎn)單使用情況,其實(shí)子元素result中也是可以通過{n}來獲取 * 的值的墓陈,具體的等到介紹result的時(shí)候在詳解恶守。
下面說一下,有關(guān)使用通配符而產(chǎn)生的匹配順序問題贡必。
<struts>
<package name="walker" extends="struts-default">
<action name="loginABC" class="MyPackage.LoginAction" method="login">
<result name="error">/error.jsp</result>
<result name="success">/index.jsp</result>
</action>
<action name="*ABC" class="MyPackage.LoginAction" method="{1}">
<result name="error">/error.jsp</result>
<result name="success">/index.jsp</result>
</action>
<action name="*" class="MyPackage.LoginAction" method="{1}">
<result name="error">/error.jsp</result>
<result name="success">/index.jsp</result>
</action>
</package>
</struts>
試想一下兔港,如果我們請(qǐng)求 loginABC,框架會(huì)調(diào)用哪個(gè)action來響應(yīng)呢仔拟?這三者都能匹配當(dāng)前請(qǐng)求的URL衫樊。在Struts框架中l(wèi)oginABC原URL優(yōu)先級(jí)最高,后面兩種優(yōu)先級(jí)相同利花,具體選擇按照先后順序科侈。在此例中優(yōu)先級(jí)為:
loginABC > *ABC > *
最后一個(gè)有關(guān)Action配置的是,為Action配置默認(rèn)值炒事,也就是在URL無法匹配到具體的某個(gè)Action的時(shí)候臀栈,默認(rèn)的Action會(huì)去響應(yīng)此URL。
<struts>
<package name="walker" extends="struts-default">
//為默認(rèn)Action指定name
<default-action-ref name="err" />
//為默認(rèn)Action指定class和處理結(jié)果
<action name="err" class="MyPackage.DefaultAction">
<result name="error">/error.jsp</result>
</action>
<action name="login" class="MyPackage.LoginAction" method="login">
<result name="error">/error.jsp</result>
<result name="success">/index.jsp</result>
</action>
</package>
</struts>
public class DefaultAction extends ActionSupport {
public String execute() throws Exception{
return ERROR;
}
}
這樣一旦用戶輸入了不合法的URL挠乳,我們一律跳轉(zhuǎn)到錯(cuò)誤頁面权薯。這一點(diǎn)在安全性方面還是很重要的。
二睡扬、配置處理結(jié)果
?????之前我們一直都在介紹有關(guān)Action的一些配置操作盟蚣,但是始終沒有說明Action返回的一個(gè)字符串是如何對(duì)應(yīng)于物理視圖資源的。其實(shí)從Action返回的字符串要想能夠被核心攔截器識(shí)別是對(duì)應(yīng)于哪個(gè)物理視圖威蕉,是需要在Struts.xml中進(jìn)行配置的刁俭。本小節(jié)就來學(xué)習(xí)下對(duì)處理結(jié)果的配置橄仍。
/*這是之前的Struts.xml配置文件*/
<struts>
<package name="walker" extends="struts-default">
<action name="login" class="MyPackage.LoginAction" method="login">
<result name="error">/error.jsp</result>
<result name="success">/index.jsp</result>
</action>
</package>
</struts>
我么可以看出來韧涨,配置邏輯視圖和物理視圖之間的映射是使用 result 元素來實(shí)現(xiàn)的。配置result元素時(shí)候通常是需要指定兩個(gè)屬性:
- name:對(duì)應(yīng)于Action返回的字符串的值
- type:指定結(jié)果類型侮繁,默認(rèn)值是dispatcher虑粥,可以省略
對(duì)于上面的兩個(gè)屬性,name屬性中指定了一個(gè)字符串宪哩,如果該Action返回的是對(duì)應(yīng)的字符串娩贷,那么核心攔截器就會(huì)知道該視圖的物理位置。至于type屬性锁孟,我們打開sturts-default.xml文件:
<result-types>
<result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/>
//默認(rèn)類型
<result-type name="dispatcher" class="org.apache.struts2.dispatcher.ServletDispatcherResult" default="true"/>
<result-type name="httpheader" class="org.apache.struts2.dispatcher.HttpHeaderResult"/>
<result-type name="redirectAction" class="org.apache.struts2.dispatcher.ServletActionRedirectResult"/>
<result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/>
<result-type name="xslt" class="org.apache.struts2.views.xslt.XSLTResult"/>
<result-type name="plainText" class="org.apache.struts2.dispatcher.PlainTextResult" />
<result-type name="postback" class="org.apache.struts2.dispatcher.PostbackResult" />
</result-types>
以上是Struts框架為我們提供的默認(rèn)的type類型彬祖,至于這些type具有什么作用茁瘦,馬上介紹。此處我們還應(yīng)該知道储笑,如果想要自定義一個(gè)結(jié)果類型的話甜熔,首先需要手寫一個(gè)繼承自com.opensymphony.xwork2.Result,然后在struts.xml文件中使用上述的元素配置定義突倍。最后我們就可以在result元素中使用了腔稀。
?????首先我們我們看第一個(gè)type類型:plainText,它沒什么實(shí)際的意義羽历,主要用于顯示視圖的源代碼焊虏。例如:
<struts>
<package name="walker" extends="struts-default">
<action name="login" class="MyPackage.LoginAction" method="login">
<result name="error">/error.jsp</result>
//此處指定了type類型為plainText
<result name="success" type="plainText">/index.jsp</result>
</action>
</package>
</struts>
可以看到,返回的是index的源代碼秕磷。從此例我們可以看出诵闭,type的作用類似于告訴核心攔截器,對(duì)于剛剛拿到的物理視圖澎嚣,該以怎樣的形式響應(yīng)用戶涂圆,默認(rèn)的是dispather,就是轉(zhuǎn)發(fā)的意思币叹,也就是forward請(qǐng)求該頁面润歉,而對(duì)于我們剛剛指定的typeplainText,就是響應(yīng)用戶以源代碼颈抚。雖然例子沒什么實(shí)際價(jià)值踩衩,但是我們從中推測(cè)出type究竟在對(duì)應(yīng)物理視圖的過程中扮演了怎樣的角色。
?????第二個(gè)type類型是:redirect贩汉。它和dispather很是類似驱富,只不過dispather是同一次請(qǐng)求的轉(zhuǎn)發(fā)操作,而redirect則是重新的一次request匹舞,會(huì)丟失上次請(qǐng)求中的所有參數(shù)值褐鸥。由于和dispather很是類似,此處不再贅述赐稽。
第三個(gè)type類型是:redirectAction叫榕。它和redirect又很相似,只不過redirect一般用于請(qǐng)求具體的資源姊舵,而redirectAction主要用于請(qǐng)求Action晰绎,形成Action處理鏈。
<struts>
<package name="walker" extends="struts-default">
<default-action-ref name="err"/>
<action name="err" class="MyPackage.DefaultAction">
<result name="error">/error.jsp</result>
</action>
<action name="login" class="MyPackage.LoginAction" method="login">
<result name="error">/error.jsp</result>
<result name="success" type="redirectAction">err</result>
</action>
</package>
</struts>
如上述代碼所示括丁,我們loginAction處理完成之后荞下,通過result元素的type屬性指定了下一個(gè)action為err。對(duì)于同package下的Action可以使用相對(duì)路勁,如果非相同的package尖昏,則需要使用Parma元素添加命名空間仰税。
<struts>
<package name="walker" extends="struts-default" namespace="/aaa">
<default-action-ref name="err"/>
<action name="err" class="MyPackage.DefaultAction">
<result name="error">/error.jsp</result>
</action>
</package>
<package name="walker2" extends="struts-default">
<action name="login" class="MyPackage.LoginAction" method="login">
<result name="error">/error.jsp</result>
<result name="success" type="redirectAction">
<param name="actionName">err</param>
<param name="namespace">/aaa</param>
</result>
</action>
</package>
</struts>
代碼比較簡(jiǎn)單,這里就不在贅述了抽诉。
最后介紹一點(diǎn)有關(guān)result配置的內(nèi)容肖卧,我們可以使用全局結(jié)果來使得某些結(jié)果可以被所有的Action使用。我們看個(gè)例子:
<struts>
<package name="walker2" extends="struts-default">
<global-results>
<result name="error">/error.jsp</result>
</global-results>
<action name="login" class="MyPackage.LoginAction">
<result name="success" type="redirectAction">
<param name="actionName">err</param>
<param name="namespace">/aaa</param>
</result>
</action>
</package>
</struts>
我們?cè)趌ogin這個(gè)Action中并沒有配置error對(duì)應(yīng)的result元素掸鹅,但是使用global-results元素配置了一個(gè)全局的結(jié)果塞帐,也就是如果某個(gè)Action返回error,但是在自己的result子元素中沒有找到該結(jié)果對(duì)應(yīng)的物理視圖巍沙,就會(huì)跑到全局下搜索葵姥,如果找到立即使用。此例中我們故意輸錯(cuò)密碼句携,看到的結(jié)果如下:
雖然我們沒有配置error結(jié)果對(duì)應(yīng)的物理視圖榔幸,但是通過查找全局的結(jié)果,框架還是找到error.jsp并forward結(jié)果返回矮嫉。需要注意的是削咆,局部結(jié)果的優(yōu)先級(jí)是高于全局的,也就是如果某個(gè)Action返回的結(jié)果可以在自己的result元素中找到,就不會(huì)搜索全局下的結(jié)果。因?yàn)槭侨值拿2埃褂玫臅r(shí)候還是慎重茸习。
篇幅限制践付,未完待續(xù)。。。