关键在于后端统一捕获、结构化响应、前端解析展示;需定义继承RuntimeException的业务异常类并携带错误码和提示信息,再通过@ControllerAdvice和@ExceptionHandler全局拦截返回标准JSON响应。

Java 自定义异常要在前端调用时给出明确提示,关键不在于“抛出异常”,而在于**后端统一捕获、结构化响应、前端解析展示**。单纯 throw 一个自定义异常,前端收到的只是 500 或空响应,根本看不到提示内容。
后端:用统一异常处理器包装自定义异常
定义业务异常类(如 BusinessException),继承 RuntimeException(避免强制 try-catch),并携带错误码和提示信息:
public class BusinessException extends RuntimeException {
private final int code;
private final String message;
public BusinessException(int code, String message) {
super(message);
this.code = code;
this.message = message;
}
// getter 省略
}
再通过 @ControllerAdvice + @ExceptionHandler 全局拦截,返回标准 JSON 响应(如 {"code": 4001, "message": "用户名已存在", "data": null}):
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
立即学习“Java免费学习笔记(深入)”;
@ExceptionHandler(BusinessException.class)
public ResponseEntity
return ResponseEntity.ok(ApiResponse.fail(e.getCode(), e.getMessage()));
}
前端:约定响应结构,提取 message 展示
无论使用 Axios、Fetch 还是 Vue/React 的请求库,都要在响应拦截器中统一处理:
- 检查 response.data.code 是否为成功码(如 200),非成功则取 response.data.message 提示用户
- 对 4xx/5xx 状态码(如网络失败、服务不可用)做兜底提示,避免空白页或静默失败
- 避免直接 alert,推荐使用 UI 框架的 Message/Notification 组件(如 Element Plus 的
ElMessage.error())
前后端协作要点
- 错误码需文档化:维护一份错误码表(如 4001=用户名重复,4002=手机号格式错误),前后端共用,便于定位和国际化
- message 面向用户,不暴露堆栈或敏感信息:后端日志记录完整异常,但返回给前端的 message 应简洁友好(如“验证码已过期”而非“Redis key not found”)
- 避免在 controller 里直接 return 异常对象:那只是把异常序列化成 JSON,没走异常处理器,code/message 无法控制
补充:接口层可加校验前置提示
对于表单类操作,前端也可做轻量校验(如邮箱格式、必填项),提前拦截,减少无效请求;但最终以服务端校验为准——自定义异常正是用来兜住那些前端无法预判的业务规则冲突(如并发注册、库存扣减超限等)。

















