SpringMVC的異常處理

 

方式一

try....catch...finally,在catch中捕獲、處理異常web

 


 

 

方式二

設置默認的全局異常處理器。spring

 

發生異常時,一級一級往上拋,數據庫

這個過程當中,若是異常被catch捕獲、處理,那就沒事了;瀏覽器

若是沒有對應的catch來捕獲、處理異常,最終被拋到DispatcherServlet、web服務器,web服務器的處理方式是:傳回一堆錯誤信息顯示在瀏覽器中給用戶看。服務器

 

咱們能夠設置一個默認的全局異常處理器,拋到DispatcherServlet時,由DispatcherServlet調用默認的全局異常處理器來處理異常。app

至關於設置了一個全局的catch。jvm

 

 

新建一個類,實現HandlerExceptionResolver接口便可:ide

@Component
public class MyExceptionResolver implements HandlerExceptionResolver {

    @Override
    public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
        ModelAndView mav = new ModelAndView("error");
        mav.addObject("msg", e.getMessage());
        return mav;
    }
}
  • 須要把這個類放到Spring容器中,能夠用<bean>來配置,也能夠用@Component標註。
  • 會自動傳入異常對象,咱們能夠從這個異常對象中獲取異常信息
  • 返回值是ModelAndView類型,這個類會在jvm以前攔截沒人要的異常,調用resolveException()來處理,並用指定的視圖來響應。能夠向視圖傳遞異常信息。

 

 

本來會在瀏覽器頁面上顯示一堆錯誤信息,全是專業名詞、仍是英文,對用戶很不友好。函數

此種方式,能夠指定視圖、自定義要顯示的信息,對用戶很友好。this

缺點是統一處理未經捕獲的異常,無論什麼樣的異常,處理方式都同樣,太籠統。

 

 


 

 

方式三   

使用自定義的異常類。

 

(1)新建包com.chy.exception,用來放自定義的異常類。而後編寫多個自定義的異常類。

  好比轉帳,可能出現:

  • 餘額不足,NoMoneyException
  • 對方帳戶不存在,UserNotFoundException
  • 帳戶被凍結,FrozenException
public class NoMoneyException extends Exception{
    private String msg;

    public NoMoneyException(String msg) {
        super();
        this.msg = msg;
    }

    public String getMsg() {
        return msg;
    }
}

提供String類型的字符串來表示異常信息,對應的構造函數來建立異常對象,提供對應的getter方法來獲取異常信息。

以一樣的方式建立其它2個異常。

 

alt+insert時,不要使用String  message,這個是基類Exception的參數,表示代碼執行的錯誤信息。用咱們本身寫的變量就OK。

咱們自定義的異常不是爲了處理代碼錯誤,代碼錯誤直接try...catch就行了,不必自定義異常。

自定義異經常使用於友好提示用戶,好比說dao層查詢到餘額不足,我直接拋一個NoMoneyException,代碼執行自己是沒有錯誤的,異常是手動拋的。

 

 

 

(2)在dao層拋出異常

public class UserDao{

    public void transfer(int to,int from,double amount) throws NoMoneyException,UserNotFoundException,FrozenException {
        //此處省略鏈接數據庫查詢
        //.....

        //餘額不足
        if (餘額不足){
            throw new NoMoneyException("您當前餘額xx元,餘額不足,沒法完成轉帳!");
        }
        //對方帳號不存在
        if (對方帳號不存在){
            throw new UserNotFoundException("對方帳號xxxxxxxxxx不存在!");
        }
        //對方帳號被凍結
        if (對方帳號被凍結){
            throw new FrozenException("對方帳號xxxxxxxxxx已被凍結,沒法向對方轉帳!");
        }


        //....
    }
}

不使用catch來處理,要在方法簽名上拋出異常。

 

 

在對應的service層的方法簽名上也要拋出來:

public class UserService{
    public void transfer(int to,int from,double amount) throws NoMoneyException,UserNotFoundException,FrozenException {
        //調用dao層
    }
}

 

 

 

(3)在controller中處理異常

@org.springframework.stereotype.Controller
public class UserController {

    @RequestMapping("/transfer")
    public ModelAndView transfer() {
        try {
            //調用service層
        }catch (NoMoneyException e){
            //能夠調用e.getMsg()獲取自定義的異常信息,轉發到某個視圖、傳遞數據
            //.....
        }catch (UserNotFoundException e){
            //....
        }catch (FrozenException e){
            //......
        }
    }

}

 

 

也能夠在全局異常類中處理:

@Component
public class MyExceptionResolver implements HandlerExceptionResolver {

    @Override
    public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
        //按異常的種類來進行對應的處理,
        if (e instanceof NoMoneyException){
            //.....
        }
        if (e instanceof UserNotFoundException){
            //.....
        }
        if (e instanceof FrozenException){
            //.....
        }

    }

}

若是處理方式都相同,好比都是轉發到某個視圖、顯式自定義的錯誤信息,那就沒必要寫if判斷來區分異常類型,直接寫處理。

一樣能夠調用視圖、傳遞數據。

 

 

方式三一般和try...catch配合使用:

  • try...catch處理代碼錯誤,好比文件找不到、空指針異常等,代碼執行自己出了問題;
  • 方式三主要用於咱們自定義的錯誤,代碼執行自己沒問題。
相關文章
相關標籤/搜索