Struts2+Spring2+Hibernate3 web應(yīng)用示例(四)
Posted on 2007-09-30 09:56 詩特林 閱讀(13755) 評(píng)論(5) 編輯 收藏 所屬分類: Struts六、 創(chuàng)建Action類:BookAction
有Struts 1.x經(jīng)驗(yàn)的朋友都知道Action是Struts的核心內(nèi)容,當(dāng)然Struts 2.0也不例外。不過,Struts 1.x與Struts 2.0的Action模型很大的區(qū)別。
Struts 1.x |
Stuts 2.0 |
|
接口 |
必須繼承org.apache.struts.action.Action或者其子類 |
無須繼承任何類型或?qū)崿F(xiàn)任何接口 |
表單數(shù)據(jù) |
表單數(shù)據(jù)封裝在FormBean中 |
表單數(shù)據(jù)包含在Action中,通過Getter和Setter獲取 |
1、建立BookAction類

























































































































































































































































com.sterning.books.web.actions.BookAction.java
(1)、默認(rèn)情況下,當(dāng)請(qǐng)求bookAction.action發(fā)生時(shí)(這個(gè)會(huì)在后面的Spring配置文件中見到的),Struts運(yùn)行時(shí)(Runtime)根據(jù)struts.xml里的Action映射集(Mapping),實(shí)例化com.sterning.books.web.actions.BookAction類,并調(diào)用其execute方法。當(dāng)然,我們可以通過以下兩種方法改變這種默認(rèn)調(diào)用。這個(gè)功能(Feature)有點(diǎn)類似Struts 1.x中的LookupDispathAction。
在classes/sturts.xml中新建Action,并指明其調(diào)用的方法;
訪問Action時(shí),在Action名后加上“!xxx”(xxx為方法名)。
(2)、細(xì)心的朋友應(yīng)該可能會(huì)發(fā)現(xiàn)com.sterning.books.web.actions.BookAction.java中Action方法(execute)返回都是SUCCESS。這個(gè)屬性變量我并沒有定義,所以大家應(yīng)該會(huì)猜到它在ActionSupport或其父類中定義。沒錯(cuò),SUCCESS在接口com.opensymphony.xwork2.Action中定義,另外同時(shí)定義的還有ERROR, INPUT, LOGIN, NONE。
此外,我在配置Action時(shí)都沒有為result定義名字(name),所以它們默認(rèn)都為success。值得一提的是Struts 2.0中的result不僅僅是Struts 1.x中forward的別名,它可以實(shí)現(xiàn)除forward外的很激動(dòng)人心的功能,如將Action輸出到FreeMaker模板、Velocity模板、JasperReports和使用XSL轉(zhuǎn)換等。這些都過result里的type(類型)屬性(Attribute)定義的。另外,您還可以自定義result類型。
(3)、使用Struts 2.0,表單數(shù)據(jù)的輸入將變得非常方便,和普通的POJO一樣在Action編寫Getter和Setter,然后在JSP的UI標(biāo)志的name與其對(duì)應(yīng),在提交表單到Action時(shí),我們就可以取得其值。
(4)、Struts 2.0更厲害的是支持更高級(jí)的POJO訪問,如this.getBook().getBookPrice()。private Books book所引用的是一個(gè)關(guān)于書的對(duì)象類,它可以做為一個(gè)屬性而出現(xiàn)在BookActoin.java類中。這樣對(duì)我們開發(fā)多層系統(tǒng)尤其有用。它可以使系統(tǒng)結(jié)構(gòu)更清晰。
(5)、有朋友可能會(huì)這樣問:“如果我要取得Servlet API中的一些對(duì)象,如request、response或session等,應(yīng)該怎么做?這里的execute不像Struts 1.x的那樣在參數(shù)中引入。”開發(fā)Web應(yīng)用程序當(dāng)然免不了跟這些對(duì)象打交道。在Strutx 2.0中可以有兩種方式獲得這些對(duì)象:非IoC(控制反轉(zhuǎn)Inversion of Control)方式和IoC方式。
非IoC方式
要獲得上述對(duì)象,關(guān)鍵是Struts 2.0中com.opensymphony.xwork2.ActionContext類。我們可以通過它的靜態(tài)方法getContext()獲取當(dāng)前Action的上下文對(duì)象。另外,org.apache.struts2.ServletActionContext作為輔助類(Helper Class),可以幫助您快捷地獲得這幾個(gè)對(duì)象。
HttpServletRequest request = ServletActionContext.getRequest();
HttpServletResponse response = ServletActionContext.getResponse();
HttpSession session = request.getSession();
如果你只是想訪問session的屬性(Attribute),你也可以通過ActionContext.getContext().getSession()獲取或添加session范圍(Scoped)的對(duì)象。
IoC方式
要使用IoC方式,我們首先要告訴IoC容器(Container)想取得某個(gè)對(duì)象的意愿,通過實(shí)現(xiàn)相應(yīng)的接口做到這點(diǎn)。如實(shí)現(xiàn)SessionAware, ServletRequestAware, ServletResponseAware接口,從而得到上面的對(duì)象。
1、對(duì)BookAction類的Save方法進(jìn)行驗(yàn)證
正如《Writing Secure Code》文中所寫的名言All input is evil:“所有的輸入都是罪惡的”,所以我們應(yīng)該對(duì)所有的外部輸入進(jìn)行校驗(yàn)。而表單是應(yīng)用程序最簡(jiǎn)單的入口,對(duì)其傳進(jìn)來的數(shù)據(jù),我們必須進(jìn)行校驗(yàn)。Struts2的校驗(yàn)框架十分簡(jiǎn)單方便,只在如下兩步:
在Xxx-validation.xml文件中的<message>元素中加入key屬性;
在相應(yīng)的jsp文件中的<s:form>標(biāo)志中加入validate="true"屬性,就可以在用Javascript在客戶端校驗(yàn)數(shù)據(jù)。
其驗(yàn)證文件為:BooksAction-save-validation.xml





















1、對(duì)BookAction類的Save方法進(jìn)行驗(yàn)證的資源文件
注意配置文件的名字應(yīng)該是:配置文件(類名-validation.xml)的格式。BooksAction類的驗(yàn)證資源文件為:BooksAction.properties






com.sterning.books.web.actions.BooksAction.properties
資源文件的查找順序是有一定規(guī)則的。之所以說Struts 2.0的國際化更靈活是因?yàn)樗梢愿鶕?jù)不同需要配置和獲取資源(properties)文件。在Struts 2.0中有下面幾種方法:
(1)、使用全局的資源文件。這適用于遍布于整個(gè)應(yīng)用程序的國際化字符串,它們?cè)诓煌陌?/span>package)中被引用,如一些比較共用的出錯(cuò)提示;
(2)、使用包范圍內(nèi)的資源文件。做法是在包的根目錄下新建名的package.properties和package_xx_XX.properties文件。這就適用于在包中不同類訪問的資源;
(3)、使用Action范圍的資源文件。做法為Action的包下新建文件名(除文件擴(kuò)展名外)與Action類名同樣的資源文件。它只能在該Action中訪問。如此一來,我們就可以在不同的Action里使用相同的properties名表示不同的值。例如,在ActonOne中title為“動(dòng)作一”,而同樣用title在ActionTwo表示“動(dòng)作二”,節(jié)省一些命名工夫;
(4)、使用<s:i18n>標(biāo)志訪問特定路徑的properties文件。在使用這一方法時(shí),請(qǐng)注意<s:i18n>標(biāo)志的范圍。在<s:i18n name="xxxxx">到</s:i18n>之間,所有的國際化字符串都會(huì)在名為xxxxx資源文件查找,如果找不到,Struts 2.0就會(huì)輸出默認(rèn)值(國際化字符串的名字)。
例如:某個(gè)ChildAction中調(diào)用了getText("user.title"),Struts 2.0的將會(huì)執(zhí)行以下的操作:
查找ChildAction_xx_XX.properties文件或ChildAction.properties;
查找ChildAction實(shí)現(xiàn)的接口,查找與接口同名的資源文件MyInterface.properties;
查找ChildAction的父類ParentAction的properties文件,文件名為ParentAction.properties;
判斷當(dāng)前ChildAction是否實(shí)現(xiàn)接口ModelDriven。如果是,調(diào)用getModel()獲得對(duì)象,查找與其同名的資源文件;
查找當(dāng)前包下的package.properties文件;
查找當(dāng)前包的父包,直到最頂層包;
在值棧(Value Stack)中,查找名為user的屬性,轉(zhuǎn)到user類型同名的資源文件,查找鍵為title的資源;
查找在struts.properties配置的默認(rèn)的資源文件,參考例1;
輸出user.title。
未完待續(xù) 。。。。。。