Использование нескольких ресурсных пакетов в JSF - PullRequest
7 голосов
/ 22 июля 2011

Я пытаюсь получить доступ к нескольким пакетам ресурсов со страницы JSF.У меня есть два пакета ресурсов:

  • general_messages.properties
  • module_message.properties

Я хочу получить доступ к обоим этим пакетам ресурсов в файле JSF.Один из способов сделать это - определить конкретные свойства для каждого из этих пакетов:

<f:loadBundle basename="com.sample.general_messages" var="general"/>
<f:loadBundle basename="com.sample.module_message" var="module"/>

Есть ли способ получить доступ к обоим пакетам ресурсов, используя одно и то же имя переменной.Что-то вроде:

<f:loadBundle basename="com.sample.general_messages, com.sample.module_message" var="general"/>

Или любой другой лучший способ получить доступ к нескольким пакетам ресурсов?

Ответы [ 3 ]

5 голосов
/ 15 октября 2012

Вы отметили свой вопрос в Spring, поэтому я рекомендую использовать Spring MessageSource.Spring MessageSource может объединять многие файлы свойств даже в иерархическом порядке.Это дает вам много преимуществ по сравнению со старой Java ResourceBundle.

Вы можете определить пружину MessageSource в вас spring-config.xml следующим образом:

<!--
Application messages configuration.
-->
<bean id="messageSource" name="resourceBundle"
    class="org.springframework.context.support.ReloadableResourceBundleMessageSource"
    p:fallbackToSystemLocale="false"
    p:cacheSeconds="0">
    <property name="basenames">
        <list>
            <value>/messages/Messages</value>
<!--        <value>${application.messages}</value>-->
        </list>
    </property>
</bean>

Чем вы можете определить свой Classкоторый расширяет ResourceBundle следующим образом (нуждается в некоторой очистке и рефакторинге):

public class SpringResourceBundle extends ResourceBundle
{

    private MessageSource messages;
    private FacesContext fc;
    private Locale locale = null;

    public SpringResourceBundle()
    {
        fc = FacesContext.getCurrentInstance();
        WebApplicationContext webAppCtx = (WebApplicationContext) fc.getExternalContext().getApplicationMap().get(
                WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
        messages = (MessageSource) webAppCtx.getBean("messageSource");
    }

    @Override
    public Locale getLocale()
    {
        Locale loc = fc.getELContext().getLocale();
        if (fc.getExternalContext() != null) {
            loc = fc.getExternalContext().getRequestLocale();
        }
        try {
            UIViewRoot viewRoot = fc.getViewRoot();
            if (viewRoot != null) {
                loc = viewRoot.getLocale();
            }
            if (loc == null) {
                loc = fc.getApplication().getDefaultLocale();
            }

        } catch (Throwable th) {
            System.out.println(th.getMessage());
            loc = locale;
        }
        locale = loc;
        return loc;
    }

    @Override
    protected Object handleGetObject(String key)
    {
        try {
            return messages.getMessage(key, null, getLocale());
        } catch (NoSuchMessageException e) {
            return "???" + key + "???";
        }
    }

    @Override
    public Enumeration<String> getKeys()
    {
        return Collections.enumeration(Collections.EMPTY_LIST);
    }
}

Finnaly в faces-config.xml объявляет ваш пакет ресурсов с классом выше.Примерно так:

<application>
    <locale-config>
       <default-locale>en</default-locale>
       <supported-locale>cs</supported-locale>
       <supported-locale>de</supported-locale>
       <supported-locale>en</supported-locale>
    </locale-config>
    <message-bundle>your.package.SpringResourceBundle</message-bundle>
</application>

Вот вам Spring SpringSource в JSF.Надеюсь, это понятно.

0 голосов
/ 24 июля 2011

Единственная ситуация (о которой я знаю), в которой JSF проверяет несколько файлов на один и тот же пакет, - это если вы предоставляете пакеты для нескольких локалей (см. Предоставление локализованных сообщений и меток ).

Возможно, вы сможете указать тег f:loadBundle на класс, который расширяет ResourceBundle вместо файла свойств, и использовать этот класс для ссылки на несколько файлов свойств.Хотя я не пробовал этого раньше.

Кроме того, если вы используете Seam, он предоставляет возможность зарегистрировать несколько «глобальных» пакетов, а также пакетов, которые могут быть связаны с одним из нескольких представлений (facelets).на все это можно ссылаться, используя messages например #{messages.my_message}, как описано здесь (это для шва 2, в шве 3 он может немного отличаться).Я думаю, это то, что вы после того, как.

0 голосов
/ 23 июля 2011

Если два пакета ресурсов содержат один и тот же ключ, то какие пакеты ресурсов следует использовать для разрешения этого ключа? Итак, IMO, я не думаю, что одно и то же имя переменной может быть назначено нескольким пакетам ресурсов.

Возможно, вы можете объединить все .properties в один .properties в процессе сборки (убедитесь, что все ключи в объединенном файле свойств уникальны, например, добавив некоторый префикс в каждый ключ.). Затем вы используете это единственное объединенное .properties во всем приложении.

...