spring - 如何重用Spring或Java的语言环境查找代码?

标签 spring internationalization locale

我正在做一个Spring Web应用程序。

我需要支持一些语言环境,例如ko(韩语),ru(俄语),en(英语)等。

我可以通过诸如RequestContextUtils.getLocale(request)或LocaleChangeInterceptor之类的方法来捕获浏览器的语言环境。

但是,浏览器的语言环境可能不是我的Web应用程序支持的语言环境。我必须将其解析为壁橱或默认语言环境。

基本上,我需要了解在给定浏览器语言环境和一些语言环境值(例如ko,ru和en)的情况下如何获取解析的语言环境。

我的理解是Spring具有这样的语言环境解析代码,因为它能够在给定浏览器语言环境的情况下找到正确的资源包。我希望将Spring的代码重用于语言环境解析,但不确定如何执行。请注意,此问题与查找浏览器的语言环境或显示正确的消息无关。

编辑

根据我跟踪Spring的代码,看来Spring依赖JDK来查找确切或最接近的语言环境。我刚刚发现了这一点,并认为这是我想要的:

资源束查找顺序
https://sites.google.com/site/openjdklocale/design-notes/resource-bundle-lookup-order

请注意,我不需要找到正确的资源包。我只需要获取给定语言环境和一些已知语言环境的现有JDK代码返回的语言环境。因此,我希望重用现有的JDK的查找代码。任何想法?

我正在使用JDK 7。



感谢您的帮助和输入!

问候。

最佳答案

完全重用

要重用JDK逻辑,可以在类路径中为每个已知的语言环境(例如test_fr_CA.properties,test_fr.properties,test_en_US.properties,test_en.properties,test.properties)创建一个属性文件。如果您想匹配根语言环境(test.properties),请不要忘记它。然后,只需为有问题的语言环境创建资源束,然后检查它以查看实际使用的语言环境。

ResourceBundle rb = ResourceBundle.getBundle("test", Locale.FRENCH);
System.out.println("Locale used is:"+rb.getLocale().toString());


这些文件可以动态创建,并在测试后清除。

高级代码复制,低级别重用

您可以在java.util.ResourceBundle.getBundleImpl(...)中复制高级代码。这基本上是通过在有关语言环境中重用java.util.ResourceBundle.Control.getCandidateLocales(...)的候选语言环境列表中查找匹配项(使用您自己的匹配逻辑,例如equalString()表示形式)。如果没有匹配项,则可以通过重用java.util.ResourceBundle.Control.getFallbackLocale(...)来获取所讨论语言环境的下一个后备语言环境。对于每个后备语言环境,请尝试匹配候选列表中的语言环境,并在循环中重复进行后备语言,直到没有后备语言环境为止。请注意,根语言环境将是每个候选列表中的最后一个候选语言,但是除非您用尽了所有后备语言环境,否则应将其跳过。

此方法不需要创建文件。您可以在getCandidateLocales(...)中使用不存在的baseName并获取FallbackLocale(...)调用,并将每个候选语言环境与您的已知语言环境列表进行比较以进行匹配。

一个简单的例子如下:

    ResourceBundle.Control rbControl = ResourceBundle.Control.getControl(ResourceBundle.Control.FORMAT_PROPERTIES);
    Locale localeInQuestion = Locale.CHINA;
    List<Locale> knownLocales = Arrays.asList(new Locale[] {Locale.CANADA_FRENCH, Locale.FRENCH, Locale.US, Locale.UK, Locale.ENGLISH, Locale.ROOT});
    String nonExistentBaseName = "bogus";

    Locale matchingLocale = null;
    Boolean reachedRootLocaleMatch = false;

    outerloop:
    for (Locale targetLocale = localeInQuestion;
            targetLocale != null;
            targetLocale = rbControl.getFallbackLocale(nonExistentBaseName, targetLocale)) {
        List<Locale> candidateLocales = rbControl.getCandidateLocales(nonExistentBaseName, targetLocale);
        for (Iterator iterator = candidateLocales.iterator(); iterator.hasNext();) {
            Locale currentCandidateLocale = (Locale) iterator.next();
            if (knownLocales.contains(currentCandidateLocale)) {
                if (currentCandidateLocale.equals(Locale.ROOT)) {
                    reachedRootLocaleMatch = true;
                }
                else {
                    matchingLocale = currentCandidateLocale;
                    break outerloop;
                }
            }
        }
    }

    if (matchingLocale == null && reachedRootLocaleMatch) {
        matchingLocale = Locale.ROOT;
    }

    if (matchingLocale != null) {
        System.out.println("The matching locale is: "+matchingLocale.toString());
    }
    else {
        System.out.println("There was no matching locale");
    }

关于spring - 如何重用Spring或Java的语言环境查找代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16877621/

相关文章:

reactjs - 在项目上运行formatjs提取时,未返回任何消息。有什么想法吗?

asp.net - 如何在 ASP.NET 中本地化 App_GlobalResources?

python - 字符串格式化python

datetime - 日期的格式是否取决于用户的区域设置和日历系统?

Spring CORS No 'Access-Control-Allow-Origin' header 存在

java - 当我们在后台获取异常时,Tomcat 将显示特定错误的错误页面

java - 如何在 Spring Integration 中实现这个 TCP 流读取器?

正确复数的 Java 国际化 (i18n)

java - 父类(super class)上的 PostConstruct 注释

Grails 设置语言环境不会改变语言