Как удалить FacesMessages из FacesContext?

На моем экране у меня есть раскрывающийся список (выбрать поле), при выборе любого из вариантов в этом раскрывающемся списке, я показываю одно или несколько текстовых полей рядом с полем выбора, используя javascript/css - display: none и display: блок. Все эти элементы ввода находятся в одной и той же форме jsf. Каждый из элементов управления ввода имеет свой собственный валидатор. Проблема заключается в том, что пользователь выбирает параметр1 из поля выбора и не вводит значение или вводит неправильное значение для inputbox1, я добавляю пользовательский FacesMessage в Validator и отображается соответствующим образом, и предположим, что пользователь второй раз выбирает опцию2 и вводит неправильное значение для inputbox2, то в валидаторе добавляется еще один FacesMessage. Но Теперь обе сообщения отображаются - означает - сообщение для inputbox1 и inputbox2 - что неверно. Мое предположение состоит в том, что это происходит потому, что они существуют в одной и той же форме, и их экземпляры еще не уничтожены в FacesContext и в UIView. Я решил удалить сообщения таким образом

Iterator<FacesMessage> msgIterator = FacesContext.getCurrentInstance().getMessages();
    while(msgIterator.hasNext())
    {
        msgIterator.next();
        msgIterator.remove();
    }

Но это иногда дает java.util.NoSuchElementException org.apache.myfaces.shared_impl.renderkit.html.HtmlMessagesRendererBase $MessagesIterator.next

Итак, 2 вопроса:

1) В чем проблема при удалении FacesMessages таким образом? Я использую myfaces-api-1.2.3.jar и myfaces-impl-1.2.3.jar

2) Есть ли лучший подход для обработки моего сценария? Я хочу показывать релевантные сообщения каждый раз, когда обрабатывается запрос jsf.

Спасибо

Ответ 1

Проблема заключалась не в том, что я не смог удалить сообщения из FacesContext. Проблема заключалась в том, что каждый раз, когда была отправлена ​​форма, было мало элементов управления вводами (которые не отображались с использованием display: none), которые сохраняли некоторые значения(), поэтому код Validators and Backing Bean добавил FacesMessages для этих невидимых элементов управления вводом в FacesContext. Теперь, каждый раз, когда был выбран параметр select, я очистил другие поля формы, которые не были необходимы, и поэтому сообщения не добавляются.

Ответ 2

Насколько мне известно, этого недостаточно, поскольку в

org.apache.myfaces.context.servlet.FacesContextImpl

(версия: 2.0.15, редакция: 1364593), есть 2 списка сообщений (_orderedMessages и _messages), и ваш метод очищает только _orderedMessages.

Чтобы очистить _messages, выполните следующие действия:

Iterator<String> itIds = FacesContext.getCurrentInstance().getClientIdsWithMessages();
while (itIds.hasNext()) {
    List<FacesMessage> messageList = FacesContext.getCurrentInstance().getMessageList(itIds.next());
    if (!messageList.isEmpty()) { // if empty, it will be unmodifiable and throw UnsupportedOperationException...
        messageList.clear();
    }
}

Также обратите внимание, что это очень хрупко, поскольку он зависит от деталей реализации, но я не мог найти лучшего способа: (

Ответ 3

Я не использую MyFaces, поэтому я не могу подробно останавливаться на этом, но в Sun RI (Mojarra) ошибка неустранимых граней была исправлена ​​в версии 1.2_07 около 1,5 лет назад.

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

Ответ 4

FacesContext context = FacesContext.getCurrentInstance();
Iterator<FacesMessage> it = context.getMessages();
while ( it.hasNext() ) {
    it.next();
    it.remove();
}

Ответ 5

if (FacesContext.getCurrentInstance().getMessages() != null) {
        FacesContext.getCurrentInstance().getMessages().remove();
    }