轉載請注明原文地址:http://www.cnblogs.com/ygj0930/p/6403033.html
在項目中的應用見: https://github.com/ygj0930/CoupleSpace
Java本身定義了兩個throwable類的子類,error類與exception類。而這些原生的異常除非是開發人員,否則一般人是看不懂的。那怎么辦呢?我們可以在開發時,繼承異常類,來自定義異常,並且在View層統一處理異常將之轉變為用戶能懂的信息以及控制項目跳過異常操作,維持項目的正常運行。
一:自定義Error類或Exception類
public class BaseError extends Error { protected String key; protected Object[] args; /** * * @param key 異常提示信息 */ public BaseError(String key) { super(key); this.key = key; } /** * * @param key 異常提示信息 * @param cause 異常對象 */ public BaseError(String key, Throwable cause) { super(key, cause); this.key = key; } /** * * @param key 異常提示信息 * @param args 在拋異常時把某些數據也拋給異常處理者 */ public BaseError(String key, Object ... args) { super(key); this.key = key; this.args = args; } /** * * @param key 異常提示信息 * @param cause 異常對象 * @param args 在拋異常時把某些數據也拋給異常處理者 */ public BaseError(String key, Throwable cause, Object ... args) { super(key, cause); this.key = key; this.args = args; } //在捕獲並處理異常時,獲取異常的詳細信息。比如在filter層統一處理異常時通過以下方法獲取所處理異常的信息來在view層作出應答 public String getKey() { return key; } public Object[] getArgs() { return args; } }
public class MyException extends RuntimeException { protected String key; protected Object[] args; public MyException(String key) { super(key); this.key = key; } public MyException(String key, Throwable cause) { super(key, cause); this.key = key; } public MyException(String key, Object ... args) { super(key); this.key = key; this.args = args; } public MyException(String key, Throwable cause, Object ... args) { super(key, cause); this.key = key; this.args = args; } public String getKey() { return key; } public Object[] getArgs() { return args; } }
Error和Exception都是實現了Throwable接口的,二者的區別主要在於:程度的不同。
Error是系統機器的錯誤,比如虛擬機內存溢出等嚴重問題,通常出現系統異常的時候項目都已經要停止運行的了。一般不會對error進行捕捉和處理,因為這些問題不是代碼可以修復的。
而Exception一般是運行過程中出現的邏輯錯誤、誤操作等輕度的問題,不會導致項目停止運行,只不過引發異常的操作不能正常完成而已。對於異常,我們一般進行捕捉處理,轉化為runtime異常的子類進行拋出,在過濾器統一進行處理以提供良好的用戶體驗並維持項目繼續運。
二:在項目代碼的try-catch()塊中包裝異常
在項目代碼中,有可能出現異常、運行錯誤的地方,用try-catch語句捕捉異常。把異常記錄到日志后,再把捕獲的異常包裝成自定義異常(注意:自定義的異常必須是繼承自RuntimeException的才可以拋出。其他Exception的不可以的)進行拋出。在一個filter處進行統一的攔截處理,作出用戶能理解的處理提示並進行有效的異常控制,以免項目崩潰,使得用戶跳過異常操作繼續使用項目。
比如:
try{ 數據庫操作 } catch (ClassNotFoundException e) { logger.error("ClassNotFoundException in ArticleDAO!", e); throw new MyException("ClassNotFoundError", e); } catch (SQLException e) { logger.error("SQLException in ArticleDAO!", e); throw new MyException("SQLError", e); }
三:配置一個過濾器位於過濾鏈的頂端,對所有進出項目的異常進行捕捉處理。
根據所捕捉到的異常不同來進行不同的提示信息,並控制項目在發生異常后如何響應,以維持項目繼續運行。
比如:
public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { String err=""; try { arg2.doFilter(arg0, arg1); }catch(Error e){ err="系統錯誤"; }catch(MyException e){ err=e.getKey(); }catch (Exception e) { err="系統異常"; } PrintWriter out = arg1.getWriter(); if(!err.equals("")){ out.print("<script>alert('"+err+"');window.location='index.jsp';</script>"); out.close();} }
切記,這個過濾器需配置在過濾鏈的第一位!