7.類型轉(zhuǎn)換桶至、消息處理與國際化

7.類型轉(zhuǎn)換、消息處理與國際化

@(10_Struts2)[JavaEE, Struts2]

  • 前邊我們說過了 Http協(xié)議 有兩個缺陷一個是無狀態(tài)茶袒、一個是純文本
  • 純文本也就是說Http請求中的內(nèi)容都是以字符串的形式發(fā)送的凉馆。
  • 但是Java又是一個強類型語言薪寓,所以將一個字符串轉(zhuǎn)換成Java中的數(shù)據(jù)類型這一重任就落在了Struts2的肩膀上。
  • 類型轉(zhuǎn)換最常見的可能就是將將10/29/2015轉(zhuǎn)換為一個date類型等澜共。
  • 關于類型轉(zhuǎn)換我們要做的主要有兩件事:
    • 類型轉(zhuǎn)換失敗后的處理预愤。
    • 特殊類型的自定義類型轉(zhuǎn)換器

類型轉(zhuǎn)換失敗消息處理

  • 類型轉(zhuǎn)換失敗
    • 若 Action 類沒有實現(xiàn) ValidationAware 接口: Struts 在遇到類型轉(zhuǎn)換錯誤時仍會繼續(xù)調(diào)用其 Action 方法, 就好像什么都沒發(fā)生一樣.

    • 若 Action 類實現(xiàn) ValidationAware 接口:Struts 在遇到類型轉(zhuǎn)換錯誤時將不會繼續(xù)調(diào)用其 Action 方法:

      • Struts 將檢查相關 action 元素的聲明是否包含著一個 name=input 的 result.
      • 如果有, Struts 將把控制權(quán)轉(zhuǎn)交給那個 result 元素;
      • 若沒有 input 結(jié)果, Struts 將拋出一個異常
    • 實現(xiàn) ValidationAware 接口咳胃,在之前的文章中我們提到,我們可以繼承 com.opensymphony.xwork2.ActionSupport 類的形式來實現(xiàn) ValidationAware 接口旷太, 在ActionSupport 中已經(jīng)幫我們實現(xiàn)好了


  • 類型轉(zhuǎn)換出錯時如何處理

    • 如果我們輸入錯誤的數(shù)字展懈,想轉(zhuǎn)換為年齡;當我們的 result name="input" 的時候供璧,會返回到這個結(jié)果頁面存崖。
    • 錯誤的年齡
    • 但是對于這種錯誤的提示,我們需要處理
  • 類型轉(zhuǎn)換錯誤消息的定制

    • 作為默認的 default 攔截器的一員, ConversionError 攔截器負責添加與類型轉(zhuǎn)換有關的出錯消息(前提: Action 類必須實現(xiàn)了 ValidationAware 接口)和保存各請求參數(shù)的原始值.
    • 若字段標簽使用的不是 simple 主題, 則非法輸入字段將導致一條有著如上圖格式的出錯消息睡毒。
  • 覆蓋默認的出錯消息

    • 在對應的 Action 類所在的包中新建 ActionClassName.properties 文件, ClassName 即為包含著輸入字段的 Action 類的類名
    • 在屬性文件中添加如下鍵值對: invalid.fieldvalue.fieldName=Customer Message
# EmployeeAction.properties
invalid.fieldvalue.age=年齡格式不正確来惧,請重新輸入!
  • 自定義的消息
  • 定制出錯消息的樣式:

    • 每一條出錯消息都被打包在一個 HTML span 元素里, 可以通過覆蓋其行標為 errorMessage 的那個 css 樣式來改變出錯消息的格式.
    • 顯示錯誤消息: 如果是 simple 主題, 可以通過 <s:fielderror fieldName=“filedname”></s:fielderror> 標簽顯示錯誤消息
    • 通過s:fielderror 標簽
<s:form action="emp_update" theme="simple">
    <s:hidden name="id"></s:hidden>
    姓名:<s:textfield name="name"></s:textfield> <br>
    年齡:<s:textfield name="age" ></s:textfield>
    <!-- 通過標簽獲取錯誤消息 -->
    <span style="color:red"><s:fielderror fieldName="age"></s:fielderror></span><br>
    部門: <s:textfield name="dept"></s:textfield><br>
    職務:<s:textfield name="role"></s:textfield><br>
    <s:submit value="修改"></s:submit>
</s:form>
  • 但是對于這種錯誤消息的格式我們是可以修改的演顾,修改其默認的 freemark 模板
  • struts2-core-2.3.15.3.jar 的 /template/simple/fielderror.ftl供搀,這是 struts2 默認自帶的錯誤消息模板隅居,我們在 src 路徑下建立相同的包和模板,并且修改里面的 html 標簽葛虐。刪除文件中錯誤消息的 的 ul胎源、li、span便簽

![刪除的模板

  • 效果

自定義類型轉(zhuǎn)換器

  • 定制類型轉(zhuǎn)換器

  • 自定義類型轉(zhuǎn)換器必須實現(xiàn) ongl.TypeConverter 接口或?qū)@個接口的某種具體實現(xiàn)做擴展

  • 擴展 StrutsTypeConverter 類

    • 在大多數(shù)類型轉(zhuǎn)換器里, 需要提供從 String 類型到非 String 類型和與此相反的轉(zhuǎn)換功能
    • 在 StrutsTypeConverter 中有兩個抽象方法:
  • 配置自定義的類型轉(zhuǎn)換器

    • 在應用程序里使用一個自定義的類型轉(zhuǎn)換器之前, 必須先對它進行配置. 這種配置既可以基于字段, 也可以基于類型
    • 基于字段類型轉(zhuǎn)換配置-局部轉(zhuǎn)換器
      • 可以為某個 Model(該 Model 類也可能是 Action) 的各個屬性分別配置一個自定義的轉(zhuǎn)換器.
      • 創(chuàng)建一個屬性文件: ModelClassName-conversion.properties, 該文件需和相對應的 Model(Model有可能是一個Action) 類放在同一個目錄下
      • fieldName=Converter全類名屿脐,例如: birth=org.pan.struts2.conver.DateConverter
    • 基于類型-全局轉(zhuǎn)換器
      • 在資源目錄下涕蚤,src 或者 其他的 resources 創(chuàng)建 xwork-conversion.properties文件
      • xwork-conversion.properties 文件里把每一個需要進行類型轉(zhuǎn)換的類與一個類型轉(zhuǎn)換器關聯(lián)起來
      • java.util.Date=org.pan.struts2.conver.DateConverter
      • 若類型轉(zhuǎn)換失敗,給出自定義的信息的诵。

復雜屬性万栅,集合協(xié)同工作

  • 復雜屬性
    • 類型轉(zhuǎn)換與復雜屬性配合使用
    • form 標簽的 name 屬性可以被映射到一個屬性的屬性.
    • 復雜屬性
<s:form action="user_add">
    <s:textfield name="user.name" label="姓名"></s:textfield>
    <s:textfield name="user.gender" label="性別"></s:textfield>
    <s:textfield name="user.address" label="地址"></s:textfield>
    <s:textfield name="user.mgr.name" label="經(jīng)理名稱"></s:textfield>
    <s:textfield name="user.mgr.birth" label="經(jīng)理生日"></s:textfield>
    <s:submit value="添加"></s:submit>
</s:form>
  • 集合協(xié)同
    • 類型轉(zhuǎn)換與 Collection 配合使用

國際化

  • 概述

    • 在程序設計領域, 把在無需改寫源代碼即可讓開發(fā)出來的應用程序能夠支持多種語言和數(shù)據(jù)格式的技術(shù)稱為國際化.
    • 與國際化對應的是本地化, 指讓一個具備國際化支持的應用程序支持某個特定的地區(qū)
    • Struts2 國際化是建立在 Java 國際化基礎上的:
    • 為不同國家/語言提供對應的消息資源文件
      • Struts2 框架會根據(jù)請求中包含的
        • Locale 加載對應的資源文件
      • 通過程序代碼取得該資源文件中
      • 指定 key 對應的消息
  • 默認攔截器棧中有一個i18n攔截器,這個攔截器用來設置當前Locale信息

    • 當i18n攔截器被調(diào)用時西疤,他會先去查找request_locale這個請求參數(shù)烦粒,它會根據(jù)干參數(shù)來創(chuàng)建一個Locale對象。并將Locale對象放入進session域中瘪阁。之后在加載國際化資源文件時就根據(jù)剛剛創(chuàng)建的Locale對象
  • 當i18n攔截的請求中沒有request_locale這個參數(shù)撒遣,

  • 它會先去session中獲取Locale對象,如果session中管跺,則直接使用該對象

  • 如果session中沒有义黎,則會根據(jù)用戶瀏覽器信息或本地服務器的信息去創(chuàng)建一個Locale對象并使用

  • 配置國際化資源文件

    • Action 范圍資源文件:
      • 在Action類文件所在的路徑建立名為ActionName_language_country.properties 的文件
    • 包范圍資源文件:
      • 在包的根路徑下建立文件名為package_language_country.properties 的屬性文件豁跑,一旦建立廉涕,處于該包下的所有 Action 都可以訪問該資源文件。
      • 注意:包范圍資源文件的 baseName 就是package艇拍,不是Action所在的包名狐蜕。
    • 全局資源文件
      • 命名方式: basename_language_country.properties
      • struts.xml <constant name="struts.custom.i18n.resources" value="baseName"/>
<!-- 配置國際化資源 -->
<constant name="struts.custom.i18n.resources" value="i18n"/>
  • 臨時指定資源文件:<s:i18n.../> 標簽的 name 屬性指定臨時的國際化資源文件
  • 總結(jié):
    • 國際化資源文件加載的順序如何呢 ?
      • 離當前 Action 較近的將被優(yōu)先加載.
    • 假設我們在某個 ChildAction 中調(diào)用了getText("username")
      • (1)加載和 ChildAction 的類文件在同一個包下的系列資源文件 ChildAction.properties
      • (2)加載 ChildAction 實現(xiàn)的接口 IChild,且和 IChildn 在同一個包下 IChild.properties 系列資源文件卸夕。
      • (3)加載 ChildAction 父類 Parent层释,且和 Parent 在同一個包下的 baseName 為 Parent.properties 系列資源文件。
      • (4) 若 ChildAction 實現(xiàn) ModelDriven 接口快集,則對于getModel()方法返回的model 對象贡羔,重新執(zhí)行第(1)步操作。
      • (5) 查找當前包下 package.properties 系列資源文件个初。
      • (6) 沿著當前包上溯乖寒,直到最頂層包來查找 package.properties 的系列資源文件。
      • (7) 查找 struts.custom.i18n.resources 常量指定 baseName 的系列資源文件院溺。
      • (8) 直接輸出該key的字符串值楣嘁。
  • Action 范圍國際化
  • package 范圍國際化
  • 全局的國際化
    • 首先需要去 struts.xml 中指定baseName
<!-- 指定國際化 baseName, 以便于建立全局的國際化資源文件 -->
<constant name="struts.custom.i18n.resources" value="myI18n"></constant>
  • 全局的配置
  • 在這還需要講到一種方式:在頁面國際化資源

    • 如果我們在資源路徑下建立好了 國際化資源,但是沒有在 struts.xml 中配置 baseName
    • 我們可以使用 <s:i18n name="baseName"> 標簽來獲取
    <!-- 如果是配置了頁面國際化資源文件,
    那么國際的內(nèi)容只能在i18n標簽中使用逐虚,一旦離開i18n標簽則不能使用 -->
    <s:i18n name="myI18n">
        <s:text name="username"></s:text>
        <s:form>
            <s:textfield name="username" key="username"></s:textfield>
            <s:password name="password" key="password"></s:password>
            <s:submit key="submit"></s:submit>
        </s:form>
    </s:i18n>

  • 訪問國際化消息
    • JSP 頁面訪問國際化消息

      • 不帶占位符:
        • <s:text name="key"/>
        • 表單元素的 label 屬性:可替換為 key 或使用 getText() 方法聋溜,并對其進行強制 OGNL 解析,使用%{}
      • 帶占位符:
        • 在 <s:text.../> 標簽中使用多個 <s:param.../> 標簽來填充消息中的占位符痊班。
        • Struts2 直接在國際化消息資源文件中通過 “${}” 使用表達式勤婚,該表達式將從值棧中獲取對應的屬性值(對象棧 和 Map 棧)
    • Action 訪問國際化消息:

      • 若 Action 類繼承了 ActionSupport ,則可調(diào)用 TextProvider 接口的 getText 方法涤伐。

  • 利用超鏈接實現(xiàn)動態(tài)加載國際化資源文件
    • Struts2 使用 i18n 攔截器 處理國際化馒胆,并且將其注冊在默認的攔截器中
    • i18n攔截器在執(zhí)行Action方法前,自動查找請求中一個名為request_locale 的參數(shù)凝果。
    • 如果該參數(shù)存在祝迂,攔截器就將其作為參數(shù),轉(zhuǎn)換成Locale對象器净,并將其設為用戶默認的Locale(代表國家/語言環(huán)境)型雳。并把其設置為 session 的 WW_TRANS_I18N_LOCALE 屬性
    • request 沒有名為request_locale 的參數(shù),則 i18n 攔截器會從 Session 中獲取 WW_TRANS_I18N_LOCALE 的屬性值山害,若該值不為空纠俭,則將該屬性值設置為瀏覽者的默認Locale
    • 若 session 中的 WW_TRANS_I18N_LOCALE 的屬性值為空,則從 ActionContext 中獲取 Locale 對象浪慌。
<!-- 必須是 struts 請求,使得 i18 攔截器工作 -->
<a href="userLogin.action?request_locale=en_US">English</a>
<a href="userLogin.action?request_locale=zh_CN">中文</a>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末冤荆,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子权纤,更是在濱河造成了極大的恐慌钓简,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,826評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件汹想,死亡現(xiàn)場離奇詭異外邓,居然都是意外死亡,警方通過查閱死者的電腦和手機古掏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評論 3 395
  • 文/潘曉璐 我一進店門损话,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人槽唾,你說我怎么就攤上這事席镀。” “怎么了夏漱?”我有些...
    開封第一講書人閱讀 164,234評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長顶捷。 經(jīng)常有香客問我挂绰,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,562評論 1 293
  • 正文 為了忘掉前任葵蒂,我火速辦了婚禮交播,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘践付。我一直安慰自己秦士,他們只是感情好,可當我...
    茶點故事閱讀 67,611評論 6 392
  • 文/花漫 我一把揭開白布永高。 她就那樣靜靜地躺著隧土,像睡著了一般。 火紅的嫁衣襯著肌膚如雪命爬。 梳的紋絲不亂的頭發(fā)上曹傀,一...
    開封第一講書人閱讀 51,482評論 1 302
  • 那天,我揣著相機與錄音饲宛,去河邊找鬼皆愉。 笑死,一個胖子當著我的面吹牛艇抠,可吹牛的內(nèi)容都是我干的幕庐。 我是一名探鬼主播,決...
    沈念sama閱讀 40,271評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼家淤,長吁一口氣:“原來是場噩夢啊……” “哼异剥!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起媒鼓,我...
    開封第一講書人閱讀 39,166評論 0 276
  • 序言:老撾萬榮一對情侶失蹤届吁,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后绿鸣,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體疚沐,經(jīng)...
    沈念sama閱讀 45,608評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,814評論 3 336
  • 正文 我和宋清朗相戀三年潮模,在試婚紗的時候發(fā)現(xiàn)自己被綠了亮蛔。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,926評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡擎厢,死狀恐怖究流,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情动遭,我是刑警寧澤芬探,帶...
    沈念sama閱讀 35,644評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站厘惦,受9級特大地震影響偷仿,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,249評論 3 329
  • 文/蒙蒙 一酝静、第九天 我趴在偏房一處隱蔽的房頂上張望节榜。 院中可真熱鬧,春花似錦别智、人聲如沸宗苍。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽讳窟。三九已至,卻和暖如春蛇数,著一層夾襖步出監(jiān)牢的瞬間挪钓,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評論 1 269
  • 我被黑心中介騙來泰國打工耳舅, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留碌上,地道東北人。 一個月前我還...
    沈念sama閱讀 48,063評論 3 370
  • 正文 我出身青樓浦徊,卻偏偏與公主長得像馏予,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子盔性,可洞房花燭夜當晚...
    茶點故事閱讀 44,871評論 2 354

推薦閱讀更多精彩內(nèi)容