1、全局異常處理,指的是對於程序中產生的Exception進行的處理。產生了異常之后,可以統一跳轉到一個頁面進行錯誤提示,也可以通過Restful形式返回錯誤信息。
注意:關於全局錯誤與全局異常的區別。全局錯誤,指的是對http狀態碼進行的錯誤跳轉處理,全局異常指的是發生某些異常(如果處理的是Exception,則表示處理全部異常)之后的跳轉頁面。兩者屬於並行的概念,在項目開發中建議同時配置兩者。
2、首先,創建一個全局異常處理,該類可以處理所有的Exception異常。
1 package com.demo.config; 2 3 import javax.servlet.http.HttpServletRequest; 4 5 import org.springframework.web.bind.annotation.ControllerAdvice; 6 import org.springframework.web.bind.annotation.ExceptionHandler; 7 import org.springframework.web.servlet.ModelAndView; 8 9 /** 10 * 11 * @author 12 * 13 * 作為一個控制層的切面處理 14 * 15 */ 16 @ControllerAdvice 17 public class GlobalExceptionAdvice { 18 19 public static final String DEFAULT_ERROR_VIEW = "error"; // 錯誤顯示頁error.html 20 21 /** 22 * 出現異常會執行此方法 23 * 24 * @param request 25 * @param e 26 * @return 27 */ 28 @ExceptionHandler(Exception.class) 29 public ModelAndView defaultErrorHandler(HttpServletRequest request, Exception e) { 30 // 設置跳轉路徑 31 ModelAndView mav = new ModelAndView(GlobalExceptionAdvice.DEFAULT_ERROR_VIEW); 32 // 保存異常信息 33 mav.addObject("exception", e); 34 // 獲取請求的路徑 35 mav.addObject("url", request.getRequestURL()); 36 return mav; 37 } 38 39 }
然后在src/main/view/templates下面創建error.html頁面,進行錯誤信息顯示,注意,必須將error.html頁面創建到src/main/view/templates下面的,不然無法進行跳轉顯示的。
1 <!DOCTYPE html> 2 <html xmlns="http://www.thymeleaf.org"></html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Insert title here</title> 6 </head> 7 <body> 8 <h1>搞事情啊!!!</h1> 9 10 <!-- 輸出url屬性 --> 11 <p th:text="${url}"></p> 12 <p th:text="${exception}"></p> 13 14 </body> 15 </html>
創建一個控制器,主要作用是產生一個異常信息,以觀察全局異常處理是否生效。
1 package com.demo.controller; 2 3 import org.springframework.stereotype.Controller; 4 import org.springframework.web.bind.annotation.RequestMapping; 5 import org.springframework.web.bind.annotation.ResponseBody; 6 7 @Controller 8 public class SpringBootController { 9 10 @RequestMapping(value = "/world") 11 @ResponseBody 12 public String hello() { 13 int result = 1 / 0; 14 System.out.println("hello world!!!"); 15 return "error404"; 16 } 17 18 }
只要訪問http://127.0.0.1:8081/world路徑,就會產生異常,而產生異常之后將統一跳轉到error.html頁面。

項目結構,如下所示:

切記:SpringBoot項目中Thymeleaf的動態頁面需要保存在templates(src/main/resources/templates)目錄中,頁面的擴展名默認使用的是*.html,如果開發者覺得這樣的設計不合理,也可以通過application.yml配置文件自行修改。
Thyemeleaf靜態資源,在進行Web信息顯示的過程中,除了可以配置動態顯示頁面之外,也可以配置靜態資源(如*.html、*.css、*.js等)。對於靜態資源,要求其必須放在源文件夾的static(src/main/resources/static)目錄中。
3、可以設計為基於Restful錯誤信息提示。在發生異常之后采用跳轉的形式來處理,而SpringBoot最大的特點是支持Restful處理,因此為了描述異常,也可以直接采用Restful的形式回應異常信息,即不再跳轉到HTML頁面進行顯示。
1 package com.demo.config; 2 3 import javax.servlet.http.HttpServletRequest; 4 5 import org.springframework.http.HttpStatus; 6 import org.springframework.web.bind.annotation.ExceptionHandler; 7 import org.springframework.web.bind.annotation.RestControllerAdvice; 8 9 /** 10 * 11 * @author 12 * 13 * 作為一個控制層的切面處理 14 * 15 */ 16 @RestControllerAdvice // 使用restful風格進行返回 17 public class GlobalExceptionAdvice { 18 19 public static final String DEFAULT_ERROR_VIEW = "error"; // 錯誤顯示頁error.html 20 21 /** 22 * 出現異常會執行此方法 23 * 24 * @param request 25 * @param e 26 * @return 27 */ 28 @ExceptionHandler(Exception.class) // 處理所有異常 29 public Object defaultErrorHandler(HttpServletRequest request, Exception e) { 30 // 搞一個內部類 31 class ErrorInfo { 32 private Integer code; 33 private String message; 34 private String url; 35 36 public Integer getCode() { 37 return code; 38 } 39 40 public void setCode(Integer code) { 41 this.code = code; 42 } 43 44 public String getMessage() { 45 return message; 46 } 47 48 public void setMessage(String message) { 49 this.message = message; 50 } 51 52 public String getUrl() { 53 return url; 54 } 55 56 public void setUrl(String url) { 57 this.url = url; 58 } 59 60 } 61 62 ErrorInfo errorInfo = new ErrorInfo(); 63 errorInfo.setCode(HttpStatus.INTERNAL_SERVER_ERROR.value()); // 狀態碼 64 errorInfo.setMessage(e.getMessage()); // 保存錯誤信息 65 errorInfo.setUrl(request.getRequestURI().toString()); // 保存錯誤路徑 66 return errorInfo; 67 } 68 69 }
如果使用@RestControllerAdvice注解,則此時的異常處理將使用Restful風格,程序發生異常之后的運行效果,如下所示:

