如何在复合组件中参数化requiredMessage属性?

时间:2012-02-14 16:56:33

标签: localization jsf-2 composite-component

BalusC为有关如何为每个复合组件设置消息的问题提供了一个很好的答案。 Specifying different error messages for different composite components 答案涉及使用每个组件资源包。

我已经应用了这种方法,但是当我在消息中使用{0}来指定当前组件标签作为消息的一部分时,{0}将在我的错误中呈现,而不是被解析。当我使用这种方法时,标签的分辨率是否可用?或者我是否必须在复合组件中手动构建错误消息? e.g。

requiredMessage="#{cc.resourceBundleMap.requiredMessage} #{cc.attrs.prefix} #{cc.attrs.label}"

我想更深层次的问题是如何在资源包中设置参数化消息字符串?我是否需要构建某种自定义消息解析器?

1 个答案:

答案 0 :(得分:2)

不幸的是,requiredMessage(以及validatorMessageconverterMessage)属性默认情况下不可参数化。我认为无论如何它都没有意义,因为它们特别与特定的组件相关联。复合组件通常不包含多个相同的组件。您需要为每个组件指定单独的消息。

理论上,create a custom EL function可以进行消息格式化工作。该方法看起来像这样:

public static String format(String message, Object argument1, Object argument2) {
    return MessageFormat.format(message, argument1, argument2);
}

将使用这样的东西:

requiredMessage="#{util:format(cc.resourceBundleMap.requiredMessage, cc.attrs.prefix, cc.attrs.label)}"

唯一的缺点是你不能创建可以采用varargs的EL函数。这是EL规范的限制。因此,如果您打算能够传递变量参数,则需要为所需的每个参数创建单独的EL函数和Java方法。

作为一种完全不同的替代方法,您可以创建自定义Validator并将其附加到特定输入组件。您甚至可以将验证器方法直接放在与<cc:interface componentType>复合组件关联的“后备组件”中。如果删除required属性,则会立即调用此验证程序,您可以自由地按照自己的方式撰写邮件。

E.g。

<h:inputText id="foo" validator="#{cc.validateFoo}" requiredMessage="#{cc.resourceBundleMap.requiredMessage}" />

public void validateFoo(FacesContext context, UIComponent component, Object value) {
    if (value == null || value.toString().trim().isEmpty()) {
        String requiredMessage = (String) component.getAttributes().get("requiredMessage");
        String prefix = (String) getAttributes().get("prefix");
        String label = (String) getAttributes().get("label");
        throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR,
            MessageFormat.format(requiredMessage, prefix, label), null));
    }
}