ciekawy przypadek. Dla wszystkich, następujące minimalne kod reprodukuje to:
Facelet:
<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>
Fasola:
@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;
}
}
Jeśli wywołać Facelet z viewparam.xhtml?id=12
będzie wyświetlać 12
ekranie. Jeśli wprowadzisz coś ważnego, np. aaaaa
, id zniknie z adresu URL, ale nadal będzie wyświetlany na ekranie (z uwzględnieniem stanowego charakteru komponentów interfejsu użytkownika).
Jednak ... jak podano w OP, jak tylko pojawi się jakikolwiek błąd weryfikatora (np. Wpisanie a
), identyfikator zostanie trwale utracony. Wprowadzenie prawidłowych danych wejściowych nie spowoduje ich przywrócenia. Wygląda to prawie jak błąd, ale próbowałem zarówno Mojarra 2.1, jak i Myfaces 2.1 i oba mają takie samo zachowanie.
Aktualizacja:
Po pewnym kontroli, problem wydaje się być w tej metodzie `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));
}
A potem dokładniej ta metoda:
public String getStringValue(FacesContext context) {
String result = null;
if (hasValueExpression()) {
result = getStringValueFromModel(context);
} else {
result = (null != rawValue) ? rawValue : (String) getValue();
}
return result;
}
Ponieważ hasValueExpression()
jest prawdą, spróbuje uzyskać wartość z modelu (backing bean). Ale ponieważ ten komponent bean był ograniczony zasięgiem, nie będzie miał żadnej wartości dla tego żądania, ponieważ sprawdzanie poprawności właśnie zakończyło się niepowodzeniem, a zatem żadna wartość nigdy nie została ustawiona.W efekcie wartość stanu UIViewParameter
jest nadpisywana przez to, co back bean bean zwraca jako domyślną (zazwyczaj null, ale to zależy oczywiście od twojej fasoli).
Jednym z obejść jest utworzenie fasoli @ViewScoped
, która i tak często jest lepszym zakresem (zakładam, że użyjesz tego parametru do pobrania użytkownika z usługi, i może nie trzeba tego robić w kółko przy każdym odesłaniu zwrotnym) .
Inną alternatywą jest utworzenie własnej wersji UIViewParameter
, która nie próbuje uzyskać wartości z modelu, jeśli sprawdzanie poprawności zakończyło się niepowodzeniem (jak w zasadzie wszystkie inne komponenty UIInput
).
używasz 'includeViewParams = TRUE w swojej złożenia skargi? – bluefoot
Nie, ale mój program obsługi nie jest wywoływany: przesłanie kończy się niepowodzeniem w kroku sprawdzania poprawności. – DenisGL