在 Spring Boot 项目已经开发完成后,想要实现国际化(i18n),让所有提示信息(后端返回的错误消息、成功消息、异常信息、枚举描述等)支持多语言,处理流程如下:
1. 创建国际化资源文件(messages.properties)
在 src/main/resources 目录下(新建 i18n 子目录),创建以下文件:
1src/main/resources/2└── i18n/3├── messages.properties # 默认语言(通常是中文或英文)4├── messages_zh_CN.properties # 简体中文5├── messages_en_US.properties # 美式英文6├── messages_zh_TW.properties # 繁体中文(可选)7└── messages_ja.properties # 日语(可选)
messages.properties(中文示例):
1# 通用提示2success=操作成功3error.system=系统异常,请稍后重试4error.notfound=资源不存在56# 业务提示7user.login.success=登录成功8user.login.fail=用户名或密码错误9user.notfound=用户不存在
messages_en_US.properties(英文示例):
1success=Operation successful2error.system=System error, pleasetryagain later3error.notfound=Resource not found45user.login.success=Login successful6user.login.fail=Username or password is incorrect7user.notfound=User not found
注意:
- 文件名必须以 messages 开头(Spring Boot 默认查找规则)。
- 所有提示统一放在 i18n 目录下,方便管理。
2. 配置 application.yml(或 application.properties)
1# application.yml2spring:3messages:4basename: i18n/messages # 资源文件基础名(支持通配符)5encoding: UTF-8 # 必须是 UTF-86fallback-to-system-locale:false# 推荐设置为false(找不到对应语言时不回退到系统默认Locale)7use-code-as-default-message:true# 找不到key时直接返回code(调试方便,上线可改为false)
1# properties2spring.messages.basename=i18n/messages3spring.messages.encoding=UTF-84spring.messages.fallback-to-system-locale=false5spring.messages.use-code-as-default-message=true
3. 自定义 LocaleResolver 和 LocaleChangeInterceptor(支持前端传参切换语言)
Spring Boot 默认使用AcceptHeaderLocaleResolver(根据请求头 Accept-Language 自动识别),生产环境通常还需要支持通过参数或 cookie 切换语言。
使用 SessionLocaleResolver + LocaleChangeInterceptor:
1@Configuration2publicclassLocaleConfigimplementsWebMvcConfigurer {34//默认语言5@Bean6publicLocaleResolver localeResolver() {7SessionLocaleResolver localeResolver =newSessionLocaleResolver();8localeResolver.setDefaultLocale(Locale.SIMPLIFIED_CHINESE);//默认简体中文9returnlocaleResolver;10}1112//拦截器:支持 ?lang=zh_CN 或 ?lang=en_US 切换语言13@Bean14publicLocaleChangeInterceptor localeChangeInterceptor() {15LocaleChangeInterceptor lci =newLocaleChangeInterceptor();16lci.setParamName("lang");//前端传参名17returnlci;18}1920@Override21publicvoidaddInterceptors(InterceptorRegistry registry) {22registry.addInterceptor(localeChangeInterceptor());23}24}
若优先从请求头识别,再支持参数切换,可以自定义 LocaleResolver(更灵活)。
4. 在代码中使用 MessageSource 获取国际化消息
方式一:注入 MessageSource
1@RestController2@RequestMapping("/api")3publicclassUserController {45@Autowired6privateMessageSource messageSource;78@GetMapping("/test")9publicResponseEntity<String> test(Locale locale) {//Locale 可选从参数注入10//方式1:直接使用 locale 参数11String msg = messageSource.getMessage("user.login.success",null, locale);1213//方式2:从 LocaleContextHolder 获取当前语言(推荐!)14String msg2 = messageSource.getMessage("user.login.success",null, LocaleContextHolder.getLocale());1516returnResponseEntity.ok(msg2);17}18}
方式二:统一封装工具类
1@Component2publicclassMessageUtils {34privatestaticMessageSource messageSource;56@Autowired7publicvoidsetMessageSource(MessageSource messageSource) {8MessageUtils.messageSource =messageSource;9}1011/**12* 获取国际化消息13*/14publicstaticString getMessage(String code, Object... args) {15returnmessageSource.getMessage(code, args, LocaleContextHolder.getLocale());16}1718publicstaticString getMessage(String code) {19returngetMessage(code, (Object)null);20}21}
使用方式:
1thrownewBusinessException(MessageUtils.getMessage("user.notfound"));2//或3returnResult.error(MessageUtils.getMessage("error.system"));
5. 全局异常处理中使用国际化
1@RestControllerAdvice2publicclassGlobalExceptionHandler {34@ExceptionHandler(BusinessException.class)5publicResult<?>handleBusinessException(BusinessException e) {6//假设 BusinessException 里面存了 messageCode7String message =MessageUtils.getMessage(e.getCode(), e.getArgs());8returnResult.error(message);9}1011@ExceptionHandler(Exception.class)12publicResult<?>handleException(Exception e) {13returnResult.error(MessageUtils.getMessage("error.system"));14}15}
6. 支持参数占位符
1# messages.properties2user.age.limit=年龄必须在 {0} 到 {1} 岁之间
1String msg = MessageUtils.getMessage("user.age.limit", 18, 60);2//输出:年龄必须在 18 到 60 岁之间
7. 常见最佳实践总结
| 处理点 | 处理方式 |
|---|---|
| 资源文件位置 | /* by 01022.hk - online tools website : 01022.hk/zh/reproduce.html */ src/main/resources/i18n/messages_*.properties |
| 默认语言 | 简体中文(/* by 01022.hk - online tools website : 01022.hk/zh/reproduce.html */ Locale.SIMPLIFIED_CHINESE) |
| 语言切换方式 | 请求头Accept-Language+?lang=zh_CN |
| 消息获取方式 | 优先使用LocaleContextHolder.getLocale() |
| 工具类 | 封装MessageUtils统一获取 |
| 异常消息 | 全部使用 code + MessageUtils 获取 |
| 找不到key | 建议use-code-as-default-message=false |
| 编码 | 必须UTF-8 |
8. 测试方法
- 浏览器开发者工具 → Network → 修改请求头 Accept-Language: en-US,en;q=0.9
- 或直接在 URL 后加 ?lang=en_US
完成以上步骤,你的 Spring Boot 项目就实现了标准的国际化支持,所有提示信息都可以根据用户语言自动切换。