У меня есть приложение JSF 2.2, где пользователь должен вводить значения BigDecimal
в <h:inputText>
. Для такого входного поля a valueChangeListener
сконфигурирован для вызова изменений ввода. Вот код XHTML:
<h:form id="theForm">
<h:inputText id="bd" value="#{bean.bd}"
valueChangeListener="#{bean.bdChangedListener()}"/>
<h:commandButton id="submit" value="Submit" />
</h:form>
В большинстве случаев это нормально. Вызывается метод bdChangedListener()
, когда значение изменено и нажата кнопка отправки. Значение верно передано модели.
Однако, если я ввел 1.1
и изменил его на 1.10
, новое значение будет привязано к модели, но valueChangeListener
никогда не называется! Отладка показала, что причина этого в javax.faces.component.UIInput#compareValues()
. JavaDoc из
этот метод говорит:
Возвращает true, если новое значение отличается от предыдущего. Сначала сравните два значения, передав значение методу equals на аргумент предыдущий. Если этот метод возвращает true, верните true. Если это метод возвращает false, и оба аргумента реализуют java.lang.Comparable, сравните два значения, передав значение в compareTo метод по аргументу previous. Возвращает true, если этот метод возвращает 0, false в противном случае.
Мне кажется, это намеренно. Но почему?
Пользовательский ввод изменился, и есть приложения, в которых важна шкала BigDecimal
. Поэтому JSF не должен просто игнорировать измененный ввод, но уведомлять меня! Он обновляет модель с новым значением, почему она пропускает метод valueChangeListener?
Как я мог избежать этого поведения и получать уведомление в чистом виде? (Я знаю, что могу подключиться к сеттерам, но это не то, что я называю чистым способом!)
Любые идеи?
Дальнейшее чтение и комментарии
В дополнение к вышеизложенному я хочу упомянуть, что я уже читал такие вопросы, как BigDecimal equals() и compareTo(). Я понимаю, почему BigDecimal equals()
и compareTo()
ведут себя так, как они, и я бы сказал, что это правильно. Поведение BigDecimal не является проблемой, проблема UIInput.compareValues()
.
Также конвертер (как предлагается в комментариях или уже удаленных ответах) не сохранит мой день. Вход пользователя правильно преобразован, и мне нужен BidDecimal, включая точный масштаб в моем приложении. Любой конвертер, возвращающий BigDecimal, не изменит наблюдаемое поведение.
Класс оболочки вокруг BigDecimal может решить мою проблему, но это не то, что я считаю чистым решением. Я действительно хочу знать, почему UIInput ведет себя так, как это делает.