SpringBoot部落格開發之異常處理

xbhog發表於2021-08-30

異常處理:

背景:

最近在搭建屬於自己的個人部落格(碼農小白的執念),自己搭建後端的時候首先考慮的是異常處理。個人也是一邊學習一邊做,難免有疏漏的地方,希望朋友們在不對的地方提醒下。

技術棧:

  1. springBoot 2.5.3
  2. Mybatis-plus
  3. thymeleaf
  4. mysql

該部落格簡單記錄一下自己的學習過程,如果後面作出簡單的demo來,那麼會整理其中的細節釋出出來。

異常處理

個人粗糙的學習和理解,我把異常錯誤分為三個,4xx,5xx,error(自定義)

常用的是404和500響應

  • 404 (未找到) 伺服器找不到請求的網頁
  • 伺服器內部錯誤 伺服器遇到錯誤,無法完成請求

在templates檔案下建立404.html、500.html和error.html

如果建立的是4xx.html和5xx.html,那麼當頁面找不到或者程式內部錯誤的話,SpringBoot自動匹配到這兩個頁面,具體的原始碼在這裡就不分析,感興趣的可以去學習下。

當我想將錯誤資訊返回到我自定義的頁面怎麼寫?

我們自頂向下來思考:

  1. 我們訪問頁面的時候,頁面發生錯誤也好,找不到也好,是不是都要走它請求的Url,那我們怎麼處理這個請求呢?
  2. 這時候我們自然而然的想到攔截器,所以編寫ControllerExceptionHandler類,來專門攔截所有的異常請求。
  3. 當我們處理完異常後,把這個流放行,或者返回我們需要的自定義頁面上。

這樣就實現了我們上述的需求。

所需要的技術點:

  1. @ControllerAdvice
    • 配合 @ExceptionHandler註解結合使用,當異常拋到controller層時,可以對異常進行統一的處理,規定返回的json格式或者跳轉到指定的錯誤頁面等.
  2. @ExceptionHandler(Exception.class) // 表示 捕獲 全部異常
  3. ModelAndView 其實就是兩個作用,一個是指定返回頁面,另一個是在返回頁面的同時新增屬性

通過Logger來列印獲取相關的異常資訊:

//獲取異常的資訊
logger.error(() -> {
    return String.format("Request URL : %s,Exception : %s ", request.getRequestURL(),e);
},e);

在這裡自己走了一些彎路,小夥子自己走窄了,導包倒錯了?。這裡我導的包是mybatis中的:

import org.mybatis.logging.Logger;
import org.mybatis.logging.LoggerFactory;

傳參一直不對,只能走原始碼的路子了,看看自己呼叫的什麼玩意:最後就寫成了上述的程式碼格式。

我看其他人寫的程式碼的時候才恍然大明白,如下:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

logger.error("Requst URL : {},Exception : {}", request.getRequestURL(),e);

可能有的朋友感覺沒啥,但是我自己調了半個小時才出來,菜是原罪。

Logger這個只是在控制檯輸出,或者繫結了日誌,會輸出到日誌中。

接著上述問題通過ModelAndView類實現:

ModelAndView像極了Model。

ModelAndView modelAndView = new ModelAndView();  //例項化一個ModelAndView
modelAndView.addObject("url",request.getRequestURL());  //獲取的url新增到model中
modelAndView.addObject("exception",e);  //獲取的異常資訊
//返回給error頁面
modelAndView.setViewName("error/error");
return modelAndView;

敲黑板:來新需求了!

如果我想從所有的異常中剝離出404異常並返回給SpringBoot讓他自動處理頁面怎麼解。

按照學習的來說。當頁面為null的時候,向上丟擲一個自定義的異常類,該異常類標註了異常狀態。

throw new NotFoundException("部落格找不到,請聯絡管理員"); //自定義類
@ResponseStatus(HttpStatus.NOT_FOUND)
public class NotFoundException extends RuntimeException{
    public NotFoundException() {
        super();
    }
    public NotFoundException(String message) {
        super(message);
    }
}

然後我們可以在總的異常中通過AnnotationUtils.findAnnotation通過傳入AnnotatedElement註解型別來查詢方法或者類物件上的註解。

如果滿足條件可以丟擲異常讓SpringBoot接管。

if (AnnotationUtils.findAnnotation(e.getClass(), ResponseStatus.class) != null) {
    throw e;
}

結束:

如果你看到這裡或者正好對你有所幫助,希望能點個關注或者推薦,感謝;

有錯誤的地方,歡迎在評論指出,作者看到會進行修改。

相關文章