前面介紹了Spring Boot 如何整合定時任務已經Spring Boot 如何建立異步任務和定時任務。
接下來主要講解如何在SpringBoot應用中使用統一異常處理。如何實作對異常資料與正常的業務資料統一以json形式傳回?
一、為什麼要統一異常處理
目前我們項目架構基本上都是前後端分離的模式,采用Restful接口形式協定開發,前台不管任何業務邏輯,隻是接受現實資料。但是如果背景發生異常像資料庫異常、權限問題、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等錯誤。
推薦閱讀:
SpringBoot從小白到精通(十)使用Interceptor攔截器,一學就會! SpringBoot從小白到精通(九)使用@Async實作異步執行任務 SpringBoot從小白到精通(八)熟悉@EnableScheduling,一秒搞定定時任務 SpringBoot從小白到精通(七)使用Redis實作高速緩存架構 SpringBoot從小白到精通(六)使用Mybatis實作增删改查【附詳細步驟】 SpringBoot從小白到精通(五)Thymeleaf的文法及常用标簽 SpringBoot從小白到精通(四)Thymeleaf頁面模闆引擎 SpringBoot從小白到精通(三)系統配置及自定義配置 SpringBoot從小白到精通(二)如何傳回統一的資料格式 SpringBoot從小白到精通(一)如何快速建立SpringBoot項目