【问题标题】:Internationalization in JSF, when to use message-bundle and resource-bundle?JSF 中的国际化,何时使用消息包和资源包?
【发布时间】:2025-12-24 03:35:12
【问题描述】:

我应该何时以及如何在faces-config.xml 中使用<resource-bundle><message-bundle> 标签进行本地化?这两者之间的区别对我来说不是很清楚。

【问题讨论】:

    标签: jsf localization internationalization


    【解决方案1】:

    <message-bundle> 将在您想要覆盖 JSF 验证/转换所使用的 JSF 默认警告/错误消息时使用。 您可以在JSF specification 的第 2.5.2.4 章中找到默认警告/错误消息的键。

    例如,com.example.i18n 包中的Messages_xx_XX.properties 文件如下,它会覆盖默认的required="true" 消息:

    com/example/i18n/Messages_en.properties

    javax.faces.component.UIInput.REQUIRED = {0}: This field is required
    

    com/example/i18n/Messages_nl.properties

    javax.faces.component.UIInput.REQUIRED = {0}: Dit veld is vereist
    

    可以如下配置(不带语言环境说明符_xx_XX 和文件扩展名!):

    <message-bundle>com.example.i18n.Messages</message-bundle>
    

    &lt;resource-bundle&gt; 将在您想要注册在整个 JSF 应用程序中可用的本地化资源包时使用,而无需在每个视图中指定 &lt;f:loadBundle&gt;

    例如,Text_xx_XX.properties 包中的Text_xx_XX.properties 文件如下:

    com/example/i18n/Text_en.properties

    main.title = Title of main page
    main.head1 = Top heading of main page
    main.form1.input1.label = Label of input1 of form1 of main page
    

    com/example/i18n/Text_nl.properties

    main.title = Titel van hoofd pagina
    main.head1 = Bovenste kop van hoofd pagina
    main.form1.input1.label = Label van input1 van form1 van hoofd pagina
    

    可以如下配置(不带语言环境说明符_xx_XX 和文件扩展名!):

    <resource-bundle>
        <base-name>com.example.i18n.Text</base-name>
        <var>text</var>
    </resource-bundle>
    

    并在main.xhtml中使用如下:

    <h:head>
        <title>#{text['main.title']}</title>
    </h:head>
    <h:body>
        <h1 id="head1">#{text['main.head1']}</h1>
        <h:form id="form1">
            <h:outputLabel for="input1" value="#{text['main.form1.input1.label']}" />
            <h:inputText id="input1" label="#{text['main.form1.input1.label']}" />
        </h:form>
    </h:body>
    

    ValidationMessages(JSR303 Bean 验证)

    从 Java EE 6 / JSF 2 开始,还有新的 JSR303 Bean Validation API,由 javax.validation.constraints 包的 @NotNullSize@Max 等注释表示。您应该了解此 API 与 JSF完全无关。它不是 JSF 的一部分,但 JSF 在验证阶段恰好有 支持。 IE。它确定并识别 JSR303 实现(例如 Hibernate Validator)的存在,然后将验证委托给它(顺便说一下,可以使用 &lt;f:validateBean disabled="true"/&gt; 禁用它)。

    根据JSR303 specification 的第 4.3.1.1 章,自定义 JSR303 验证消息文件需要准确名称为 ValidationMessages_xx_XX.properties,并且需要放在 root 的类路径(因此,不在包中!)。


    本地化

    在上述示例中,文件名中的_xx_XX 代表(可选)语言和国家代码。如果这完全不存在,那么它将成为默认(后备)捆绑包。如果存在语言,例如_en,然后当客户端在Accept-Language HTTP 请求标头中明确请求此语言时,将使用它。这同样适用于国家,例如_en_US_en_GB

    您可以在faces-config.xml&lt;locale-config&gt; 元素中为消息和资源包指定支持的语言环境。

    <locale-config>
        <default-locale>en</default-locale>
        <supported-locale>nl</supported-locale>
        <supported-locale>de</supported-locale>
        <supported-locale>es</supported-locale>
        <supported-locale>fr</supported-locale>
    </locale-config>
    

    需要通过&lt;f:view locale&gt; 设置所需的语言环境。另见Localization in JSF, how to remember selected locale per session instead of per request/view

    【讨论】:

    • 你好 Balus C,我们可以使用多个 以及如何从 java bean 调用它?
    • 在使用 时需要特别注意文件夹结构。如果说你在 faces-config.xml org.abc.def.messagesmsg 中有以下内容所有 message.properties、message_es.properties、message_de.properties 应仅位于“src/main/resources/org/abc/def 文件夹”中。即不要在“def”文件夹下创建“消息”文件夹。直到 'def' 是资源包所期望的,它期望找到所有 messages_xx.properties 文件。