Spring全局异常拦截不构建前端提示器,而是通过统一返回体(含业务化code、用户友好msg)、分层异常处理及HTTP状态码协同,为前端提供可解析的错误信号,支撑自适应提示。

Spring 体系的全局异常拦截本身不直接“构建前端提示器”,但它为前端提供稳定、结构一致、可预测的错误响应,是前端实现自适应提示(如 Toast、Modal、表单红边、登录跳转等)的前提和基础。关键不在后端造提示框,而在后端输出能让前端“看懂并自动决策”的错误信号。
统一返回体:前端提示的“语义字典”
前端提示是否准确,取决于它能否从响应中快速识别错误类型。这要求后端返回体必须包含可编程解析的字段,而非仅靠 HTTP 状态码或模糊 message。
-
code 字段必须业务化:不要只用 500/400 这类通用码。定义如
40101(token 过期)、40302(无权限访问接口)、40005(手机号格式错误)。前端可按 code 前两位跳转登录页,按后两位高亮具体输入框。 -
msg 字段需用户友好且不含堆栈:禁止返回
java.lang.NullPointerException;应返回"请先选择商品规格"。若需调试,额外加debugInfo字段(仅开发环境返回)。 - data 字段保持空或 null:失败响应中 data 应为 null,避免前端误取 undefined 导致渲染异常。
分层异常拦截:让每类错误有专属处理路径
不能所有异常都塞进一个 @ExceptionHandler(Exception.class)。要按来源和意图拆解:
-
参数校验异常(BindingResult / @Valid):捕获
MethodArgumentNotValidException,提取每个字段的rejectedValue + defaultMessage,组装成{"phone": "手机号不能为空"}结构,前端一键绑定表单错误。 -
业务异常(如 BusinessException):显式抛出
throw new BusinessException(40003, "库存不足"),拦截器直接映射为{code: 40003, msg: "库存不足"},前端根据 code 触发购物车刷新或弹窗提醒。 -
系统级异常(NullPointerException 等):兜底拦截
RuntimeException,统一记日志 + 返回{code: 50000, msg: "系统繁忙,请稍后再试"},不暴露任何内部信息。 -
HTTP 状态码协同:在对应
@ExceptionHandler方法上加@ResponseStatus(HttpStatus.UNAUTHORIZED),确保 token 过期时既返回code=40101,又发出 HTTP 401 状态,便于 Axios 拦截器全局跳转登录页。
前端自适应提示的落地配合点
后端只管“说清楚”,前端负责“听懂后行动”。常见联动方式:
-
拦截 401/403 状态码:Axios 响应拦截器中判断
response.status === 401,清 localStorage token 并跳转 /login;无需解析 response.data.code。 -
解析 code 字段做精细化提示:对非 4xx/5xx 的成功响应(如 200),检查
data.code !== 200,按 code 映射提示类型:40001→Toast.error,40302→Modal.confirm,40101→store.dispatch('logout')。 -
保留原始请求上下文:后端异常处理器中可通过
HttpServletRequest.getRequestURL()获取请求路径,写入 response 的traceId或path字段,方便前端上报错误时附带链路信息。
避免踩坑的硬性约束
很多项目提示失效,问题常出在后端松散约定:
- 禁止在 Controller 内写 try-catch 返回 Result.error:这会绕过全局拦截器,导致部分接口响应结构不一致,前端逻辑分支爆炸。
-
禁止在拦截器里吞掉原始异常日志:记录日志必须包含完整堆栈(
log.error("API异常", ex)),否则线上出问题无法定位。 -
前后端必须共用一份 code 文档或枚举类:建议用 Swagger 注释或单独维护
ErrorCode.md,每次新增业务异常需同步更新文档并通知前端。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











