大多數(shù)的表單交互中,用戶都需要看到操作的結(jié)果。以一致的方式顯示錯誤和信息是一個好的框架應(yīng)該具備的功能。在前面一節(jié)中,我們討論了通過消息資源對象本地化消息。通過名/值對讓消息資源對象和屬性文件對應(yīng)。一個基于struts的應(yīng)用會在處理資源包之前在ActionErrors對象中收集和查找,確認(rèn)和通知信息。下面的圖示解釋了struts中涉及到錯誤處理機(jī)制的類。
我們將簡單的討論前面解釋的交互動作。我們將看到struts怎樣從本地特定消息中獲得消息key,又怎么在視圖中以一致的方式得到處理。我們將用jsp作為視圖組件。
用ActionError標(biāo)識錯誤
實現(xiàn)Action.execute(…) 或 ActionForm.validate(…)方法,應(yīng)該可以捕捉驗證和應(yīng)用程序特定錯誤到ActionErrors對象中,他們組成了ActionError對象。一個ActionError對象有一個消息key和一個可選對象用來存放動態(tài)返回的消息。參考上一節(jié)的相關(guān)信息,一個ActionErros對象不用關(guān)心本地化和相關(guān)的資源包就可以創(chuàng)建。我們可以處理118N當(dāng)ActionError對象處理消息時。可以參考ActionErrorAPI獲得完全的創(chuàng)建ActionError對象的方法列表。一旦一個ActionError對象創(chuàng)建,就應(yīng)該使用ActionError對象的ActionError.add方法添加到ActionError對象組中,并且傳遞ActionError和檢測到校驗錯誤的屬性名。為了保存錯誤消息而不關(guān)聯(lián)到屬性,可以用ActionErrors.GLOBAL_ERROR代替屬性參數(shù)。使用屬性名創(chuàng)建ActionError對象在ActionErrors一節(jié)解釋。ActionError類擴(kuò)展ActionMessage類;和struts1.1一樣,ActionError類簡單的把調(diào)用委托給ActionMessage類。
用ActionErrors管理錯誤
ActionErrors對象使用HashMap方式管理所有ActionError對象,名是消息屬性名,值是ActionMessageItem對象。ActionMessageItem作為inner類聲明在ActionMessages中。每一個ActionMessageItem對象由一個唯一的序列號和一個包含屬性對應(yīng)所有校驗錯誤的的ArrayList對象組成。序列號用來排序ActionMessageItem集合,其中的校驗錯誤通過開始標(biāo)記為invalid的屬性獲得。ActionErrors.get返回一個ArrayList的迭代器,其中容納了ActionError對象集合。這個迭代對象通過定制ErrorsTag標(biāo)簽引用,將在下節(jié)解釋。
在請求處理器,比如在Action.execute中,ActionErrors應(yīng)該用屬性名Action.ERROR_KEY保存到HttpServletRequest中;這個操作通過調(diào)用action基類的saveErrors方法,傳遞請求對象和ActionErrors對象作為參數(shù)。ActionErrors作為ActionForm.validate(…)的結(jié)果產(chǎn)生,由在請求對象中的RequestProcessor使用Action.ERROR_KEY保存。下一個視圖可以用ErrorsTag來獲得ActionErrors對象;ErrorsTag可以用在jsp中。
ActionErrors類擴(kuò)展了actionMessages類。ActionErrors提供了靜態(tài)成員GLOBAL_ERROR,ActionMessages提供了靜態(tài)成員GLOBAL_MESSAGE,這些靜態(tài)成員當(dāng)消息不是特定屬性時可以作為keys用。如果要保存ActionMessages對象到請求處理對象中,傳遞請求對象和ActionMessages對象給Action.saveMessages(…)方法即可;Action.saveMessages(…)對象使用Action.MESSAGE_KEY保存到請求對象中。
如果想簡單的獲得消息keys,不用屬性和動態(tài)參數(shù),可以用org.apache.struts.util.RequestUtils.getActionErrors(…)方法轉(zhuǎn)換一個String對象,String數(shù)組,或一個ErrorMessages對象(Vector)到一個ActionErrors對象中。對于這種方式,getActionErrors(…)會用ActionErrors.GLOBAL_ERROR代替屬性參數(shù)。
用ErrorsTag顯示錯誤
這個定制的標(biāo)簽顯示消息到HTML文檔中。它使用Action.ERROR_KEY從HttpServletRequest中獲得ActionErrors對象,然后使用ActionErrors.get()方法獲得容納ActionError對象的ArrayList的迭代器。對ArrayList中的每一個ActionError對象,一個本地消息被寫到response流中。默認(rèn)使用session中的本地對象;但是可以在標(biāo)簽中定義相反的本地屬性。默認(rèn)情況下,資源包用Action.MESSAGES_KEY保存到上下文中,除潛昵┒ㄒ辶似淥糶浴R孕枰哺親試窗綣桓鲆隕系幕咀試次募枰芾硎薄:蛃truts1.1一樣,一個ErrorsTag僅能使用一個資源包家族(有相同的基本名稱),因此在ActionErrors對象中的所有錯誤應(yīng)該在資源包家族中都可以找到。因為ActionErrors對象中的所有ActionError對象都用屬性名登記了,消息可以通過在ErrorsTag中定義一個屬性名對應(yīng)。ErrorsTag使用消息keys‘errors.header’和‘errors.footer’提供錯誤消息顯示的標(biāo)題和格式。