SpringMVC通過注解實(shí)現(xiàn)全局異常處理問題小結(jié)
一、為什么需要全局異常處理?
開發(fā)應(yīng)用程序的過程中會(huì)遇到各種各樣的異常,如數(shù)據(jù)庫連接異常,網(wǎng)絡(luò)請(qǐng)求異常和業(yè)務(wù)邏輯異常等。傳統(tǒng)的try-catch模式在各個(gè)controller中處理由于太過于分散,代碼冗余度過高,導(dǎo)致維護(hù)成本過高。
全局處理能夠高效地解決這一問題
二、Spring全局異常的處理方式
SpringMVC通過@ControllerAdvice和@ExceptionHandler注解來實(shí)現(xiàn)全局異常處理
實(shí)現(xiàn)步驟:
1 創(chuàng)建自定義異常類
2 創(chuàng)建全局異常處理器,使用@ControllerAdvice注解
3 在處理器類中定義異常處理方法,使用@ExceptionHandler注解指定處理的異常類型
4 在異常處理方法中定義異常響應(yīng)的格式和內(nèi)容
三、具體實(shí)現(xiàn)
1 創(chuàng)建自定義異常類(以用戶未找到為例)
// 用戶未找到異常
public class UserNotFoundException extends RuntimeException {
public UserNotFoundException() {
super();
}
public UserNotFoundException(String message) {
super(message);
}
}
// 數(shù)據(jù)驗(yàn)證異常
public class ValidationException extends RuntimeException {
public ValidationException(String message) {
super(message);
}
}2 創(chuàng)建全局異常處理器
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
// 全局異常處理器,會(huì)攔截所有控制器拋出的異常
@ControllerAdvice
public class GlobalExceptionHandler {
// 處理用戶未找到異常
@ExceptionHandler(UserNotFoundException.class)
@ResponseBody // 將返回結(jié)果轉(zhuǎn)換為JSON
@ResponseStatus(HttpStatus.NOT_FOUND) // 設(shè)置HTTP狀態(tài)碼為404
public Result<Void> handleUserNotFoundException(UserNotFoundException e) {
return Result.error(404, e.getMessage());
}
// 處理數(shù)據(jù)驗(yàn)證異常
@ExceptionHandler(ValidationException.class)
@ResponseBody
@ResponseStatus(HttpStatus.BAD_REQUEST) // 設(shè)置HTTP狀態(tài)碼為400
public Result<Void> handleValidationException(ValidationException e) {
return Result.error(400, e.getMessage());
}
// 處理其他未捕獲的異常
@ExceptionHandler(Exception.class)
@ResponseBody
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) // 設(shè)置HTTP狀態(tài)碼為500
public Result<Void> handleOtherExceptions(Exception e) {
// 實(shí)際項(xiàng)目中可以在這里記錄日志
return Result.error(500, "服務(wù)器內(nèi)部錯(cuò)誤:" + e.getMessage());
}
}3 在控制器中使用
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/{id}")
public Result<User> getUser(@PathVariable Long id) {
// 這里不再需要try-catch,異常會(huì)被全局異常處理器捕獲
User user = userService.getUserById(id);
if (user == null) {
throw new UserNotFoundException("用戶不存在,ID: " + id);
}
return Result.success(user);
}
@PostMapping
public Result<User> createUser(@RequestBody User user) {
if (user.getName() == null || user.getName().isEmpty()) {
throw new ValidationException("用戶名不能為空");
}
User savedUser = userService.saveUser(user);
return Result.success(savedUser);
}
}四、工作原理
- 當(dāng)控制器方法中拋出異常時(shí),Spring 會(huì)查找是否有匹配的
@ExceptionHandler @ControllerAdvice注解的類會(huì)被 Spring 掃描到,并作為全局異常處理器- Spring 會(huì)根據(jù)拋出的異常類型,找到對(duì)應(yīng)的
@ExceptionHandler方法 - 執(zhí)行異常處理方法,返回統(tǒng)一的響應(yīng)結(jié)果
五、高級(jí)用法
- 異常處理的優(yōu)先級(jí):
- 控制器內(nèi)部的
@ExceptionHandler優(yōu)先于全局異常處理器 - 子類異常的處理器優(yōu)先于父類異常的處理器
- 控制器內(nèi)部的
- 結(jié)合日志記錄:
@ExceptionHandler(Exception.class)
public Result<Void> handleOtherExceptions(Exception e) {
log.error("發(fā)生未捕獲異常", e); // 記錄異常日志
return Result.error(500, "服務(wù)器內(nèi)部錯(cuò)誤");
}六、總結(jié)
全局異常處理是 SpringMVC框架中一個(gè)非常實(shí)用的功能,通過@ControllerAdvice和@ExceptionHandler注解可以輕松實(shí)現(xiàn):
- 減少重復(fù)代碼,提高開發(fā)效率
- 統(tǒng)一異常響應(yīng)格式,便于前端處理
- 集中管理異常處理邏輯,便于維護(hù)
- 可以結(jié)合日志記錄,方便問題排查
掌握全局異常處理,能讓你的代碼更加健壯、優(yōu)雅。
到此這篇關(guān)于SpringMVC通過注解實(shí)現(xiàn)全局異常處理問題小結(jié)的文章就介紹到這了,更多相關(guān)SpringMVC全局異常處理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
IDEA中Maven報(bào)錯(cuò)Cannot resolve xxx的解決方法匯總(親測(cè)有效)
在IDEA中的pom文件中添加了依賴,并且正確加載了相應(yīng)依賴,pom文件沒有報(bào)紅,看起來像是把所有依賴庫全部加載進(jìn)來了,但是代碼中使用依賴的類庫使報(bào)紅,本文給大家介紹了IDEA中Maven報(bào)錯(cuò)Cannot resolve xxx的解決方法匯總,需要的朋友可以參考下2024-06-06
Java實(shí)現(xiàn)數(shù)據(jù)更新和事件通知的觀察者模式
Java觀察者模式是一種行為型設(shè)計(jì)模式,用于實(shí)現(xiàn)對(duì)象間的一對(duì)多依賴關(guān)系。當(dāng)一個(gè)對(duì)象的狀態(tài)發(fā)生改變時(shí),它的所有依賴對(duì)象都會(huì)收到通知并自動(dòng)更新。觀察者模式可以實(shí)現(xiàn)松耦合,增強(qiáng)了系統(tǒng)的可維護(hù)性和可拓展性2023-04-04
MybatisPlus中插入數(shù)據(jù)后獲取該對(duì)象主鍵值的實(shí)現(xiàn)
這篇文章主要介紹了MybatisPlus中插入數(shù)據(jù)后獲取該對(duì)象主鍵值,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09
Java后臺(tái)與微信小程序的數(shù)據(jù)交互實(shí)現(xiàn)
這篇文章主要介紹了Java后臺(tái)與微信小程序的數(shù)據(jù)交互實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12
SpringBoot Scheduling定時(shí)任務(wù)的示例代碼
springBoot提供了定時(shí)任務(wù)的支持,通過注解簡單快捷,對(duì)于日常定時(shí)任務(wù)可以使用。本文詳細(xì)的介紹一下使用,感興趣的可以了解一下2021-08-08
解決MyBatisPlus的updateBatchById()批量修改失效問題
這篇文章主要介紹了解決MyBatisPlus的updateBatchById()批量修改失效問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-08-08
MyBatis Plus關(guān)閉SQL日志打印的方法
這篇文章主要介紹了MyBatis-Plus如何關(guān)閉SQL日志打印,文中通過圖文結(jié)合講解的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2024-02-02

