来自f:datetimeConverter的“验证错误:值无效”错误

时间:2011-03-23 14:23:34

标签: validation date jsf jsf-2 selectoneradio

以下代码创建了两个单选按钮。每个选项都包含一个日期值,该值已成功转换为格式为“yyyy-MM-dd”的标签。一旦我做出选择并单击下一个按钮,我得到以下错误“j_idt12:comDateChoice:验证错误:值无效”。这似乎很简单,但有些事情是错误的。你们有人发现它吗?

我在glassfish中使用JSF 2.0。

支持bean

public List<SelectItem> getComDateList() {
    List<SelectItem> items = new ArrayList<SelectItem>();
    Calendar cal = GregorianCalendar.getInstance();
    cal.set(Calendar.DAY_OF_MONTH, 1);
    cal.add(Calendar.MONTH, 1);
    Date nextFirst = cal.getTime();
    cal.add(Calendar.MONTH, 1);
    Date followingFirst = cal.getTime();
    items.add(new SelectItem(nextFirst, new SimpleDateFormat("yyyy-MM-dd").format(nextFirst)));
    items.add(new SelectItem(followingFirst, new SimpleDateFormat("yyyy-MM-dd").format(followingFirst)));
    return items;
}

JSF代码

<h:panelGrid columns="2">
                    <h:outputLabel value="#{msg.FinanceCommencementDate}" for="comDateChoice"/>
                    <h:selectOneRadio id="comDateChoice" value="#{signUpBean.current.commencementDate}" layout="pageDirection">
                        <f:convertDateTime type="date" dateStyle="short"/>
                        <f:selectItems  value="#{signUpBean.comDateList}"/>
                    </h:selectOneRadio>
                </h:panelGrid>

1 个答案:

答案 0 :(得分:3)

如果所选项目值未通过任何可用选择项目值的Object#equals()检查,则会发生此错误。如果getter在表单提交请求的应用请求值阶段返回了与显示表单的初始请求期间不同的列表,则会发生这种情况。

因为您正在重构getter中的列表而不是在视图范围bean的构造函数中构造一次,所以Date对象将在每次调用时获得不同的时间戳,它将是几分钟/秒与初始Date对象相比,未来。因此equals()将失败。

将此逻辑移动到bean的构造函数中并重写getter,以便它执行它应该执行的操作:仅返回数据。不要在getter中加载逻辑。您还应该将bean放在视图范围中,以便在提交表单时不会重新运行构造函数。

@ManagedBean
@ViewScoped
public class SignUpBean {

    private List<SelectItem> comDateList;

    public SignUpBean() {
        comDateList = new ArrayList<SelectItem>();
        // Fill it here.
    }

    public List<SelectItem> getComDateList() {
        return comDateList; // In getters, do nothing else than returning data!
    }

}

更新:转换器也是问题的潜在根源。您基本上已经指示它在渲染HTML页面时剥离时间。因此,它会在转换回Date时使用默认时间。使用

<f:convertDateTime pattern="yyyy-MM-dd HH:mm:ss.SSS Z" />

或预先重置Calendar上的时间和时区:

cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
cal.setTimeZone(TimeZone.getTimeZone("GMT"));

这样您就可以只使用<f:convertDateTime type="date" />