springboot 之 i18n国际化 (展示信息国际化)一
Spring Boot 的国际化(i18n,internationalization)机制基于 Spring Framework 的 MessageSource 接口和 LocaleResolver 组件,能够根据用户语言环境动态返回对应语言的文本。下面从原理和使用示例两个维度进行详细解析。
一、核心原理
1. 核心组件
| 组件 | 作用 |
|---|---|
MessageSource |
消息源接口,负责加载 .properties 国际化资源文件,并根据 key 和 Locale 返回对应语言的消息。默认实现是 ResourceBundleMessageSource。 |
LocaleResolver |
解析当前请求的区域(Locale),决定使用哪种语言。Spring Boot 默认使用 AcceptHeaderLocaleResolver,即从 HTTP 请求头 Accept-Language 中读取。 |
LocaleChangeInterceptor(可选) |
拦截器,允许通过 URL 参数(如 ?lang=zh_CN)动态切换语言。 |
2. 工作流程
- 启动时:Spring Boot 自动配置
MessageSource,扫描classpath:i18n/messages*.properties文件。 - 请求到达时:
LocaleResolver从请求中(Header / Cookie / Session / Parameter)获取当前Locale。- 控制器调用
messageSource.getMessage(key, args, locale)。 MessageSource根据basename + Locale定位到具体.properties文件(如messages_zh_CN.properties),返回对应值。
- 若未匹配到 Locale:回退到默认文件(如
messages.properties)或系统默认语言(可通过配置关闭)。
二、使用示例(完整步骤)
步骤 1:创建国际化资源文件
在 src/main/resources 下创建目录 i18n,并添加以下文件:
resources/
└── i18n/
├── messages.properties # 默认(兜底)
├── messages_zh_CN.properties # 简体中文
├── messages_zh_TW.properties # 繁体中文
└── messages_en_US.properties # 英文(美国)
内容示例:
# messages.properties(默认)
greeting=Hello, {0}!
user.login=Login
# messages_zh_CN.properties
greeting=你好,{0}!
user.login=登录
# messages_en_US.properties
greeting=Hello, {0}!
user.login=Login
⚠️ 注意:
.properties文件需保存为 UTF-8 编码,并在 IDE 中启用 Transparent native-to-ascii conversion(如 IDEA 设置中勾选),避免中文乱码。
步骤 2:配置 application.yml
spring:
messages:
basename: classpath:i18n/messages # 资源文件前缀(不带 .properties)
encoding: UTF-8
fallback-to-system-locale: false # 禁用系统语言回退
default-locale: zh_CN # 默认语言
cache-duration: 3600s # 缓存时间(生产建议开启)
步骤 3:自定义 Locale 解析方式(支持 URL 参数切换)
默认只支持 Accept-Language Header。若想通过 ?lang=zh_CN 切换,需自定义 LocaleResolver 并注册拦截器。
// config/I18nConfig.java
package com.example.demo.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
import java.util.Locale;
@Configuration
public class I18nConfig implements WebMvcConfigurer {
@Bean
public LocaleResolver localeResolver() {
SessionLocaleResolver resolver = new SessionLocaleResolver();
resolver.setDefaultLocale(Locale.SIMPLIFIED_CHINESE); // 默认简体中文
return resolver;
}
@Bean
public LocaleChangeInterceptor localeChangeInterceptor() {
LocaleChangeInterceptor interceptor = new LocaleChangeInterceptor();
interceptor.setParamName("lang"); // 通过 ?lang=zh_CN 切换
return interceptor;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(localeChangeInterceptor());
}
}
步骤 4:在 Controller 中使用
// controller/I18nController.java
@RestController
public class I18nController {
@Autowired
private MessageSource messageSource;
@GetMapping("/hello")
public String hello(@RequestParam String name) {
// 获取当前 Locale(由 LocaleResolver 设置)
Locale locale = LocaleContextHolder.getLocale();
// 获取国际化消息,支持参数占位符 {0}, {1}...
return messageSource.getMessage("greeting", new Object[]{name}, locale);
}
@GetMapping("/login-text")
public String loginText() {
return messageSource.getMessage("user.login", null, LocaleContextHolder.getLocale());
}
}
步骤 5:测试
-
默认语言(zh_CN)
GET /hello?name=张三 # 返回:你好,张三! -
切换为英文
GET /hello?name=Tom&lang=en_US # 返回:Hello, Tom! -
切换为繁体中文
GET /login-text?lang=zh_TW # 返回:登錄
三、高级用法
1. 支持数据库动态国际化(运行时修改)
- 实现自定义
MessageSource,从数据库加载键值对。 - 配合缓存(如 Caffeine/Redis)提升性能。
2. 校验注解国际化
@NotBlank(message = "{validate.required.name}")
private String name;
配合 ValidationMessages.properties 实现校验提示多语言。
3. 前端集成(前后端分离)
- 后端提供
/api/i18n/{lang}接口返回 JSON 格式的语言包。 - 前端(Vue/React)根据用户选择加载对应语言包。
四、常见问题
| 问题 | 解决方案 |
|---|---|
| 中文乱码 | 确保 .properties 文件为 UTF-8 编码,并开启 IDE 的 ASCII 转换选项 |
| 语言不切换 | 检查是否注册了 LocaleChangeInterceptor,且参数名匹配(如 lang) |
| 找不到资源文件 | 检查 basename 路径是否正确(classpath:i18n/messages 对应 resources/i18n/messages_xx.properties) |
| 生产环境缓存失效 | 设置 spring.messages.cache-duration,避免频繁读取文件 |
总结
Spring Boot 国际化 = 资源文件 + MessageSource + LocaleResolver。
通过简单配置即可支持多语言,结合 LocaleChangeInterceptor 实现灵活的语言切换,适用于单体应用或前后端分离架构。对于复杂场景(如动态语言包),可扩展 MessageSource 实现数据库驱动的国际化方案。
本文来自博客园,作者:蓝迷梦,转载请注明原文链接:https://www.cnblogs.com/hewei-blogs/articles/19510455

浙公网安备 33010602011771号