JSF getValue () v.s. getSubmittedValue () - PullRequest
       9

JSF getValue () v.s. getSubmittedValue ()

17 голосов
/ 04 ноября 2008

В последнее время я разрабатывал несколько приложений JSF, и меня беспокоит несогласованность API-интерфейсов веб-компонентов.

Я заметил, что существует крайне непредсказуемое поведение при вызове .getValue () или .getSubmittedValue () для объекта компонента JSF в коде на стороне сервера. Иногда, когда я вызываю .getValue () в раскрывающемся списке, я замечаю, что получаю значение таким, каким оно было, ДО того, как я выбрал свое значение (таким образом, значение из последнего обновления страницы), из которого .getSubmittedValue () получает мне правильное значение, как таковое:

UIInput name = new UIInput(); // This is the control I have in a bean.

public void submit(ActionEvent ae)
{
    someMethod(name.getValue().toString());          // Retrieves the "old" value
    someMethod(name.getSubmittedValue().toString()); // Retrieves the correct value 
}

Кроме того, я заметил, что вызов .getSubmittedValue () для поля формы иногда приводит к исключению нулевого указателя, потому что это значение не было создано в объекте компонента, и в этом случае, когда я вызываю .getValue () в этом В случае, если я получаю правильное значение, например:

HtmlInputText name = new HtmlInputText(); // This is the control I have in a bean.

public void submit(ActionEvent ae)
{
    someMethod(name.getValue().toString());          // Retrieves the correct value
    someMethod(name.getSubmittedValue().toString()); // Throws NullPointerException 
}

Это просто "изюминка" инфраструктуры JSF или я просто неправильно использую API ПОЛНОСТЬЮ ?? Любое понимание этих двух методов будет с благодарностью. Приветствия.

Ответы [ 4 ]

29 голосов
/ 18 июля 2009

Так как это результат # 1 в Google для поиска по getValue по сравнению с getSubmittedValue, я просто хотел бы добавить, что разница между ними имеет решающее значение при проверке (т. Е. При написании собственного валидатора)

Чтобы процитировать документацию API для getSubmittedValue ():

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

Источник: http://myfaces.apache.org/core11/myfaces-api/apidocs/javax/faces/component/UIInput.html#getSubmittedValue()

Это означает, что если проверка / преобразование было выполнено для привязки, к которой вы пытаетесь получить доступ, вы должны вызвать getValue (), в противном случае вам придется вызывать getSubmittedValue () и самостоятельно разбирать ее. Порядок, в котором они происходят, похоже, определяется их порядком в пользовательском интерфейсе, но я не думаю, что это гарантировано. Даже если это так, вы не должны рассчитывать на это, так как изменение поля в вашем пользовательском интерфейсе не должно нарушать ваш код.

Вы можете определить, была ли выполнена проверка / преобразование, просто посмотрев, что возвращает isLocalValueSet (). Если он возвращает true, тогда проверка / преобразование выполнено, поэтому вам следует вызвать getValue (). В противном случае вам нужно вызвать getSubmittedValue (), и это даст вам необработанный ввод, введенный пользователем, и вы, вероятно, захотите проанализировать его во что-то более осмысленное.

Например, объект календаря будет возвращать объект Date при вызове getValue (), но объект String при вызове getSubmittedValue (). Ваш конвертер должен проанализировать строку в Date, чтобы ее можно было проверить.

Было бы замечательно, если бы в спецификации JSF был метод, который сделал бы это для нас, но AFAIK - нет. Если определенные даты должны быть раньше других, а некоторые требуются только при определенных обстоятельствах, для этого потребуется написать несколько валидаторов. Так что это может легко стать проблемой. Это похоже на то, что вы не можете выполнять какую-либо проверку пустого поля, а это значит, что вы не можете сделать это поле обязательным условием. Если проверка была выполнена для всех полей, даже пустых, можно было бы написать специальный валидатор, чтобы вызвать исключение, если оно требуется и не требуется. Есть некоторые вещи с JSF, которые просто боль; если / пока они не исправлены, мы просто должны иметь с ними дело.

Чтобы поговорить со спецификой вопроса в оригинальном сообщении: разница здесь в том, где вы находитесь в жизненном цикле. Метод submit выглядит как слушатель действия для кнопки, которая ставит ее в конце жизненного цикла; действия и прослушиватели действий запускаются на этапе «Вызвать приложение», который предшествует ответу рендеринга, но после проверки. Если вы собираетесь программировать в JSF, вы должны изучить и понять жизненный цикл. Это стоит времени.

5 голосов
/ 04 ноября 2008

Цитировать документацию по EditableValueHolder.getSubmittedValue :

Возвращает значение submitValue, равное этот компонент. Этот метод должен использоваться только функцией encodeBegin () и / или методы encodeEnd () этого компонент или его соответствующий Renderer.

Как правило, вы даже не будете звонить getValue . Вместо этого атрибут value компонента должен быть привязан к вашей модели (возможно, компоненту). Ваша бизнес-логика будет взаимодействовать с моделью, а не с компонентом.

Если отправленное значение не устанавливается в качестве значения, то я предполагаю, что некоторая проверка не пройдена. Единственная проблема в том, что ваше мероприятие проводится. Два предположения о проблеме здесь:

  • У вас устаревшая ссылка на объект компонента.
  • Вы установили атрибут немедленный для UICommand , что означает, что событие происходит в фазе, когда компонент находится в неподходящем состоянии.

С предоставленной информацией невозможно быть уверенным.

0 голосов
/ 11 октября 2017

TL; DR ответ:

UIViewRoot viewRoot = context.getViewRoot();
UIInput input = (UIInput)viewRoot.findComponent(":form:inputID");

String inputValueString;

if (input.isLocalValueSet()) {
  inputValueString = (String)input.getValue(); //validated and converted already
} else {
  inputValueString = (String)input.getSubmittedValue(); //raw input
}

или, по крайней мере, так говорят другие ответы ...

Просто используйте .getSubmittedValue() и разберитесь с последствиями необходимости конвертировать необработанный ввод (если необходимо, если этот необработанный ввод требует преобразования). .getValue() не работает в этом отношении, даже с кодом выше. Он задерживает отправленное значение, если вы его используете, и это недопустимо.

0 голосов
/ 07 августа 2014

Я работаю на xpages, которые основаны на JSF, так что ... это может быть то же самое ...

В любом случае, getSubmittedValue (); всегда возвращает то, что вы видите на вкладке сети firebug / chrome develepers. Это значение в отправленном пакете. Я показал (chrome) на вкладке заголовков, в разделе данных формы, с именем $$ xspsubmitvalue.

С другой стороны, getValue () зависит от компонента. <- не уверен на 100%. </p>

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...