spring项目实现国际化流程解析
作者:makowin
SpringBoot实现国际化(i18n)的步骤包括创建国际化资源文件、配置application.yml、自定义LocaleResolver和LocaleChangeInterceptor、在代码中使用MessageSource获取国际化消息,本文介绍spring项目实现国际化流程,感兴趣的朋友一起看看吧
在 Spring Boot 项目已经开发完成后,想要实现国际化(i18n),让所有提示信息(后端返回的错误消息、成功消息、异常信息、枚举描述等)支持多语言,处理流程如下:
1. 创建国际化资源文件(messages.properties)
在 src/main/resources 目录下(新建 i18n 子目录),创建以下文件:
src/main/resources/
└── i18n/
├── messages.properties # 默认语言(通常是中文或英文)
├── messages_zh_CN.properties # 简体中文
├── messages_en_US.properties # 美式英文
├── messages_zh_TW.properties # 繁体中文(可选)
└── messages_ja.properties # 日语(可选)messages.properties(中文示例):
# 通用提示 success=操作成功 error.system=系统异常,请稍后重试 error.notfound=资源不存在 # 业务提示 user.login.success=登录成功 user.login.fail=用户名或密码错误 user.notfound=用户不存在
messages_en_US.properties(英文示例):
success=Operation successful error.system=System error, please try again later error.notfound=Resource not found user.login.success=Login successful user.login.fail=Username or password is incorrect user.notfound=User not found
注意:
- 文件名必须以 messages 开头(Spring Boot 默认查找规则)。
- 所有提示统一放在 i18n 目录下,方便管理。
2. 配置 application.yml(或 application.properties)
# application.yml
spring:
messages:
basename: i18n/messages # 资源文件基础名(支持通配符)
encoding: UTF-8 # 必须是 UTF-8
fallback-to-system-locale: false # 推荐设置为 false(找不到对应语言时不回退到系统默认Locale)
use-code-as-default-message: true # 找不到key时直接返回code(调试方便,上线可改为false)# properties spring.messages.basename=i18n/messages spring.messages.encoding=UTF-8 spring.messages.fallback-to-system-locale=false spring.messages.use-code-as-default-message=true
3. 自定义 LocaleResolver 和 LocaleChangeInterceptor(支持前端传参切换语言)
Spring Boot 默认使用 AcceptHeaderLocaleResolver(根据请求头 Accept-Language 自动识别),生产环境通常还需要支持通过参数或 cookie 切换语言。
使用 SessionLocaleResolver + LocaleChangeInterceptor:
@Configuration
public class LocaleConfig implements WebMvcConfigurer {
// 默认语言
@Bean
public LocaleResolver localeResolver() {
SessionLocaleResolver localeResolver = new SessionLocaleResolver();
localeResolver.setDefaultLocale(Locale.SIMPLIFIED_CHINESE); // 默认简体中文
return localeResolver;
}
// 拦截器:支持 ?lang=zh_CN 或 ?lang=en_US 切换语言
@Bean
public LocaleChangeInterceptor localeChangeInterceptor() {
LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
lci.setParamName("lang"); // 前端传参名
return lci;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(localeChangeInterceptor());
}
}若优先从请求头识别,再支持参数切换,可以自定义 LocaleResolver(更灵活)。
4. 在代码中使用 MessageSource 获取国际化消息
方式一:注入 MessageSource
@RestController
@RequestMapping("/api")
public class UserController {
@Autowired
private MessageSource messageSource;
@GetMapping("/test")
public ResponseEntity<String> test(Locale locale) { // Locale 可选从参数注入
// 方式1:直接使用 locale 参数
String msg = messageSource.getMessage("user.login.success", null, locale);
// 方式2:从 LocaleContextHolder 获取当前语言(推荐!)
String msg2 = messageSource.getMessage("user.login.success", null, LocaleContextHolder.getLocale());
return ResponseEntity.ok(msg2);
}
}方式二:统一封装工具类
@Component
public class MessageUtils {
private static MessageSource messageSource;
@Autowired
public void setMessageSource(MessageSource messageSource) {
MessageUtils.messageSource = messageSource;
}
/**
* 获取国际化消息
*/
public static String getMessage(String code, Object... args) {
return messageSource.getMessage(code, args, LocaleContextHolder.getLocale());
}
public static String getMessage(String code) {
return getMessage(code, (Object) null);
}
}使用方式:
throw new BusinessException(MessageUtils.getMessage("user.notfound"));
// 或
return Result.error(MessageUtils.getMessage("error.system"));5. 全局异常处理中使用国际化
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(BusinessException.class)
public Result<?> handleBusinessException(BusinessException e) {
// 假设 BusinessException 里面存了 messageCode
String message = MessageUtils.getMessage(e.getCode(), e.getArgs());
return Result.error(message);
}
@ExceptionHandler(Exception.class)
public Result<?> handleException(Exception e) {
return Result.error(MessageUtils.getMessage("error.system"));
}
}6. 支持参数占位符
# messages.properties
user.age.limit=年龄必须在 {0} 到 {1} 岁之间 String msg = MessageUtils.getMessage("user.age.limit", 18, 60);
// 输出:年龄必须在 18 到 60 岁之间7. 常见最佳实践总结
| 处理点 | 处理方式 |
|---|---|
| 资源文件位置 | src/main/resources/i18n/messages_*.properties |
| 默认语言 | 简体中文(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 项目就实现了标准的国际化支持,所有提示信息都可以根据用户语言自动切换。
到此这篇关于spring项目国际化流程的文章就介绍到这了,更多相关spring项目国际化流程内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
