【问题标题】:Using Multiple Resource bundles in JSF在 JSF 中使用多个资源包
【发布时间】:2011-10-10 19:49:20
【问题描述】:

我正在尝试从 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"/>

或者任何其他访问多个资源包的最佳方式?

【问题讨论】:

  • 我在想 Spring Framework 是否有解决方案?

标签: spring jsf richfaces


【解决方案1】:

您使用 Spring 标记了您的问题,因此我建议您使用 Spring MessageSource。 Spring MessageSource 甚至可以分层聚合许多属性文件。与旧的 java ResourceBundle 相比,它为您提供了许多优势。

您可以像这样在spring-config.xml 中定义spring MessageSource

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

这里是 JSF 中的 Spring MessageSource。希望可以理解。

【讨论】:

    【解决方案2】:

    JSF 检查同一个包的多个文件的唯一情况(据我所知)是您为多个语言环境提供包(请参阅Providing Localized Messages and Labels)。

    您也许可以将f:loadBundle 标记指向扩展ResourceBundle 的类而不是属性文件,并使用该类来引用多个属性文件。不过我之前没试过。

    此外,如果您使用 Seam,它提供了注册多个“全局”包以及可以与多个视图(facelets)之一关联的包的能力,所有这些都可以使用messages 引用,例如#{messages.my_message}here 所述(这是针对Seam 2,在Seam 3 中可能略有不同)。我想这就是你所追求的。

    【讨论】:

      【解决方案3】:

      如果两个资源包包含相同的键,那么应该使用哪些资源包来解析这个键?所以,IMO,我不认为同一个变量名可以分配给多个资源包。

      也许,您可以在构建过程中将所有.properties 合并为一个.properties(确保合并的属性文件中的所有键都是唯一的,例如,通过在每个键中添加一些前缀。)。然后你在整个应用程序中使用这个单一的合并.properties

      【讨论】:

      • 这是解决方案之一,但是如果必须将应用程序模块化,并且当有很多字段时,将所有内容都放在一个属性文件中将变得笨拙且难以管理。确实必须有一个解决方案来解决这个问题。我正在尝试更多地探索如何使它工作。快速思考:Spring Framework 是否为我们提供了解决方案??
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-09
      • 1970-01-01
      • 2011-03-06
      相关资源
      最近更新 更多