【问题标题】:PrimeFaces calendar accepts invalid dates as inputPrimeFaces 日历接受无效日期作为输入
【发布时间】:2012-11-25 16:02:45
【问题描述】:

我遇到的问题是 PrimesFaces 3.4.1 日历。当使用通过按钮或输入字段焦点激活的弹出日期选择器时,您只能选择工作正常的有效日期,快乐的日子!

当您在输入字段中手动添加日期时会出现问题,如果您添加无效日期,PrimeFaces 日历组件会尽力将其转换为有效日期然后发送,这意味着后端验证是不行。下面是一些有趣的翻译:

  • 30/02/2012 变为 2/6/2014
  • 322/05/2012 变为 5/10/2038
  • 01/14/2012 变为 4/1/2012

要重现这种疯狂,请查看PrimeFaces Calendar Showcase

我已经看到了使用 readOnlyInput='true' 属性的解决方案,但这似乎只能防止在字段中输入字母,而不是数字或斜线。以下是我实施的日历的一个实例:

<p:calendar id="fldDateOfBirth"
            value="#{pc_CreateUser.user.dateOfBirth}"
            binding="#{pc_CreateUser.dobComp}"
            navigator="true"
            pattern="dd/MM/yyyy"
            maxlength="10"
            yearRange="-100"
            validator="#{pc_CreateUser.validateDOB}"
            title="#{msg.user_date_format_default_tip}"
            converterMessage="#{msg.user_error_dob_invalid}"
            readOnlyInput="true"
            showOn="button" />

明智的解决方案我愿意接受任何建议:

  1. 这是 PrimeFaces 中的常见问题吗?有什么技巧可以用来 修复它?
  2. 我可以在发送日期之前使用 JavaScript 来验证日期吗? 完全阻止所有用户输入?
  3. 还有什么我没想到的!

在此先感谢,这已经给我带来了几个星期的问题!

【问题讨论】:

    标签: java validation jsf primefaces calendar


    【解决方案1】:

    在 faces-config.xml 添加这个

    <converter>
        <converter-id>localDateConverter</converter-id>
        <converter-class>com.utility.LocalDateConverter</converter-class>
    </converter>
    

    在上面的类中,即 LocaldateConverter 添加下面的代码

    /**
     * @param facesContext .
     * @param uiComponent .
     * @param input .
     * @return Object .
     */
    @Override
    public Object getAsObject(final FacesContext facesContext, final UIComponent   uiComponent, final String input) {
        if (StringUtils.isBlank(input)) {
            return null;
        }
        final String componentPattern = (String) uiComponent.getAttributes().get("datePattern");
        final String patternToUse = componentPattern != null ? componentPattern : CommonConstants.OUTPUT_DATE_FORMAT;
        try {
            final DateFormat fmt = new SimpleDateFormat(patternToUse);
            Date convertedDate = new java.sql.Date(fmt.parse(input).getTime());
            return convertedDate;
        } catch (Exception e) {
            throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Invalid Date Format", null));
        }
    }
    
    /**
     * @param facesContext .
     * @param uiComponent .
     * @param obj .
     * @return String .
     */
    @Override
    public String getAsString(final FacesContext facesContext, final UIComponent uiComponent, final Object obj) {
        if (obj==null) {
            return null;
        }
        final Date date = (Date) obj;
        return date.toString();
    }
    

    【讨论】:

    • 这有什么帮助?你甚至不告诉他们你在做什么。您所做的只是复制当前已经标准的 jsf 日期时间转换器。
    【解决方案2】:

    &lt;p:calendar&gt; 在幕后使用 SimpleDateFormat,而 SimpleDateFormat 默认使用 lenient 解析,导致溢出的值滚动到下一个日期度量级别。例如。 1 月 32 日将变为 2 月 1 日,依此类推。

    用纯 Java 术语来说,这可以通过 DateFormat#setLenient() 关闭,传递 false。另请参阅此问题:validating a date using dateformat

    在 JSF 术语中,您基本上需要提供一个使用非宽松DateFormat 的自定义转换器。幸运的是,标准 JSF 已经以&lt;f:convertDateTime&gt; 的形式提供了这样一个开箱即用的功能,因此您可以直接使用它。

    <p:calendar ...>
        <f:convertDateTime pattern="dd/MM/yyyy" />
    </p:calendar>
    

    【讨论】:

    • 这很奏效!感谢您的解决方案和解释,非常感谢。
    • 如果使用旧版本的 primefaces 并使用此 convertDateTime 会导致转换返回 null,并且您会收到 javascript 错误。 (getDate == null)。如果您可以升级到 PF 4,那太遗憾了,我不能并且正在寻找替代方案 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-21
    • 1970-01-01
    • 1970-01-01
    • 2020-05-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多