Using Multiple Resource bundles in JSF

生来就可爱ヽ(ⅴ<●) 提交于 2019-12-18 12:34:21

问题


I am trying to access multiple resource bundles from a JSF page. I have two resource bundles:

  • general_messages.properties
  • module_message.properties

I want to access both these resource bundles in a JSF file. One way I can do this is to define specific properties for each of these bundles:

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

Is there a way I can access both these resource bundles using the same variable name. Something like:

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

Or any other best way to access multiple resource bundles?


回答1:


You tagged your question with Spring, so I recommend you using Spring MessageSource. Spring MessageSource can aggregate many property files even hierarchically. It gives you many advantages over old java ResourceBundle.

You can define spring MessageSource in you spring-config.xml like this:

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

Than you can define your Class which extends ResourceBundle like this (Needs some cleaning and refactoring):

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 in faces-config.xml declare your resource bundle with Class above. Something like this:

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

Here you go Spring MessageSource in JSF. Hope it's understandable.




回答2:


If two resource bundles contain the same key , then which resource bundles should be used to resolve this key ? So ,IMO ,I don't think the same variable name can be assigned to multiple resource bundles.

Perhaps , you can merge all the .properties into a single .properties in your build process (make sure all keys in the merged properties file is unique , for example , by adding some prefix in each key.) . Then you use this single merged .properties throughout the application.




回答3:


The only situation (that I know of) in which JSF checks multiple files for the same bundle is if you are providing bundles for multiple locales (see Providing Localized Messages and Labels).

You might be able to point the f:loadBundle tag to a class that extends ResourceBundle instead of a properties file and use that class to reference multiple properties files. I haven't tried that before though.

Also, if you are using Seam, it provides the ability to register multiple 'global' bundles as well as bundles that can be associated with one of more views (facelets), all of which can be referenced using messages e.g. #{messages.my_message} as described here (that's for Seam 2, it may be a little different in Seam 3). I think that's what you're after though.



来源:https://stackoverflow.com/questions/6786618/using-multiple-resource-bundles-in-jsf

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!