Интересный случай. Для всех это воспроизводит следующий минимальный код:
Лицевая панель:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
>
<f:metadata>
<f:viewParam id="id" name="id" value="#{viewParamBean.id}"/>
</f:metadata>
<h:body>
<h:messages />
#{viewParamBean.id} <br/>
<h:form>
<h:inputText value="#{viewParamBean.text}" >
<f:validateLength minimum="2"/>
</h:inputText>
<h:commandButton value="test" action="#{viewParamBean.actionMethod}"/>
</h:form>
</h:body>
</html>
Бин:
@ManagedBean
@RequestScoped
public class ViewParamBean {
private long id;
private String text;
public void actionMethod() {
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
Если вы вызовете Facelet с помощью viewparam.xhtml?id=12
, на экране отобразится 12
. Если вы затем введете что-то действительное, например. aaaaa
идентификатор исчезнет из URL-адреса, но продолжит отображаться на экране (из-за природы компонентов пользовательского интерфейса с сохранением состояния).
Однако... как упоминалось в OP, как только произойдет какая-либо ошибка валидатора (например, ввод a
), идентификатор будет безвозвратно потерян. Последующий ввод действительного ввода не вернет его обратно. Это почти похоже на ошибку, но я пробовал и Mojarra 2.1, и Myfaces 2.1, и обе ведут себя одинаково.
Обновление:
После некоторой проверки проблема, похоже, заключается в этом методе `UIViewParameter' (Mojarra):
public void encodeAll(FacesContext context) throws IOException {
if (context == null) {
throw new NullPointerException();
}
// if there is a value expression, update view parameter w/ latest value after render
// QUESTION is it okay that a null string value may be suppressing the view parameter value?
// ANSWER: I'm not sure.
setSubmittedValue(getStringValue(context));
}
А затем более конкретно этот метод:
public String getStringValue(FacesContext context) {
String result = null;
if (hasValueExpression()) {
result = getStringValueFromModel(context);
} else {
result = (null != rawValue) ? rawValue : (String) getValue();
}
return result;
}
Поскольку hasValueExpression()
истинно, он попытается получить значение из модели (бэк-бина). Но поскольку этот bean-компонент находится в области запроса, он не будет иметь никакого значения для этого запроса, поскольку проверка только что завершилась неудачно, и, следовательно, значение никогда не устанавливалось. По сути, значение с сохранением состояния UIViewParameter
перезаписывается тем, что вспомогательный компонент возвращает по умолчанию (обычно это значение null, но, конечно, это зависит от вашего компонента).
Одним из обходных путей является создание bean-компонента @ViewScoped
, что в любом случае часто является лучшей областью действия (я предполагаю, что вы используете параметр для получения пользователя из службы, и, возможно, нет необходимости делать это снова и снова при каждой обратной передаче).
Другой альтернативой является создание собственной версии UIViewParameter
, которая не пытается получить значение из модели, если проверка не удалась (как это делают все остальные компоненты UIInput
).
person
Arjan Tijms
schedule
31.07.2011
includeViewParams=true
в своем действии отправки? - person bluefoot   schedule 31.07.2011