Spring 6/Spring Boot 3新特性:優(yōu)雅的業(yè)務(wù)異常處理
當(dāng)你使用Spring Boot(Spring MVC)進(jìn)行RESTful API開發(fā)的時(shí)候,你會(huì)發(fā)現(xiàn)HTTP的狀態(tài)碼很多時(shí)候不能足夠有效的傳遞錯(cuò)誤的信息。
HTTP里有一個(gè)RFC 7807規(guī)范:https://www.rfc-editor.org/rfc/rfc7807。這個(gè)規(guī)范里定義了HTTP API的“問題細(xì)節(jié)”(Problem Details)內(nèi)容。
該規(guī)范定義了一個(gè)“問題細(xì)節(jié)”(Problem Details),用它來攜帶HTTP錯(cuò)誤返回信息,避免自定義新的錯(cuò)誤返回格式。我們通常情況下是自己定義錯(cuò)誤返回格式的。
Spring 6.0為我們提供了一個(gè)org.springframework.http.ProblemDetail 來實(shí)現(xiàn)該規(guī)范。
RFC 7807是一個(gè)很簡單的規(guī)范。它定義了一個(gè)JSON格式,并關(guān)聯(lián)了一個(gè)媒體類型(media type),這個(gè)JSON格式包含了五個(gè)可選成員來描述問題細(xì)節(jié):
type:一個(gè)URI引用,用來識(shí)別問題的類型。這個(gè)URI的路徑內(nèi)容應(yīng)該用來顯示人類可讀的信息來描述類型;
title:人類可讀的問題類型描述;相同類型的問題,應(yīng)該總是相同的描述;
status:HTTP狀態(tài)碼,將它包含在問題細(xì)節(jié)里是一種方便的方式;
detail:人類可讀的問題實(shí)例描述,解釋為什么當(dāng)前的問題發(fā)生在這個(gè)特定的場(chǎng)景下;
instance:一個(gè)URI引用,用來識(shí)別問題實(shí)例。這個(gè)URI的內(nèi)容應(yīng)該用來描述問題實(shí)例,但不是必須的。
我們首先建立一個(gè)演示項(xiàng)目:
1、通常的業(yè)務(wù)異常處理方法
定義一個(gè)業(yè)務(wù)異常類。異常含義為:當(dāng)Person找不到的時(shí)候拋出的業(yè)務(wù)異常。
注冊(cè)這個(gè)業(yè)務(wù)異常到全局異常處理。
通過在@RestControllerAdvice 中定義全局的切面處理。
通過@ExceptionHandler 來處理指定異常的處理方式。
這里返回的格式就是我們自定義的ErrorMsg格式。我們通過自定義這個(gè)ErroMsg完成和接口使用者協(xié)議,完成對(duì)業(yè)務(wù)異常的處理。
需自定義的錯(cuò)誤返回
測(cè)試控制器
啟動(dòng)程序,訪問:http://localhost:8080/getPerson
2、基于“問題細(xì)節(jié)”的業(yè)務(wù)異常處理
基于我們常規(guī)的異常處理,其實(shí)已經(jīng)能滿足我們的業(yè)務(wù)需求,使用RFC 7807規(guī)范,我們可以免去自定義的異常錯(cuò)誤格式(ErrorMsg ),使用Spring 6.0給我們提供的ProblemDetail ,這樣我們以后再無需自己自定義異常返回格式,且在不同的項(xiàng)目之間有了標(biāo)準(zhǔn),從而客戶端在使用的時(shí)候有了可預(yù)測(cè)性。
Spring 6.0的做法也很簡單,我們只需要將我們自定返回的ErrorMsg 修改成ProblemDetail 即可。我們看一下示例代碼:
值得說的是ProblemDetail 還支持設(shè)置一個(gè)Map的properties:
這樣也為我們的定制擴(kuò)展提供了更大的空間。
啟動(dòng),訪問:http://localhost:8080/getPerson,其實(shí)的錯(cuò)誤返回符合RFC 7807規(guī)范。
注意查看返回的頭信息,我們看到了,返回?cái)?shù)據(jù)的媒體類型為:application/problem+json:
感謝支持我的書:《從企業(yè)級(jí)開發(fā)到云原生微服務(wù):Spring Boot實(shí)戰(zhàn)》
參考資料:https://docs.spring.io/spring-framework/docs/6.0.0-RC2/javadoc-api/org/springframework/http/ProblemDetail.html
文章出自:??愛科學(xué)的衛(wèi)斯理??,如有轉(zhuǎn)載本文請(qǐng)聯(lián)系愛科學(xué)的衛(wèi)斯理今日頭條號(hào)。