加载了错误的Java资源包

时间:2013-07-25 12:12:46

标签: java internationalization resources translation locale

在我的应用程序中,我使用java资源包来翻译其标签。 我目前有两个文件:

  • resources.properties,标签为英文(默认语言)
  • resources_fr.properties,带有法语
  • 标签

然后,我使用以下命令加载bundle属性:

ResourceBundle.getBundle(RESOURCE_BUNDLE_NAME, locale);

...其中locale是用户的区域设置。

当我使用法语网络浏览器时,没关系,我正在用法语获取所有消息,因为我的语言环境正确设置为fr。 但是,当我将浏览器切换到英语时,它们仍然是法语!

使用en_US语言环境正确设置locale变量,但getBundle方法返回带有fr语言环境的包,而不是仅返回默认包...

这是正常行为吗?我很惊讶,因为我期望当语言环境没有附加特定的资源包时(例如法语)使用resources.properties的英文值...

2 个答案:

答案 0 :(得分:2)

这是正常的结果,但如果您没有仔细阅读getBundle的(相当冗长的)描述,那就非常令人惊讶。重要的是:

  

如果找不到匹配的资源包,则调用默认控件的getFallbackLocale方法,该方法返回当前的默认语言环境。使用此语言环境生成一个新的候选语言环境名称序列,然后再次搜索,如上所述。

这有点出乎意料。只有在尝试使用除指定语言环境之外的默认语言环境之后,该方法才会执行您期望的操作:

  

如果仍未找到结果包,则仅查找基本名称。

这是桌面应用程序的合理行为。毕竟,如果您在给定机器的默认语言环境的情况下成功启动了Java应用程序,那么如果应用程序使用默认语言环境而不是您指定的语言环境,则应该知道如何处理该应用程序。但是,如果您的应用程序是Web服务器并且使用了服务器的区域设置而不是您在浏览器中指定的首选项,则生成的页面可能会非常困难。

处理此问题的正确方法是禁止使用回退区域设置。您可以通过指定附加参数ResourceBundle.Control.getNoFallbackControl(ResourceBundle.Control.FORMAT_DEFAULT)在代码中执行此操作,从而生成

ResourceBundle.getBundle(RESOURCE_BUNDLE_NAME, locale, 
    ResourceBundle.Control.getNoFallbackControl(
        ResourceBundle.Control.FORMAT_DEFAULT));

(当我多次需要这个时,我通常会在某个地方为其他参数定义一个常量。)这会导致你期望的行为。

答案 1 :(得分:0)

这可能有助于澄清您的问题:

http://docs.oracle.com/javase/tutorial/i18n/resbundle/propfile.html

  

这些Locale对象应该与在。中创建的属性文件匹配   前两步。例如,Locale.FRENCH对象对应   到LabelsBundle_fr.properties文件。 Locale.ENGLISH没有   匹配LabelsBundle_en.properties文件,因此默认文件将是   使用