1

由于某些原因,有一项功能已从 Web 应用程序转移到 Web 服务。在 Web 应用程序方面,我们使用 FMT 标签来检索本地化文本,并且它过去工作正常。现在我需要在 Web 服务应用程序上实现相同的功能。为了实现这一点,我想到了使用 ResourceBundle 类,但是由于 Web 服务是无状态的,我不想调用 ResourceBundle.getBundle(filename)

因为它可能会在我每次调用 Web 服务调用时调用 IO 操作。相反,由于我的语言环境键不是很大,我想将所有 ResourceBundles 加载到单例 Map 中并传递键并获得捆绑类型的方法。

对此有疑问:a.) 这种方法好吗?b.) 如何在我的单例映射中使用 resourcebundle 加载所有语言环境,即有没有一种方法可以加载语言环境文件夹中提到的所有语言环境文件,而无需明确提及每个文件的名称。

提前感谢任何帮助。

Rgards,

瓦布哈夫

4

2 回答 2

2

首先要做的事情是:我永远不会让我的网络服务“感知区域设置”。向用户显示本地化消息是调用者的工作。Web 服务是一个后端组件,它不关心语言,只关心屏幕分辨率。但不管怎么说...

...如果我无法就我的 web 服务“i18n 感知”进行讨价还价,我会将每个捆绑文件加载到java.util.Properties对象中,然后将所有这些对象放入 Map 并使其在应用程序的上下文。

希望这可以帮助!

于 2012-11-07T06:16:06.023 回答
1

正如 Daniel 指出的那样,创建与语言环境无关的 Web 服务确实很有意义。最好的方法是只返回标识符(例如资源键名)并将它们解析为客户端上的适当消息。

但是,如果您使用 JavaScript 访问代码,则无法真正使用上述方法,您需要实际翻译。
在这种情况下,您需要为实际的资源文件构建一些访问层。可以使用Wea​​kHashMap并按需加载资源文件来完成。

为了清楚我的意思,我认为您需要以下方面的内容:

public class ResourceLayer {
    private final WeakHashMap<Locale, ResourceBundle> cache =
                      new WeakHashMap<>();

    public String getString(String key, Locale locale) {
        ResourceBundle resources = cache.get(locale);

        if (resources == null) {
            resources = ResourceBundle.getBundle(BASE_NAME, locale);
            cache.put(locale, resources);
        }

        try {
            return resources.getString(key);
        } catch (MissingResourceException mre) {        
            logger.error("The translation for " + key
                    + " is missing for locale " + locale.toLanguageTag());
            // Visually indicate an error
            return "!" + key + "!";
        }
    }
}

这里要说几点。WeakHashMap 将在需要时保留文件,因此它不会对内存占用造成太大影响。您将在此示例中阅读的ResourceBundle实际上是PropertyResourceBundle类的实例。您可能想检查一下,但实际实现会一次性读取所有属性文件并将其备份到 HashMap 中。因此,只有第一次访问给定语言资源时,您才会进行 I/O 操作。
这是内存消耗和磁盘使用之间的某种折衷,因此您可能需要为常用语言预加载内容...

最后但并非最不重要的。我并没有真正推荐该解决方案,但您实际上可以将资源放入数据库(这会损害 Localizability)并按需读取。

于 2012-11-07T21:38:53.393 回答