日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

SpringBoot异常处理的简单理解

發(fā)布時間:2025/3/16 javascript 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SpringBoot异常处理的简单理解 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Springboot異常處理:

1、局部異常處理:

直接對Controller類進(jìn)行操作

?

2、全局統(tǒng)一異常處理

Springboot兩種全局異常統(tǒng)一處理的方式:

A使用繼承BasicErrorController 來實現(xiàn)

B通過@ControllerAdvice 注解來處理統(tǒng)一錯誤(Advice 異常處理)

?

(1)Java 異常的 Root 是 Throwable, 其下有 Error 和 Exception. Error 是 JVM 級的致命錯誤, 應(yīng)用系統(tǒng)內(nèi)部一般不用關(guān)心這類錯誤. Exception 是異常的父類, 其下分為兩類, 一類是 Runtime Exception, 一類是 Checked Exception. Checked Exception 是那些編譯器能檢查到的異常, 如果一個函數(shù)中拋出了這類異常, 我們要么 catch 它, 要么在函數(shù)簽名上繼續(xù)拋出去, 否則程序?qū)⒉荒芫幾g通過。

Runtime Exception 有, 包括 RuntimeException 和它的子類. 比如 ArrayIndexOutOfBoundsException/ClassCastException/被 0 除等.?
Checked Exception 有: Exception 類和所有非 RuntimeException 類的異常都屬于 checked exception, 比如 IoException 等.

(2)dao、service、controller出現(xiàn)的未知異常都通過throws Exception向上拋出,最后由springmvc前端控制器交由異常處理器進(jìn)行異常處理,springmvc提供全局異常處理器進(jìn)行統(tǒng)一的異常處理,一個系統(tǒng)只有一個異常處理器。Springboot也有統(tǒng)一的異常處理器ControllerAdvice。

一般思路:系統(tǒng)有自定義異常時,在程序中手動拋出throw MyException,對于未知異常通過在函數(shù)上聲明throws Exception向上拋出,dao拋給service,service再拋給Controller,最后Controller拋給前端控制器,前端控制器調(diào)用全局異常處理器進(jìn)行處理。

(3)異常處理的一般實踐步驟。

===================================
自定義類的最佳實踐:
===================================
1. 先定義一個基類 BusinessException, 繼承自 RuntimeException.?
2. 定義一套BusinessErrorCode 枚舉類型, 包含 BusinessErrorCode/HttpStatus/BusinessErrorMessage, 這里的 BusinessErrorCode 不同于 HttpStatus, 它是業(yè)務(wù)上的錯誤代碼 (int 型).?
2. 在 BusinessException 基類上, 加上綁定 BusinessErrorCode 枚舉類型的機(jī)制.?
3. 基于 BusinessException 定義一組子類, 比如 UserNotLoginException/PermissionForbiddenException/DataNotFoundException 等等, 并將這些子類加入到一個 BusinessExceptionEnum 枚舉中, 方便使用.

?

===================================
Spring 項目數(shù)據(jù)驗證最佳實踐
===================================
1. 針對 UI 輸入檢查, 如果 js 前端檢查有困難, 可以在 Controller 層使用 Pojo validation 手段做檢查, 然后前端使用 ajax 拿到校驗結(jié)果. 檢查過程沒有觸發(fā) UI 完整渲染, 用戶體驗會很好.?
2. Controller 層使用 validation 進(jìn)行檢查, 可以在視圖函數(shù)的形參上檢查, 或者在視圖函數(shù)內(nèi)部檢查.?
3. Service 層, 使用 org.springframework.util.Assert 進(jìn)行數(shù)據(jù)驗證, 比如 Assert.notNull(user, "user is not null.");
4. DAO 層, 不做任何數(shù)據(jù)驗證, 因為所有數(shù)據(jù)問題應(yīng)該在Service層或Controller層做個驗證.


===================================
Spring 各層封裝的手法
===================================
1. DAO 層, 函數(shù)的形參最好以 DO 類做參數(shù), 而不是傳入很多個字段參數(shù). 這樣的好處是, 避免Table增刪字段, DAO層函數(shù)定義也要跟著修改, 上層的調(diào)用代碼也要修改.?
2. DAO 層, insert 和 update 要獨(dú)立為兩個函數(shù). 到底是新增還是更新, 應(yīng)由 Service 層進(jìn)行邏輯控制.?
3. Service 層函數(shù)的形參, 到底是使用 DO 類, 還是簡單的屬性清單, 看具體情況吧.


===================================
Spring 日志和異常處理的最佳實踐
===================================
異常處理的基本思路是: 早拋出, 晚捕獲. 日志輸出的基本思路是, 詳盡但不冗余.?
落實到具體的項目中, 在不同分層中, 應(yīng)采用不同的規(guī)則, 一般的分層有: DAO -> Service -> Controller -> 統(tǒng)一異常 Controller 層.

1. DAO 層:?
? ?(1) 盡量不 catch 任何異常, 該向上拋就拋.?
? ?(2) 不用記錄 log 日志, 或者僅使用 logger.debug() 記錄

2. Service 層的做法:?
? ? (1) @Transactional 注解應(yīng)該加在 Service 層上.?
? ??(2) 對于一些關(guān)鍵問題, 比如 Checked Exception 或者數(shù)據(jù)的問題, 應(yīng)該及時 throw new BusinessException 異常, 以確保事務(wù)完整.?
? ??(3) throw new BusinessException 時的日志, 為了避免日志重復(fù), 不需要 log 日志輸出.?
? ??(4) Service 層一般的日志級別, 應(yīng)該用 logger.debug() 記日志.?
? ??(5) Service 層函數(shù)的返回值應(yīng)該是 Optional 類型, 方便 Controller 做 null 判斷.


3. Controller 層:?
? ?(1) Controller 層負(fù)責(zé)組裝 Service, 在關(guān)鍵步驟上應(yīng)該加日志輸出 (info 級別)?
? ?(2) Controller 層不應(yīng)再主動 throw 異常.?
4. 統(tǒng)一異常 Controller 層:?
? ?(1) 通過 json 或 UI 返回詳細(xì)的報錯信息, 包括 HttpStatus 和詳盡的 BusinessErrorCode/BusinessErrorMessage 以及 DetailErrorMessage(來源于 exception.getMessage()), 甚至包括 exception 的 stack trace.?
? ?(2) 對于 Exception 類的異常, 說明這是我們預(yù)料之外的報錯, 應(yīng)該使用 logger.error() 級別記錄;?
? ?(3) 對于 BusinessException 和子類的異常, 則說明我們的程序已經(jīng)預(yù)料到了, 事物該回滾也已經(jīng)回滾了, 所以應(yīng)該以 logger.warn() 或 logger.info() 記錄日志.?
? ?(4) 對于 Spring Boot 缺省的 /error 進(jìn)行定制, 增加一些"系統(tǒng)主頁"和"返回"的鏈接, 改善用戶體驗.

(4)一些重要的注意事項:

Adao層一般不需要拋出異常,有事務(wù)的情況下,會將service的異常拋出到控制層做處理的,不然可能會影響事務(wù)的回滾,如果不存在事務(wù),則可以直接在service層進(jìn)行處理。

B針對預(yù)期可能發(fā)生的異常(檢查類型(checked)),在代碼手動處理異常可以try/catch捕獲,可以向上拋出,可以聲明。

try-catch 是在當(dāng)前位置處理異常,嘗試能不能正常的走完整個作用域,如果不能則拋出一個異常。
throws是向上拋出異常,用來聲明一個方法可能產(chǎn)生的所有異常,不做任何處理而是將異常往上傳,誰調(diào)用我我就拋給誰,throws在方法后邊聲明異常,其實就是自己不想對異常做出任何的處理,告訴別人自己可能出現(xiàn)的異常,交給別人處理

throw 就是拋出一個具體的異常,并獲取這個異常的引用,這個異常會被拋到外部的環(huán)境,由外部環(huán)境進(jìn)行處理。

?

C 在service中如果聲明了@Transactional,但是又在方法里面自己捕獲了異常,也就是try catch掉了,那就不會回滾了,因為切入點根本沒捕獲到,也談不上調(diào)用增強(qiáng)處理中的方法了。解決:1.拋出RuntimeException 2.拋出Exception,同時在事務(wù)聲明中加上@Transactional(rollbackFor = Exception.class)

?

?

總結(jié)

以上是生活随笔為你收集整理的SpringBoot异常处理的简单理解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。