Java異常分類及統一處理詳解_java

來源:互聯網
上載者:User

一、異常分類

       java異常分為"檢查"和"非檢查"兩類,"檢查"二字的意思是,代碼編譯時間,編譯器會去Check一下有沒有進行異常處理(捕獲或向上拋),對于歸類為需要檢查的異常,若沒處理,編譯就過不去。
       初學的時候,常常想為啥異常要這樣分類處理? 後來明白了些,異常不過兩種:主觀和客觀,一個大多數情況下可以避免,一個大多數情況下無法避免。
       像NullPointerException這類異常,大多跟程式員素質掛鈎(開發好,測試好, 基本不會在系統運行後蹦出來), 基本是可以避免的,java文法當初把它們對類為‘非檢查異常',也算給程式員和編譯器省了不少事;
      而像IOException這類跟外在環境有關的異常,幾乎是不可避免的(指不定哪一天那一秒網路就掛了),但是當不期而遇時,程式還是要有所作為,所以編譯器有必要督促一下程式員,Check一下,看看是是否對這些可能不期而至的異常進行了處理。當Exception對象傳遞到某個節點後,程式就可以執行一些措施了,比如:給使用者返回一個提示("系統繁忙,請重試"),給監控平台推送一個異常訊息等等。

二、異常的統一返回處理

1、容器處理

下面列舉Tomcat的處理方式,在web.xml下配置,按http返回碼或Exception類型來處理:

<error-page> <error-code>404</error-code> <location>/WEB-INF/views/error/404.jsp</location> </error-page>  <error-page> <error-code>500</error-code> <location>/WEB-INF/views/error/500.jsp</location> </error-page>   <error-page> <exception-type>java.lang.Throwable</exception-type> <location>/WEB-INF/views/error/throwable.jsp</location> </error-page>

缺點:無法處理不需要返回html的請求,比如ajax;

2、架構處理

下面列舉Spring MVC的處理方式

(1)使用Spring MVC內建的簡單異常處理器SimpleMappingExceptionResolver;
(2)實現介面HandlerExceptionResolver 自訂異常處理器; (建議使用,可支援ajax等擴充)
(3)使用@ExceptionHandler註解實現異常處理;

第(1)種,在spring-mvc.xml下配置

 <!-- 將Controller拋出的異常轉到特定視圖 --> <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">  <property name="exceptionMappings">   <props>    <!-- 不同異常分開跳轉-->     <!-- 可以自訂不同的異常-->        <prop key="com.test.MyException1">/error/e1</prop>    <prop key="com.test.MyException2">/error/e2</prop>    <!-- 如果不想自訂異常,只配置下面的即可-->     <prop key="java.lang.Throwable">/error/500</prop>   </props>  </property> </bean>

缺點:無法處理不需要返回html的請求; 

 第(2)種,自訂HandlerExceptionResolver介面的實作類別

/** * 自訂異常處理器:支援ajax * @author wangxu * */public class MyExceptionHandler implements HandlerExceptionResolver {  public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {  /* 區分ajax */ boolean isAjax = request.getHeader("X-Requested-With") != null && "XMLHttpRequest".equals(request  .getHeader("X-Requested-With").toString()); if (!isAjax) { if (ex instanceof com.test.MyException1) { return new ModelAndView("/error/e1"); } else if (ex instanceof com.test.MyException1) { return new ModelAndView("/error/e2"); } else { return new ModelAndView("/error/500"); } } String jsonRes = "{\"message\":\"" + "系統異常" + "\"}";// 自訂結構和前台對接 PrintWriter out = null; try { out = response.getWriter(); request.setCharacterEncoding("utf-8"); response.setContentType("text/plain;charset=utf-8"); out.print(jsonRes); out.flush(); } catch (IOException e) { e.printStackTrace(); } finally { out.close(); } return null; }}

並在spring-mvc.xml下註冊處理器

<bean id="exceptionHandler" class="com.test.MyExceptionHandler"/>
優點:可以處理ajax請求,也方便編碼實現功能擴充,比如異常的監控等。

第(3)種,@ExceptionHandler註解

@Controllerpublic class TestExceptionHandlerController {  @ExceptionHandler({ MyException1.class }) public String exception(MyException1 e) { return "/error/e1"; } @RequestMapping("/marry") public void test() { throw new MyException1("沒錢!"); }}

缺點:@ExceptionHandler的方法,必須和可能拋異常的方法在一同個Controller下。(不建議使用)

3、結合

實際項目中,在處理異常的統一返回時,會將一些自訂的異常或者擴充交給架構,將http返回碼的映射交給容器,因為http返回碼更外層,有些到不了架構,有些對於架構來說就不是一個異常(比如404之與Spring MVC)。架構是運行在容器裡的,當架構優先拿到異常並做了返回處理,容器就不會再進行映射。

以上就是本文的全部內容,希望對大家的學習有所協助。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.