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: 八嘎雅鹿,没有这个人]
相关推荐
葫芦和十三5 小时前
图解 MongoDB 19|Oplog:复制的真正载体,不是文档是操作
后端·mongodb·agent
葫芦和十三5 小时前
图解 MongoDB 20|复制延迟与 catch up:Secondary 为什么跟不上
后端·mongodb·agent
IT_陈寒10 小时前
SpringBoot自动配置的坑,我的API突然就404了
前端·人工智能·后端
ServBay11 小时前
为什么说 MCP 是 2026 年开发者必须掌握的黄金协议?
后端·mcp
程序员夏洛11 小时前
Spring Boot 多模块项目中 IDEA 提示 Cannot resolve symbol 的一次排查记录
后端
子兮曰11 小时前
OpenMontage 深度解剖:你的 AI 编程助手,其实是个视频工作室
前端·后端·ai编程
子兮曰11 小时前
前端工具链的「Rust 化」:一场没有赢家的军备竞赛?
前端·后端·rust
爱勇宝12 小时前
从 Ctrl+CV 到 Enter:程序员正在失去什么
前端·后端·程序员
码事漫谈13 小时前
EdgeOne Makers + WorkBuddy:零基础也能快速搭建可上线的 AI 智能体(附图文教程)
后端