Java自定义异常应与HTTP状态码解耦:异常聚焦业务语义并持错误枚举引用,Web层通过@ControllerAdvice统一映射状态码,网关可二次适配。

Java 中自定义异常应与 HTTP 状态码解耦但协同设计:异常本身聚焦业务语义,状态码由 Web 层映射决定;通过枚举统一管理错误码、HTTP 状态码和提示语,再配合全局异常处理器完成精准响应。
用枚举封装错误码 + HTTP 状态码
避免在异常类里硬编码状态码。定义统一的错误码枚举,每个项明确携带业务码、提示语和对应 HTTP 状态码:
- 实现通用接口(如 IErrorCode),含 getCode()、getMsg()、getHttpStatus()
- 按模块分段编号,例如用户模块用 1001(参数错误)、1002(用户不存在)
- 让自定义异常(如 BizException)在构造时接收该枚举,内部只存引用,不复制状态码
自定义异常不直接设状态码,而是携带可识别标识
异常对象是业务层产物,不应感知 HTTP 协议细节。关键做法是:
- 异常类保留对错误枚举的引用(如 private final IErrorCode errorCode)
- 不重写 getCause() 或强行塞入 status 字段,避免污染异常链
- 若需传递上下文(如订单号),用额外字段(如 private final Map<String, Object> context),但不用于状态码判断
Web 层统一映射状态码(ControllerAdvice)
真正决定返回哪个 HTTP 状态码的,是 Spring MVC 的异常处理机制:
立即学习“Java免费学习笔记(深入)”;
- 编写 @RestControllerAdvice 类,用 @ExceptionHandler(BizException.class) 拦截
- 从异常中取出 errorCode.getHttpStatus(),构造 ResponseEntity.status(...).body(...)
- 对同一异常类型,不同场景可返回不同状态码(如用户不存在 → 404;权限不足 → 403),靠枚举区分
网关层二次适配(可选增强)
当服务部署在微服务架构中,网关可进一步标准化状态码输出:
- 后端响应体中带 X-App-Code: 1002 响应头,网关据此转为 404
- 或解析标准错误 JSON 中的 "code": 1002 字段,映射为对应 HTTP 状态码并重写响应
- 确保网关不透传原始 500,也不把所有失败都转成 200 + 自定义 code


















