два поля даты — одно теряет свое значение, другое работает

#jsf #datefield

#jsf #поле даты

Вопрос:

У меня есть форма с двумя полями ввода даты. Первое поле с именем DateFrom всегда теряет свое значение при перезагрузке страницы, в то время как второе поле с именем DateTo работает отлично. Когда я заполняю оба поля, оба значения передаются компоненту пользовательского интерфейса, и оба успешно используются для фильтрации представления (списка элементов). Компонент пользовательского интерфейса хранит оба значения в statusObject с областью действия сеанса.

Но после того, как страница была обновлена, только DateTo по-прежнему заполняется, в то время как DateFrom one пуст. Я добавил некоторые System.out.println() ‘s к получателям и установкам значений, чтобы посмотреть, что произойдет, и оба установщика вызываются со значением, затем оба получателя возвращают значение. Поле DateFrom просто игнорирует значение, которое оно получает от компонента пользовательского интерфейса.

Я использую поле даты, предоставляемое браузером, отсюда и a:type=»дата».

Страница выглядит так:

 <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
          "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:a="http://xmlns.jcp.org/jsf/passthrough"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:h="http://java.sun.com/jsf/html">
<h:head/>

<h:body>
  <ui:composition>

    <f:loadBundle basename="de.myapp.Resources" var="bundle"/>

<!-- Some stuff removed for readability -->

    <h:form enctype="multipart/form-data" id="filterForm">
      <div class="filterBar">
        <div class="filterElement">
          <h:inputText a:type="date" id="dateFrom" size="8" maxlength="10"
                       value="#{myBean.dateFrom}"
                       converter="dateConverter"/>
        </div>
        <div class="filterElement">
          <h:inputText a:type="date" id="dateTo" size="8" maxlength="10"
                       value="#{myBean.dateTo}"
                       converter="dateConverter"/>
        </div>
      </div>
      <div class="filterElement">
        <h:commandButton id="refreshButton"
                         action="#{myBean.refreshList}"
                         value=" #{bundle.refresh}"/>
      </div>

    </h:form>

<!-- Some more stuff removed for readability -->

  </ui:composition>
</body>
</html>
 

Я проверил, что слова DateFrom и DateTo не встречаются в тех частях страницы, которые я удалил.

Геттеры и сеттеры в компоненте пользовательского интерфейса

 public Date getDateFrom() {
  System.out.println("getDateFrom() -> "   statusObjet.getDateFrom());
  return statusObjet.getDateFrom();
}

public void setDateFrom(final Date dateFrom) {
  if (dateFrom != null) {
    System.out.println("setDateFrom( "   dateFrom   " )");
  } else  {
    System.err.println("setDateFrom( NULL )"); // my IDE shows this colored red in the console
  }
  statusObjet.setDateFrom(dateFrom);
}

public Date getDateTo() {
  System.out.println("getDateTo() -> "   statusObjet.getDateTo());
  return statusObjet.getDateTo();
}

public void setDateTo(final Date dateTo) {
  if (dateTo != null) {
    System.out.println("setDateTo( "   dateTo   " )");
  } else {
    System.err.println("setDateTo( NULL )"); // my IDE shows this colored red in the console
  }
  statusObjet.setDateTo(dateTo);
}
 

За исключением идентификатора и значения EL, оба поля идентичны. Геттеры и сеттеры также идентичны (я дважды проверил это). Фактически, весь код для DateTo является копией DateFrom, которая была изменена в редакторе после копирования (замените все в выделении).

Почему DateTo работает, а DateFrom нет?

Комментарии:

1. Я не вижу никаких очевидных проблем, которые могли бы вызвать это в опубликованном вами коде. Проблема, вероятно, в другой части кода, где вы вызываете методы getDateFrom() или setDateFrom()

2. Сначала это тоже было моим подозрением. Это одна из причин, по которой я добавил System.out.println() ‘s. Нет доступа к установщику из любой другой части кода.

Ответ №1:

Оказалось, что проблема заключалась не в поле даты, а в введенной дате (и недостатке в dateConverter):

Я всегда тестировал форму, используя 1 января и 31 декабря того же года.

Зная, что при вводе даты в браузере используется формат даты, зависящий от языка браузера, а не от языка веб-сайта, я написал dateConverter, который понимает наиболее важные форматы, все они с начальными нулями и без них для однозначных значений.
Недостаток заключался в том, что он getAsString() возвращал формат даты без начальных нулей, и браузер не понял, например, 2019-1-1.

Решение: используйте отдельный формат даты, который вводит начальные нули для getAsString() и возвращает 2019-01-01.