java - messagesource - ¿Cómo puedo usar parámetros nombrados en un archivo messages.properties?
spring internationalization properties file (6)
Desafortunadamente, la API MessageFormat
no admite parámetros con nombre, solo argumento-índice:
Patrones y su interpretación
MessageFormat usa patrones de la siguiente forma:
MessageFormatPattern:
String
MessageFormatPattern FormatElement String
FormatElement:
{ ArgumentIndex }
{ ArgumentIndex , FormatType }
{ ArgumentIndex , FormatType , FormatStyle }
¿Hay alguna manera de tener registros de message.properties de la siguiente manera?
message.myMessage=This message is for ${name} in ${location}
Opuesto a
message.myMessage = This message is for {0} in {1}
Cuando estoy creando los mensajes, no sé necesariamente el orden / cuántos parámetros se necesitan, pero puedo pasar varias propiedades por nombre y solo se usarán las correctas.
Después de enfrentar la misma pregunta y meter el código fuente, encontré un "agujero de bucle" que lo hace posible de una manera muy fácil:
message.myMessage = This message is for {0,,name} in {1,,location}
Este enfoque no elimina el uso de números. La razón para usarlo es para dar pistas a la gente de la traducción.
Echa un vistazo a ICU4J
Permite algo como esto:
message.myMessage=This message is for {name} in {location}.
Y es mucho más poderoso que los simples reemplazos sugeridos, ya que puede realizar un formateo de configuración de los parámetros (es decir, "la suscripción caduca el: {fecha de caducidad, fecha, larga})
http://icu-project.org/apiref/icu4j/com/ibm/icu/text/MessageFormat.html
Es posible usar la biblioteca de apache commons lang.
https://commons.apache.org/proper/commons-lang/
Properties messages = ...
Map<String, String> m = new HashMap<>();
m.put("name", "Mithu");
m.put("location", "Dhaka");
StrSubstitutor sub = new StrSubstitutor(m);
String msg = sub.replace(messages.getProperty("message.myMessage"));
// msg = This message is for Mithu in Dhaka
Me temo que no, los parámetros son una matriz de objetos, por lo que no hay manera de definir nombres para ellos. Si siempre pasa la matriz de parámetros en el mismo orden, podría usarlos así:
message.myMessage = This message is for {0} in {1}
message.myNameMessage = This message is for {0}
message.myLocationMessage = This message is for people in {1}
message.myAlternateMessage = The message params are location: {1}; name: {0}
Todo es posible para aquellos que lo intentan ... Nunca escuché algo así para Java, pero puedes escribirlo por ti mismo.
Por favor, eche un vistazo a este ejemplo:
public String format(String message, String... arguments) {
for (String argument : arguments) {
String[] keyValue = argument.split("=");
if (keyValue.length != 2)
throw new IllegalArgumentException("Incorrect argument: " + argument);
String placeholder = "${" + keyValue[0] + "}";
if (!message.contains(placeholder))
throw new IllegalArgumentException(keyValue[0] + " does not exists.");
while (message.contains(placeholder))
message = message.replace(placeholder, keyValue[1]);
}
return message;
}
No es lo ideal, ya que en realidad lo llamaría con una cadena codificada (lo que generalmente es una mala idea) y se vería obligado a usar solo cadenas, pero se puede hacer. La única pregunta es si es práctico.