最近需要用到国际化,所以稍微研究了下。
现在都是前后端分离,所以前端后端需要分开来实现。前端 vue 的话,用 vue-i18n 来实现,本文就不写了。后端也就是一些打印日志,以及返回给前端的文案(提示信息等)需要进行国际化。
国际化的话,原理没什么好研究的,会用就行,所以直接上代码了。
在 resources 目录下创建 i18n 目录,然后在 i18n 目录下创建如下三个文件:
图中的 [Resource Bundle 'message'] 不用管,它自己生成的。然后三个配置文件的名称不能乱写,要按照这个格式。
然后分别在中文和英文配置文件中添加如下内容:
hello.world=你好,世界
hello.world=hello world
messages.properties 中内容可以为空。
spring 通过 MessageSource 来实现对国际化的支持。这里用它的一个实现类:ResourceBundleMessageSource。代码如下:
@Configuration
public class LocaleConfig {
@Bean
public ResourceBundleMessageSource messageSource() {
Locale.setDefault(Locale.CHINA);
ResourceBundleMessageSource source = new ResourceBundleMessageSource();
source.setBasenames("i18n/messages");
source.setUseCodeAsDefaultMessage(true);
source.setDefaultEncoding("UTF-8");
return source;
}
}
之后就可以通过 messageSource 这个 bean 来获取国际化资源了。
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
@ActiveProfiles("local")
@Slf4j
public class I18NTest {
@Autowired
private MessageSource messageSource;
@Test
public void test() {
String message = messageSource.getMessage("hello.world", new String[0], Locale.US);
log.info("获取的值:【" + message + "】");
}
}
写法很简单,直接调用 messageSource 的 getMessage 方法,传入 key 和 Locale 就行。第二个参数我这里用不到,所以没过多研究,传个空数组就行。
不过,我这里也不需要在页面上实时切换语言,只要在启动时确定语言版本就行,所以完全可以把需要的 Locale 配置到 application.yaml 中,之后再对 messageSource.getMessage 方法做下封装,这样的话,调用的时候只需要传入一个参数就行了!
1)首先,在 application.yaml 中增加 Locale 配置
i18n:
locale: en
2)编写 I18nService 接口以及对应的实现类
其中:@Value("${i18n.locale}") 是获取 yaml 中的配置
public interface I18nService {
String getMessage(String key);
}
@Slf4j
@Service
public class I18nServiceImpl implements I18nService {
@Autowired
private MessageSource messageSource;
// 获取使用的国际化配置
@Value("${i18n.locale}")
private String i18nLocale;
@Override
public String getMessage(String key) {
Locale locale = "en".equals(i18nLocale) ? Locale.US : Locale.CHINA;
return messageSource.getMessage(key, new String[0], locale);
}
}
3)使用 I18nService 来获取资源
@Autowired
private I18nService i18nService;
@Test
public void test() {
String message = i18nService.getMessage("hello.world");
log.info("获取到的值:【" + message + "】");
}
可以看到,现在在获取资源时,只需要传入 key 值就行了,不再需要传入3个参数!方便了很多。