最清晰可维护的多语言提示方案是用枚举管理错误码并配合资源文件映射:枚举仅存code、key和args,文案交由messages_zh_CN.properties等资源文件提供,通过MessageSource按Locale动态解析,实现错误码、语言文案、业务逻辑三者解耦。
直接用枚举管理错误码 + 资源文件映射,是实现多语言提示最清晰、可维护性最强的方式。关键不是“抛异常时写死字符串”,而是让异常携带一个可查表的键,再由统一机制按当前语言查出对应文案。
定义带国际化的错误码枚举
枚举里不存具体文字,只存唯一编码和默认语言(如中文)的占位符模板(用于兜底或日志),真正展示文案交给资源文件:
- 每个枚举项包含 code(数字码)、key(消息键)、args(可选参数个数或类型说明)
- key 值必须与 .properties 文件中的键名严格一致,例如 USER_NOT_FOUND
- 避免在枚举中 hardcode 英文或中文文案,只保留 key 作为桥梁
准备多语言资源文件
在 src/main/resources/i18n/ 下放标准命名的 properties 文件,确保 UTF-8 编码:
-
messages_zh_CN.properties:
USER_NOT_FOUND=用户 {0} 不存在 -
messages_en_US.properties:
USER_NOT_FOUND=User {0} not found -
messages_ja_JP.properties:
USER_NOT_FOUND={0} ユーザーが存在しません
注意:占位符统一用 {0}、{1},和 MessageFormat 兼容;中文/日文字符保存前建议用 IDE 自动转义或确认编码无误。
封装异常构造与消息解析逻辑
不推荐每次 throw 都手动查 ResourceBundle。建一个工具类或基类完成“key → 文案”转换:
- 从请求头(如 X-Lang: en-US)或 Spring 的 LocaleContextHolder 获取当前 Locale
- 调用 MessageSource.getMessage(key, args, locale) —— 这比裸用 ResourceBundle 更健壮,自动处理缺失 key 的 fallback
- 自定义异常(如 BusinessException)在构造时只传枚举项,内部委托 MessageSource 解析
在 Web 层统一输出带语言的响应
@ControllerAdvice 捕获异常后,不再返回 ex.getMessage(),而是:
- 提取异常中的枚举 key 和 args
- 再次通过 MessageSource 按客户端 Locale 渲染最终提示
- 组装成标准 JSON 响应体(code + message + data),前端直接展示,无需二次翻译
这样,新增一种语言只需加一个 properties 文件,改提示只需改资源文件,加新错误码只需扩枚举 —— 三者完全解耦。











