|
|
|
發新文章 |
|
|
Struts異常處理(原創) 異 常是當JVM(JAVA虛擬機)在執行應用程序的某個方法的時候遇到的非正常現象,JVM就會生成一個異常對象,拋給客戶以便客戶進行異常處理. Struts框架的異常處理機制建立在java異常處理的基礎之上.在研究Struts異常處理之前,先回顧一下java異常處理原理,理解java虛擬 機JVM的異常處理過程有助于應用設計正確的異常處理方法.處理異常需要JVM付出不小的開銷,所以用于必須慎重使用. JAVA 異常是在java程序運行的時候遇到非正常的情況而創建的對象,它封裝了異常信息,java異常的根類為java.lang.Throwable,整個類 有兩個直接子類java.lang.Error和java.lang.Exception.Error是程序本身無法恢復的嚴重錯誤.Exception 則表示可以被程序捕獲并處理的異常錯誤.JVM用方法調用棧來跟蹤每個線程中一系列的方法調用過程,該棧保存了每個調用方法的本地信息.對于獨立的 JAVA程序,可以一直到該程序的main方法.當一個新方法被調用的時候,JVM把描述該方法的棧結構置入棧頂,位于棧頂的方法為正確執行的方法.當一 個JAVA方法正常執行完畢,JVM回從調用棧中彈處該方法的棧結構,然后繼續處理前一個方法.如果java方法在執行代碼的過程中拋出異常,JVM必須 找到能捕獲異常的catch塊代碼.它首先查看當前方法是否賊這樣的catch代碼塊,如果存在就執行該catch代碼塊,否則JVM回調用棧中彈處該方 法的棧結構,繼續到前一個方法中查找合適的catch代碼塊.最后如果JVM向上追到了main()方法,也就是一直把異常拋給了main()方法,仍然 沒有找到該異常處理的代碼塊,該線程就會異常終止,如果該線程是主線程,應用程序也隨之終止,此時JVM將把異常直接拋給用戶,在用戶終端上會看到原始的 異常信息.回顧完了JAVA的異常處理機制,就要開始研究Struts的異常處理了. Struts 框架在視圖層和控制層提供了對異常處理的支持.Struts的控制器負責捕獲各種異常,包括控制器運行中本身拋出的異常,以及調用模型的業務方法的異常. 當異常被控制器捕獲的時候,在異常處理代碼塊中,創建描述異常信息的ActionMessage對象把它保存在ActionMessages或者它的子類 ActionErrors對象中,然后把它保存在特定的范圍內,比如request或session.接下來在視圖層
標簽檢索特定范圍的ActionMessages對象,把本地化錯誤消息輸出到頁面上.這種異常處理機制可以避免用戶看到原始的 java異常信息.可以更友好的把錯誤信息展示給用戶. Struts 框架處理異常是以JVM的異常處理機制為基礎的,盡管它提供了強大的通用錯誤處理機制,但是不能保證捕獲到所有的異?;蛘咤e誤.當錯誤發生的時候,如果 Struts不能處理這種異?;蛘咤e誤,就把錯誤拋給JavaWeb容器.容器先查看是否在Web應用發布描述文件中配置了元素,如果存在該元素就返回元素的子元素指定的錯誤頁面,否則就會把錯誤直接拋給用戶.下面簡單介紹一 Struts幾個重要的類的異常處理機制,如果想了解這幾個類的更深的異常機制,建議查看Struts源代碼. 1) ActionServlet類的peocess()方法不捕獲任何異常,僅僅聲明向上層調用方法拋出異常. 2) RequestProcessor類是Struts框架處理異常的核心組件. 3) ExceptionHandler類是默認的異常處理類,它的execute()方法負責處理異常. 根據打造技術Blog,尋求JAVA精髓! Servlet規范,當容器捕獲到異常的時候,將查看是否在Web.xml中配置了相應的元素,如果存在,就會返回其子元素指定的錯誤頁面.舉個簡單明了的例子如下: 500 /error.jsp javax.servlet.ServletException /error.jsp Struts框架也允許以配置的方式來處理異 常,配置方法可以避免在Action類中通過硬編碼來處理異常,提高應用的靈活性,可重用性和可維護性.對于Action類的execute()方法拋出 的異常會先查找異常處理元素,如果是被嵌套在元素中就表示是全局異常處理元素,對所有的Action都適用.如果是嵌套在元素中,就表示局部的異常處理元素,僅對當前的Action適用.闡 述一下元素的屬性: 1) type:指定待處理的異常類 2) handler:指定異常處理類.默認是ExceptionHandler.如果自己要定義必須繼承它 3) path:指定轉發路徑 4) key:指定錯誤消息key.根據這個key到ResourceBundle中尋找匹配的消息文本 5) bundle:指定ResourceBundle,如果沒設置將使用哦么人的ResourceBundle 6) scope:指定ActionMessages對象的存放范圍,默認request,也可以設置session Struts框架提供了強大的異常處理功能,Struts控制器負責捕獲異常,并把異常包裝與 ResourceBundle綁定的 ActionMessages對象,在視圖層
標簽能夠顯示出來,主要可以通過配置的方式和編程的方式實現,這里不推 薦用編程的方法,可以增強程序的靈活性,可重用性,可維護性. (網友們的支持,是我繼續寫技術文章的動力!) Struts的異常處理機制總的來說,在struts新的版本中加入了對異常的處理,稱之為:Exception Handling,標志著作為一個整體的解決框架,struts原來越趨于成熟。 通 常來說,以前在用struts開發的過程中,對于異常的處理,主要是采用手動處理的方式:如通過try/catch等等捕獲異常,然后定制個性化的比較詳 細的錯誤信息放進ActionError中,然后在具體的返回頁面中把這些錯誤信息反饋給用戶(包括開發員)。異常原始的信息不管是最終用戶還是開發員都是不希望看到的。 下面著重講一下在struts中是如何通過配置文件來解決異常。 Struts中的Exception Handleing不難,簡單高效是業內給其的一個比較好的評價。 通過配置文件(主要是struts-config.xml)來定制異常處理,就象定義formbean一樣,定制異常也有兩種方法,姑且把它分為:“全局異常”和“局部異常”。 全局異常,定義方法如下: ………… ………… 上 述代碼在struts-config.xml中定義了一個全局異常,它的作用是拋出InvalidiItemsCatalogNameException (本處的意思是當在添加商品分類的時候發現該類別已經存在)異常的時候返回到error.jsp中,并且攜帶自定的比較規范的異常信息 expired.InvalidItemsCatalogName,expired.InvalidItemsCatalogName可以在應用程序的資源配置文件中找到,如: expired.InvalidItemsCatalogName=你要添加的商品類別已經存在,請添加新的類別! 局部異常,定義方法如下: ………… ………… (關于Tiles的內容參看我的另一篇文章“Struts使用Tiles輔助開發”) 下面我們把關注的目光放在具體action里,看看struts是如何進行異常處理的 //ItemsCatalogAction.java package com.iplateau.jshop.action.ItemsCatalogAction import com.iplateau.jshop.business.ItemsCatalogMap; import com.iplateau.jshop.action.ItemsCatalogForm; import ***; public class ItemsCatalogAction extends BaseAction { public ActionForward execute( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { String flg=”error”; String act=request.getParameter(“act”); ItemsCatalogMap map=new ItemsCatalogMap(); ItemsCatalogForm thisform=( ItemsCatalogForm)form; // ItemsCatalogMap為具體的處理商品類別的類 if(act.equals(“create”)) { map.validateNameOfCatalog(thisform); map.create(thisform); flg=”success”; return mapping.findForward(flg); } else{ return mapping.findForward(flg); } } } 上便是一個簡單的action,其中用act的具體內容來判斷此時的action要處理的操作,如act為cteate的時候,處理的是商品類別的添加等等。 看了上邊的代碼,可以了解,在調用具體的業務類進行添加商品類別以前先要判斷此時要添加的商品類別的合法性,如: 調用map.validateNameOfCatalog(thisform); 其中在ItemsCatalogMap定義的validateNameOfCatalog 方法拋出InvalidiItemsCatalogNameException。 下面讓我們運行一下添加商品類別的例子,如果此時數據庫中已經存在“牛奶制品”這個商品類別,而我們又要添加此類別的時候,程序如我們預想的一樣轉到error.jsp并且顯示了我們要先是的錯誤信息:你要添加的商品類別已經存在,請添加新的類別! 其實就這么簡單,我們的定制的異常在程序中并不需要用try/catch來捕獲,一旦出現了我們已經定義的異常那么就會轉到相應得頁面,并且攜帶定制的信息。 還記得在struts先前的版本中我們的請求都是通過action的perform來處理,可是現在都要通過execute來處理,就其原因一個很重要的就是“成全”Exception Handling。為什么呢? 因為perform在聲明的時候僅僅拋出IOException 和ServletException,這遠遠不能滿足Exception Handling的要求,那么讓我們看看execute是怎樣的:它籠統的拋出Exception(所有異常的父類) 上 面的闡述只是一個引子,而且默認struts的異常是通過org.apache.struts.action. ExceptionHandler來處理的,你可以定義自己的處理方式,只要繼承它并實現其中的execute方法,這個方法在ExceptionHandler的定義如下: public ActionForward execute (Exception ex, ExceptionConfig ae, ActionMapping mapping, ActionForm formInstance, HttpServletRequest request, HttpServletResponse response) throws ServletException 具體而且專業的分析Exception Handling的內容,請參看《Programming Jakarta Struts》第10章??這本書的電子版網上很多地方可以下載。 原文地址 http://tech.ccidnet.com/pub/article/c322_a74029_p1.html
|