Java Web總體異常處理

        在實際的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>
相關文章
相關標籤/搜索