应统一返回Result<T>类,含code、message、timestamp、data字段,分层捕获异常并匹配HTTP状态码,覆盖Filter、异步及定时任务等全链路场景。

返回标准格式的错误响应 JSON,核心是“统一结构 + 明确语义 + 全链路覆盖”。不能只靠一个 @ExceptionHandler(Exception.class) 一锅端,也不能让不同异常返回 Map、String 或 ResponseEntity 混乱格式。
定义不可变的响应体类
所有接口——无论成功或失败——必须返回同一个 Java 类实例,比如 Result<T>:
- 包含固定字段:
code(数字错误码)、message(用户提示)、timestamp(可选)、data(仅成功时非 null) - 提供静态工厂方法:
Result.success(data)和Result.fail(int code, String msg)或Result.fail(ErrorCode error) - 若用 Lombok,务必加
@NoArgsConstructor,否则 Jackson 反序列化响应体可能失败
按类型分层捕获并构造 Result
在 @RestControllerAdvice 中,异常处理顺序决定健壮性:
详细的 Three.js 3D 图形参考,涵盖场景设置、相机、几何体、材质、光照、动画、控制器、加载器、数学工具和调试。
-
优先捕获自定义业务异常:如
BusinessException,直接映射为Result.fail(e.getCode(), e.getMessage()),HTTP 状态码通常用 400 -
接着处理参数校验异常:如
MethodArgumentNotValidException,提取BindingResult中的字段错误,组装成带details字段的增强版错误响应(如{"code":400,"message":"参数校验失败","details":[{"field":"email","msg":"邮箱格式不正确"}]}) -
最后兜底系统异常:如
NullPointerException、SQLException,记录完整堆栈日志,返回通用Result.fail(500, "系统繁忙,请稍后再试"),绝不暴露敏感信息
确保 HTTP 状态码与语义匹配
仅 JSON 结构一致还不够,HTTP 状态码必须反映真实语义,前端才能合理分流:
- 业务拒绝类(如“手机号已注册”)→ 400 Bad Request
- 资源未找到(如 ID 不存在)→ 404 Not Found
- 并发冲突(如乐观锁失败)→ 409 Conflict
- 服务不可用(如依赖下游超时)→ 503 Service Unavailable
- 其他未预期错误 → 500 Internal Server Error
覆盖非 Controller 场景
@RestControllerAdvice 只拦截进入 Controller 的请求。以下场景需额外处理:
-
Filter / Interceptor 抛异常:用自定义 Filter 包裹
filterChain.doFilter(),catch 所有 Exception 并写入HttpServletResponse,返回Result.fail()JSON - 异步任务(@Async):无法被全局处理器捕获,需在任务内部 try-catch + 手动上报错误日志或告警
- 定时任务(@Scheduled):同理,必须自行捕获并记录,避免静默失败

















