【问题标题】:Do resource bundles in Java support runtime string substitution?Java 中的资源包是否支持运行时字符串替换?
【发布时间】:2010-03-15 22:56:35
【问题描述】:

您可以使用 Java ResourceBundle 执行以下操作吗?

在属性文件中...

example.dynamicresource=You currently have {0} accounts.

在运行时...

int accountAcount = 3;
bundle.get("example.dynamicresource",accountCount,param2,...);

给出结果

“您目前有 3 个帐户。”

【问题讨论】:

    标签: java resourcebundle


    【解决方案1】:

    不能不使用MessageFormat类,如:

    String pattern = bundle.getString("example.dynamicresource");
    String message = MessageFormat.format(pattern, accountCount);
    

    【讨论】:

    • 虽然这可行,但 ResourceBundle 不一定能做到这一点。 ResourceBundle 没有机制。
    【解决方案2】:

    ResourceBundle 本身不支持属性占位符。通常的想法是从捆绑包中获取字符串,并将其粘贴到 MessageFormat 中,然后使用它来获取参数化消息。

    如果您使用的是 JSP/JSTL,那么您可以结合使用 <fmt:message><fmt:param> 来执行此操作,它在后台使用 ResourceBundleMessageFormat

    如果你碰巧使用的是Spring,那么它有ResourceBundleMessageSourcedoes something similar,并且可以在你程序的任何地方使用。这个MessageSource 抽象(结合MessageSourceAccessor)比ResourceBundle 更好用。

    【讨论】:

      【解决方案3】:

      有多种方法,具体取决于您使用的查看技术。如果您使用的是“plain vanilla”Java(例如 Swing),请使用前面回答的 MessageFormat API。如果您使用的是 web 应用程序框架(这是真的,如果我在这里正确判断您的问题历史),那么方式取决于您使用的视图技术和/或 MVC 框架。如果它是例如“plain vanilla”JSP,那么您可以为此使用 JSTL fmt:message

      <fmt:message key="example.dynamicresource">
          <fmt:param value="${bean.accountCount}">
      </fmt:message>
      

      如果是例如 JSF,您可以使用 h:outputFormat

      <h:outputFormat value="#{bundle['example.dynamicresource']}">
          <f:param value="#{bean.accountCount}">
      </h:outputFormat>
      

      最好的办法是查阅您正在使用的技术/框架的文档(或在此处说明,以便我们提供更合适和更详细的答案)。

      【讨论】:

        【解决方案4】:

        Struts 有一个很好的实用程序,名为 MessageResources,它完全符合您的要求......

        例如

        MessageResources resources = getResources(request, "my_resource_bundle"); // Call your bundle exactly like ResourceBundle.getBundle() method
        resources.getMessage("example.dynamicresource",accountCount,param2,...);
        

        限制 它只允许最多 3 个参数(即资源属性、param1、...、param3)。

        我建议按照 David Sykes 的建议使用 MessageFormat(如果您想使用 3 个以上的参数值)。

        PSgetResources 方法仅在 Struts Action 类中可用。

        【讨论】:

        • 作为说明/更新:Struts 1.x Web 框架已达到其end of life,自 2013 年 5 月起不再受到官方支持。
        • 作为补充:Struts 2 以 getText() 方法的形式提供了更好的替代方案。这些方法在 ActionSupport 类实现的TextProvider 接口中定义。有两种getText() 方法支持消息参数替换:一种采用数组,另一种采用列表,并且都对参数数量没有任何(合理的)限制。跨度>
        • @informatik01 虽然您的答案此时有效,但此答案发布于 2010 年 3 月,当时仍然支持 Struts 1.x。
        • 我知道,这就是为什么我将第一条评论标记为更新。我并没有试图妥协你的答案,这只是给不知道这些变化的其他人的提示。没有冒犯:-)
        【解决方案5】:

        我认为您不能将这项工作用于非英语属性文件。

        我的 message.properties 文件有以下行:

        info.fomat.log.message.start=开始解析 {0} 格式的日志消息。

        我的 message_fr_FR.properties 文件有以下行:

        info.fomat.log.message.start=A partir d'analyser le message connector {0} 格式。

        此代码仅适用于英文代码

        String.format((String) 消息 .getString(GlobalConstants.MESSAGE_FORMAT_START), GlobalConstants.STR_JSON));

        当我的语言/区域设置是法语时,它确实用值替换占位符:-(

        甚至 MessageFormat.fomat() 也不好

        【讨论】:

        • 使用 String.format(..) 时,您可以使用经典的 C 格式格式说明符,例如 '%d'、'%s'。
        • MRay:根据@tleveque 的回答,您的法语文本中的单引号可能是问题所在。当您将字符串更改为 info.fomat.log.message.start=A partir d''analyser le message connector {0} 格式时会发生什么。
        【解决方案6】:

        我不相信 ResourceBundle 自己可以做到这一点,但 String 可以:

        String.format(bundle.getString("example.dynamicresource"), accountCount);
        

        【讨论】:

          【解决方案7】:

          请记住,在使用 MessageFormat.format() 时,如果要表示单引号 ('),则需要在资源包中使用双引号 ('')。

          【讨论】:

            【解决方案8】:

            MessageFormoat#format 适用于以下情况:

            greetingTo=Have Param, saying hello {0}
            

            您可以像这样声明两个方法,其中 RB 是 ResourceBundle 的一个实例:

            /**This is a method that takes the param to substitute the placeholder**/
            public String getString(String key, Object... params  ) {
                try {
                    return MessageFormat.format(this.RB.getString(key), params);
                } catch (MissingResourceException e) {
                    return "[" + key + "]";
                }
            }
            
            /**Without a param, this will derectly delegate to ResourceBundle#getString**/
            public String getString(String key) {
                try {
                    return this.RB.getString(key);
                } catch (MissingResourceException e) {
                    return "[" + key + "]";
                }
            } 
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-10-04
              • 2012-09-01
              • 1970-01-01
              • 2016-09-24
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多