Локализация с использованием языка хинди в JSF 2.0

Я использую этот английский в хинди конвертер Unicode. Полученный код помещается в MessageBundle_hi_IN.properties файл.

Когда ограничение нарушается как обязательное текстовое поле. Соответствующее сообщение об ошибке должно быть взято из этого файла и отображено на языке хинди, но оно отображает тот же Unicode, что и в файле, без преобразования, например,

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

Ожидается, что будет показано на хинди, как.

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

Это означает, что "нельзя оставлять пустым".


Страница XHTML.

<?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>

Соответствующий управляемый компонент.

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);
    }
}

Файл face-config.xml.

<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>

Это работает в JSP что-то вроде,

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

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

Что здесь не так? Я использую неправильный конвертер? Этот язык не поддерживается JSF?

1 ответ

Решение

Это,

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

это HTML-экранированная форма хинди. В рамках встроенной функции предотвращения XSS-атак JSF любой выходной текст неявно экранируется от HTML. Таким образом, этот HTML-экранированный хинди заканчивается двойным экранированием в сгенерированном HTML следующим образом (щелкните правой кнопкой мыши по View Source, чтобы увидеть его самостоятельно):

&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;

Это приводит к тому, что он появляется в исходном HTML-экранированном виде после интерпретации веб-браузером.

В конце концов, используя HTML-экранированную форму &#XXXX; в .properties файл не правильный подход. Вы должны использовать Unicode-экранированную форму \uXXXX вместо. Смотрите также Javadocjava.util.Properties, Немного приличная IDE, такая как Eclipse, уже делает это автоматически, когда вы редактируете файл с .properties расширение в Java-проекте. Вы можете просто напечатать хинди там обычным способом, и Eclipse автоматически избавится от него. Однако, если вы используете другой редактор, или если вы не можете понять, как правильно настроить редактор, вам нужно будет использовать предоставленный JDK native2ascii инструмент. Снова, смотрите вышеупомянутый Javadoc для деталей.

В конечном счете, правильная форма вашего хинди с экранированием в Юникоде выглядит следующим образом (я скопировал после того, как Eclipse избежал его):

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

Поместите это в ваш .properties файл.

То, что он работает в унаследованной JSP, объясняется просто тем, что он является довольно устаревшей и неэффективной технологией представления, не имеет формы неявного предотвращения атак XSS и, следовательно, не скрывает HTML-текст любого шаблона.


Вне зависимости от конкретной проблемы, для случая, когда вы еще этого не знали, вы также можете просто написать хинди прямо в исходный код файла Facelets. Вам нужно только убедиться, что ваш редактор настроен на использование UTF-8 для сохранения текстовых файлов. Конвертер, который вы нашли, абсолютно бесполезен для современной разработки JSF.

Другие вопросы по тегам