1. 程式人生 > 其它 >Spring MVC異常處理

Spring MVC異常處理

在 Spring MVC 應用的開發中,不管是操作底層資料庫,還是業務層或控制層,都會不可避免地遇到各種可預知的、不可預知的異常。我們需要捕捉處理異常,才能保證程式不被終止。

Spring MVC 有以下 3 種處理異常的方式:

  1. 使用 Spring MVC 提供的簡單異常處理器 SimpleMappingExceptionResolver。
  2. 實現 Spring 的異常處理介面 HandlerExceptionResolver,自定義自己的異常處理器。
  3. 使用 @ExceptionHandler 註解實現異常處理

1. @ExceptionHandler

區域性異常處理僅能處理指定 Controller 中的異常。

示例 1:

下面使用 @ExceptionHandler 註解實現。定義一個處理過程中可能會存在異常情況的 testExceptionHandle 方法。

@RequestMapping("/testExceptionHandle")
public String testExceptionHandle(@RequestParam("i") Integer i) {
    System.out.println(10 / i);
    return "success";
}

顯然,當 i=0 時會產生算術運算異常。

下面在同一個類中定義處理異常的方法。

@ExceptionHandler({ ArithmeticException.class })
public String testArithmeticException(Exception e) {
    System.out.println("列印錯誤資訊 ===> ArithmeticException:" + e);
    // 跳轉到指定頁面
    return "error";
}

注意:該註解不是加在產生異常的方法上,而是加在處理異常的方法上。

異常頁面 error.jsp 程式碼如下。

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>錯誤頁面</title>
</head>
<body>
    發生算術運算異常,請重新輸出資料!
</body>
</html>

訪問地址:http://localhost:8080/springmvcDemo2/testExceptionHandle?i=0,頁面跳轉到 error.jsp 頁面,執行結果如圖 1 所示。


圖 1:error.jsp頁面

控制器輸出結果如下。

列印錯誤資訊 ===> ArithmeticException:java.lang.ArithmeticException: / by zero

@ExceptionHandler 註解定義的方法優先順序問題:例如發生的是 NullPointerException,但是宣告的異常有 RuntimeException 和 Exception,這時候會根據異常的最近繼承關係找到繼承深度最淺的那個@ExceptionHandler 註解方法,即標記了 RuntimeException 的方法。

被 @ExceptionHandler 標記為異常處理方法,不能在方法中設定別的形參。但是可以使用 ModelAndView 向前臺傳遞資料。

使用區域性異常處理,僅能處理某個 Controller 中的異常,若需要對所有異常進行統一處理,可使用以下兩種方法。

2. HandlerExceptionResolver

Spring MVC 通過HandlerExceptionResolver 處理程式異常,包括處理器異常、資料繫結異常以及控制器執行時發生的異常。HandlerExceptionResolver 僅有一個介面方法,原始碼如下。

public interface HandlerExceptionResolver {
    @Nullable
    ModelAndView resolveException(
            HttpServletRequest request, HttpServletResponse response, @Nullable Object handler, Exception ex);
}

發生異常時,Spring MVC 會呼叫resolveException() 方法,並轉到 ModelAndView 對應的檢視中,返回一個異常報告頁面反饋給使用者。

示例 2:在 net.biancheng.exception 包中建立一個 HandlerExceptionResolver 介面的實現類 MyExceptionHandler,程式碼如下。

package net.biancheng.exception;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

public class MyExceptionHandler implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2,
            Exception arg3) {
        Map<String, Object> model = new HashMap<String, Object>();
        // 根據不同錯誤轉向不同頁面(統一處理),即異常與View的對應關係
        if (arg3 instanceof ArithmeticException) {
            return new ModelAndView("error", model);
        }
        return new ModelAndView("error-2", model);
    }
}

在 springmvc-servlet.xml 檔案中新增以下程式碼。

<!--託管MyExceptionHandler-->
<bean class="net.biancheng.exception.MyExceptionHandler"/>

再次訪問 http://localhost:8080/springmvcDemo2/testExceptionHandle?i=0,頁面跳轉到 error.jsp 頁面,執行結果如上圖 1 所示。

3. SimpleMappingExceptionResolver

全域性異常處理可使用SimpleMappingExceptionResolver 來實現。它將異常類名對映為檢視名,即發生異常時使用對應的檢視報告異常。

示例 3:在 springmvc-servlet.xml 中配置全域性異常,程式碼如下。

<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    <!-- 定義預設的異常處理頁面,當該異常型別註冊時使用 -->
    <property name="defaultErrorView" value="error"></property>
    <!-- 定義異常處理頁面用來獲取異常資訊的變數名,預設名為exception -->
    <property name="exceptionAttribute" value="ex"></property>
    <!-- 定義需要特殊處理的異常,用類名或完全路徑名作為key,異常頁名作為值 -->
    <property name="exceptionMappings">
        <props>
            <prop key="ArithmeticException">error</prop>
            <!-- 在這裡還可以繼續擴充套件對不同異常型別的處理 -->
        </props>
    </property>
</bean>

再次訪問 http://localhost:8080/springmvcDemo2/testExceptionHandle?i=0,頁面跳轉到 error.jsp 頁面,執行結果如上圖 1 所示。

from

http://c.biancheng.net/spring_mvc/exception.html