1. 程式人生 > >SpringBoot入門系列(十一)統一異常處理的實現

SpringBoot入門系列(十一)統一異常處理的實現

前面介紹了Spring Boot 如何整合定時任務已經Spring Boot 如何建立非同步任務和定時任務。不清楚的朋友可以看看之前的文章:《Spring Boot 入門系列文章》

接下來主要講解如何在SpringBoot應用中使用統一異常處理。

 

為什麼要統一異常處理

專案開發形式為前後端分離,採用Restful介面形式開發,對異常的處理與頁面業務資料統一以json形式返回。但是如果後臺發生異常像資料庫異常,Shiro異常,Redis異常等等異常時,前端通常顯示顯示一個非常難看的錯誤頁面,這對於使用者來說非常不友好,所以我們需要對各種系統異常進行統一處理,然後返回我們想要的結果。

 

 

如何實現

Spring Boot 實現統一異常處理的方法主要有以下兩種:

第一種:使用@ControllerAdvice和@ExceptionHandler註解

第二種:使用ErrorController類來實現。

使用ErrorController的方式比較簡單,這裡就不介紹了。今天主要就講講如何使用@ControllerAdvice和@ExceptionHandler註解的方式實現統一異常處理。

1.統一異常處理類

package com.weiz.exception;

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

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;

import com.weiz.utils.JSONResult;

@ControllerAdvice
public class GlobalExceptionHandler  {

    public static final String ERROR_VIEW = "error";


    @ExceptionHandler(value = Exception.class)
    public Object errorHandler(HttpServletRequest reqest, 
            HttpServletResponse response, Exception e) throws Exception {
        
        e.printStackTrace();
        // 是否ajax請求
        if (isAjax(reqest)) {
            return JSONResult.errorException(e.getMessage());
        } else {
            ModelAndView mav = new ModelAndView();
            mav.addObject("exception", e);
            mav.addObject("url", reqest.getRequestURL());
            mav.setViewName(ERROR_VIEW);
            return mav;
        }
    }
    
    public static boolean isAjax(HttpServletRequest httpRequest){
        return  (httpRequest.getHeader("X-Requested-With") != null  
                    && "XMLHttpRequest"
                        .equals( httpRequest.getHeader("X-Requested-With")) );
    }
}

說明:

  1、註解@ControllerAdvice表示這是一個控制器增強類,當控制器發生異常就會被此攔截器被攔截。

  2、註解@ExceptionHandler 定義攔截的異常類,可以獲取丟擲的異常資訊。這裡可以定義多個攔截方法,攔截不同的異常類,並且可以獲取丟擲的異常資訊,自由度更大。

 

2. 錯誤頁面

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8" />
    <title>捕獲全域性異常</title>
</head>
<body>
    <h1 style="color: red">發生錯誤:</h1>
    <div th:text="${url}"></div>
    <div th:text="${exception.message}"></div>
</body>
</html>

說明:這裡用的是thymeleaf 模板,這個之前介紹過:《SpringBoot入門系列(四)整合模板引擎Thymeleaf》

 

3. 測試類

建立一個測試異常的controller

package com.weiz.controller;

import com.weiz.utils.JSONResult;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping("err")
public class ErrorController {

    @RequestMapping("/error")
    public String error() {
        
        int a = 1 / 0;
        
        return "thymeleaf/error";
    }
    
    @RequestMapping("/ajaxerror")
    public String ajaxerror() {
        
        return "thymeleaf/ajaxerror";
    }
    
    @RequestMapping("/getAjaxerror")
    @ResponseBody
    public JSONResult getAjaxerror() {
        
        int a = 1 / 0;
        
        return JSONResult.ok();
    }
}

 

測試

在瀏覽器中輸入:http://localhost:8088/err/error

 

 最後

以上,就把Spring Boot統一異常處理講完了。這裡只介紹了使用@ControllerAdvice註解實現異常處理的方法,還有ErrorController的實現方式,大家可以去了解。

註解@ControllerAdvice方式只能處理控制器丟擲的異常,而類ErrorController方式可以處理所有的異常,包括未進入控制器的錯誤,比如404,401等錯誤。

&n