Primefaces“required”属性错误:如何修复它?

时间:2017-11-29 20:24:02

标签: jsf primefaces

我被这个错误吓到了:

我有以下字段

<p:selectOneMenu id="selectOption"
        required="true"
        requiredMessage="#{bundle.mandatory_field_message}"
        rendered="#{myBean.previousOptionSelected eq 'Correct Option'}"
        value="#{myBean.selectedOption}">
    <c:if test="#{myBean.optionsList.size() ne 1}">
        <f:selectItem itemLabel="#{bundle.default_select}" itemValue="null" />
    </c:if>
    <f:selectItems value="#{myBean.optionsList}" var="opt"
            itemValue="#{opt}" itemLabel="#{opt.description}" />
    <f:ajax event="change" render="msgSelectOption" />
</p:selectOneMenu>
<p:messages id="msgSelectOption" for="selectOption" display="text" />

当我尝试提交包含此字段的表单时,即使选择了一个值并且实际上正确分配了bean中的值,也会显示requiredMessage

我目前正在使用带有jsf 2.0的primefaces 5.3(不能:无法升级)

1 个答案:

答案 0 :(得分:0)

我几乎找到了答案here,但我仍会在这篇文章中解释,因为参考答案没有直接解决这个问题:

代码示例中使用的对象似乎没有经历任何类型的转换。虽然我之前可以使用没有转换器的对象,但它们实际上是enum而这个不是。因此,似乎任何时候我需要一个不是枚举的自定义对象,我需要为它创建一个转换器(手动将数据序列化为字符串或只是使用id并从可能的对象列表中恢复数据)

这对我有用:

<p:selectOneMenu id="selectOption"
        converter="optionConverter"
        required="true"
        requiredMessage="#{bundle.mandatory_field_message}"
        rendered="#{myBean.previousOptionSelected eq 'Correct Option'}"
        value="#{myBean.selectedOption}">
    <c:if test="#{myBean.optionsList.size() ne 1}">
        <f:selectItem itemLabel="#{bundle.default_select}" itemValue="" />
    </c:if>
    <f:selectItems value="#{myBean.optionsList}" var="opt"
            itemValue="#{opt}" itemLabel="#{opt.description}" />
    <f:ajax event="change" render="msgSelectOption" />
</p:selectOneMenu>
<p:messages id="msgSelectOption" for="selectOption" display="text" />

使用以下转换器:

@FacesConverter(forClass = myPackage.OptionClass.class, value="optionconverter")
public class OptionConverter implements Converter{

    public Object getAsObject(FacesContext facesContext, UIComponent component, String submittedValue) {
        if (submittedValue != null && !submittedValue.trim().equals("")) {
            for (OptionClass opt : OptionListingService.getEntries()) {
                if (submittedValue.equalsIgnoreCase(opt.getUniqueID())) {
                    return opt;
                }
            }
        }
        return null;
    }

    public String getAsString(FacesContext facesContext, UIComponent component, Object value) {
        if (value == null || value.equals("")) {
            return "";
        } else {
            return ((OptionClass)value).getUniqueID();
        }
    }
}

另请注意,我在此项目中将itemValue="null"的值更改为itemValue=""

<f:selectItem itemLabel="#{bundle.default_select}" itemValue="" />

这是必要的,因为转换器会将值解释为String,因此会尝试转换id等于"null"的字符串值。代码仍然有效,但我喜欢(并且这也是一个更好的实践)尽可能干净地操作数据。

感谢 Dusan Kovacevic 指出可能的转换器问题。