应根据环境配置动态调整异常响应行为:开发环境暴露详细堆栈便于排查,生产环境隐藏敏感信息、返回友好提示并确保日志完整可追溯;通过@profile或配置属性控制响应内容,日志始终记录完整异常对象。

在全局异常处理中区分生产环境和开发环境,核心是**根据环境配置动态调整异常响应行为**:开发环境要暴露详细信息便于排查,生产环境则必须隐藏敏感细节、返回友好提示、并确保日志完整可追溯。
用 Spring Profile 控制不同环境的异常响应
Spring 提供了 @Profile 注解,可让同一套 @ControllerAdvice 类在不同环境下执行不同逻辑。推荐做法是定义一个统一的全局处理器类,再通过 profile 分支控制响应内容:
- 开发环境(
@Profile("dev")):返回完整堆栈、HTTP 状态码设为 500,前端可展示详细错误(如 Swagger 或调试页面) - 生产环境(
@Profile("prod")):只返回通用错误码和提示语,HTTP 状态码仍为 500 或按业务约定设为 4xx/5xx,同时强制记录完整异常到日志文件
避免硬编码,用配置驱动行为
不建议在代码里写 if ("prod".equals(env)) 这类判断。应通过 Spring Boot 的 application.yml 配置开关,并注入使用:
- 在
application-prod.yml中设app.exception.show-stacktrace: false - 在
application-dev.yml中设app.exception.show-stacktrace: true - 在异常处理器中用
@Value("${app.exception.show-stacktrace:false}")获取该值,决定是否把e.getStackTrace()加入响应体
日志记录必须始终完整,与响应分离
无论什么环境,异常对象本身都要完整记录到日志系统中。区别只在于“是否把堆栈返回给调用方”:
- 开发环境响应体可含
e.toString() + "\n" + Arrays.toString(e.getStackTrace()) - 生产环境响应体仅含
R.error("系统繁忙,请稍后再试", 500)这类标准化结果 - 但两种环境都必须执行
log.error("全局异常捕获", e)—— 注意是带异常对象的重载方法,否则堆栈会丢失
额外加固:生产环境禁用调试信息泄露
除了响应体,还要防范其他渠道泄露堆栈:
- 禁用 Spring Boot 默认的
/error白页:在application-prod.yml中设置server.error.whitelabel.enabled: false - 确保反向代理(如 Nginx)不将后端原始错误页透出,统一由网关或前端兜底
- 自定义异常类型(如
BizException)的 message 字段,不要拼接数据库字段名、SQL 片段等敏感内容
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











