Domanda

I'm using this English to Hindi Unicode converter. The code produced is placed in the MessageBundle_hi_IN.properties file.

When a constraint is violated like a mandatory text field. A corresponding error message should be picked up from this file and displayed in Hindi language but it displays the same Unicode as in the file without any conversion like,

खालि नहि रख शकते.

It is expected to be shown in Hindi like.

खालि नहि रख शकते.

It means "Cannot be left blank."


The XHTML page.

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html lang="#{localeBean.language}"
      xmlns="http://www.w3.org/1999/xhtml"      
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:p="http://primefaces.org/ui"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:f="http://java.sun.com/jsf/core">

        <f:view locale="#{localeBean.locale}">

        <h:head>
            <title>Title</title>
        </h:head>

        <h:body>                

            <h:form>
                <h:selectOneMenu id="languages" value="#{localeBean.language}" onchange="submit();" style="position: absolute; right: 0; top: 50px;">
                    <f:selectItem itemValue="en" itemLabel="English" />
                    <f:selectItem itemValue="hi" itemLabel="Hindi" />
                </h:selectOneMenu>
            </h:form>

        </h:body>
    </f:view>
</html>

The corresponding managed bean.

package admin.mangedbean;

import java.io.Serializable;
import java.util.Locale;
import javax.annotation.PostConstruct;
import javax.faces.context.FacesContext;

@ManagedBean
@SessionScoped
public final class LocaleBean implements Serializable
{
    private Locale locale;
    private static final long serialVersionUID = 1L;

    public LocaleBean() {}

    @PostConstruct
    private void init()
    {
        locale = FacesContext.getCurrentInstance().getViewRoot().getLocale();
    }

    public Locale getLocale()
    {
        return locale;
    }

    public String getLanguage()
    {
        return locale.getLanguage();
    }

    public void setLanguage(String language)
    {
        if(language.equals("hi"))
        {
            locale = new Locale(language, "IN");
        }
        else
        {
            locale = new Locale(language);
        }

        FacesContext.getCurrentInstance().getViewRoot().setLocale(locale);
    }
}

The faces-config.xml file.

<application>
    <message-bundle>
        messages.MessageBundle
    </message-bundle>

    <locale-config>
        <default-locale>en</default-locale>
        <supported-locale>hi_IN</supported-locale>
    </locale-config>

    <resource-bundle>
        <base-name>messages.ResourceBundle</base-name>
        <var>messages</var>
    </resource-bundle>
</application>

This works in JSP something like,

<fmt:setLocale value="hi_IN"/>
<fmt:setBundle basename="bundles.resourceBundle_hi_IN" var="resourceBundle"/> 

<fmt:message key="someKey" bundle="${resourceBundle}"/>

What is going wrong here? Am I using a wrong converter? Is this language not supported by JSF?

È stato utile?

Soluzione

This,

&#2326;&#2366;&#2354;&#2367; &#2344;&#2361;&#2367; &#2352;&#2326; &#2358;&#2325;&#2340;&#2375;&#46;

is the HTML-escaped form of Hindi. As part of JSF's builtin XSS-attack prevention, any output text is implicitly HTML-escaped. So, effectively, this HTML-escaped Hindi ends up double-escaped in generated HTML as follows (rightclick, View Source to see it yourself):

&amp;#2326;&amp;#2366;&amp;#2354;&amp;#2367; &amp;#2344;&amp;#2361;&amp;#2367; &amp;#2352;&amp;#2326; &amp;#2358;&amp;#2325;&amp;#2340;&amp;#2375;&amp;#46;

Which causes it to appear in its original HTML-escaped form once interpreted by the webbrowser.

After all, using HTML-escaped form &#XXXX; in a .properties file is not the right approach. You should use Unicode-escaped form \uXXXX instead. See also the javadoc of java.util.Properties. A bit decent IDE like Eclipse already does it automatically when you edit a file with .properties extension in a Java-flavored project. You can just type out Hindi in there the usual way and Eclipse will automagically escape it. If you're however using a different editor, or if you can't figure how to configure the editor right, then you'd need to use the JDK-provided native2ascii tool. Again, see the aforelinked Javadoc for detail.

Ultimately, the proper Unicode-escaped form of your Hindi looks like this (I copypasted after Eclipse escaped it):

\u0916\u093E\u0932\u093F \u0928\u0939\u093F \u0930\u0916 \u0936\u0915\u0924\u0947.

Put this unmodified in your .properties file.

That it works in legacy JSP is simply because it has as being a rather legacy and inferior view technology no form of implicit XSS attack prevention and therefore doesn't HTML-escape any template text.


Unrelated to the concrete problem, for the case you didn't already knew it, you can also just write Hindi straight in the source code of a Facelets file. You only need to make sure that your editor is configured to use UTF-8 to save text files. The converter you found is absolutely useless for modern JSF development.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top