版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家! !1Struts2Struts2講師:講師:高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家! !2Struts2Struts2是在WebWork2基礎(chǔ)發(fā)展而來(lái)的。和struts1一樣, Struts2也屬于MVC框架。不過(guò)有一點(diǎn)大家需要注意的是:盡管Struts2和struts1在名字上的差別不是很大,但Struts2和struts1在代碼編寫(xiě)風(fēng)格上幾乎是不一樣的。那么既然有了struts1,為何還要推出struts2。主要是因?yàn)閟truts2有以下優(yōu)點(diǎn):1 在軟件設(shè)計(jì)上Struts2沒(méi)有像struts1那樣跟Servlet API和str
2、uts API有著緊密的耦合,Struts2的應(yīng)用可以不依賴于Servlet API和struts API。 Struts2的這種設(shè)計(jì)屬于無(wú)侵入式設(shè)計(jì),而Struts1卻屬于侵入式設(shè)計(jì)。public class OrderListAction extends Action public ActionForward execute(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response)throws Exception 2 Struts2提供了攔截器,利用攔截器
3、可以進(jìn)行AOP編程,實(shí)現(xiàn)如權(quán)限攔截等功能。3 Strut2提供了類(lèi)型轉(zhuǎn)換器,我們可以把特殊的請(qǐng)求參數(shù)轉(zhuǎn)換成需要的類(lèi)型。在Struts1中,如果我們要實(shí)現(xiàn)同樣的功能,就必須向Struts1的底層實(shí)現(xiàn)BeanUtil注冊(cè)類(lèi)型轉(zhuǎn)換器才行。4 Struts2提供支持多種表現(xiàn)層技術(shù),如:JSP、freeMarker、Velocity等5 Struts2的輸入校驗(yàn)可以對(duì)指定方法進(jìn)行校驗(yàn),解決了Struts1長(zhǎng)久之痛。6 提供了全局范圍、包范圍和Action范圍的國(guó)際化資源文件管理實(shí)現(xiàn)高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家! !3搭建Struts2開(kāi)發(fā)環(huán)境搭建Struts2環(huán)境時(shí),我們一般需要做以
4、下幾個(gè)步驟的工作:1找到開(kāi)發(fā)Struts2應(yīng)用需要使用到的jar文件.2編寫(xiě)Struts2的配置文件3在web.xml中加入Struts2 MVC框架啟動(dòng)配置高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家! !4搭建Struts2開(kāi)發(fā)環(huán)境-開(kāi)發(fā)Struts2應(yīng)用依賴的jar文件我們可以到下載struts-2.x.x-all.zip,目前最新版為2.1.8。下載完后解壓文件,開(kāi)發(fā)struts2應(yīng)用需要依賴的jar文件在解壓目錄的lib文件夾下。不同的應(yīng)用需要的JAR包是不同的。下面給出了開(kāi)發(fā)Struts 2程序最少需要的JAR。struts2-core-2.x.x.jar :Struts 2框
5、架的核心類(lèi)庫(kù)xwork-core-2.x.x.jar :XWork類(lèi)庫(kù),Struts 2在其上構(gòu)建ognl-2.6.x.jar :對(duì)象圖導(dǎo)航語(yǔ)言(Object Graph Navigation Language),struts2框架通過(guò)其讀寫(xiě)對(duì)象的屬性freemarker-2.3.x.jar :Struts 2的UI標(biāo)簽的模板使用FreeMarker編寫(xiě)commons-logging-1.x.x.jar :ASF出品的日志包,Struts 2框架使用這個(gè)日志包來(lái)支持Log4J和JDK 1.4+的日志記錄。commons- 文件上傳組件,2.1.6版本后必須加入此文件高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家高級(jí)
6、軟件人才實(shí)作培訓(xùn)專(zhuān)家! !5搭建Struts2開(kāi)發(fā)環(huán)境- Struts2應(yīng)用的配置文件Struts2默認(rèn)的配置文件為struts.xml ,該文件需要存放在WEB-INF/classes下,該文件的配置模版如下:注意:此文件在開(kāi)發(fā)的時(shí)候是放到src目錄下,程序編譯后會(huì)自動(dòng)拷貝到WEB-INF/classes目錄下。此文件我們可以不用自己手寫(xiě)直接到Struts框架的例子程序中拷貝過(guò)來(lái)稍稍修改一下即可高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家! !6搭建Struts2開(kāi)發(fā)環(huán)境-Struts2在web中的啟動(dòng)配置在struts1.x中, struts框架是通過(guò)Servlet啟動(dòng)的。在strut
7、s2中,struts框架是通過(guò)Filter啟動(dòng)的。他在web.xml中的配置如下: struts2 org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter !- 自從Struts 2.1.3以后,下面的FilterDispatcher已經(jīng)標(biāo)注為過(guò)時(shí) org.apache.struts2.dispatcher.FilterDispatcher - struts2 /*在StrutsPrepareAndExecuteFilter的init()方法中將會(huì)讀取類(lèi)路徑下默認(rèn)的配置文件struts.xml完成初始化操作。注
8、意注意:struts2讀取到struts.xml的內(nèi)容后,以javabean形式存放在內(nèi)存中,以后struts2對(duì)用戶的每次請(qǐng)求處理將使用內(nèi)存中的數(shù)據(jù),而不是每次都讀取struts.xml文件高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家! !7第一個(gè)Struts2應(yīng)用-HelloWorld在默認(rèn)的配置文件struts.xml 中加入如下配置: /WEB-INF/page/hello.jsp 高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家! !8Struts.xml配置中的包介紹 /WEB-INF/page/hello.jsp 在struts2框架中使用包來(lái)管理Action,包的作用和ja
9、va中的類(lèi)包是非常類(lèi)似的,它主要用于管理一組業(yè)務(wù)功能相關(guān)的action。在實(shí)際應(yīng)用中,我們應(yīng)該把一組業(yè)務(wù)功能相關(guān)的Action放在同一個(gè)包下。配置包時(shí)必須指定name屬性,該name屬性值可以任意取名,但必須唯一,他不對(duì)應(yīng)java的類(lèi)包,如果其他包要繼承該包,必須通過(guò)該屬性進(jìn)行引用。包的namespace屬性用于定義該包的命名空間,命名空間作為訪問(wèn)該包下Action的路徑的一部分,如訪問(wèn)上面例子的Action,訪問(wèn)路徑為:/test/helloworld.action。 namespace屬性可以不配置,對(duì)本例而言,如果不指定該屬性,默認(rèn)的命名空間為“”(空字符串)。通常每個(gè)包都應(yīng)該繼承str
10、uts-default包, 因?yàn)镾truts2很多核心的功能都是攔截器來(lái)實(shí)現(xiàn)。如:從請(qǐng)求中把請(qǐng)求參數(shù)封裝到action、文件上傳和數(shù)據(jù)驗(yàn)證等等都是通過(guò)攔截器實(shí)現(xiàn)的。 struts-default定義了這些攔截器和Result類(lèi)型??梢赃@么說(shuō):當(dāng)包繼承了struts-default才能使用struts2提供的核心功能。 struts-default包是在struts2-core-2.x.x.jar文件中的struts-default.xml中定義。 struts-default.xml也是Struts2默認(rèn)配置文件。 Struts2每次都會(huì)自動(dòng)加載 struts-default.xml文件。包還
11、可以通過(guò)abstract=“true”定義為抽象包,抽象包中不能包含action。高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家! !9第一個(gè)Struts2應(yīng)用-HellWorld例子中使用到的cn.itcast.action.HelloWorldAction類(lèi)如下:package cn.itcast.action;public class HelloWorldActionprivate String message;public String getMessage() return message;public void setMessage(String message) this.me
12、ssage = message;public String execute() this.message = 我的第一個(gè)struts2應(yīng)用;return success;高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家! !10第一個(gè)Struts2應(yīng)用-HelloWorld例子中使用到的/WEB-INF/page/hello.jsp如下: 第一個(gè)struts2應(yīng)用 $message 可以使用EL表達(dá)式訪問(wèn)Action中的屬性。高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家! !11訪問(wèn)HelloWorld應(yīng)用在struts1中,通過(guò)節(jié)點(diǎn)的path屬性指定訪問(wèn)該action的URL路徑。在st
13、ruts2中,情況就不是這樣了,訪問(wèn)struts2中action的URL路徑由兩部份組成:包的命名空間+action的名稱(chēng),例如訪問(wèn)本例子HelloWorldAction的URL路徑為:/test/helloworld (注意:完整路徑為::端口/內(nèi)容路徑/test/helloworld)。另外我們也可以加上.action后綴訪問(wèn)此Action。 /WEB-INF/page/hello.jsp 高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家! !12Action名稱(chēng)的搜索順序1獲得請(qǐng)求路徑的URI,例如url是:path1/path2/path3/test.action2首先尋找namesp
14、ace為/path1/path2/path3的package,如果不存在這個(gè)package則執(zhí)行步驟3;如果存在這個(gè)package,則在這個(gè)package中尋找名字為test的action,當(dāng)在該package下尋找不到action 時(shí)就會(huì)直接跑到默認(rèn)namaspace的package里面去尋找action(默認(rèn)的命名空間為空字符串“” ) ,如果在默認(rèn)namaspace的package里面還尋找不到該action,頁(yè)面提示找不到action 3尋找namespace為/path1/path2的package,如果不存在這個(gè)package,則轉(zhuǎn)至步驟4;如果存在這個(gè)package,則在這個(gè)pa
15、ckage中尋找名字為test的action,當(dāng)在該package中尋找不到action 時(shí)就會(huì)直接跑到默認(rèn)namaspace的package里面去找名字為test的action ,在默認(rèn)namaspace的package里面還尋找不到該action,頁(yè)面提示找不到action 4尋找namespace為/path1的package,如果不存在這個(gè)package則執(zhí)行步驟5;如果存在這個(gè)package,則在這個(gè)package中尋找名字為test的action,當(dāng)在該package中尋找不到action 時(shí)就會(huì)直接跑到默認(rèn)namaspace的package里面去找名字為test的action ,
16、在默認(rèn)namaspace的package里面還尋找不到該action,頁(yè)面提示找不到action 5尋找namespace為/的package,如果存在這個(gè)package,則在這個(gè)package中尋找名字為test的action,當(dāng)在package中尋找不到action或者不存在這個(gè)package時(shí),都會(huì)去默認(rèn)namaspace的package里面尋找action,如果還是找不到,頁(yè)面提示找不到action。高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家! !13Action配置中的各項(xiàng)默認(rèn)值 /WEB-INF/page/hello.jsp 1如果沒(méi)有為action指定class,默認(rèn)是Ac
17、tionSupport。2如果沒(méi)有為action指定method,默認(rèn)執(zhí)行action中的execute() 方法。3如果沒(méi)有指定result的name屬性,默認(rèn)值為success。高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家! !14Action中result的各種轉(zhuǎn)發(fā)類(lèi)型/WEB-INF/page/hello.jspresult配置類(lèi)似于struts1中的forward,但struts2中提供了多種結(jié)果類(lèi)型,常用的類(lèi)型有: dispatcher(默認(rèn)值)、 redirect 、 redirectAction 、 plainText。在result中還可以使用$屬性名表達(dá)式訪問(wèn)actio
18、n中的屬性,表達(dá)式里的屬性名對(duì)應(yīng)action中的屬性。如下:/view.jsp?id=$id下面是redirectAction 結(jié)果類(lèi)型的例子,如果重定向的action中同一個(gè)包下: helloworld如果重定向的action在別的命名空間下:helloworld/testplaintext:顯示原始文件內(nèi)容,例如:當(dāng)我們需要原樣顯示jsp文件源代碼 的時(shí)候,我們可以使用此類(lèi)型。/xxx.jspUTF-8高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家! !15多個(gè)Action共享一個(gè)視圖-全局result配置當(dāng)多個(gè)action中都使用到了相同視圖,這時(shí)我們應(yīng)該把result定義為全局視圖。
19、struts1中提供了全局forward,struts2中也提供了相似功能:/message.jsp高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家! !16為Action的屬性注入值Struts2為Action中的屬性提供了依賴注入功能,在struts2的配置文件中,我們可以很方便地為Action中的屬性注入值。注意:屬性必須提供setter方法。public class HelloWorldActionprivate String savePath;public String getSavePath() return savePath;public void setSavePath(Str
20、ing savePath) this.savePath = savePath; ./images/WEB-INF/page/hello.jsp上面通過(guò)節(jié)點(diǎn)為action的savePath屬性注入“/images”高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家! !17指定需要Struts 2處理的請(qǐng)求后綴前面我們都是默認(rèn)使用.action后綴訪問(wèn)Action。其實(shí)默認(rèn)后綴是可以通過(guò)常量”struts.action.extension“進(jìn)行修改的,例如:我們可以配置Struts 2只處理以.do為后綴的請(qǐng)求路徑: 如果用戶需要指定多個(gè)請(qǐng)求后綴,則多個(gè)后綴之間以英文逗號(hào)(,)隔開(kāi)。如: 高級(jí)軟件
21、人才實(shí)作培訓(xùn)專(zhuān)家高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家! !18細(xì)說(shuō)常量定義常量可以在struts.xml或perties中配置,建議在struts.xml中配置,兩種配置方式如下:在在struts.xml文件中配置常量文件中配置常量 在在perties中配置常量中配置常量struts.action.extension=do因?yàn)槌A靠梢栽谙旅娑鄠€(gè)配置文件中進(jìn)行定義,所以我們需要了解struts2加載常量的搜索順序:pertiesweb.xml如果在多個(gè)文件中配
22、置了同一個(gè)常量,則后一個(gè)文件中配置的常量值會(huì)覆蓋前面文件中配置的常量值.高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家! !19常用的常量介紹 高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家! !20Struts2的處理流程StrutsPrepareAndExecuteFilterInterceptorActionResultJsp/html用戶請(qǐng)求Struts2內(nèi)置的一些攔截器或用戶自定義攔截器用戶編寫(xiě)的action類(lèi),類(lèi)似struts1中的Action類(lèi)似struts1中的forward響應(yīng)StrutsPrepareAndExecuteFilter是Struts 2框架的核心控制器,它
23、負(fù)責(zé)攔截由/*指定的所有用戶請(qǐng)求,當(dāng)用戶請(qǐng)求到達(dá)時(shí),該Filter會(huì)過(guò)濾用戶的請(qǐng)求。默認(rèn)情況下,如果用戶請(qǐng)求的路徑不帶后綴或者后綴以.action結(jié)尾,這時(shí)請(qǐng)求將被轉(zhuǎn)入Struts 2框架處理,否則Struts 2框架將略過(guò)該請(qǐng)求的處理。當(dāng)請(qǐng)求轉(zhuǎn)入Struts 2框架處理時(shí)會(huì)先經(jīng)過(guò)一系列的攔截器,然后再到Action。與Struts1不同,Struts2對(duì)用戶的每一次請(qǐng)求都會(huì)創(chuàng)建一個(gè)Action,所以Struts2中的Action是線程安全的。高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家! !21為應(yīng)用指定多個(gè)struts配置文件在大部分應(yīng)用里,隨著應(yīng)用規(guī)模的增加,系統(tǒng)中Action的數(shù)量
24、也會(huì)大量增加,導(dǎo)致struts.xml配置文件變得非常臃腫。為了避免struts.xml文件過(guò)于龐大、臃腫,提高struts.xml文件的可讀性,我們可以將一個(gè)struts.xml配置文件分解成多個(gè)配置文件,然后在struts.xml文件中包含其他配置文件。下面的struts.xml通過(guò)元素指定多個(gè)配置文件:通過(guò)這種方式,我們就可以將Struts 2的Action按模塊添加在多個(gè)配置文件中。高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家! !22動(dòng)態(tài)方法調(diào)用如果Action中存在多個(gè)方法時(shí),我們可以使用!+方法名調(diào)用指定方法。如下:public class HelloWorldActionp
25、rivate String message;.public String execute() throws Exceptionthis.message = 我的第一個(gè)struts2應(yīng)用;return success;public String other() throws Exceptionthis.message = 第二個(gè)方法;return success;假設(shè)訪問(wèn)上面action的URL路徑為: /struts/test/helloworld.action要訪問(wèn)action的other() 方法,我們可以這樣調(diào)用:/struts/test/helloworld!other.action如
26、果不想使用動(dòng)態(tài)方法調(diào)用,我們可以通過(guò)常量struts.enable.DynamicMethodInvocation關(guān)閉動(dòng)態(tài)方法調(diào)用。高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家! !23使用通配符定義action/WEB-INF/page/hello.jsppublic class HelloWorldActionprivate String message;.public String execute() throws Exceptionthis.message = 我的第一個(gè)struts2應(yīng)用;return success;public String other() throws Ex
27、ceptionthis.message = 第二個(gè)方法;return success;要訪問(wèn)other()方法,可以通過(guò)這樣的URL訪問(wèn):/test/helloworld_other.action高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家! !24接收請(qǐng)求參數(shù)采用基本類(lèi)型接收請(qǐng)求參數(shù)采用基本類(lèi)型接收請(qǐng)求參數(shù)(get/post)在Action類(lèi)中定義與請(qǐng)求參數(shù)同名的屬性,struts2便能自動(dòng)接收請(qǐng)求參數(shù)并賦予給同名屬性。請(qǐng)求路徑: public class ProductAction private Integer id; public void setId(Integer id) /s
28、truts2通過(guò)反射技術(shù)調(diào)用與請(qǐng)求參數(shù)同名的屬性的setter方法來(lái)獲取請(qǐng)求參數(shù)值 this.id = id; public Integer getId() return id; 采用復(fù)合類(lèi)型接收請(qǐng)求參數(shù)采用復(fù)合類(lèi)型接收請(qǐng)求參數(shù)請(qǐng)求路徑: public class ProductAction private Product product; public void setProduct(Product product) duct = product; public Product getProduct() return product;Struts2首先通過(guò)反射技術(shù)調(diào)用Prod
29、uct的默認(rèn)構(gòu)造器創(chuàng)建product對(duì)象,然后再通過(guò)反射技術(shù)調(diào)用product中與請(qǐng)求參數(shù)同名的屬性的setter方法來(lái)獲取請(qǐng)求參數(shù)值。高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家! !25關(guān)于struts2.1.6接收中文請(qǐng)求參數(shù)亂碼問(wèn)題struts2.1.6版本中存在一個(gè)Bug,即接收到的中文請(qǐng)求參數(shù)為亂碼(以post方式提交),原因是struts2.1.6在獲取并使用了請(qǐng)求參數(shù)后才調(diào)用HttpServletRequest的setCharacterEncoding()方法進(jìn)行編碼設(shè)置 ,導(dǎo)致應(yīng)用使用的就是亂碼請(qǐng)求參數(shù)。這個(gè)bug在struts2.1.8中已經(jīng)被解決,如果你使用的是str
30、uts2.1.6,要解決這個(gè)問(wèn)題,你可以這樣做:新建一個(gè)Filter,把這個(gè)Filter放置在Struts2的Filter之前,然后在doFilter()方法里添加以下代碼public void doFilter(.)HttpServletRequest req = (HttpServletRequest) request;req.setCharacterEncoding(UTF-8);/應(yīng)根據(jù)你使用的編碼替換UTF-8filterchain.doFilter(request, response);高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家! !26自定義類(lèi)型轉(zhuǎn)換器java.util.D
31、ate類(lèi)型的屬性可以接收格式為2009-07-20的請(qǐng)求參數(shù)值。但如果我們需要接收格式為的請(qǐng)求參數(shù),我們必須定義類(lèi)型轉(zhuǎn)換器,否則struts2無(wú)法自動(dòng)完成類(lèi)型轉(zhuǎn)換。import java.util.Date;public class HelloWorldAction private Date createtime;public Date getCreatetime() return createtime;public void setCreatetime(Date createtime) this.createtime = createtime;高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家
32、! !27自定義類(lèi)型轉(zhuǎn)換器public class DateConverter extends DefaultTypeConverter Override public Object convertValue(Map context, Object value, Class toType) SimpleDateFormat dateFormat = new SimpleDateFormat(yyyyMMdd);try if(toType = Date.class)/當(dāng)字符串向Date類(lèi)型轉(zhuǎn)換時(shí)String params = (String) value;/ Request.getParamet
33、erValues() return dateFormat.parse(params0);else if(toType = String.class)/當(dāng)Date轉(zhuǎn)換成字符串時(shí)Date date = (Date) value;return dateFormat.format(date); catch (ParseException e) return null;將上面的類(lèi)型轉(zhuǎn)換器注冊(cè)為局部類(lèi)型轉(zhuǎn)換器:在Action類(lèi)所在的包下放置ActionClassNperties文件,ActionClassName是Action的類(lèi)名,后面的-
34、perties是固定寫(xiě)法,對(duì)于本例而言,文件的名稱(chēng)應(yīng)為HelloWorldAperties 。在properties文件中的內(nèi)容為:屬性名稱(chēng)=類(lèi)型轉(zhuǎn)換器的全類(lèi)名對(duì)于本例而言, HelloWorldAperties文件中的內(nèi)容為:createtime= cn.itcast.conversion.DateConverter高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家! !28自定義全局類(lèi)型轉(zhuǎn)換器將上面的類(lèi)型轉(zhuǎn)換器注冊(cè)為全局類(lèi)型轉(zhuǎn)換器:在WEB-INF/classes下放置pe
35、rties文件 。在properties文件中的內(nèi)容為:待轉(zhuǎn)換的類(lèi)型=類(lèi)型轉(zhuǎn)換器的全類(lèi)名對(duì)于本例而言, perties文件中的內(nèi)容為:java.util.Date= cn.itcast.conversion.DateConverter高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家! !29訪問(wèn)或添加request/session/application屬性public String scope() throws Exception ActionContext ctx = ActionContext.getContext(); ctx.getApplic
36、ation().put(app, 應(yīng)用范圍);/往ServletContext里放入app ctx.getSession().put(ses, session范圍);/往session里放入ses ctx.put(req, request范圍);/往request里放入req return scope;JSP: $applicationScope.app $sessionScope.ses $requestScope.req 高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家! !30獲取HttpServletRequest / HttpSession / ServletContext / Ht
37、tpServletResponse對(duì)象方法一,通過(guò)ServletActionContext.類(lèi)直接獲?。簆ublic String rsa() throws ExceptionHttpServletRequest request = ServletActionContext.getRequest();ServletContext servletContext = ServletActionContext.getServletContext();request.getSession() HttpServletResponse response = ServletActionContext.get
38、Response();return scope;方法二,實(shí)現(xiàn)指定接口,由struts框架運(yùn)行時(shí)注入:public class HelloWorldAction implements ServletRequestAware, ServletResponseAware, ServletContextAwareprivate HttpServletRequest request;private ServletContext servletContext;private HttpServletResponse response;public void setServletRequest(HttpSer
39、vletRequest req) this.request=req;public void setServletResponse(HttpServletResponse res) this.response=res;public void setServletContext(ServletContext ser) this.servletContext=ser;高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家! !31文件上傳第一步:在第一步:在WEB-INF/lib下加入下加入commons-、commons-io-1.3.2.jar。這兩個(gè)文件可以從下載。這兩個(gè)文件可以從下載。第二步:把第
40、二步:把form表的表的enctype設(shè)置為:設(shè)置為:“multipart/form-data“,如下:如下: 第三步:在第三步:在Action類(lèi)中添加以下屬性,類(lèi)中添加以下屬性,屬性紅色部分對(duì)應(yīng)于表單中文件字段的名稱(chēng)屬性紅色部分對(duì)應(yīng)于表單中文件字段的名稱(chēng):public class HelloWorldAction private File uploadImage;/得到上傳的文件 private String uploadImageContentType;/得到文件的類(lèi)型 private String uploadImage得到文件的名稱(chēng) /這里略省了屬性的getter/setter方法 p
41、ublic String upload() throws ExceptionString realpath = ServletActionContext.getServletContext().getRealPath(/images); = new );if(!() ();(uploadImage, new , uploadImage);return success; 高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家! !32多文件上傳第一步:在第一步:在WEB-INF/lib下加入下加入commons-、commons-io-1.3.2.jar。這兩個(gè)文件可以從下載。這兩個(gè)文件可以從下載。第
42、二步:把第二步:把form表的表的enctype設(shè)置為:設(shè)置為:“multipart/form-data“,如下:如下: 第三步:在第三步:在Action類(lèi)中添加以下屬性,類(lèi)中添加以下屬性,屬性紅色部分對(duì)應(yīng)于表單中文件字段的名稱(chēng)屬性紅色部分對(duì)應(yīng)于表單中文件字段的名稱(chēng):public class HelloWorldAction private File uploadImages;/得到上傳的文件 private String uploadImagesContentType;/得到文件的類(lèi)型 private String uploadImages得到文件的名稱(chēng) /這里略省了屬性的getter/se
43、tter方法 public String upload() throws ExceptionString realpath = ServletActionContext.getServletContext().getRealPath(/images); = new );if(!() ();for(int i=0 ;iuploadImages.length; i+) = uploadImagesi; (uploadImage, new , uploadImagesi);return success; 高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家! !33自定義攔截器要自定義攔截器需要實(shí)現(xiàn)co
44、erceptor.Interceptor接口:public class PermissionInterceptor implements Interceptor private static final long serialVersionUID = -51783102L; public void destroy() public void init() public String intercept(ActionInvocation invocation) throws Exception System.out.println(進(jìn)入攔截器);
45、if(session里存在用戶)String result = invocation.invoke();elsereturn “l(fā)ogon”;/System.out.println(返回值:+ result);/return result; 高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家! !34自定義攔截器 /WEB-INF/page/hello.jsp因?yàn)閟truts2中如文件上傳,數(shù)據(jù)驗(yàn)證,封裝請(qǐng)求參數(shù)到action等功能都是由系統(tǒng)默認(rèn)的defaultStack中的攔截器實(shí)現(xiàn)的,所以我們定義的攔截器需要引用系統(tǒng)默認(rèn)的defaultStack,這樣應(yīng)用才可以使用struts2框架提供的眾
46、多功能。如果希望包下的所有action都使用自定義的攔截器,可以通過(guò)把攔截器定義為默認(rèn)攔截器。注意:每個(gè)包只能指定一個(gè)默認(rèn)攔截器。另外,一旦我們?yōu)樵摪械哪硞€(gè)action顯式指定了某個(gè)攔截器,則默認(rèn)攔截器不會(huì)起作用。高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家! !35輸入校驗(yàn)在struts2中,我們可以實(shí)現(xiàn)對(duì)action的所有方法進(jìn)行校驗(yàn)或者對(duì)action的指定方法進(jìn)行校驗(yàn)。對(duì)于輸入校驗(yàn)struts2提供了兩種實(shí)現(xiàn)方法:1. 采用手工編寫(xiě)代碼實(shí)現(xiàn)。2. 基于XML配置方式實(shí)現(xiàn)。高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家! !36手工編寫(xiě)代碼實(shí)現(xiàn)對(duì)action中所有方法輸入校驗(yàn)通過(guò)重
47、寫(xiě)validate() 方法實(shí)現(xiàn), validate()方法會(huì)校驗(yàn)action中所有與execute方法簽名相同的方法。當(dāng)某個(gè)數(shù)據(jù)校驗(yàn)失敗時(shí),我們應(yīng)該調(diào)用addFieldError()方法往系統(tǒng)的fieldErrors添加校驗(yàn)失敗信息(為了使用addFieldError()方法,action可以繼承ActionSupport ),如果系統(tǒng)的fieldErrors包含失敗信息,struts2會(huì)將請(qǐng)求轉(zhuǎn)發(fā)到名為input的result。在input視圖中可以通過(guò)顯示失敗信息。validate()使用例子:使用例子:public void validate() if(this.mobile=null
48、 | .equals(this.mobile.trim() this.addFieldError(username, 手機(jī)號(hào)不能為空); else if(!Ppile(1358d9).matcher(this.mobile.trim().matches()this.addFieldError(“mobile, 手機(jī)號(hào)的格式不正確); 驗(yàn)證失敗后,請(qǐng)求轉(zhuǎn)發(fā)至驗(yàn)證失敗后,請(qǐng)求轉(zhuǎn)發(fā)至input視圖:視圖:/WEB-INF/page/addUser.jsp在在addUser.jsp頁(yè)面中使用頁(yè)面中使用顯示失敗信息。顯示失敗信息。高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家! !37手工編寫(xiě)代碼實(shí)現(xiàn)
49、對(duì)action指定方法輸入校驗(yàn)通過(guò)validateXxx()方法實(shí)現(xiàn), validateXxx()只會(huì)校驗(yàn)action中方法名為Xxx的方法。其中Xxx的第一個(gè)字母要大寫(xiě)。當(dāng)某個(gè)數(shù)據(jù)校驗(yàn)失敗時(shí),我們應(yīng)該調(diào)用addFieldError()方法往系統(tǒng)的fieldErrors添加校驗(yàn)失敗信息(為了使用addFieldError()方法,action可以繼承ActionSupport ),如果系統(tǒng)的fieldErrors包含失敗信息,struts2會(huì)將請(qǐng)求轉(zhuǎn)發(fā)到名為input的result。在input視圖中可以通過(guò)顯示失敗信息。validateXxx()方法使用例子:方法使用例子:public St
50、ring add() throws Exception return success;public void validateAdd() if(username=null & .equals(username.trim() this.addFieldError(username, 用戶名不能為空用戶名不能為空);驗(yàn)證失敗后,請(qǐng)求轉(zhuǎn)發(fā)至驗(yàn)證失敗后,請(qǐng)求轉(zhuǎn)發(fā)至input視圖:視圖:/WEB-INF/page/addUser.jsp在在addUser.jsp頁(yè)面中使用頁(yè)面中使用顯示失敗信息。顯示失敗信息。高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家! !38輸入校驗(yàn)的流程1。類(lèi)型轉(zhuǎn)換器對(duì)
51、請(qǐng)求參數(shù)執(zhí)行類(lèi)型轉(zhuǎn)換,并把轉(zhuǎn)換后的值賦給action中的屬性。2。如果在執(zhí)行類(lèi)型轉(zhuǎn)換的過(guò)程中出現(xiàn)異常,系統(tǒng)會(huì)將異常信息保存到ActionContext,conversionError攔截器將異常信息添加到fieldErrors里。不管類(lèi)型轉(zhuǎn)換是否出現(xiàn)異常,都會(huì)進(jìn)入第3步。3。系統(tǒng)通過(guò)反射技術(shù)先調(diào)用action中的validateXxx()方法,Xxx為方法名。4。再調(diào)用action中的validate()方法。5。經(jīng)過(guò)上面4步,如果系統(tǒng)中的fieldErrors存在錯(cuò)誤信息(即存放錯(cuò)誤信息的集合的size大于0),系統(tǒng)自動(dòng)將請(qǐng)求轉(zhuǎn)發(fā)至名稱(chēng)為input的視圖。如果系統(tǒng)中的fieldErrors沒(méi)
52、有任何錯(cuò)誤信息,系統(tǒng)將執(zhí)行action中的處理方法。高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家! !39基于XML配置方式實(shí)現(xiàn)對(duì)action的所有方法進(jìn)行輸入校驗(yàn)使用基于XML配置方式實(shí)現(xiàn)輸入校驗(yàn)時(shí),Action也需要繼承ActionSupport,并且提供校驗(yàn)文件,校驗(yàn)文件和action類(lèi)放在同一個(gè)包下,文件的取名格式為:ActionClassName-validation.xml,其中ActionClassName為action的簡(jiǎn)單類(lèi)名,-validation為固定寫(xiě)法。如果Action類(lèi)為cn.itcast.UserAction,那么該文件的取名應(yīng)為:UserAction-val
53、idation.xml。下面是校驗(yàn)文件的模版: true 用戶名不能為空! 指定action中要校驗(yàn)的屬性,指定校驗(yàn)器,上面指定的校驗(yàn)器requiredstring是由系統(tǒng)提供的,系統(tǒng)提供了能滿足大部分驗(yàn)證需求的校驗(yàn)器,這些校驗(yàn)器的定義可以在xwork-2.x.jar中的com.opensymphony.xwork2.validator.validators下的default.xml中找到。為校驗(yàn)失敗后的提示信息,如果需要國(guó)際化,可以為message指定key屬性,key的值為資源文件中的key。在這個(gè)校驗(yàn)文件中,對(duì)action中字符串類(lèi)型的username屬性進(jìn)行驗(yàn)證,首先要求調(diào)用trim(
54、)方法去掉空格,然后判斷用戶名是否為空。高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家! !40編寫(xiě)校驗(yàn)文件時(shí),不能出現(xiàn)幫助信息在編寫(xiě)ActionClassName-validation.xml校驗(yàn)文件時(shí),如果出現(xiàn)不了幫助信息,可以按下面方式解決:windwos-preferences-myeclipse-files and editors-xml-xmlcatalog點(diǎn)“add”,在出現(xiàn)的窗口中的location中選“”,然后在xwork-2.1.2解壓目錄的srcjava目錄中選擇xwork-validator-1.0.3.dtd,回到設(shè)置窗口的時(shí)候不要急著關(guān)閉窗口,應(yīng)把窗口中的Key
55、Type改為URI 。Key改為高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家! !41struts2提供的校驗(yàn)器列表系統(tǒng)提供的校驗(yàn)器如下:required (必填校驗(yàn)器,要求field的值不能為null)requiredstring (必填字符串校驗(yàn)器,要求field的值不能為null,并且長(zhǎng)度大于0,默認(rèn)情況下會(huì)對(duì)字符串去前后空格)stringlength(字符串長(zhǎng)度校驗(yàn)器,要求field的值必須在指定的范圍內(nèi),否則校驗(yàn)失敗,minLength參數(shù)指定最小長(zhǎng)度,maxLength參數(shù)指定最大長(zhǎng)度,trim參數(shù)指定校驗(yàn)field之前是否去除字符串前后的空格)regex(正則表達(dá)式校驗(yàn)器,檢
56、查被校驗(yàn)的field是否匹配一個(gè)正則表達(dá)式.expression參數(shù)指定正則表達(dá)式,caseSensitive參數(shù)指定進(jìn)行正則表達(dá)式匹配時(shí),是否區(qū)分大小寫(xiě),默認(rèn)值為true)int(整數(shù)校驗(yàn)器,要求field的整數(shù)值必須在指定范圍內(nèi),min指定最小值,max指定最大值)double(雙精度浮點(diǎn)數(shù)校驗(yàn)器,要求field的雙精度浮點(diǎn)數(shù)必須在指定范圍內(nèi),min指定最小值,max指定最大值)fieldexpression(字段OGNL表達(dá)式校驗(yàn)器,要求field滿足一個(gè)ognl表達(dá)式,expression參數(shù)指定ognl表達(dá)式,該邏輯表達(dá)式基于ValueStack進(jìn)行求值,返回true時(shí)校驗(yàn)通過(guò),否則
57、不通過(guò))email(郵件地址校驗(yàn)器,要求如果field的值非空,則必須是合法的郵件地址)url(網(wǎng)址校驗(yàn)器,要求如果field的值非空,則必須是合法的url地址)date(日期校驗(yàn)器,要求field的日期值必須在指定范圍內(nèi),min指定最小值,max指定最大值)conversion(轉(zhuǎn)換校驗(yàn)器,指定在類(lèi)型轉(zhuǎn)換失敗時(shí),提示的錯(cuò)誤信息)visitor(用于校驗(yàn)action中的復(fù)合屬性,它指定一個(gè)校驗(yàn)文件用于校驗(yàn)復(fù)合屬性中的屬性)expression(OGNL表達(dá)式校驗(yàn)器,expression參數(shù)指定ognl表達(dá)式,該邏輯表達(dá)式基于ValueStack進(jìn)行求值,返回true時(shí)校驗(yàn)通過(guò),否則不通過(guò),該校
58、驗(yàn)器不可用在字段校驗(yàn)器風(fēng)格的配置中)高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家! !42校驗(yàn)器的使用例子required 必填校驗(yàn)器 性別不能為空!requiredstring 必填字符串校驗(yàn)器 true 用戶名不能為空!stringlength:字符串長(zhǎng)度校驗(yàn)器102true高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家! !43校驗(yàn)器的使用例子email:郵件地址校驗(yàn)器電子郵件地址無(wú)效regex:正則表達(dá)式校驗(yàn)器 手機(jī)號(hào)格式不正確!高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家! !44校驗(yàn)器的使用例子int:整數(shù)校驗(yàn)器1150年齡必須在1-150之間字段OGNL表達(dá)式校驗(yàn)器!C
59、DATAimage() 文件不能為空高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家! !45基于XML配置方式對(duì)指定action方法實(shí)現(xiàn)輸入校驗(yàn)當(dāng)校驗(yàn)文件的取名為ActionClassName-validation.xml時(shí),會(huì)對(duì) action中的所有處理方法實(shí)施輸入驗(yàn)證。如果你只需要對(duì)action中的某個(gè)action方法實(shí)施校驗(yàn),那么,校驗(yàn)文件的取名應(yīng)為:ActionClassName-ActionName-validation.xml,其中ActionName為struts.xml中action的名稱(chēng)。例如:在實(shí)際應(yīng)用中,常有以下配置:/WEB-INF/page/message.jsp/
60、WEB-INF/page/addUser.jspUserAction中有以下兩個(gè)處理方法:public String add() throws Exception .public String update() throws Exception .要對(duì)add()方法實(shí)施驗(yàn)證,校驗(yàn)文件的取名為: UserAction-user_add-validation.xml要對(duì)update()方法實(shí)施驗(yàn)證,校驗(yàn)文件的取名為: UserAction-user_update-validation.xml高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家高級(jí)軟件人才實(shí)作培訓(xùn)專(zhuān)家! !46基于XML校驗(yàn)的一些特點(diǎn)當(dāng)為某個(gè)action提供了Acti
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2026年寧波前灣新區(qū)衛(wèi)生系統(tǒng)事業(yè)單位公開(kāi)招聘高層次人才42人筆試參考題庫(kù)及答案解析
- 2026廣東云浮見(jiàn)習(xí)崗位人員招聘2人備考考試試題及答案解析
- 2026云南弘玉滇中人力資源產(chǎn)業(yè)園運(yùn)營(yíng)管理有限公司就業(yè)見(jiàn)習(xí)崗位招募2人備考題庫(kù)及答案詳解參考
- 2026國(guó)新新格局(北京)私募證券基金管理有限公司相關(guān)崗位招聘1人備考題庫(kù)附答案詳解
- 2026云南文山州動(dòng)物衛(wèi)生監(jiān)督所招聘城鎮(zhèn)公益性崗位工作人員1人備考題庫(kù)及參考答案詳解一套
- 2026新余市12345政務(wù)服務(wù)便民熱線招聘5人備考題庫(kù)帶答案詳解
- 2026山東濟(jì)南市屬事業(yè)單位招聘初級(jí)綜合類(lèi)崗位人員111人備考題庫(kù)及答案詳解(考點(diǎn)梳理)
- 2026年度青島市李滄區(qū)所屬事業(yè)單位公開(kāi)招聘工作人員備考題庫(kù)(32名)及一套答案詳解
- 2026年食品營(yíng)養(yǎng)與健康專(zhuān)業(yè)知識(shí)測(cè)試題目集
- 2026中國(guó)印鈔造幣集團(tuán)有限公司校園招聘12人備考題庫(kù)參考答案詳解
- (2025年)鐵路貨運(yùn)考試題及答案
- 2026年榆能集團(tuán)陜西精益化工有限公司招聘?jìng)淇碱}庫(kù)及參考答案詳解一套
- 2026年及未來(lái)5年中國(guó)化妝品玻璃瓶行業(yè)市場(chǎng)深度分析及發(fā)展趨勢(shì)預(yù)測(cè)報(bào)告
- 2026年魯教版初三政治上冊(cè)月考真題試卷(含答案)
- 物業(yè)春節(jié)前安全生產(chǎn)培訓(xùn)課件
- 企業(yè)安全生產(chǎn)責(zé)任制培訓(xùn)教材(標(biāo)準(zhǔn)版)
- 零缺陷培訓(xùn)教學(xué)課件
- 2026年餐飲企業(yè)稅務(wù)合規(guī)培訓(xùn)課件與發(fā)票管理風(fēng)控方案
- 2025年及未來(lái)5年市場(chǎng)數(shù)據(jù)中國(guó)蓖麻油行業(yè)投資潛力分析及行業(yè)發(fā)展趨勢(shì)報(bào)告
- 2025年湖北煙草專(zhuān)賣(mài)局真題試卷及答案
- 2025-2026學(xué)年廣東省廣州113中學(xué)八年級(jí)(上)期中語(yǔ)文試卷
評(píng)論
0/150
提交評(píng)論