统一响应需定义result和businessexception基类,禁用堆栈填充以提升性能;全局异常处理器按类型返回结构化json,业务异常透传、系统异常兜底,确保前端获取语义化错误信息。
☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 多模态理解力帮你轻松跨越从0到1的创作门槛☜☜☜

在Qoder开发Spring Boot项目时,遇到参数校验失败、数据库连接中断或第三方接口超时等异常,前端不能直接看到500错误页或堆栈信息,必须返回结构清晰、语义明确的JSON响应。
定义统一响应体与业务异常基类
新建Result<t></t>类,含code、message、data三个字段,提供success()和error()静态工厂方法。
创建抽象类BusinessException继承RuntimeException,构造时传入ErrorCode枚举和可变参数,【关键:调用super(message, null, false, false)禁用堆栈填充】,避免高频业务异常(如“手机号已注册”)带来性能损耗。
再按场景派生具体异常,例如InvalidParamException(400)、ResourceNotFoundException(404)、ThirdPartyServiceException(503)。
编写全局异常处理器
创建类GlobalExceptionHandler,标注@RestControllerAdvice。
方法一:处理业务异常
用@ExceptionHandler(BusinessException.class)捕获所有业务异常,提取errorCode.getCode()和errorCode.getMessage(args),组装Result.error(code, message)返回,HTTP状态码设为errorCode.getHttpStatus()。
方法二:兜底处理系统异常
用@ExceptionHandler(Exception.class)捕获未被显式声明的异常,记录完整堆栈到日志,返回固定提示“系统繁忙”,HTTP状态码设为500。注意:该方法必须放在最后,否则会覆盖更具体的异常处理逻辑。
在Service层主动抛出业务异常
第一步:在用户注册逻辑中检查用户名是否已存在 → 若存在,直接throw new ResourceConflictException("用户名已被占用");
第二步:调用短信服务前校验手机号格式 → 若不合法,throw new InvalidParamException("手机号格式错误");
第三步:执行数据库插入操作 → 若因唯一索引冲突抛出DuplicateKeyException,在DAO层用@ExceptionHandler捕获并转为ResourceConflictException向上抛出。
这一步不写try-catch,让异常穿透到全局处理器——业务代码只表达“什么错了”,不决定“怎么响应”。
验证异常响应效果
启动应用,用Postman请求一个故意触发InvalidParamException的接口,观察返回体是否为{"code":400,"message":"手机号格式错误","data":null},HTTP状态码是否为400。
再触发一次空指针异常,确认返回{"code":500,"message":"系统繁忙","data":null}且无堆栈泄露。











