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,就不写了。

     

 总结

  第一遍尝试的时候,不要想着"创新",老老实实按着网上的教程一模一样的写吧,尽量减少差异点,保证程序先能运行起来。然后再按照自己的想法进行调整,这样即使出问题了也能快速纠正,符合"小步快走"的策略。

posted @ 2020-12-04 16:44  上课爱睡觉  阅读(283)  评论(0)    收藏  举报