你必須得會的SpringBoot全局統(tǒng)一處理異常詳解
1. 前言
今天和大家討論的是Spring Boot如何統(tǒng)一處理異常。這里先說一下我們?yōu)槭裁葱枰纸y(tǒng)一處理異常?其實理由很簡單,因為程序在運行的過程中,不可避免會產(chǎn)生各種各樣的錯誤。比如說用戶傳過來的參數(shù)不正確,無法連接上數(shù)據(jù)庫,或者在計算某個任務(wù)的時候超時等。所以我們一般需要合理的拋出各種異常信息。這些異常信息,一旦不處理,前端就會得到一個500的服務(wù)器內(nèi)部錯誤,直接展示非常的不友好不優(yōu)雅,所以我們需要將這些異常捕獲,并告知前端,到底錯在了哪里。另一個問題是,我們不可能直接將完整的異常信息返回,因為可能涉及到一些內(nèi)部的重要信息,不能隨意泄露,所以我們還需要對異常信息進行過濾和轉(zhuǎn)換,值給前端返回可讀的,簡潔的,準確的說明信息。
這就是為什么我們需要全局異常處理。
這將又會是干貨滿滿的一期,全程無尿點不廢話只抓重點教,具有非常好的學習效果,拿好小板凳準備就坐!希望學習的過程中大家認真聽好好學,學習的途中有任何不清楚或疑問的地方皆可評論區(qū)留言或私信,bug菌將第一時間給予解惑,那么廢話不多說,直接開整!Fighting??!
2. 環(huán)境說明
本地的開發(fā)環(huán)境:
- 開發(fā)工具:IDEA 2021.3
- JDK版本: JDK 1.8
- Spring Boot版本:2.3.1 RELEASE
- Maven版本:3.8.2
3.正文
這里bug菌提供的一種思路是使用全局異常處理器。全局異常處理器不僅能夠捕獲默認的異常,還能夠捕獲各種自定義異常。一個簡單的全局異常處理器代碼如下:
3.1定義全局異常處理器
GlobalExceptionHandler.java
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
private Map<String, Object> getResult(ErrorCodeEnum e, boolean status) {
Map<String, Object> map = new HashMap<>();
map.put("success", status);
map.put("code", e.getKey());
map.put("msg", e.getValue());
return map;
}
/**
* 參數(shù)校驗不通過
*
* @param e 異常信息
* @param request 請求信息
*/
@ExceptionHandler(value = ParamsException.class)
@ResponseStatus(HttpStatus.OK)
public Map<String, Object> handleObjectExistException(ParamsException e,
HttpServletRequest request) {
return getResult(ErrorCodeEnum.PARAM_EXIST_EXCEPTION, false);
}
/**
* 用戶校驗不通過
*
* @param e 異常信息
* @param request 請求信息
*/
@ResponseStatus(HttpStatus.OK)
@ExceptionHandler(value = TokenExpireException.class)
public Map<String, Object> handle(TokenExpireException e, HttpServletRequest request) {
return getResult(ErrorCodeEnum.USER_NOT_LOGIN, false);
}
/**
* 全局異常處理
*
* @param e 異常信息
* @param request 請求信息
*/
@ResponseStatus()
@ExceptionHandler(value = Throwable.class)
public Map<String, Object> handle(Exception e, HttpServletRequest request) {
return getResult(ErrorCodeEnum.SYSTEM_ERROR, false);
}
}這里我對所有的異常信息返回結(jié)果都做了統(tǒng)一的處理,只返回success,code,msg三個字段。在內(nèi)部封裝了一個getResult私有方法,便于統(tǒng)一處理,然后分別使用不同的方法處理不同的異常信息,比如ParamsException,TokenExpireException,SystemRunningException等
以上的這仨皆屬于自定義異常,代碼如下:
3.2定義參數(shù)異常ParamsException類
這里先定義參數(shù)異常的信息撲捉,思路也比較簡單,就是除了msg之外,不需要接收code,只便于更加靈活的實現(xiàn)返回值數(shù)據(jù)。
public class ParamsException extends RuntimeException {
private static final long serialVersionUID = 1L;
private String message;
public ParamsException() {
}
public ParamsException(String msg) {
this.message = msg;
}
public ParamsException(ErrorCodeEnum e) {
this.message = e.getValue();
}
@Override
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}3.3定義異常TokenExpireException類
這里我們再來定義一個撲捉token用戶登陸信息過期的異常類,目的是更直接用于相關(guān)token異常信息的捕捉。由于我們直接也是定義了默認的token Error錯誤碼枚舉,顧我們也是只需要定義msg信息的接收即可,但如果你都想自定義,那你就把對應(yīng)的code、success、msg都定義賦值也行,具體代碼如下:
package com.example.demo.exception;
import com.example.demo.enums.ErrorCodeEnum;
/**
* 用戶登陸信息過期異常
*/
public class TokenExpireException extends RuntimeException {
private static final long serialVersionUID = 1L;
private String message;
public TokenExpireException() {
}
public TokenExpireException(String msg) {
this.message = msg;
}
public TokenExpireException(ErrorCodeEnum e) {
this.message = e.getValue();
}
@Override
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}3.4定義一個ExceptionController測試
這里我們寫兩個接口直接模擬異常返回,查閱具體的異常信息是否被正常捕捉,然后其他的測試你們就自己玩啦,這里給大家舉個例子。
3.4.1測試參數(shù)異常
我們直接定義一個Get請求,然后設(shè)置一個參數(shù),我們在傳值的過程中,我們直接傳空,我們即可驗證是否能捕獲參數(shù)異常的全局信息返回。
@RestController
@RequestMapping("/exception")
@Api(tags = "全局異常測試模塊", description = "全局異常測試模塊")
public class ExceptionController {
@Autowired
private UserService userService;
/**
* 根據(jù)用戶id查詢用戶信息
*/
@GetMapping("/find-user-by-id")
@ApiOperation(value = "根據(jù)用戶id查詢用戶信息", notes = "根據(jù)用戶id查詢用戶信息")
public ResultResponse<UserEntity> saveUser(@RequestParam("userId") String userId) throws ParamsException {
if (StringUtils.isBlank(userId)) {
throw new ParamsException(PARAM_EXIST_EXCEPTION);
}
return new ResultResponse<>(userService.getById(userId));
}
}3.4.2Swagger請求校驗
重啟項目,我們將userId參數(shù)傳空格,我們直接請求,可以看看接口返回體具體是啥內(nèi)容?

可以看到,正是我們展示的PARAM_EXIST_EXCEPTION(101001, "參數(shù)異常")這句,我們也可以自定義,也可以采用默認的提示,成功的并統(tǒng)一處理了返回結(jié)果。
3.4.3測試token異常
測試代碼如下,僅供參考:
@GetMapping("/login")
@ApiOperation(value = "登錄", notes = "登錄")
public ResultResponse<Boolean> login(@RequestParam("token") String token) throws TokenExpireException {
throw new TokenExpireException();
}3.4.4Swagger請求校驗
重啟項目后請求一遍,可以看下接口的返回值如下:

可以發(fā)現(xiàn),我們成功的捕獲到了默認的Exception異常和自定義的TokenExpireException異常,并統(tǒng)一處理了返回結(jié)果。
兩輪測試結(jié)果比較令人滿意,希望能幫助到大家,剩下的測試或者自定義異常,你們可以大膽發(fā)揮,這里我就不一一贅述啦。
3.5附上接口返回錯誤碼枚舉類
具體代碼如下,僅供參考:
/**
* 接口返回錯誤碼枚舉
*/
public enum ErrorCodeEnum implements IEnum {
/* 系統(tǒng)異常 */
SYSTEM_RUNNING(100000, "系統(tǒng)運行異常"),
SYSTEM_ERROR(101000, "系統(tǒng)未知異常"),
PARAM_EXIST_EXCEPTION(101001, "參數(shù)異常"),
/* token相關(guān) */
TOKEN_IS_EMPTY(102001, "該請求沒有攜帶token!請先獲取token"),
TOKEN_IS_INVALID(102002, "token失效,請重新登錄!"),
TOKEN_IS_ERROR(102003, "非法token!請重新登錄!"),
USER_NOT_LOGIN(103006, "請先登錄"),
;
private Integer key;
private String value;
ErrorCodeEnum(Integer key, String value) {
this.key = key;
this.value = value;
}
@Override
public Integer getKey() {
return this.key;
}
@Override
public String getValue() {
return this.value;
}
}以上就是你必須得會的SpringBoot全局統(tǒng)一處理異常詳解的詳細內(nèi)容,更多關(guān)于SpringBoot統(tǒng)一處理異常的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
MyBatis-Plus中使用Wrapper自定義SQL的詳細步驟
在 MyBatis-Plus 中使用 Wrapper 自定義 SQL 可以靈活組合條件并復(fù)用條件邏輯,通過 ${ew.customSqlSegment} 占位符注入 Wrapper 生成的 SQL 片段,本文給大家介紹了詳細步驟和示例,需要的朋友可以參考下2025-07-07
windows11下jdk同時安裝多個版本并自由切換全網(wǎng)最詳細教程
一臺電腦可以同時安裝多個版本jdk,建議兩個,最多不超三個,安裝多個JDK版本可能會占用較多的磁盤空間,這篇文章主要介紹了windows11下jdk同時安裝多個版本并自由切換的相關(guān)資料,需要的朋友可以參考下2025-11-11
Java設(shè)計模式之共享模式/享元模式(Flyweight模式)介紹
這篇文章主要介紹了Java設(shè)計模式之共享模式/享元模式(Flyweight模式)介紹,本文講解了為什么使用共享模式/享元模式、如何使用共享模式/享元模式、Flyweight模式在XML等數(shù)據(jù)源中應(yīng)用等內(nèi)容,需要的朋友可以參考下2015-03-03
SpringBoot使用WebSocket實現(xiàn)向前端推送消息功能
WebSocket協(xié)議是基于TCP的一種新的網(wǎng)絡(luò)協(xié)議,它實現(xiàn)了瀏覽器與服務(wù)器全雙工(full-duplex)通信——允許服務(wù)器主動發(fā)送信息給客戶端,本文給大家介紹了SpringBoot使用WebSocket實現(xiàn)向前端推送消息功能,需要的朋友可以參考下2024-05-05
SpringBoot緩存抽象@Cacheable與緩存管理器配置方法
SpringBoot的緩存抽象通過@Cacheable注解和CacheManager接口,提供了靈活高效的緩存管理,本文詳細介紹了@Cacheable的使用技巧、緩存管理器配置方法、自定義鍵生成策略以及緩存同步與失效機制,幫助開發(fā)者構(gòu)建高效的緩存策略,優(yōu)化應(yīng)用性能,感興趣的朋友一起看看吧2025-03-03
SpringMVC解析JSON請求數(shù)據(jù)問題解析
這篇文章主要介紹了SpringMVC解析JSON請求數(shù)據(jù)問題解析,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-04-04
關(guān)于Spring3 + Mybatis3整合時多數(shù)據(jù)源動態(tài)切換的問題
這篇文章主要介紹了關(guān)于Spring3 + Mybatis3整合時多數(shù)據(jù)源動態(tài)切換的問題,需要的朋友可以參考下2017-04-04

