【问题标题】:How to set the Locale Value based on the country the user belongs to如何根据用户所属的国家/地区设置区域设置值
【发布时间】:2012-04-30 10:37:14
【问题描述】:

目前我的 J2EE 应用程序支持以下国家/地区

MessagesBundle_en_GB.properties (United Kingdom )
MessagesBundle_en_US.properties (United States )
MessagesBundle_it_IT.properties (Italy )
MessagesBundle_pt_BR.properties (Brazil )
MessagesBundle_sv_SE .properties (Sweden)

所以我为上面所有这些国家制作了一个属性文件,并在其中定义了键值对。 我正在为这个概念使用资源包。

我将访问密钥名称的方式是这种方式

bundle.getString("userName"));
bundle.getString("Mobile"));

现在我的问题是,

如何在 JSP 页面中设置 Locale 值,因为用户可能属于上述任何国家/地区

请告诉我,非常感谢

// 这个是硬编码的,如何动态设置??

ResourceBundle bundle = ResourceBundle.getBundle("MessagesBundle", Locale.UK);

【问题讨论】:

    标签: java internationalization


    【解决方案1】:

    使用ResourceBundle.getBundle(BUNDLE_NAME).getString(key); 访问字符串。

    更新默认区域设置时,例如viaLocale.setDefault(<REQUIRED_LOCALE>);清除ResourceBundle缓存:ResourceBundle.clearCache();

    ResourceBundle.getBundle(BUNDLE_NAME).getString(key); 的下一次调用应该返回所选语言环境的本地化字符串。

    【讨论】:

    • 感谢您的回答,但是如何动态设置区域设置值?对于意大利用户,我需要将其动态设置为 Locale.IT,如果对于美国用户,我需要将其动态设置为 Locale.US?那么如何根据用户位置动态呢??
    【解决方案2】:

    最简单的方法是实现HttpFilter。例如在 web.xml 中调用它 LocaleHttpFilter. It should be mapped to/*`,因此每次请求到达您的应用程序时都会调用它。

    过滤器会发现您的请求并决定当前的语言环境。它可以根据 URL 参数、HTTP 标头、GeoIP 查找等做出决定。一旦决定了它应该调用的语言环境:

    Locale.setDefault(locale)

    然后就可以使用了

    ResourceBundle.getBundle("MessageBundle").getString("hello");

    在您的代码中的任何位置。此行将根据在过滤器中设置的当前语言环境返回字符串 "hello" 的值。

    【讨论】:

    • 正如我所提到的,用户可以属于上述任何国家,例如,如果意大利人打开,我需要显示意大利内容??那么在这种情况下,如果我需要将 Locale 值设置为意大利,我该怎么办?我不确定是否必须使用 HttPServletRequest.getLocale() 来获取本地值?谢谢。
    【解决方案3】:

    第一件事:您可以在您的后端代码中使用ResourceBundle.getBundle(Locale)。但是,您应该永远直接在 JSP 页面中使用它。你应该 use JSTL 代替。现在,让我们进入细节。

    没有必要直接使用 ResourceBundle 的好主意有两个原因。一个与此有关:

    <% 
    try {
      ResourceBundle rb = ResourceBundle.getBundle("messages", locale);
    } catch (MissingResourceException mre) {
       // LOG THIS!
    }
    %>
    

    这看起来很丑,不是吗?那是因为您必须提防MissingResourceException,如果没有您要查找的基本名称的捆绑包,则会抛出该错误。更糟糕的是,如果给定场景中没有密钥,则可能会引发相同的异常:

    rb.getString("key");
    

    所以你还需要考虑到这一点:

    <% 
    try {
      rb.getString("key");
    } catch (MissingResourceException mre) {
       // LOG THIS!
    }
    %>
    

    它看起来怎么样?
    当然,您可以从 ResourceBundle 派生并覆盖这些方法,这样它们就不会抛出异常,但这比这要多得多:

    <fmt:setLocale value="fr_CA" scope="session"/>
    <fmt:bundle basename="com.taglib.weblog.Greeting">
    <fmt:message key="com.taglib.weblog.Greeting.greeting">
    

    这就是您应该将 JSTL 与 JSP 一起使用的原因。在this article 中阅读有关如何将 JSTL 用于 i18n 的更多信息。

    现在,您最初的问题是关于语言协商(W3C 术语)或区域设置检测(如果您愿意)。如何在 JSP 应用程序中做到这一点?
    最简单和最典型的场景是读取 HTTP 的 Accept-Language 标头的内容。在 Java Servlet 世界中,这意味着调用 ServletRequest's getLocale()getLocales() 方法并分配给 HttpSession 对象中的变量,可以从 JSP 页面访问。如果你想知道如何在 servlet 端访问 HttpSession,有一个getSession() 方法。

    如果您可以直接访问 Servlet,这将有效。如果您不需要创建(或分配现有的)区域设置过滤器,它将为您完成所有这些工作。正如您可能想象的那样,这是相当常见的情况。这就是人们已经(很久以前)编写必要课程的原因。你可以在几个框架中找到,让我特别提到Spring Framework
    我知道这听起来可能很奇怪,但是如果您正在寻找简单的解决方案,那么学习和使用常见的 Web 框架(即 Spring MVC)比重新发明轮子更好。我知道学习曲线可能有点陡峭,但值得。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多