一、國(guó)際化概念(了解)
1、什么是國(guó)際化
軟件的國(guó)際化:軟件開(kāi)發(fā)時(shí),要使它能同時(shí)應(yīng)對(duì)世界不同地區(qū)和國(guó)家的訪問(wèn),并針對(duì)不同地區(qū)和國(guó)家的訪問(wèn),提供相應(yīng)的、符合來(lái)訪者閱讀習(xí)慣的頁(yè)面或數(shù)據(jù)。
2、什么需要國(guó)際化
程序:需要國(guó)際化。
數(shù)據(jù):是什么樣的就是什么樣的。
比如:
用戶注冊(cè)的表單,有用戶名,密碼這5個(gè)漢字,在zh_CN語(yǔ)言環(huán)境,顯示的就是用戶名和密碼。但是在en_US語(yǔ)言環(huán)境,顯示的就應(yīng)該是username和password。這就是程序。
用戶名輸入的是【張三】,密碼輸入的是【test】,那無(wú)論在什么語(yǔ)言環(huán)境都應(yīng)該是是【張三】和【test】。這就是數(shù)據(jù)。
3、固定文本的國(guó)際化
例如:消息提示,錯(cuò)誤提示和菜單,導(dǎo)航欄等等固定文本。
步驟:
3.1、創(chuàng)建一個(gè)消息資源包
一個(gè)資源包由多個(gè)文件組成,這些文件名都有命名規(guī)范:主要文件名語(yǔ)言代碼國(guó)家代碼.properties。 語(yǔ)言代碼:由iso規(guī)定的。國(guó)家代碼:有iso規(guī)定的
當(dāng)文件只有主要文件名.properties時(shí),表明它是默認(rèn)資源包。瀏覽器會(huì)根據(jù)不同的語(yǔ)言環(huán)境找對(duì)應(yīng)語(yǔ)言環(huán)境的資源包,當(dāng)沒(méi)有時(shí),找默認(rèn)的。
每個(gè)資源包的內(nèi)容都由相同的key和對(duì)應(yīng)語(yǔ)言環(huán)境的value組成。
比如:
message_zh_CN.properties message_zh_HK.properties message_en_US.properties
3.2、讀取資源包中的內(nèi)容

jsp中使用國(guó)際化:


使用jstl的fmt標(biāo)簽:

二、Struts2中的國(guó)際化(了解)
1、Struts2中使用國(guó)際化的前提
首先,我們要知道,在Struts2中,所有的消息提示都是基于國(guó)際化的。
其次,要想在Struts2中使用國(guó)際化,動(dòng)作類必須繼承ActionSupport類。
2、Struts2中使用國(guó)際化
2.1、配置資源包
a、配置全局資源包

b、配置包范圍的資源包

資源包名稱命名規(guī)范:package_語(yǔ)言代碼_國(guó)家代碼.properties(固定的)。以此種命名方式的資源包能被該包及其子包中的動(dòng)作類訪問(wèn)。
優(yōu)先級(jí):高于全局消息資源包
c、局部消息資源包(只為動(dòng)作類來(lái)使用的)

資源包名稱命名規(guī)范:動(dòng)作類名稱語(yǔ)言代碼國(guó)家代碼.properties。以此種命名方式的資源包,只為動(dòng)作類服務(wù)。
優(yōu)先級(jí)最高(就近原則)。
Struts2中資源包的搜索順序:

2.2、讀取資源包的內(nèi)容
a、動(dòng)作類中的讀取方式(實(shí)際開(kāi)發(fā)中幾乎從來(lái)不用)

b、在頁(yè)面中讀取資源包內(nèi)容
直接訪問(wèn)jsp:


通過(guò)動(dòng)作類訪問(wèn)jsp

c、自由指定讀取資源包

三、Struts2中的攔截器(特別重要)
1、攔截器的重要性
Struts2中的很多功能都是由攔截器完成的。比如:servletConfig,staticParam,params,modelDriven等等。
是AOP編程思想的一種應(yīng)用形式。
2、攔截器的執(zhí)行時(shí)機(jī):

3、自定義攔截器
3.1、攔截器的類試圖(初級(jí)版本):

3.2、編寫步驟:
a、編寫一個(gè)類,繼承AbstractInterceptor類或者實(shí)現(xiàn)Interceptor接口。重寫intercept方法。

b、配置攔截器:注意攔截器必須先聲明再使用

3.3、執(zhí)行順序

3.4、多個(gè)攔截器的執(zhí)行順序

3.5、intercept方法的返回值

4、攔截器的應(yīng)用:
4.1、檢查登錄的攔截器案例
配置文件:

動(dòng)作類:

攔截器:

頁(yè)面:

4.2、案例中的問(wèn)題
問(wèn)題:由于我們寫了自己的攔截器,默認(rèn)的攔截器不起作用了。
解決辦法:
a、把默認(rèn)攔截器加入到配置文件中

b、a中暴露的問(wèn)題:當(dāng)有多個(gè)攔截器時(shí),需要改寫的地方非常多。
解決辦法:抽取公共的包,把全局配置放入公共包中。

c、b中的問(wèn)題:還要再每個(gè)動(dòng)作方法中引入攔截器。能不能不寫呢?
思路:我們?cè)谠O(shè)置【開(kāi)發(fā)模式】時(shí),覆蓋掉了一個(gè)default.properties中的常量,能不能把struts-default.xml中的默認(rèn)攔截器棧的設(shè)置給覆蓋掉呢?答案是可以的。

解決辦法:

d、c中出現(xiàn)的問(wèn)題:當(dāng)使用了默認(rèn)攔截器棧,這時(shí)候三個(gè)動(dòng)作login,showIndex和show1Action都將被檢查登錄的攔截器攔截。
解決辦法:
需要通過(guò)AbstractInterceptor類的子類入手,通過(guò)查看發(fā)現(xiàn),該類還有一個(gè)子類是抽象的:

所以我們?cè)谧远x攔截器時(shí),還可以繼承MethodFilterInterceptor并且重寫doIntercept方法。

并且在struts的配置文件中,配置需要攔截哪些方法,和需要放過(guò)哪些方法。

e、d中遺留的問(wèn)題:我們?cè)诼暶鲿r(shí)配置了哪些方法需要攔截,哪些方法不需要攔截。但是在沒(méi)有寫動(dòng)作類和動(dòng)作方法之前,不確定方法名叫什么。
解決辦法:我們需要在使用攔截器的時(shí)候給它注入?yún)?shù)。

4.3、攔截器類視圖(全):

四、文件的上傳(攔截器)和下載(stream結(jié)果類型)
1、文件上傳
必要前提:
a.表單method必須是post;
b.enctype取值必須是multipart/form-data;
c.提供文件選擇域。

動(dòng)作類:

2、文件上傳的配置
2.1、文件上傳大小限制(默認(rèn)是2MB)
如果上傳文件超過(guò)了默認(rèn)大小,upload攔截器會(huì)轉(zhuǎn)向一個(gè)input的邏輯視圖。






a、改變上傳文件大小限制:
思路1:給Struts2的攔截器注入?yún)?shù):(行不通)


思路2:在struts.xml中改變default.properties文件中的常量。


2.2、限制文件上傳的類型
a、通過(guò)限制上傳文件的擴(kuò)展名
思路:給fileUpload攔截器注入?yún)?shù)


當(dāng)上傳非限定擴(kuò)展名時(shí):有如下錯(cuò)誤提示

b、通過(guò)限制上傳文件的MIME類型

當(dāng)上傳非限定MIME類型時(shí):有如下錯(cuò)誤提示

3、出錯(cuò)后的錯(cuò)誤信息中文提示(Struts2中的所有文本提示都是基于國(guó)際化的)
默認(rèn)信息提示在:struts2-core.jar\org.apache.struts2\struts-message.properties

解決辦法:用國(guó)際化消息資源包,把對(duì)應(yīng)的key取值改為中文即可。
常用的key值:


4、多文件上傳
jsp頁(yè)面:

配置文件:

動(dòng)作類:

運(yùn)行結(jié)果:

5、文件下載:其實(shí)就是一種結(jié)果類型(Stream)
動(dòng)作類:

配置文件:

運(yùn)行結(jié)果:

問(wèn)題:文件名不能在配置文件中寫死,需要根據(jù)實(shí)際情況獲取。
解決辦法:
動(dòng)作類:

配置文件:

運(yùn)行結(jié)果:

五、OGNL簡(jiǎn)介(非常重要)
1、什么是OGNL
OGNL是Object Graphic Navigation Language(對(duì)象圖導(dǎo)航語(yǔ)言)的縮寫,它是一個(gè)單獨(dú)的開(kāi)源項(xiàng)目。 Struts2框架使用OGNL作為默認(rèn)的表達(dá)式語(yǔ)言。
2、OGNL的功能
前提:OGNL是struts2整合的一個(gè)開(kāi)源項(xiàng)目,所以在struts2中,要想使用OGNL表達(dá)式,必須使用Struts2標(biāo)簽庫(kù)
2.1、支持普通方法的調(diào)用


(EL表達(dá)式只能調(diào)用靜態(tài)方法)
2.2、訪問(wèn)靜態(tài)成員(靜態(tài)屬性,靜態(tài)方法)



OGNL改寫文件下載:


2.3、操作集合對(duì)象
a、創(chuàng)建List對(duì)象:


b、創(chuàng)建Map對(duì)象:


六、contextMap(非常重要)
1、動(dòng)作類的生命周期
明確:動(dòng)作類是多例的,每次動(dòng)作訪問(wèn),動(dòng)作類都會(huì)實(shí)例化。所以是線程安全的。與Struts1的區(qū)別是,struts1的動(dòng)作類是單例的。
2、請(qǐng)求動(dòng)作的數(shù)據(jù)存放
問(wèn)題:
每次請(qǐng)求時(shí),都會(huì)產(chǎn)生一些請(qǐng)求數(shù)據(jù),這些數(shù)據(jù)存放到哪里去了?
明確:
在每次動(dòng)作執(zhí)行前,核心控制器StrutsPrepareAndExecuteFilter都會(huì)創(chuàng)建一個(gè)ActionContext和ValueStack對(duì)象。且每次動(dòng)作訪問(wèn)都會(huì)創(chuàng)建。
這兩個(gè)對(duì)象存儲(chǔ)了整個(gè)動(dòng)作訪問(wèn)期間用到的數(shù)據(jù)。并且把數(shù)據(jù)綁定到了線程局部變量(ThreadLocal)上了。所以是線程安全的。


3、contextMap:存儲(chǔ)數(shù)據(jù)
Struts2的官方文檔對(duì)contextMap的說(shuō)明:


注意:
除了value stack之外,全是map,而contextMap也是一個(gè)map。其實(shí)就是Map中又封裝的Map。(很像dbutils中KeyedHandler封裝數(shù)據(jù)的結(jié)構(gòu),只是封裝數(shù)據(jù)的結(jié)構(gòu))
查看contextMap中的數(shù)據(jù):
在頁(yè)面上使用<s:debug/>


測(cè)試存入數(shù)據(jù):

