In this article we assume that you already have an idea about configuring ressource bundles in JSF, how to use it in your pages and also how to configure jsf pages encoding ...
This blog entry is realy independante from JSF version, and it works for both JSF1 and JSF2 ;-)
We suppose that you want to write "Arabic" like "loginBean.username.label = اسم المستخدم " in the message resource bundle (properties) file and you try to save it you will get this error:
"Save couldn't be completed Some characters cannot be mapped using "ISO-85591-1" character encoding. Either change encoding or remove the character ..." because the default mechanism loading of properties files is in "ISO-8559-1-1".
If you change the file encoding to UTF-8, you will be able to save the file but you can not print your messages correctly in JSF !!
To get it work you have to change the default mechanism loading to UTF-8 by implementing a custom ressource bundle class using UTF-8 Control
public class I18nRessourceBundle extends ResourceBundle {
protected static final String BUNDLE_EXTENSION = "properties";
protected static final String CHARSET = "UTF-8";
public static final Control UTF8_CONTROL = new UTF8Control();
public I18nRessourceBundle() {
setParent(ResourceBundle.getBundle("Propety_File_Ressource",
FacesContext.getCurrentInstance().getViewRoot().getLocale(), UTF8_CONTROL));
}
@Override
protected Object handleGetObject(String key) {
return parent.getObject(key);
}
@Override
public EnumerationgetKeys() {
return parent.getKeys();
}
public static class UTF8Control extends Control {
public ResourceBundle newBundle
(String baseName, Locale locale, String format, ClassLoader loader, boolean reload)
throws IllegalAccessException, InstantiationException, IOException
{
// The below code is copied from default Control#newBundle() implementation.
// Only the PropertyResourceBundle line is changed to read the file as UTF-8.
String bundleName = toBundleName(baseName, locale);
String resourceName = toResourceName(bundleName, BUNDLE_EXTENSION);
ResourceBundle bundle = null;
InputStream stream = null;
if (reload) {
URL url = loader.getResource(resourceName);
if (url != null) {
URLConnection connection = url.openConnection();
if (connection != null) {
connection.setUseCaches(false);
stream = connection.getInputStream();
}
}
} else {
stream = loader.getResourceAsStream(resourceName);
}
if (stream != null) {
try {
bundle = new PropertyResourceBundle(new InputStreamReader(stream, CHARSET));
} finally {
stream.close();
}
}
return bundle;
}
}
}
We assume that you have a properties file Propety_File_Ressource in your ressource folder
So in JSF configuration you should use:
...
package_name.I18nRessourceBundle
msgBlog
Insted of
...
Propety_File_Ressource
msgBlog
Enjoy it!
Worked Perfectly! Thanks!
ReplyDeleteHi badr,
ReplyDeleteI did exactly as in the blog but it give me "java.util.MissingResourceException: Can't find bundle for base name com.upnormal.aflete.backEnd.util.bundles.I18nRessourceBundle" exception any ideas ?