JAVA 国际化
前言
前天公司的项目的国际化部分出了问题,以前的同事在新开发的功能上,只修改中文的国际化配置文件,其他语言的配置文件都没改。唉,烦。
上家公司的国际化部分是由前端做的,这家公司是由后端做的,正好趁此机会了解一下Java 后端的国际化方式。本来以为只是简单的重复,没想到遇到个大坑,这个大坑的最根本原因还没找出来,因为没办法debug追踪下去了,后续想到好办法或者和其他同事讨论下是什么原因吧,所幸这种情况也不容易遇到
Java国际化
1. 添加国际化文件



2. 国际化文件转Unicode
native2ascii [options] [inputfile [outputfile]] 参数选项 options -reverse:将 Latin-1 或 Unicode 编码转为本地编码 -encoding encoding_name:指定转换时使用的编码 inputfile:要转换的文件 outputfile:转换后的文件
官网帮助文档:https://docs.oracle.com/javase/7/docs/technotes/tools/solaris/native2ascii.html
支持的编码格式:https://docs.oracle.com/javase/7/docs/technotes/guides/intl/encoding.doc.html
3. 使用ResourceBundle对象
@Test public void process(){ Locale localeEn = new Locale("en", "US"); Locale localeZh = new Locale("zh", "CN"); ResourceBundle rbEn = ResourceBundle.getBundle("i18n/messages", localeEn); ResourceBundle rbZh = ResourceBundle.getBundle("i18n/messages", localeZh); System.out.println("en-US:" + rbEn.getString("helloWorld")); System.out.println("en-US:" + MessageFormat.format(rbEn.getString("time"), "08:00")); System.out.println("zh-CN:" + rbZh.getString("helloWorld")); System.out.println("zh-CN:" + MessageFormat.format(rbZh.getString("time"), "08:00"));
}

SpringBoot国际化
1. 添加国际化文件(有大坑)

注意:
1. messages.properties必须存在,里面可以什么都不填
2. i18n这个文件夹必须有,文件夹名称可以另取,但是这一层必须存在
2. 配置

3. 注入MessageSource并使用
@Autowired private MessageSource messageSource; @Test public void messageSourceTest(){ Locale localeEn = new Locale("en", "US"); Locale localeZh = new Locale("zh", "CN"); System.out.println("en-US:" + messageSource.getMessage("helloWorld",null,localeZh)); System.out.println("en-US:" + MessageFormat.format(messageSource.getMessage("time",null,localeZh), "08:00")); System.out.println("zh-CN:" + messageSource.getMessage("helloWorld",null,localeEn)); System.out.println("zh-CN:" + MessageFormat.format(messageSource.getMessage("time",null,localeEn), "08:00")); }
大坑分析
1. 问题表象:

2. 通过在公司已有的项目中 debug ,发现 ResourceBundleMessageSource 这个 bean 是由 MessageSourceAutoConfiguration 配置的,具体的发现过程这里先跳过,讲起来太曲折了。
3. 然后就是发现 MessageSourceAutoConfiguration 的下面这个条件没有满足,导致没法注入。

4. 进一步debug,发现100行这里在参数name="messages"时返回的是一个空数组,而name="i18n/messages"就能返回有1个元素的数组。后续没能下载到源码,没办法进一步深入debug,就不写了。
总结
第一遍尝试的时候,不要想着"创新",老老实实按着网上的教程一模一样的写吧,尽量减少差异点,保证程序先能运行起来。然后再按照自己的想法进行调整,这样即使出问题了也能快速纠正,符合"小步快走"的策略。

浙公网安备 33010602011771号