一、國際化概念(瞭解)
1、什麼是國際化
軟件
的國際化:軟件開發時,要使它能同時應對世界不同地區和國家的訪問,並針對不同地區和國家的訪問,提供相應的、符合來訪者閱讀習慣的頁面或數據。
2、什麼需要國際化
程序:需要國際化。 輸入的數據:是什麼樣的就是什麼樣的。 比如:
- 用戶註冊的表單,有用戶名,密碼這5個漢字,在zh_CN語言環境,顯示的就是用戶名和密碼。但是在en_US語言環境,顯示的就應該是username和password。這就是
程序
。 - 用戶名輸入的是【張三】,密碼輸入的是【test】,那無論在什麼語言環境都應該是是【張三】和【test】。這就是
數據
。
3、固定文本的國際化
例如:消息提示、錯誤提示和菜單,導航欄等等固定文本。 步驟:
3.1、創建一個消息資源包
一個資源包由多個文件組成,這些文件名都有命名規範:主要文件名_語言代碼_國家代碼.properties
。
語言代碼:由iso規定的。國家代碼:由iso規定的。
當文件只有 主要文件名.properties
時,表明它是 默認資源包
。瀏覽器會根據不同的語言環境找對應語言環境的資源包,當沒有找到時,找默認的。
每個資源包的內容都由 相同的key
和 對應語言環境的value
組成。
比如:
message_zh_CN.properties
、 message_zh_HK.properties
、message_en_US.properties
3.2、讀取資源包中的內容
國際化的小測試,如下圖所示:
jsp中使用國際化:
配置文件 message_zh_CN.properties
和 message_en_US.properties
的書寫:
login.jsp文件:
效果如下圖所示:
但是呢?login.jsp中不允許出現下面的java代碼塊(jsp2.0以後的規定),需要用jsp的標籤來替代。
使用jstl的fmt標籤,如下圖所示:
<% // java代碼塊 Locale locale = request.getLocale(); ResourceBundle bundle = ResourceBundle.getBundle("com.itheima.resource.message",locale); %>
二、Struts2中的國際化(瞭解)
1、Struts2中使用國際化的前提
首先,我們要知道,在Struts2中,所有的消息提示都是基於國際化的。
其次,要想在Struts2中使用國際化,動作類必須 繼承ActionSupport類
。
2、Struts2中使用國際化
2.1、配置資源包 a、配置全局範圍的資源包
b、配置包範圍的資源包
該方式直接新建包範圍的資源包,添加配置文件即可,不需要在 struts.xml 中進行配置。
資源包名稱命名規範:package_語言代碼_國家代碼.properties(固定的寫法)
。以此種命名方式的資源包能 被該包及其子包中的動作類訪問
。
訪問優先級:包範圍的資源包高於全局範圍的資源包。
c、配置局部消息資源包(只爲動作類來使用的)
該方式直接新建動作類範圍的配置文件即可,也不需要在 struts.xml 中進行配置。
資源包名稱命名規範:動作類名稱_語言代碼_國家代碼.properties
。以此種命名方式的資源包,只爲動作類服務。
訪問優先級:優先級最高(就近原則)。
2.2、讀取資源包的內容 a、在動作類中的讀取資源包內容(實際開發中幾乎從來不用,學習時爲了演示而已)
b、在頁面中讀取資源包內容
Struts2中資源包的搜索順序,如下圖所示:
所在位置:/struts-2.3.15.3-all/struts-2.3.15.3/docs/WW/docs/localization.html
三、Struts2中的攔截器(特別重要)
1、攔截器的重要性
Struts2中的很多功能都是由攔截器完成的。
比如:servletConfig、staticParam、params、modelDriven等等。
是 AOP編程思想
的一種 應用
形式。
2、攔截器的執行時機
執行動作方法之前,正序執行攔截器。 執行結果視圖之後,倒序執行攔截器。 如下圖所示:
3、自定義攔截器
3.1、攔截器的類視圖結構(最終版本):
3.2、編寫自定義攔截器步驟:
a、編寫一個普通類,繼承AbstractInterceptor類
或者 實現Interceptor接口
。重寫其抽象的intercept方法。
b、在struts.xml中配置攔截器,注意攔截器必須先聲明、再使用。
效果圖如下:
這時。攔截器幹活啦,攔截成功,哈哈,該我想幹什麼就幹什麼啦!(壞笑)
3.3、攔截器的執行順序 攔截器 --> 動作方法 --> 結果視圖 --> 攔截器 --> 瀏覽器響應頁面,如下圖所示:
3.4、多個攔截器的執行順序 當有多個攔截器的時候,是由使用順序決定執行順序,與聲明順序無關。
3.5、intercept方法的返回值是邏輯結果視圖的值。打印下該方法的返回值即可,就不放圖啦!
4、攔截器的應用
4.1、檢查登錄的攔截器案例 配置文件struts.xml:
動作類:
攔截器:
頁面:
4.2、案例中的問題 問題:由於我們寫了自己的攔截器,默認的攔截器不起作用了。 解決辦法: a、把默認攔截器也加入到配置文件中
b、a中暴露的問題:當有多個攔截器時,需要改寫的地方非常多。
解決辦法:抽取公共的包,把全局配置放入公共包中
。
c、b中的問題:還要再每個動作方法中引入攔截器。能不能不寫呢? 思路:我們在設置【開發模式】時,覆蓋掉了一個default.properties中的常量,那我們能不能把struts-default.xml中的默認攔截器棧的設置給覆蓋掉呢?答案是可以的。
d、c中出現的問題:當我們重新定義了默認的攔截器棧,這時候三個動作login、showMain和showOther都將被檢查登錄的攔截器攔截。
解決辦法:需要通過 AbstractInterceptor類的子類
入手,通過查看發現,該類還有一個抽象的子類:MethodFilterInterceptor
,它裏面提供了兩個屬性:excludeMethods
和 includeMethods
。
excludeMethods:表示那些方法不需要攔截
includeMethods:表示哪些方法需要攔截
可以配置多個動作方法,使用,進行分割。
如下圖所示:
所以我們在自定義攔截器時,還可以 繼承MethodFilterInterceptor
並且 重寫doIntercept方法
。這種方式更好!
並且在struts的配置文件中,配置需要攔截哪些方法,和需要放過哪些方法。如下圖所示:
e、d中遺留的問題:我們在聲明時配置了哪些方法需要攔截,哪些方法不需要攔截。但是在沒有寫動作類和動作方法之前,不確定方法名叫什麼。 解決辦法:哪個動作方法需要使用攔截器,我就給它注入參數。
四、文件的上傳(攔截器)和下載(stream結果類型)(需要練一遍)
1、文件上傳
必要前提: a. 表單form的請求方式method必須是post。 b. enctype取值必須是multipart/form-data。 c. 提供一個文件選擇域。
動作類:
效果如下圖所示:
2、文件上傳的配置
2.1、文件上傳大小限制(默認大小是2MB) 如果上傳文件超過了默認大小,upload攔截器會轉向一個input的邏輯視圖。如下圖所示:
按照input的邏輯視圖提示,增加結果視圖,和增加顯示動作錯誤提示,再次上傳,得到新的頁面結果視圖,如下圖所示:
a、改變上傳文件大小限制: 思路1:在struts.xml中改變default.properties文件中的常量。
思路2:給Struts2默認的攔截器棧中的fileUpload攔截器注入參數:(行不通)
2.2、限制文件上傳的類型 a、通過限制上傳文件的擴展名 思路:給Struts2默認的攔截器棧中的fileUpload攔截器注入參數:
當上傳非限定擴展名時,有如下錯誤提示:
b、通過限制上傳文件的MIME類型
當上傳非限定MIME類型時,有如下錯誤提示
3、出錯後的錯誤信息中文提示(Struts2中的所有文本提示都是基於國際化的)
默認信息提示在:項目目錄下\Web App Library\struts2-core.jar\org.apache.struts2\struts-message.properties
解決辦法:用國際化消息資源包,把對應的key取值改爲中文即可。 常用的key值,配置如下:
修改顯示錯誤的資源文件的信息,如下圖所示:
效果如下圖所示:
4、多文件上傳
jsp頁面:
配置文件struts.xml:
動作類:
運行結果:沒有問題,就不上圖啦!
5、文件下載:其實就是一種結果類型(Stream)
動作類:
配置文件:
運行結果:沒有問題,就不上圖啦! 問題:文件名不能在配置文件中寫死,需要根據實際情況獲取。 解決辦法: 動作類:
在下面的講解中。
五、OGNL簡介(非常重要)
1、什麼是OGNL?
OGNL是 Object Graphic Navigation Language
(對象圖導航
語言)的縮寫,它是一個單獨的開源項目。 Struts2框架使用OGNL作爲默認的 表達式語言
。
2、OGNL的功能
前提:OGNL是struts2整合的一個 開源項目
,所以在struts2中,要想使用OGNL表達式,必須使用 Struts2標籤庫
。
2.1、支持普通方法的調用
(EL表達式只能調用靜態方法,詳解見此鏈接:https://www.cnblogs.com/chenmingjun/p/9243454.html)
2.2、訪問靜態成員(靜態屬性,靜態方法)
如下圖所示:
2.3、操作集合對象 a、創建List對象: b、創建Map對象:
2.4、OGNL改寫文件下載文件名的問題 動作類:
struts.xml配置文件:
六、context Map(非常重要)
1、動作類的生命週期
明確:動作類是多例的,每次動作訪問,動作類都會實例化。所以是線程安全的
。與Struts1的區別是,struts1的動作類是單例的。
2、請求動作的數據存放
問題:
每次請求時,都會產生一些請求數據,這些數據存放到哪裏去了?
明確:
在每次動作執行前,核心控制器StrutsPrepareAndExecuteFilter
都會創建一個 ActionContext
和 ValueStack對象
。且每次動作訪問都會創建。
這兩個對象存儲了整個動作訪問期間用到的數據
。並且把數據綁定到了 線程局部變量(ThreadLocal)
上了。所以是線程安全的。
3、context Map:存儲數據
Struts2的官方文檔對context Map的說明:
注意: 除了value stack之外,全是map,而context Map也是一個map。其實就是Map中又封裝的Map。
(很像dbutils中KeyedHandler封裝數據的結構,注意:只是像其封裝數據的結構而已
,把結果集封裝成一個Map,Map裏面又是一個Map,大Map的key是主鍵,大Map的value是一個小Map,是一條記錄)
查看context Map中的數據:
在頁面上使用 <s:debug/>
效果如下圖所示:
測試存入數據:
未完待續,欲知後事如何,且聽下回分解…