错误码枚举只定义code和messageKey,不包含文案;异常类仅保存key、args等结构化字段,延迟至全局处理器用MessageSource按locale解析多语言提示。

用枚举定义错误码键,不存具体文案
错误码枚举只负责标识业务场景,不硬编码任何语言文字。每个枚举项包含唯一 code 和一个 messageKey(如 USER_NOT_FOUND),这个 key 就是后续查资源文件的索引。
例如:
-
USER_NOT_FOUND → 对应 properties 文件里的
USER_NOT_FOUND=用户 {0} 不存在 -
ORDER_EXPIRED → 对应
ORDER_EXPIRED=订单 {0} 已过期
这样新增语言只需加 messages_en_US.properties,改提示只需改对应 key 的值,异常类本身完全不动。
异常类只持 key 和参数,延迟解析文案
自定义异常(如 BusinessException)构造时传入枚举项或 messageKey + args,内部不立即翻译,只保存结构化字段:
立即学习“Java免费学习笔记(深入)”;
- code:业务错误码(如 "USER_001")
- key:消息键(如 "USER_NOT_FOUND")
- args:动态参数(如 new Object[]{userId})
- cause:原始异常,用于保留堆栈
文案解析推迟到真正需要展示时(比如在全局处理器里),避免在抛异常时就加载 ResourceBundle 或触发 I/O。
用 MessageSource 统一做多语言渲染
Spring Boot 项目中配置 ReloadableResourceBundleMessageSource,指定 basename 为 i18n/messages,自动匹配 messages_zh_CN.properties 等文件。
在 @ControllerAdvice 中捕获异常后,调用:
messageSource.getMessage(exception.getKey(), exception.getArgs(), locale)
其中 locale 可从 LocaleContextHolder.getLocale() 获取(自动绑定 Accept-Language 或 X-Lang 请求头)。
前端收到的就是已翻译好的提示,后端日志里仍可记录原始 key 和 args,便于排查。
关键细节不能漏
确保资源文件使用 UTF-8 编码,中文/日文字符不乱码;占位符统一用 {0}、{1},和 MessageFormat 兼容;配置 setUseCodeAsDefaultMessage(true),防止 key 找不到时返回空字符串;异常类重写 getLocalizedMessage() 方法,内部委托 MessageSource 解析——这样连日志框架调用它也能拿到本地化结果。


















