Spring全局异常处理

一、整体架构

java 复制代码
接口 BaseErrorInfoInterface   →   定义错误码规范
枚举 ResultCodeEnum            →   实现接口,统一管理错误码
自定义异常 SBException         →   运行时异常,携带业务错误码和消息
全局异常拦截 GlobalExceptionHandler  →  捕获所有异常,返回统一响应
统一返回体 Result              →   规范前后端交互 JSON 结构

二、组件配置

1.错误码接口

让所有错误码类(如枚举)有统一获取码和消息的方法,方便 SBException 构造器直接接收接口类型。

java 复制代码
public interface BaseErrorInfoInterface {  
    String getResultCode();  
    String getResultMsg();  
}

2.枚举错误码

  • 业务码命名最好见名知意,具体根据项目调整。
  • 错误码可以区分模块,比如 1001 用户模块,2001 订单模块。
java 复制代码
public enum ResultCodeEnum implements BaseErrorInfoInterface {  
    SUCCESS("200", "成功!"),  
    BODY_NOT_MATCH("400","请求的数据格式不符!"),  
    SIGNATURE_NOT_MATCH("401","业务异常!"),  
    NOT_FOUND("404", "未找到该资源!"),  
    INTERNAL_SERVER_ERROR("500", "服务器内部错误!"),  
    SERVER_BUSY("503","服务器正忙,请稍后再试!");  
  
    private final String code;  
    private final String message;  
    ResultCodeEnum (String code, String message) {  
        this.code = code;  
        this.message = message;  
    }  
  
    @Override  
    public String getResultCode() {  
        return code;  
    }  
  
    @Override  
    public String getResultMsg() {  
        return message;  
    }  
}

3.自定义异常

java 复制代码
@Getter  
public class SBException extends RuntimeException{  
    private static final long serialVersionUID = 1L;  
  
    private final String errCode;  
    private final String errMessage;  
    public SBException(BaseErrorInfoInterface baseErrorInfoInterface){  
        super(baseErrorInfoInterface.getResultMsg());  
        this.errCode = baseErrorInfoInterface.getResultCode();  
        this.errMessage = baseErrorInfoInterface.getResultMsg();  
    }  
    public SBException(BaseErrorInfoInterface baseErrorInfoInterface, Throwable cause){  
        super(baseErrorInfoInterface.getResultMsg(), cause);  
        this.errCode = baseErrorInfoInterface.getResultCode();  
        this.errMessage = baseErrorInfoInterface.getResultMsg();  
    }  
    public SBException(String errMessage){  
        super(errMessage);  
        this.errCode = ResultCodeEnum.INTERNAL_SERVER_ERROR.getResultCode();  
        this.errMessage = errMessage;  
    }  
    public SBException(String errCode, String errMessage){  
        super(errMessage);  
        this.errCode = errCode;  
        this.errMessage = errMessage;  
    }  
    public SBException(String errCode, String errMessage, Throwable cause){  
        super(errMessage, cause);  
        this.errCode = errCode;  
        this.errMessage = errMessage;  
    }  
}

4.全局异常处理

java 复制代码
@RestControllerAdvice  
@Slf4j  
public class GlobalExceptionHandler {  
    //业务问题  
    @ExceptionHandler(SBException.class)  
    public Result handleSBException(SBException e){  
        log.error("业务异常!信息:{}", e.getMessage());  
        return Result.fail(e.getErrCode(), e.getErrMessage());  
    }  
    //空指针  
    @ExceptionHandler(NullPointerException.class)  
    public Result handleNullPointerException(NullPointerException e){  
        log.error("空指针异常!信息:{}", e.getMessage());  
        return Result.fail(ResultCodeEnum. BODY_NOT_MATCH.getResultMsg());  
    }  
  
    //其他异常  
    @ExceptionHandler(Exception.class)  
    public Result handleException(Exception e){  
        log.error("异常!信息:{}", e.getMessage());  
        return Result.fail(ResultCodeEnum.INTERNAL_SERVER_ERROR.getResultMsg());  
    }  
}

5.同一返回

java 复制代码
@Data  
@AllArgsConstructor  
@NoArgsConstructor  
public class Result {  
    private Boolean success;  
    private String code;  
    private String errorMsg;  
    private Object data;  
    private Long total;  
  
    public static Result ok(){  
        return new Result(true, "200",null, null, null);  
    }  
    public static Result ok(Object data){  
        return new Result(true, "200",null, data, null);  
    }  
    public static Result ok(List<?> data, Long total){  
        return new Result(true, "200",null, data, total);  
    }  
    public static Result fail(String errorMsg){  
        return new Result(false, "401",errorMsg, null, null);  
    }  
    public static Result fail(String code, String errorMsg){  
        return new Result(false, code,errorMsg, null, null);  
    }  
}

三、测试

java 复制代码
@GetMapping("/getById")  
public Result getById(@RequestParam Integer id) {  
    familyMember familyMember = familyMemberService.getById(id);  
    if(familyMember != null){  
        return Result.ok(familyMember);  
    }else{  
        throw new SBException("401","八嘎雅鹿,没有这个人");  
    }  
}
java 复制代码
2026-05-19 13:52:59.983 ERROR 23004 --- [nio-8080-exec-3] c.g.xcq.config.GlobalExceptionHandler    : 业务异常!信息:八嘎雅鹿,没有这个人
2026-05-19 13:52:59.986  WARN 23004 --- [nio-8080-exec-3] .m.m.a.ExceptionHandlerExceptionResolver : Resolved [com.good.xcq.exception.SBException: 八嘎雅鹿,没有这个人]
相关推荐
zhoujungis6 分钟前
登录态 1 小时就掉?Django + Vue 双 Token 认证实战 | 尘世栈帧
后端
Félix25111 分钟前
Nacos学习笔记(SpringBoot/SpringCloud)
java·spring boot·spring
文丑颜不良啊16 分钟前
LeetCode1581~1600题目解析
java·leetcode
香蕉大香蕉(06敬畏市场)17 分钟前
MySQL 单点详解(06)
java·数据库·mysql·博客·实习
武子康25 分钟前
同一台 ESP32,GSM 能消回声,VoIP 为什么不行?
人工智能·后端·agent
用户693717500138429 分钟前
AI 能写代码,但工程架构还是应该由人来定
前端·后端
lqbzlll30 分钟前
Spring Boot 开启虚拟线程后接口反而变慢了?4 个排查方向和对应修法
java·spring boot·后端
七夜zippoe35 分钟前
LangChain4j vs Spring AI:Java AI 框架怎么选(对比表)
java·人工智能·spring·ai·langchain4j
悠仁さん40 分钟前
【C++】set map 使用
java·前端·c++
回家路上绕了弯43 分钟前
让 AI 成为团队的共同能力
后端