3

On the internet i found a book called JSF 2.0 cookbook.

I rode chapter 7(Internationalization) and i found it pretty simple, i tried everything there by my self, and all worked fine besides the use of characters from languages such as Russian, Arabic, Serbian...

The book says this:

A common problem when using Arabic, Chinese, Russian characters (and so on) sounds like this: "I can type such characters in an inputText component, but when I submit the form, the inserted text is displayed in Unicode characters, instead of human readable characters. How to fix this?". The solution is very simple. All you have to do is to write the following line in your JSF page:

<%@page contentType="text/html" pageEncoding="UTF-8"%>

So that's exactly what i did. I added that line at the very first line of code of my main JSF template. But it didn't work. What am i missing? all my localization property files are configured to use UTF-8:

enter image description here

Also i tried this line in my h:head tag:

<meta http-equiv="content-type" content="text/html;charset=utf-8"/>

What else do i need to be able to see text in my page writen in Russian,Arabic... The only thing i see when i change to ru,ar or sr locales is text like this:

ÙØ¨Ø­Ø« ÙÙ ØµÙØ­Ø§Øª ÙÙÙØ© ÙÙØ³Ù

Update After a while reading some articles on localization, i came to the conclusion that my app needs to do the conversions to be able to render the special characters(I dont like the solution of the scape characters in the properties file). I was following an example at this link: http://jdevelopment.nl/internationalization-jsf-utf8-encoded-properties-files/

I understand most of it, but when i try to do it in my app, i see i still see rubish on the browser. I tried in various ways, but none worked:

This is how i organized my files:

enter image description here

This is my faces-config.xml

<?xml version="1.0" encoding="UTF-8"?>

<faces-config
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
    version="2.0">
    <application>
        <message-bundle>resources.application</message-bundle>
        <locale-config>
            <default-locale>en</default-locale>
            <supported-locale>en</supported-locale>
            <supported-locale>de</supported-locale>
            <supported-locale>it</supported-locale> 
            <supported-locale>es</supported-locale> 
            <supported-locale>fr</supported-locale> 
            <supported-locale>sr</supported-locale> 
            <supported-locale>ar</supported-locale>
            <supported-locale>ru</supported-locale>
        </locale-config>

        <!-- Localization files configuration -->
        <resource-bundle>
            <!-- Path to the file -->
            <base-name>resources.messages</base-name>
            <!-- Variable representation of the file -->
            <var>msgs</var>
        </resource-bundle>              
    </application>

</faces-config>

And this is a file i found on the link above, to be able to do the conversions:

package support;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.Enumeration;
import java.util.Locale;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;

import javax.faces.context.FacesContext;

public class TextBunddle extends ResourceBundle {

    protected static final String BUNDLE_NAME = "resources.messages";
    protected static final String BUNDLE_EXTENSION = "properties";
    protected static final Control UTF8_CONTROL = new UTF8Control();

    public TextBunddle() {
        setParent(ResourceBundle.getBundle(BUNDLE_NAME,
            FacesContext.getCurrentInstance().getViewRoot().getLocale(), UTF8_CONTROL));
    }

    @Override
    protected Object handleGetObject(String key) {
        return parent.getObject(key);
    }

    @Override
    public Enumeration getKeys() {
        return parent.getKeys();
    }

    protected 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, "UTF-8"));
                } finally {
                    stream.close();
                }
            }
            return bundle;
        }
    }

}

I think the mistake is in faces-config.xml, but i dont know what is the way i should configure the file, to be able to see the localiced messages when in my pages i use comands like this one:

#{msgs.mainbaner}

This is what firebug says when i request a language change:

enter image description here

javing
  • 12,307
  • 35
  • 138
  • 211

1 Answers1

5
<%@page contentType="text/html" pageEncoding="UTF-8"%>

That's the JSP syntax. This makes no sense. You're using Facelets which uses UTF-8 by default already.

<meta http-equiv="content-type" content="text/html;charset=utf-8"/>

This is worthless if you're serving the page over HTTP instead of opening from local disk file system.


If you're seeing garbage, then the problem is caused by something else. I'd suggest to take some time to get yourself through this article: Unicode - How to get the characters right?

At least, the key points for JSF2/Facelets are:

  • Configure your IDE to use UTF-8.
  • Configure your DB/table to use UTF-8.
  • Properties files must be ISO-8859-1 and you have to use unicode escapes. But there's for JSF a workaround in flavor of a custom ResourceBundle so that you can use UTF-8 in properties files.
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • You might want to link to [your other answer](http://stackoverflow.com/questions/3645491/i18n-with-utf-8-encoded-properties-files-in-jsf-2-0-appliaction/3646601#3646601) for the part on custom resource bundles. – Vineet Reynolds Aug 15 '11 at 01:12
  • @Vineet: The unicode blog in turn links to http://jdevelopment.nl/internationalization-jsf-utf8-encoded-properties-files which contains the same example. – BalusC Aug 15 '11 at 02:17
  • I didn't notice that. Btw, any idea on the behavior of the runtime if one doesn't add the ru,ar, or sr locales to `faces-config.xml`, and also not use `f:loadBundle`? – Vineet Reynolds Aug 15 '11 at 02:22
  • @Vineet: JSF will ignore them. As to ``, it is not necessary thanks since the new `` element. – BalusC Aug 15 '11 at 02:30
  • @BalusC I am reading the article, and following a little code example i found here: http://jdevelopment.nl/internationalization-jsf-utf8-encoded-properties-files/ The first thing i get stuck, is that when i save the properties files as ISO-8859-1, eclipse tells me that i must save them to UTF-8. I have them currently at UTF-8 and i am trying to create a custom resource bundle following the example, but i cant manage to make the program find that bundle from faces-config.xml (My eclipse IDE is configured to UTF-8, i did that at the preferences page) – javing Aug 15 '11 at 09:40
  • @sfrj: The fact that you set encoding for properties file to UTF-8 does not change the way they are going to be interpreted by JSF. Believe or not, they are going to be read as ISO8859-1. So you'd have to actually escape them. The only thing I can suggest for you, is to install [JBoss Tools](http://marketplace.eclipse.org/content/jboss-tools-1) which have built-in editor which cares about conversion (and few other goodies for JSF world). – Paweł Dyda Aug 15 '11 at 09:58
  • Eclipse does that for every arbitrary file when you enter non-ISO-8859-1 characters in the file. Properties files are to be read as ISO-8859-1, but that encoding doesn't support Serbian/Russian/Arabic. Did you read and understand the "Properties files" part in the linked Unicode article? As to the bundle problem, well, perhaps you specified/used the wrong bundle name. Do you *understand* what the code is doing? Did you for example change `BUNDLE_NAME` variable to suit your bundle name? – BalusC Aug 15 '11 at 11:57
  • @BalusC i rode that article but i am still confused and not able to see the characters.(Only if i use unicode scape characters in the property files) I suspect that probably my BUNDLE_NAME is wrong(I updated my question)but i dont know how to configure it in the faces-config.xml – javing Aug 15 '11 at 12:31
  • Your `BUNDLE_NAME` is wrong. It should be `resources.messages`. You do not need unicode escapes when you use this custom `ResourceBundle`, just enter Unicode characters and save files as UTF-8. – BalusC Aug 15 '11 at 12:34
  • @BalusC My files are saved as UTF-8 and the `BUNDLE_NAME` is now fixed to `resources.messages` I still see garbage. I checked the russian properties file, it is well stored in Russian, but the browser displays garbage. – javing Aug 15 '11 at 12:41
  • What `Content-Type` header is been set on the response? Use Firebug to check it. It should be `text/html; charset=UTF-8`. – BalusC Aug 15 '11 at 12:50
  • @BalusC I used Firebug, but i dont find anywhere on the markup of the page that it says UTF-8. I am not sure how to check what is the Content-Type header on the response. – javing Aug 15 '11 at 12:59
  • Open Firebug, request the page, click the *Net* tab and then *HTML* tab, click the request to see details, look in *Headers* tab. – BalusC Aug 15 '11 at 13:01
  • @BalusC Ok i did as you said this are the results(I pasted an image with results above): `Response Headers:Content-Type text/html;charset=UTF-8` – javing Aug 15 '11 at 13:13
  • That can only mean that the properties files are not saved or not read as UTF-8. Given the fact that you're so confident that they're properly saved, it can only mean that they're read the wrong way. Did you **remove** any `` in your views? – BalusC Aug 15 '11 at 13:15
  • Oh, I see, your `` is wrong. It should point to `support.TextBunddle`! The key is to use the custom `ResourceBundle` instead! Do you understand it now? – BalusC Aug 15 '11 at 13:17
  • @BalusC I don't have any `f:loadBundle` tags in my views i thought i dont need them if i cofigure the `faces-config.xml` correctly – javing Aug 15 '11 at 13:19
  • @BalusC It worked, i understand now. Because i said `BUNDLE_NAME = "resources.messages"` the faces-config.xml should point to `support.TextBunddle`. Now it works fine in Arabic, Russian and Serbian as i wanted. I just noticed that a couple of french characters remain as�, Should i do something to fix that or i just write them as scape characters in unicode in the property files? – javing Aug 15 '11 at 13:26
  • Yes exactly. JSF must use the custom `ResourceBundle`, so it has to know about its base name `support.TextBunddle`. The custom `ResourceBundle` in turn must read the properties files using UTF-8, so it has to know about their base name `resources.messages`. As to the French problem, the properties file is apparently still saved as ISO-8859-1. Re-save it as UTF-8. – BalusC Aug 15 '11 at 13:27
  • @BalusC I restarted eclipse it is ok. Probably the file got modified. Now is ok. Thank you very much, this was a great help. – javing Aug 15 '11 at 13:46