在實際的J2EE項目中,系統內部不免會出現一些異常,就如Struts+Spring+Hibernate項目:一般一個頁面請求到達後臺之後,首先是到action(就是MVC中的controller),在action層會調用業務邏輯層service,而在service層會調用持久層dao進而得到數據,再將得到的數據一層一層返回到action層,而後經過action控制層轉發到指定頁面,而這期間均可能會發生異常,dao層可能會發生SQLException異常,service層可能會發生NullPointException異常,action層可能會發生IOException異常,若是這三層都不處理的話異常信息會拋到服務器,而後服務器會把異常信息打印到瀏覽器上(用戶看不懂信息,體驗十分很差,), 處理得好可使開發效率快速提高。 html
一般處理這些異常有兩種方法:①直接throws,②try...catch...在catch塊中不作任何處理,或者僅僅printStackTrace()把異常信息打印出來。第一種就是會在瀏覽器上打印出用戶看不懂的異常信息,第二種方法則是頁面不報錯也不執行用戶的請求。 java
如何更好的解決這些異常? 數據庫
首先,在action類、service類、dao類,若是有必要就try...catch...,catch塊內不記錄log,一般是拋出一個新異常 瀏覽器
//action層執行數據添加操做 public String save(){ try{ //調用service的save方法 service.save(obj); }catch(Exception e){ //拋出Runtime異常可以使得沒必要再方法後寫throws xx throw new RuntimeException("添加數據時發生錯誤!",e); } return "success"; }而後在異常攔截器對異常進行處理
public String intercept(ActionInvocation actioninvocation) { String result = null; // Action的返回值 try { // 運行被攔截的Action,期間若是發生異常會被catch住 result = actioninvocation.invoke(); return result; } catch (Exception e) { /** * 處理異常 */ String errorMsg = "未知錯誤!"; //經過instanceof判斷究竟是什麼異常類型 if (e instanceof BaseException) { BaseException be = (BaseException) e; be.printStackTrace(); //開發時打印異常信息,方便調試 if(be.getMessage()!=null||Constants.BLANK.equals(be.getMessage().trim())){ //得到錯誤信息 errorMsg = be.getMessage().trim(); } } else if(e instanceof RuntimeException){ //未知的運行時異常 RuntimeException re = (RuntimeException)e; re.printStackTrace(); } else{ //未知的嚴重異常 e.printStackTrace(); } //把自定義錯誤信息 HttpServletRequest request = (HttpServletRequest) actioninvocation .getInvocationContext().get(StrutsStatics.HTTP_REQUEST); /** * 發送錯誤消息到頁面 */ request.setAttribute("errorMsg", errorMsg); /** * log4j記錄日誌 */ Log log = LogFactory .getLog(actioninvocation.getAction().getClass()); if (e.getCause() != null){ log.error(errorMsg, e); }else{ log.error(errorMsg, e); } return "error"; }// ...end of catch }
須要注意的是,在使用instanceOf判斷異常類型的時候必定要從子到父依次找,好比BaseException繼承RunTimeException,則必須首先判斷是不是BaseException再判斷是RunTimeException,最後在error jsp頁面顯示出具體的錯誤信息 服務器
<body> <s:if test="%{#request.errorMsg==null}"> <p>對不起,系統發生了未知的錯誤</p> </s:if> <s:else> <p>${requestScope.errorMsg}</p> </s:else> </body>以上方式能夠攔截後臺代碼全部的異常,但若是出現數據庫連接時異常不能被捕捉的則可以使用struts2的全局異常處理機制處理
<global-results> <result name="error" >/Web/common/page/error.jsp</result> </global-results> <global-exception-mappings> <exception-mapping result="error" exception="java.lang.Exception"></exception-mapping> </global-exception-mappings>