Java – JSF 2 – bean validation: validation failed – > null value is replaced by the last valid value from the managed bean
I don't understand the behavior of jsf2 during the price period I hope someone can help me
I have a form in which the fields are verified after (Ajax) submission - OK, if the verification fails, an error message is displayed - OK
For my example, when I enter a valid birthday and the field name is empty, an error message will be displayed after submitting Now when I enter a valid name and delete the entry from the birthday field, an error message will be displayed (for birthday) (it doesn't matter), but now the old "valid" birthday is also displayed in the input box!
How to avoid this behavior? When I submit an empty field, I want to see an error message and an empty field
Here is my sample code:
I use a managedbean (testbean) that contains an entitybean (contact) Each contact message contains validation
public class Contact implements Serializable { @NotNull @Temporal(TemporalType.DATE) private Date birthday; @NotNull @Size(min=3,max=15) private String name; //... }
My managedbean:
@ManagedBean @ViewScoped public class TestBean implements Serializable { private Contact contact; @postconstruct void init() { System.out.println("init..."); contact = new Contact(); } public void newContact(ActionEvent ae) { System.out.println("newContact..."); contact = new Contact(); } public void save() { System.out.println("save..."); //TODO do something with contact... } public Contact getContact() { return contact; } public void setContact(Contact contact) {this.contact = contact;} }
Here is my JSF page:
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" > <h:body> <h:form> <h:panelGrid columns="3"> <h:outputText value="Birthday: " /> <h:inputText id="birthday" value="#{testBean.contact.birthday}"> <f:convertDateTime/> </h:inputText> <h:message for="birthday" /> <h:outputText value="Name: " /> <h:inputText id="name" value="#{testBean.contact.name}"/> <h:message for="name" /> </h:panelGrid> <h:commandButton value="submit" action="#{testBean.save}"> <f:ajax execute="@form" render="@form"/> </h:commandButton> <h:commandButton value="newContact" actionListener="#{testBean.newContact}" immediate="true"> <f:ajax render="@form"/> </h:commandButton> </h:form> </h:body> </html>
Last web Fragments of XML
<context-param> <param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name> <param-value>true</param-value> </context-param> <context-param> <param-name>javax.faces.VALIDATE_EMPTY_FIELDS</param-name> <param-value>true</param-value> </context-param>
Thanks for some tips
Solution
Your specific problem is caused by
<context-param> <param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name> <param-value>true</param-value> </context-param>
And mojarra's htmlbasicrenderer#getcurrentvalue() (at least one supervisor):
if (component instanceof UIInput) { Object submittedValue = ((UIInput) component).getSubmittedValue(); if (submittedValue != null) { // value may not be a String... return submittedValue.toString(); } } String currentValue = null; Object currentObj = getValue(component); if (currentObj != null) { currentValue = getFormattedValue(context,component,currentObj); } return currentValue;
Typically, when the uiinput component is successfully converted and validated, the submitted value will be set to null When JSF is about to redisplay the value, first check whether the submitted value is not empty before continuing to redisplay the model value However, when this context parameter is used, it is not valid, not an empty string, so it will always redisplay the original model value when you delete the initial value of the required field
To test it, set the context parameter value to false or delete it completely You'll see how it works However, it will bring the disadvantage that your model value will be confused by empty string on empty but unnecessary fields, and you will lose the advantage of JSR 303 bean validation with @ notnull annotation
To solve this problem, you must modify the first part of htmlbasicrenderer #getcurrentvalue(), as follows:
if (component instanceof UIInput && !((UIInput) component).isValid()) { Object submittedValue = ((UIInput) component).getSubmittedValue(); if (submittedValue != null) { // value may not be a String... return submittedValue.toString(); } else { return null; } }
I have reported issue 2262 to the MOHALA