When doing internationalization in Java, you assign a string key to each message. What\'s the best practice, on where to place those string keys. Goal is to allow easy refactori
I've devised this method long time ago for the shortest amount of typing necessary to get localized version of given strings and to easily add new entries as well. I think it is useful for many type of Java projects as well.
An enum class ME
(Short for MessagesEnum
) has all the definitions and its constructor converts LOREM_IPSUM
to lorem.ipsum
so that you don't have to type constructor parameter.
An I18NManager
class which is responsible for getting the Locale
from the context and constructing/caching ResourceBundle
s, preferably a Spring @Component
.
An optional ServiceRegistry
class for static access to I18NManager
instance, from ME.get()
method to complete the cycle.
The enum:
public enum ME {
USERNAME,
PASSWORD,
LOGIN,
LOGOUT,
DASHBOARD,
MENU,
OK,
CANCEL,
YES,
NO,
CONFIRM,
DELETE,
CREATE,
NEW,
EDIT,
ONLINE,
OFFLINE,
SALES_REPORTS,
...;
private String key;
ME(String key){
this.key = key;
}
ME(){
this.key = name().toLowerCase(Locale.ENGLISH).replace("_", ".");
}
public String get(){
return ServiceRegistry.get().getI18nManager().getMessage(key);
}
public String get(Object ...args ){
return ServiceRegistry.get().getI18nManager().getMessage(key, args);
}
public String key(){
return key;
}
}
I18NManager:
import java.text.MessageFormat;
import java.util.Locale;
import java.util.ResourceBundle;
public interface I18nManager {
Locale getCurrentUserLocale();
ResourceBundle getResourceBundle(Locale locale);
default String getMessage(String key) {
return getResourceBundle(getCurrentUserLocale()).getString(key); //FIXME add error handling
}
default String getMessage(String key, Object... args) {
return MessageFormat.format(getMessage(key), args);
}
}
Usage is simply:
ME.SALES_REPORTS.get()