Календарь PrimeFaces принимает недопустимые даты в качестве входных данных

проблема у меня с PrimesFaces 3.4.1 календарь. При использовании всплывающего выбора даты активируется либо через кнопку или на поле ввода фокус вы можете выбрать только действительные даты, которые работают хорошо, счастливые дни!

проблемы возникают, когда вы вручную добавляете дату в поле ввода, если вы добавляете недопустимую дату, компонент календаря PrimeFaces лучше всего догадывается о преобразовании этого в допустимую дату, а затем отправляет ее, что означает, что внутренняя проверка-нет идти. Некоторые интересные переводы ниже:

  • 30/02/2012 становится 2/6/2014
  • 322/05/2012 становится 5/10/2038
  • 01/14/2012 становится 4/1/2012

чтобы воссоздать это безумие, посмотрите на Витрина Календаря PrimeFaces.

Я видел варианты с помощью 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. ничего я не подумал!

заранее спасибо, это вызывает у меня проблемы в течение нескольких недель!

2 ответов


на <p:calendar> использует под одеялом SimpleDateFormat который в свою очередь использует по умолчанию мягкого синтаксический анализ, в результате чего переполненные значения перекатываются на следующий уровень метрики даты. Например. 32 января станет 1 февраля и т. д.

в простых терминах Java это можно отключить с помощью DateFormat#setLenient(), передает false. См. Также среди прочих этот вопрос:проверка даты с помощью параметра dateformat.

в терминах JSF вы в основном нужно предоставить пользовательский конвертер, который использует non-lenient DateFormat. К счастью, стандартный JSF уже предоставляет такую коробку во вкусе <f:convertDateTime>, так что вы можете просто использовать его напрямую.

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

в faces-config.xml добавить это

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

в вышеуказанном классе i.e 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();
}