Spring?MVC全局異常處理實(shí)戰(zhàn)詳細(xì)指南
前言
在 Spring Boot 前后端分離項(xiàng)目開(kāi)發(fā)中,異常處理是保障系統(tǒng)健壯性的關(guān)鍵環(huán)節(jié)。如果不對(duì)異常做統(tǒng)一處理,Controller 層拋出的異常會(huì)直接返回給前端雜亂的 500 錯(cuò)誤頁(yè)面或原生異常信息,不僅前端無(wú)法友好解析,還可能泄露服務(wù)端核心代碼信息,影響系統(tǒng)安全性和用戶體驗(yàn)。
而基于 Spring MVC 的@RestControllerAdvice + @ExceptionHandler實(shí)現(xiàn)的全局異常處理,正是解決這一問(wèn)題的最優(yōu)解。它就像系統(tǒng)的 “統(tǒng)一兜底管家”,能攔截項(xiàng)目中 Controller 層拋出的所有異常,將其轉(zhuǎn)換為前端能統(tǒng)一解析的標(biāo)準(zhǔn) JSON 響應(yīng)格式,讓異常處理更規(guī)范、更優(yōu)雅。本文將從核心原理、代碼實(shí)現(xiàn)、執(zhí)行流程三個(gè)維度,詳解項(xiàng)目中全局異常處理的設(shè)計(jì)與落地。
一、全局異常處理核心思想:統(tǒng)一攔截,標(biāo)準(zhǔn)化響應(yīng)
在講解具體實(shí)現(xiàn)前,先理解全局異常處理的核心設(shè)計(jì)思想,這是整個(gè)方案的基礎(chǔ):
- 統(tǒng)一兜底:將項(xiàng)目中分散在各個(gè) Controller、Service 層的異常捕獲邏輯抽離出來(lái),集中在一個(gè)類中統(tǒng)一處理,避免重復(fù)的
try-catch代碼,讓業(yè)務(wù)代碼更專注于核心邏輯; - 精準(zhǔn)匹配:針對(duì)不同類型的異常(如業(yè)務(wù)異常、SQL 異常、系統(tǒng)異常),配置對(duì)應(yīng)的異常處理方法,實(shí)現(xiàn) “什么異常用什么方式處理”;
- 標(biāo)準(zhǔn)化響應(yīng):將所有異常都轉(zhuǎn)換為項(xiàng)目統(tǒng)一的 Result 響應(yīng)格式,前端只需根據(jù)固定的格式解析(如錯(cuò)誤碼、錯(cuò)誤信息),無(wú)需適配不同的異常返回結(jié)果;
- 無(wú)侵入式:無(wú)需修改原有業(yè)務(wù)代碼,只需在需要拋異常的地方直接
throw異常即可,全局異常處理類會(huì)自動(dòng)攔截,符合 “開(kāi)閉原則”。
整個(gè)方案的核心只有一個(gè)類 ——GlobalExceptionHandler,通過(guò)兩個(gè)核心注解實(shí)現(xiàn)所有功能,代碼簡(jiǎn)潔且功能強(qiáng)大,是 Spring MVC 提供的原生解決方案,無(wú)需引入任何第三方依賴。
二、核心注解解析:@RestControllerAdvice & @ExceptionHandler
全局異常處理的實(shí)現(xiàn)依賴 Spring MVC 的兩個(gè)核心注解,這兩個(gè)注解是整個(gè)方案的 “基石”,先搞懂它們的作用,才能理解后續(xù)的代碼實(shí)現(xiàn):
1. @RestControllerAdvice:聲明全局異常處理類
- 核心作用:標(biāo)記當(dāng)前類為全局異常處理類,并具備兩個(gè)關(guān)鍵特性:
- 全局生效:能攔截整個(gè)項(xiàng)目中所有
@RestController/@Controller標(biāo)記的類拋出的異常; - 自動(dòng) JSON 序列化:處理異常的方法返回值會(huì)自動(dòng)轉(zhuǎn)換為 JSON 格式,無(wú)需再添加
@ResponseBody注解,完美適配前后端分離的 JSON 交互場(chǎng)景。
- 全局生效:能攔截整個(gè)項(xiàng)目中所有
- 底層原理:基于 AOP(面向切面編程)實(shí)現(xiàn),相當(dāng)于在所有 Controller 層方法上織入了異常捕獲的切面,當(dāng)方法拋出異常時(shí),自動(dòng)觸發(fā)對(duì)應(yīng)的異常處理邏輯。
2. @ExceptionHandler:指定處理的異常類型
- 核心作用:標(biāo)注在方法上,指定該方法專門處理某一種 / 某一類異常,如
@ExceptionHandler(BaseException.class)表示該方法處理所有BaseException及其子類的異常; - 匹配規(guī)則:當(dāng)系統(tǒng)拋出異常時(shí),Spring MVC 會(huì)根據(jù)異常的類型,自動(dòng)匹配到對(duì)應(yīng)的
@ExceptionHandler方法,精準(zhǔn)執(zhí)行處理邏輯; - 靈活度高:一個(gè)全局異常處理類中可以定義多個(gè)
@ExceptionHandler方法,分別處理不同類型的異常,實(shí)現(xiàn)異常的精細(xì)化處理。
三、核心實(shí)現(xiàn)類:GlobalExceptionHandler—— 系統(tǒng)的 “異常兜底管家”
項(xiàng)目中的全局異常處理核心類為GlobalExceptionHandler,它通過(guò)上述兩個(gè)核心注解,實(shí)現(xiàn)了業(yè)務(wù)異常和SQL 異常兩大核心場(chǎng)景的處理,同時(shí)可輕松擴(kuò)展處理其他類型的異常。以下是完整的實(shí)戰(zhàn)代碼,并附帶詳細(xì)的代碼解釋,貼合企業(yè)級(jí)開(kāi)發(fā)規(guī)范。
1. 先備基礎(chǔ):統(tǒng)一響應(yīng)類 Result & 基礎(chǔ)業(yè)務(wù)異常類 BaseException
在實(shí)現(xiàn)全局異常處理前,項(xiàng)目中需先定義統(tǒng)一響應(yīng)類 Result和基礎(chǔ)業(yè)務(wù)異常類 BaseException,這是全局異常處理的基礎(chǔ),保證異常響應(yīng)的標(biāo)準(zhǔn)化和業(yè)務(wù)異常的統(tǒng)一管理。
(1)統(tǒng)一響應(yīng)類 Result
項(xiàng)目中所有接口的返回結(jié)果都遵循該格式,異常處理也不例外,讓前端能統(tǒng)一解析響應(yīng)數(shù)據(jù):
package com.sky.result;
import lombok.Data;
/**
* 全局統(tǒng)一響應(yīng)結(jié)果類
*/
@Data
public class Result<T> {
/**
* 響應(yīng)碼:0表示成功,1/其他表示失敗
*/
private Integer code;
/**
* 響應(yīng)信息:成功時(shí)為"成功",失敗時(shí)為錯(cuò)誤信息
*/
private String msg;
/**
* 響應(yīng)數(shù)據(jù):成功時(shí)返回業(yè)務(wù)數(shù)據(jù),失敗時(shí)為null
*/
private T data;
// 快速返回成功結(jié)果(無(wú)數(shù)據(jù))
public static <T> Result<T> success() {
Result<T> result = new Result<>();
result.setCode(0);
result.setMsg("成功");
return result;
}
// 快速返回成功結(jié)果(帶數(shù)據(jù))
public static <T> Result<T> success(T data) {
Result<T> result = new Result<>();
result.setCode(0);
result.setMsg("成功");
result.setData(data);
return result;
}
// 快速返回失敗結(jié)果(自定義錯(cuò)誤信息)
public static <T> Result<T> error(String msg) {
Result<T> result = new Result<>();
result.setCode(1);
result.setMsg(msg);
return result;
}
}
(2)基礎(chǔ)業(yè)務(wù)異常類 BaseException
項(xiàng)目中所有的業(yè)務(wù)異常都繼承自該類,實(shí)現(xiàn)業(yè)務(wù)異常的統(tǒng)一管理,如密碼錯(cuò)誤、賬號(hào)鎖定、參數(shù)非法等:
package com.sky.exception;
/**
* 項(xiàng)目基礎(chǔ)業(yè)務(wù)異常類,所有業(yè)務(wù)異常都繼承此類
*/
public class BaseException extends RuntimeException {
// 構(gòu)造方法,傳入錯(cuò)誤信息
public BaseException(String message) {
super(message);
}
}
(3)業(yè)務(wù)異常子類示例(密碼錯(cuò)誤)
可根據(jù)業(yè)務(wù)需求,定義多個(gè) BaseException 的子類,實(shí)現(xiàn)更精細(xì)化的業(yè)務(wù)異常管理:
package com.sky.exception;
/**
* 密碼錯(cuò)誤異常
*/
public class PasswordErrorException extends BaseException {
public PasswordErrorException(String message) {
super(message);
}
}
2. 全局異常處理核心代碼
package com.sky.handler;
import com.sky.constant.MessageConstant;
import com.sky.exception.BaseException;
import com.sky.result.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.sql.SQLIntegrityConstraintViolationException;
/**
* 全局異常處理類,統(tǒng)一攔截并處理項(xiàng)目中所有的異常
*/
@RestControllerAdvice // 聲明全局異常處理類,返回值自動(dòng)轉(zhuǎn)JSON
@Slf4j // 日志注解,記錄異常信息
public class GlobalExceptionHandler {
/**
* 處理業(yè)務(wù)異常:捕獲BaseException及其所有子類異常
* 適用場(chǎng)景:密碼錯(cuò)誤、賬號(hào)鎖定、參數(shù)非法等自定義業(yè)務(wù)異常
*/
@ExceptionHandler(BaseException.class)
public Result<String> handleBaseException(BaseException ex) {
// 記錄異常信息,便于問(wèn)題排查
log.error("業(yè)務(wù)異常:{}", ex.getMessage(), ex);
// 將業(yè)務(wù)異常的錯(cuò)誤信息封裝為標(biāo)準(zhǔn)Result格式,返回給前端
return Result.error(ex.getMessage());
}
/**
* 處理SQL唯一約束異常:捕獲用戶名/手機(jī)號(hào)等唯一字段重復(fù)的異常
* 適用場(chǎng)景:新增員工/用戶時(shí),用戶名重復(fù);新增手機(jī)號(hào)時(shí),號(hào)碼重復(fù)等
*/
@ExceptionHandler(SQLIntegrityConstraintViolationException.class)
public Result<String> handleSQLIntegrityException(SQLIntegrityConstraintViolationException ex) {
log.error("SQL約束異常:{}", ex.getMessage(), ex);
// 異常信息示例:Duplicate entry 'zhangsan' for key 'idx_employee_username'
String message = ex.getMessage();
// 解析異常信息,提取重復(fù)的字段值,返回友好的錯(cuò)誤信息
if (message.contains("Duplicate entry")) {
String[] split = message.split(" ");
String duplicateValue = split[2].replace("'", ""); // 去除單引號(hào),如zhangsan
String msg = duplicateValue + "已存在,請(qǐng)勿重復(fù)添加";
return Result.error(msg);
}
// 其他SQL約束異常,返回通用錯(cuò)誤信息
return Result.error(MessageConstant.UNKNOWN_ERROR);
}
/**
* 處理系統(tǒng)通用異常:捕獲所有未被上述方法匹配的異常(兜底處理)
* 適用場(chǎng)景:空指針、數(shù)組越界、網(wǎng)絡(luò)異常等系統(tǒng)級(jí)異常
*/
@ExceptionHandler(Exception.class)
public Result<String> handleGlobalException(Exception ex) {
log.error("系統(tǒng)異常:{}", ex.getMessage(), ex);
// 系統(tǒng)異常不暴露具體錯(cuò)誤信息給前端,返回通用友好提示
return Result.error(MessageConstant.SYSTEM_ERROR);
}
}
3. 關(guān)鍵代碼詳解
(1)業(yè)務(wù)異常處理方法handleBaseException
- 匹配范圍:處理所有
BaseException及其子類(如PasswordErrorException、AccountLockedException),覆蓋項(xiàng)目中所有自定義的業(yè)務(wù)異常; - 處理邏輯:記錄異常日志→將異常的自定義錯(cuò)誤信息(如 “密碼錯(cuò)誤”)封裝為 Result 格式返回;
- 設(shè)計(jì)優(yōu)勢(shì):業(yè)務(wù)層只需直接拋出
new BaseException("錯(cuò)誤信息"),無(wú)需關(guān)心異常如何處理,全局異常處理類會(huì)自動(dòng)攔截,讓業(yè)務(wù)代碼更簡(jiǎn)潔。
(2)SQL 唯一約束異常處理方法handleSQLIntegrityException
- 匹配場(chǎng)景:專門處理數(shù)據(jù)庫(kù)唯一索引約束異常(如用戶名、手機(jī)號(hào)重復(fù)),該異常由數(shù)據(jù)庫(kù)直接拋出,類型為
SQLIntegrityConstraintViolationException; - 友好解析:對(duì)數(shù)據(jù)庫(kù)原生的異常信息進(jìn)行解析,提取重復(fù)的字段值,返回如 “zhangsan 已存在,請(qǐng)勿重復(fù)添加” 的友好信息,而非原生的雜亂 SQL 異常信息;
- 用戶體驗(yàn):前端收到友好的錯(cuò)誤信息后,可直接彈窗提示用戶,提升交互體驗(yàn)。
(3)系統(tǒng)通用異常處理方法handleGlobalException
- 兜底處理:匹配
Exception.class,即所有未被上述方法處理的異常都會(huì)被該方法捕獲,避免有異常未被攔截而返回原生錯(cuò)誤; - 安全設(shè)計(jì):系統(tǒng)級(jí)異常(如空指針、數(shù)組越界)的具體信息不暴露給前端,僅返回 “系統(tǒng)繁忙,請(qǐng)稍后重試” 等通用友好提示,防止泄露服務(wù)端核心代碼信息;
- 日志記錄:詳細(xì)記錄異常的堆棧信息,便于開(kāi)發(fā)人員排查問(wèn)題,實(shí)現(xiàn) “前端友好,后端可查”。
四、實(shí)戰(zhàn)使用:業(yè)務(wù)層直接拋異常,無(wú)需任何處理
完成全局異常處理類的編寫(xiě)后,在項(xiàng)目中使用變得極其簡(jiǎn)單 ——業(yè)務(wù)層只需根據(jù)業(yè)務(wù)邏輯直接拋出異常,無(wú)需編寫(xiě)任何 try-catch 代碼,全局異常處理類會(huì)自動(dòng)攔截并處理,返回標(biāo)準(zhǔn)化的 JSON 響應(yīng)。
1. 業(yè)務(wù)層拋業(yè)務(wù)異常示例(員工登錄密碼錯(cuò)誤)
在員工登錄的 Service 層中,若校驗(yàn)密碼錯(cuò)誤,直接拋出PasswordErrorException(繼承自 BaseException):
package com.sky.service.impl;
import com.sky.constant.MessageConstant;
import com.sky.entity.Employee;
import com.sky.exception.PasswordErrorException;
import com.sky.mapper.EmployeeMapper;
import com.sky.service.EmployeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class EmployeeServiceImpl implements EmployeeService {
@Autowired
private EmployeeMapper employeeMapper;
@Override
public Employee login(String username, String password) {
// 1. 根據(jù)用戶名查詢員工
Employee employee = employeeMapper.selectByUsername(username);
// 2. 用戶名不存在,拋業(yè)務(wù)異常
if (employee == null) {
throw new BaseException(MessageConstant.USERNAME_NOT_FOUND);
}
// 3. 密碼錯(cuò)誤,拋密碼錯(cuò)誤異常
if (!password.equals(employee.getPassword())) {
throw new PasswordErrorException(MessageConstant.PASSWORD_ERROR);
}
// 4. 賬號(hào)鎖定,拋業(yè)務(wù)異常
if (employee.getStatus() == 0) {
throw new BaseException(MessageConstant.ACCOUNT_LOCKED);
}
// 5. 登錄成功,返回員工信息
return employee;
}
}
2. 前端收到的標(biāo)準(zhǔn)化異常響應(yīng)
當(dāng)密碼錯(cuò)誤時(shí),全局異常處理類會(huì)自動(dòng)攔截PasswordErrorException,返回以下 JSON 響應(yīng),前端可直接解析msg字段提示用戶:
{
"code": 1,
"msg": "密碼錯(cuò)誤,請(qǐng)重新輸入",
"data": null
}3. SQL 唯一約束異常示例(新增員工用戶名重復(fù))
當(dāng)新增員工時(shí),若用戶名已存在,數(shù)據(jù)庫(kù)會(huì)拋出SQLIntegrityConstraintViolationException,全局異常處理類會(huì)解析異常信息,返回友好的響應(yīng):
{
"code": 1,
"msg": "zhangsan已存在,請(qǐng)勿重復(fù)添加",
"data": null
}4. 系統(tǒng)通用異常示例(空指針異常)
當(dāng)項(xiàng)目中出現(xiàn)空指針異常時(shí),全局異常處理類會(huì)捕獲該異常,返回通用友好提示,同時(shí)在服務(wù)端日志中記錄詳細(xì)的堆棧信息:
{
"code": 1,
"msg": "系統(tǒng)繁忙,請(qǐng)稍后重試",
"data": null
}五、完整執(zhí)行流程:從拋異常到前端收到響應(yīng)
全局異常處理的整個(gè)執(zhí)行流程完全自動(dòng)化,對(duì)開(kāi)發(fā)者無(wú)感知,具體步驟如下(以密碼錯(cuò)誤為例):
- 業(yè)務(wù)層拋異常:?jiǎn)T工登錄時(shí),Service 層校驗(yàn)密碼錯(cuò)誤,拋出
PasswordErrorException("密碼錯(cuò)誤,請(qǐng)重新輸入"); - 異常向上冒泡:該異常會(huì)從 Service 層向上拋到 Controller 層,Controller 層未編寫(xiě) try-catch 代碼,異常繼續(xù)向上拋;
- 全局?jǐn)r截異常:Spring MVC 的核心調(diào)度器
DispatcherServlet捕獲到異常,發(fā)現(xiàn)項(xiàng)目中有@RestControllerAdvice標(biāo)記的GlobalExceptionHandler類; - 匹配異常處理方法:根據(jù)異常類型
PasswordErrorException(繼承自 BaseException),自動(dòng)匹配到handleBaseException方法; - 處理異常并返回:執(zhí)行
handleBaseException方法,記錄異常日志,將異常信息封裝為標(biāo)準(zhǔn) Result 格式的 JSON 響應(yīng); - 前端接收響應(yīng):前端收到包含錯(cuò)誤碼和錯(cuò)誤信息的 JSON 數(shù)據(jù),根據(jù)
code=1判斷為失敗,解析msg字段彈窗提示用戶。
整個(gè)流程一氣呵成,無(wú)需開(kāi)發(fā)者介入,實(shí)現(xiàn)了 “拋異常即處理” 的優(yōu)雅效果。
六、擴(kuò)展場(chǎng)景:輕松適配更多異常類型
項(xiàng)目中的GlobalExceptionHandler具備極強(qiáng)的可擴(kuò)展性,若需要處理其他類型的異常,只需新增一個(gè) @ExceptionHandler 方法,指定對(duì)應(yīng)的異常類型即可,無(wú)需修改原有代碼。以下是幾個(gè)常見(jiàn)的擴(kuò)展場(chǎng)景示例:
1. 處理請(qǐng)求參數(shù)校驗(yàn)異常(@Validated 校驗(yàn)失?。?/h3>
項(xiàng)目中常用@Validated做請(qǐng)求參數(shù)的后端校驗(yàn)(如非空、長(zhǎng)度限制),校驗(yàn)失敗會(huì)拋出MethodArgumentNotValidException,新增處理方法:
/**
* 處理請(qǐng)求參數(shù)校驗(yàn)異常:@Validated校驗(yàn)失敗時(shí)觸發(fā)
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
public Result<String> handleValidException(MethodArgumentNotValidException ex) {
log.error("參數(shù)校驗(yàn)異常:{}", ex.getMessage(), ex);
// 獲取第一個(gè)校驗(yàn)失敗的錯(cuò)誤信息
String msg = ex.getBindingResult().getFieldError().getDefaultMessage();
return Result.error(msg);
}
2. 處理跨域異常
若項(xiàng)目中跨域配置不當(dāng),會(huì)拋出跨域異常,新增處理方法:
/**
* 處理跨域異常
*/
@ExceptionHandler(NoHandlerFoundException.class)
public Result<String> handleNoHandlerFoundException(NoHandlerFoundException ex) {
log.error("跨域異常:{}", ex.getMessage(), ex);
return Result.error(MessageConstant.CROSS_DOMAIN_ERROR);
}
3. 處理 Redis 連接異常
若項(xiàng)目中使用 Redis,Redis 連接失敗會(huì)拋出異常,新增處理方法:
/**
* 處理Redis連接異常
*/
@ExceptionHandler(RedisConnectionFailureException.class)
public Result<String> handleRedisException(RedisConnectionFailureException ex) {
log.error("Redis連接異常:{}", ex.getMessage(), ex);
return Result.error(MessageConstant.REDIS_CONNECT_ERROR);
}
七、方案優(yōu)勢(shì):為什么說(shuō)這是企業(yè)級(jí)項(xiàng)目的最佳實(shí)踐?
這套基于@RestControllerAdvice + @ExceptionHandler的全局異常處理方案,是 Spring MVC 項(xiàng)目中異常處理的企業(yè)級(jí)最佳實(shí)踐,相比傳統(tǒng)的分散式try-catch,具有以下核心優(yōu)勢(shì):
1. 消除重復(fù)代碼,提升代碼整潔度
將分散在各個(gè) Controller、Service 層的try-catch代碼全部抽離,集中在一個(gè)類中統(tǒng)一處理,業(yè)務(wù)代碼中只需專注于核心邏輯,無(wú)需關(guān)心異常處理,代碼更簡(jiǎn)潔、更優(yōu)雅。
2. 標(biāo)準(zhǔn)化響應(yīng),降低前后端溝通成本
所有異常都返回統(tǒng)一的 Result 格式,前端只需根據(jù)固定的code和msg字段解析響應(yīng),無(wú)需適配不同的異常返回結(jié)果,大幅降低前后端的溝通和開(kāi)發(fā)成本。
3. 精細(xì)化處理,兼顧友好性和可排查性
- 對(duì)前端友好:業(yè)務(wù)異常返回自定義的友好錯(cuò)誤信息,系統(tǒng)異常返回通用提示,避免前端收到雜亂的原生異常信息;
- 對(duì)后端友好:詳細(xì)記錄所有異常的日志(包括堆棧信息),開(kāi)發(fā)人員可通過(guò)日志快速定位問(wèn)題,實(shí)現(xiàn) “前端友好,后端可查”。
4. 無(wú)侵入式設(shè)計(jì),符合開(kāi)閉原則
無(wú)需修改原有業(yè)務(wù)代碼,只需在需要拋異常的地方直接throw即可,新增異常類型時(shí),只需新增對(duì)應(yīng)的@ExceptionHandler方法,無(wú)需修改原有處理邏輯,完全符合 “對(duì)擴(kuò)展開(kāi)放,對(duì)修改關(guān)閉” 的開(kāi)閉原則。
5. 全局生效,全覆蓋無(wú)遺漏
能攔截項(xiàng)目中所有 Controller 層拋出的異常,包括業(yè)務(wù)異常、SQL 異常、系統(tǒng)異常等,實(shí)現(xiàn)異常處理的全覆蓋,避免有異常未被攔截而返回原生 500 錯(cuò)誤。
6. 可擴(kuò)展性強(qiáng),適配所有業(yè)務(wù)場(chǎng)景
可根據(jù)項(xiàng)目需求,輕松擴(kuò)展處理任意類型的異常,只需新增方法即可,適配從簡(jiǎn)單的業(yè)務(wù)異常到復(fù)雜的系統(tǒng)異常的所有場(chǎng)景。
八、生產(chǎn)環(huán)境優(yōu)化建議
以上實(shí)現(xiàn)為項(xiàng)目基礎(chǔ)版的全局異常處理方案,在生產(chǎn)環(huán)境中,可根據(jù)實(shí)際需求進(jìn)行以下優(yōu)化,讓方案更健壯、更安全:
- 自定義錯(cuò)誤碼體系:擴(kuò)展 Result 類,增加自定義錯(cuò)誤碼(如 1001 = 密碼錯(cuò)誤、1002 = 賬號(hào)鎖定、2001 = 用戶名重復(fù)),讓前端能根據(jù)錯(cuò)誤碼做更精細(xì)化的處理(如不同的錯(cuò)誤提示樣式);
- 異常分類管理:將異常分為業(yè)務(wù)異常、系統(tǒng)異常、第三方異常(如 Redis、MQ、接口調(diào)用異常),分別進(jìn)行處理,返回不同的錯(cuò)誤碼和提示信息;
- 統(tǒng)一日志格式:規(guī)范異常日志的記錄格式,包含異常類型、錯(cuò)誤信息、請(qǐng)求 URL、請(qǐng)求 IP、用戶 ID、堆棧信息等,便于生產(chǎn)環(huán)境的日志分析和問(wèn)題排查;
- 添加異常監(jiān)控:結(jié)合監(jiān)控平臺(tái)(如 Prometheus + Grafana、ELK),對(duì)系統(tǒng)異常進(jìn)行監(jiān)控和告警,當(dāng)系統(tǒng)異常數(shù)量達(dá)到閾值時(shí),自動(dòng)發(fā)送告警通知(如郵件、釘釘、企業(yè)微信);
- 自定義異常頁(yè)面:若項(xiàng)目包含非前后端分離的頁(yè)面,可通過(guò)
@ControllerAdvice(不帶 Rest)配合ModelAndView,返回自定義的異常頁(yè)面; - 限制異常日志打印級(jí)別:生產(chǎn)環(huán)境中,業(yè)務(wù)異??纱蛴?code>INFO級(jí)別日志,系統(tǒng)異常打印
ERROR級(jí)別日志,避免日志過(guò)多導(dǎo)致磁盤溢出; - 敏感信息脫敏:對(duì)異常信息中的敏感數(shù)據(jù)(如密碼、手機(jī)號(hào)、身份證號(hào))進(jìn)行脫敏處理,防止敏感信息泄露在日志中。
九、總結(jié)
本文講解的全局異常處理方案,是Spring MVC 原生特性在企業(yè)級(jí)項(xiàng)目中的經(jīng)典落地實(shí)踐,核心是通過(guò)@RestControllerAdvice和@ExceptionHandler兩個(gè)注解,實(shí)現(xiàn)了異常的統(tǒng)一攔截、精準(zhǔn)匹配、標(biāo)準(zhǔn)化響應(yīng)。
這套方案的核心價(jià)值,不僅在于解決了前端異常解析的問(wèn)題,更在于讓異常處理與業(yè)務(wù)邏輯完全解耦—— 開(kāi)發(fā)者無(wú)需在業(yè)務(wù)層編寫(xiě)任何異常處理代碼,只需專注于業(yè)務(wù)邏輯的實(shí)現(xiàn),異常的捕獲和處理全部由全局異常處理類自動(dòng)完成。同時(shí),其無(wú)侵入式的設(shè)計(jì)和極強(qiáng)的可擴(kuò)展性,讓它能輕松適配項(xiàng)目的所有業(yè)務(wù)場(chǎng)景,從簡(jiǎn)單的業(yè)務(wù)異常到復(fù)雜的系統(tǒng)異常,都能實(shí)現(xiàn)精細(xì)化處理。
在實(shí)際項(xiàng)目開(kāi)發(fā)中,全局異常處理是必備的基礎(chǔ)功能,它是保障系統(tǒng)健壯性、提升用戶體驗(yàn)、降低開(kāi)發(fā)成本的關(guān)鍵環(huán)節(jié)。掌握這套方案,不僅能解決項(xiàng)目中的異常處理問(wèn)題,更能理解 Spring MVC 的 AOP 思想和 “集中式處理通用邏輯” 的設(shè)計(jì)理念,讓我們的代碼更規(guī)范、更優(yōu)雅、更具可維護(hù)性。
優(yōu)秀的項(xiàng)目架構(gòu),不僅能實(shí)現(xiàn)業(yè)務(wù)功能,更能在細(xì)節(jié)處做到極致 —— 而全局異常處理,正是項(xiàng)目架構(gòu)細(xì)節(jié)中 “優(yōu)雅” 的體現(xiàn)。
到此這篇關(guān)于Spring MVC全局異常處理的文章就介紹到這了,更多相關(guān)Spring MVC全局異常處理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringMVC前端和后端數(shù)據(jù)交互總結(jié)
本篇文章主要介紹了SpringMVC前端和后端數(shù)據(jù)交互總結(jié),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-03-03
springboot+thymeleaf找不到視圖的解決方案
這篇文章主要介紹了springboot+thymeleaf找不到視圖的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06
Java字符串工具類從原生到第三方庫(kù)的高效實(shí)踐詳解
字符串是我們?cè)诰幊讨凶畛J褂玫囊环N數(shù)據(jù)類型,Java中用類來(lái)描述字符串,其中最常用的字符串處理類是String,這篇文章主要介紹了Java字符串工具類從原生到第三方庫(kù)的高效實(shí)踐的相關(guān)資料,需要的朋友可以參考下2025-08-08
JDBC中Statement和Preparement的使用講解
今天小編就為大家分享一篇關(guān)于JDBC中Statement和Preparement的使用講解,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-01-01
springboot實(shí)現(xiàn)發(fā)送短信驗(yàn)證碼的示例代碼
項(xiàng)目里面有用到用戶手機(jī)號(hào)注冊(cè)發(fā)短信功能,本文主要介紹了springboot實(shí)現(xiàn)發(fā)送短信驗(yàn)證碼的示例代碼,具有一定的參考價(jià)值,感興趣的可以了解一下2023-09-09
Java導(dǎo)出Word文檔的實(shí)現(xiàn)方法詳解
這篇文章主要給大家介紹了關(guān)于Java導(dǎo)出Word文檔的實(shí)現(xiàn)方法,在日常的開(kāi)發(fā)工作中,我們時(shí)常會(huì)遇到導(dǎo)出Word文檔報(bào)表的需求,比如公司的財(cái)務(wù)報(bào)表、醫(yī)院的患者統(tǒng)計(jì)報(bào)表、電商平臺(tái)的銷售報(bào)表等等,需要的朋友可以參考下2023-08-08
SSH框架網(wǎng)上商城項(xiàng)目第18戰(zhàn)之過(guò)濾器實(shí)現(xiàn)購(gòu)物登錄功能的判斷
這篇文章主要為大家詳細(xì)介紹了SSH框架網(wǎng)上商城項(xiàng)目第18戰(zhàn):過(guò)濾器實(shí)現(xiàn)購(gòu)物登錄功能的判斷,感興趣的小伙伴們可以參考一下2016-06-06

