玩转springboot:自定义异常处理和深入异常处理原理
點個贊,看一看,好習慣!本文 GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收錄,這是我花了 3 個月總結(jié)的一線大廠 Java 面試總結(jié),本人已拿大廠 offer。
另外,原創(chuàng)文章首發(fā)在我的個人博客:blog.ouyangsihai.cn,歡迎訪問。
一、springboot原理探究
1、springboot默認錯誤處理機制
1.1、錯誤頁面
如果沒有進行處理出現(xiàn)錯誤,默認這樣處理頁面。
1.2、其他客戶端,默認響應(yīng)一個json數(shù)據(jù)
2、深入原理
2.1、查看BasicErrorController
這個類是默認處理/error請求的。下面看看源代碼
其中有這樣一段代碼來處理錯誤請求:
@Controller @RequestMapping("${server.error.path:${error.path:/error}}") public class BasicErrorController extends AbstractErrorController {@RequestMapping(produces = "text/html")//產(chǎn)生html類型的數(shù)據(jù);瀏覽器發(fā)送的請求來到這個方法處理public ModelAndView errorHtml(HttpServletRequest request,HttpServletResponse response) {HttpStatus status = getStatus(request);Map<String, Object> model = Collections.unmodifiableMap(getErrorAttributes(request, isIncludeStackTrace(request, MediaType.TEXT_HTML)));response.setStatus(status.value());//去哪個頁面作為錯誤頁面;包含頁面地址和頁面內(nèi)容ModelAndView modelAndView = resolveErrorView(request, response, status, model);}@RequestMapping @ResponseBody //產(chǎn)生json數(shù)據(jù),其他客戶端來到這個方法處理; public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {Map<String, Object> body = getErrorAttributes(request,isIncludeStackTrace(request, MediaType.ALL));HttpStatus status = getStatus(request);return new ResponseEntity<Map<String, Object>>(body, status); }其類圖如下:
下面我們還要看下一個關(guān)鍵類
2.2、DefaultErrorViewResolver
先看一下類圖
我們看看其中關(guān)鍵代碼,就知道springboot如何處理異常:
處理步驟:
一但系統(tǒng)出現(xiàn)4xx或者5xx之類的錯誤;ErrorPageCustomizer就會生效(定制錯誤的響應(yīng)規(guī)則);就會來到/error請求;就會被BasicErrorController(2.1中講解的)處理。
二、自定義異常處理響應(yīng)
2.1、自定義執(zhí)行流程
1)有模板引擎的情況下;error/狀態(tài)碼
將錯誤頁面命名為 錯誤狀態(tài)碼.html 放在模板引擎文件夾里面的error文件夾下,發(fā)生此狀態(tài)碼的錯誤就會來到 對應(yīng)的頁面。
我們可以使用4xx和5xx作為錯誤頁面的文件名來匹配這種類型的所有錯誤
頁面能獲取的信息:
timestamp:時間戳
status:狀態(tài)碼
error:錯誤提示
exception:異常對象
message:異常消息
errors:JSR303數(shù)據(jù)校驗的錯誤都在這里
例如:
2)沒有模板引擎(模板引擎找不到這個錯誤頁面),靜態(tài)資源文件夾下找(也就是static文件夾)
3)以上都沒有錯誤頁面,就是默認來到SpringBoot默認的錯誤提示頁面
2.2 單個異常處理
/*** @author 歐陽思海* @date 2018/7/25 9:57*/ @Controller @RequestMapping("/one") public class ExceptionControllerTest_2 {@RequestMapping(value = "/test", method = RequestMethod.GET)public void testException(){throw new UserNotExistException();}@ExceptionHandler(UserNotExistException.class)public Map<String,Object> exceptionHandler(Exception e) {Map<String,Object> map = new HashMap<>();map.put("code","notexist");map.put("message",e.getMessage());return map;}}說明:
- 在controller中加入被@ExceptionHandler修飾的類即可(在該注解中指定該方法需要處理的那些異常類)
- 該異常處理方法只在當前的controller中起作用
postman輸入或者瀏覽器:http://localhost:8080/one/test
2.3、全局自定義異常處理
2.3.1、自定義異常處理
我們需要寫一個MyExceptionHandler類,用@ControllerAdvice標注和@ExceptionHandler(UserNotExistException.class)標記具體使用哪個類
/*** @author 歐陽思海* @date 2018/7/26 10:58*/ @ControllerAdvice public class MyExceptionHandler {@ResponseBody@ExceptionHandler(UserNotExistException.class)public Map<String,Object> handleException(Exception e){Map<String,Object> map = new HashMap<>();map.put("code","notexist");map.put("message",e.getMessage());return map;} }說明:
-
@ControllerAdvice是controller的一個輔助類,最常用的就是作為全局異常處理的切面類
-
@ControllerAdvice可以指定掃描范圍
-
@ControllerAdvice約定了幾種可行的返回值,如果是直接返回model類的話,需要使用@ResponseBody進行json轉(zhuǎn)換
- 返回String,表示跳到某個view- 返回modelAndView- 返回model + @ResponseBody
2.3.2、controller測試
@RequestMapping(value = "/test2", method = RequestMethod.GET)public void testException(){throw new UserNotExistException();}2.3.3、測試結(jié)果
在瀏覽器輸入:http://localhost:8080/test2
點個贊,看一看,好習慣!本文 GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收錄,這是我花了 3 個月總結(jié)的一線大廠 Java 面試總結(jié),本人已拿大廠 offer。
另外,原創(chuàng)文章首發(fā)在我的個人博客:blog.ouyangsihai.cn,歡迎訪問。
最后,再分享我歷時三個月總結(jié)的 Java 面試 + Java 后端技術(shù)學習指南,這是本人這幾年及春招的總結(jié),已經(jīng)拿到了大廠 offer,整理成了一本電子書,拿去不謝,目錄如下:
現(xiàn)在免費分享大家,在下面我的公眾號 程序員的技術(shù)圈子 回復 面試 即可獲取。
有收獲?希望老鐵們來個三連擊,給更多的人看到這篇文章
1、老鐵們,關(guān)注我的原創(chuàng)微信公眾號「程序員的技術(shù)圈子」,專注于 Java、數(shù)據(jù)結(jié)構(gòu)和算法、微服務(wù)、中間件等技術(shù)分享,保證你看完有所收獲。
2、給俺點個贊唄,可以讓更多的人看到這篇文章,順便激勵下我繼續(xù)寫作,嘻嘻。
3、另外,原創(chuàng)文章首發(fā)在我的個人博客:blog.ouyangsihai.cn,歡迎訪問。
點贊是對我最大的鼓勵
↓↓↓↓↓↓
總結(jié)
以上是生活随笔為你收集整理的玩转springboot:自定义异常处理和深入异常处理原理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 玩转springboot:实现sprin
- 下一篇: 玩转springboot:整合JdbcT