gpt4 book ai didi

java - 基于插件的程序中的语言环境和 ResourceBundle

转载 作者:搜寻专家 更新时间:2023-11-01 02:35:03 26 4
gpt4 key购买 nike

我们需要开始将国际化添加到我们的程序中。值得庆幸的是,这还不是全部,只是一小部分,但我希望我们这样做的方式能够扩大到可能涵盖整个项目。问题是,我们的程序是基于插件的,所以并不是所有的字符串都属于同一个地方。

据我了解,Java 的ResourceBundle 是这样工作的。您创建了一个扩展 ResourceBundle 的类,名为 MyProgramStrings,还创建了一个名为 MyProgramStrings_frMyProgramStrings_es 的特定于语言的类> 等。这些类中的每一个都将键(字符串)映射到值(任何对象)。这取决于每个类从何处获取其数据,但它们的一个共同位置是属性文件。

您分两个阶段查找值:首先您获得正确的包,然后查询您想要的字符串。

Locale locale = Locale.getDefault(); // or = new Locale("en", "GB");
ResourceBundle rb = ResourceBundle.getBundle("MyProgramStrings", locale);
String wotsitName = rb.getString("wotsit.name");

然而,我们需要的是将多个语言环境的结果组合到一个资源空间中。例如,插件需要能够覆盖已定义的字符串,并在代码查找该字符串时返回新值。

我有点迷失在这一切之中。有人可以帮忙吗?


更新:David Waters 提问:

I have put my answer at the bottom but I would be interested in hearing how you solved this problem.

好吧,我们还没有走得太远——长期的 WIBNI 总是成为最新危机的牺牲品——但我们基于插件实现的接口(interface),按照资源具有相同的完全限定名称的约定作为界面。

所以接口(interface) UsersAPI 可能有各种不同的实现。默认情况下,该接口(interface)上的方法 getBundle() 返回等效于 ResourceBundle.get("...UsersAPI", locale)。该文件可以被替换,或者如果他们需要更复杂的东西,UsersAPI 的实现可以覆盖该方法。

到目前为止,这满足了我们的需要,但我们仍在寻找基于插件的更灵活的解决方案。

最佳答案

不必将 ResourceBundle 实现为一系列类,每个语言环境一个类(即名为 MyProgramStringsMyProgramStrings_fr, MyProgramStrings_de).如果需要,ResourceBundle 类将回退到使用属性文件:

public static void main(String[] args) {

ResourceBundle bundle = ResourceBundle.getBundle("MyResources");
System.out.println("got bundle: " + bundle);

String valueInBundle = bundle.getString("someKey");
System.out.println("Value in bundle is: " + valueInBundle);
}

如果我在类路径上有一个名为 MyResources.properties 的文件,那么此方法将导致:

got bundle: java.util.PropertyResourceBundle@42e816  
Value in bundle is: someValue

至于设置包的层次结构,或者将它们“合并”在一起,恐怕我帮不上什么忙,除了我知道 Spring 确实有一个概念 hierchical MessageSources ( link to API ) 在 java.util.ResourceBundle 之上实现,所以也许您可以使用 Spring 的功能来实现您想要的?

顺便说一句,这里是 ResourceBundle.getBundle() javadoc 的相关部分,解释了它的“搜索和实例化策略”:

http://java.sun.com/j2se/1.5.0/docs/api/java/util/ResourceBundle.html#getBundle(java.lang.String , java.util.Locale, java.lang.ClassLoader)

  • First, it attempts to load a class using the candidate bundle name. If such a class can be found and loaded using the specified class loader, is assignment compatible with ResourceBundle, is accessible from ResourceBundle, and can be instantiated, getBundle creates a new instance of this class and uses it as the result resource bundle.
  • Otherwise, getBundle attempts to locate a property resource file. It generates a path name from the candidate bundle name by replacing all "." characters with "/" and appending the string ".properties". It attempts to find a "resource" with this name using ClassLoader.getResource. (Note that a "resource" in the sense of getResource has nothing to do with the contents of a resource bundle, it is just a container of data, such as a file.) If it finds a "resource", it attempts to create a new PropertyResourceBundle instance from its contents. If successful, this instance becomes the result resource bundle.

关于java - 基于插件的程序中的语言环境和 ResourceBundle,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/282883/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com