Java中的资源包是否支持运行时字符串替换?

Java中的资源包是否支持运行时字符串替换?,java,resourcebundle,Java,Resourcebundle,您可以使用Java ResourceBundle执行以下操作吗 在属性文件中 example.dynamicresource=You currently have {0} accounts. 在运行时 int accountAcount = 3; bundle.get("example.dynamicresource",accountCount,param2,...); 给出结果 “您当前有3个帐户。”必须使用该类,例如: String pattern = bundle.getString(

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

在属性文件中

example.dynamicresource=You currently have {0} accounts.
在运行时

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

“您当前有3个帐户。”

必须使用该类,例如:

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

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

如果您使用的是JSP/JSTL,那么您可以将
结合使用,在封面下使用
ResourceBundle
MessageFormat


如果您碰巧使用的是Spring,那么它有
ResourceBundleMessageSource
,可以在程序中的任何地方使用。这个
MessageSource
抽象(与
MessageSourceAccessor
结合使用)比
ResourceBundle
好得多,我不相信ResourceBundle本身可以做到这一点,但String可以:

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

根据您使用的视图技术,有多种方法。如果您使用的是“普通的”Java(例如Swing),那么请按照前面的回答使用API。如果您使用的是webapplication框架(如果我在这里正确判断您的问题历史,这是事实),那么方法取决于您使用的视图技术和/或MVC框架。如果它是例如“普通”JSP,那么您可以使用JSTL来实现这一点

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

最好的方法是查阅您正在使用的技术/框架的文档(或者在这里告诉它,以便我们能够给出更合适、更详细的答案)。

Struts有一个很好的名为
MessageResources
的util,它完全满足您的要求

e、 g

限制 它最多只允许3个参数(即资源属性、参数1、…、参数3)

我建议使用David Sykes建议的MessageFormat(如果要使用3个以上的参数值)


PS只有在Struts
Action
类中才能使用
getResources
方法。

我认为对于非英语属性文件,您无法实现这一点

My message.properties文件包含以下行:

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

我的消息\u fr\u fr.properties文件有以下行:

info.fomat.log.message.start=partir d'le消息连接器{0}格式。

此代码仅适用于英语代码

String.format((String)messages.getString(GlobalConstants.MESSAGE_format_START),GlobalConstants.STR_JSON))

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


即使MessageFormat.fomat()也不好

请记住,当使用
MessageFormat.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 + "]";
    }
} 

当使用String.format(..)时,您可以使用经典的C格式说明符,如'%d','%s'。MRay:根据@tleveque的回答,法语文本中的单引号可能是问题所在。当您将字符串更改为info.fomat.log.message.start=A partir d''le message connecter{0}时会发生什么格式。虽然这是可行的,但ResourceBundle不一定能做到。ResourceBundle没有机制。注意/更新:Struts 1.x web框架已经达到了极限,自2013年5月以来不再受到正式支持。此外,Struts 2以getText()的形式提供了更好的替代方案方法。这些方法是在ActionSupport类实现的接口中定义的。有两个getText()方法支持消息参数替换:一个接受数组,一个接受列表,两者都没有(合理的)参数数量的限制。@informatik01虽然您的答案目前有效,但此答案发布于2010年3月,当时Struts 1.x仍然受支持。我知道,这就是为什么我将第一条评论标记为更新。我并没有试图破坏您的答案,这只是给不知道这些更改的其他人的一个提示。不菲恩斯:-)
greetingTo=Have Param, saying hello {0}
/**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 + "]";
    }
}