web-dev-qa-db-fra.com

Les regroupements de ressources dans Java prennent-ils en charge la substitution de chaînes d'exécution?

Pouvez-vous faire ce qui suit avec un Java ResourceBundle?

Dans le fichier de propriétés ...

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

Lors de l'exécution...

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

Pour donner un résultat de

"Vous avez actuellement 3 comptes."

40
benstpierre

Pas sans utiliser la classe MessageFormat , telle que:

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

À lui seul, ResourceBundle ne prend pas en charge les espaces réservés de propriété. L'idée habituelle est de prendre la chaîne que vous obtenez du bundle et de la coller dans un MessageFormat, puis de l'utiliser pour obtenir votre message paramétré.

Si vous utilisez JSP/JSTL , vous pouvez combiner <fmt:message> et <fmt:param> pour ce faire, qui utilise ResourceBundle et MessageFormat sous les couvertures.

Si vous utilisez Spring , alors il a le ResourceBundleMessageSource qui fait quelque chose de similaire , et peut être utilisé n'importe où dans votre programme. Cette abstraction MessageSource (combinée avec MessageSourceAccessor) est beaucoup plus agréable à utiliser que ResourceBundle.

10
skaffman

Il existe différentes manières, selon la technologie d'affichage que vous utilisez. Si vous utilisez "plain Vanilla" Java (par exemple Swing), utilisez alors l'API MessageFormat comme indiqué précédemment. Si vous utilisez un framework d'application web (ce qui est vrai, si je juge correctement l'historique de vos questions ici), alors la manière dépend de la technologie d'affichage et/ou du framework MVC que vous utilisez. S'il s'agit par exemple de JSP "plain vanilla", alors vous pouvez utiliser JSTL fmt:message pour cela.

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

S'il s'agit par exemple de JSF, vous pouvez utiliser h:outputFormat pour cela.

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

Le meilleur endroit est de simplement consulter la documentation de la technologie/du framework que vous utilisez (ou de le dire ici afin que nous puissions donner des réponses mieux adaptées et plus détaillées).

6
BalusC

Les jambes de force ont un utilitaire Nice appelé MessageResources qui fait exactement ce que vous demandez ....

par exemple.

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

Limitation Il n'autorise qu'un maximum de 3 paramètres (c.-à-d. Attribut de ressource, param1, ..., param3).

Je suggère d'utiliser MessageFormat (si vous souhaitez utiliser plus de 3 valeurs de paramètres) comme suggéré par David Sykes.

PS la méthode getResources est disponible uniquement dans la classe Struts Action.

3
Buhake Sindi

Je ne pense pas que vous puissiez faire ce travail pour le fichier de propriétés non anglais.

Mon fichier message.properties a la ligne suivante:

info.fomat.log.message.start = Démarrage de l'analyse du message du journal au format {0}.

Et mon fichier message_fr_FR.properties a la ligne suivante:

info.fomat.log.message.start = A partir d'analyser le format du message connecteur {0}.

Ce code ne fonctionne que pour l'anglais

String.format ((String) messages .getString (GlobalConstants.MESSAGE_FORMAT_START), GlobalConstants.STR_JSON));

Il ne PAS remplace l'espace réservé par la valeur lorsque ma langue/locale est le français :-(

Même MessageFormat.fomat () n'est pas bon

1
MRay

MessageFormoat # format fonctionnera pour le cas comme:

greetingTo=Have Param, saying hello {0}

Vous pouvez déclarer deux méthodes comme celle-ci où RB est une instance de 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 + "]";
    }
} 
0
Jaskey

Je ne crois pas que ResourceBundle puisse le faire lui-même, mais String peut:

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

N'oubliez pas que lorsque vous utilisez MessageFormat.format() vous devez utiliser un guillemet double ('') dans votre ensemble de ressources si vous souhaitez exprimer un guillemet simple (').

0
tleveque