JSF 2 - Bean Validation: validation failed -> empty values are replaced with last valid values from managed bean

前端 未结 4 1172
一向
一向 2020-12-05 08:18


I do not understand the behaviour of JSF2 during valdation. Hope someone can help me.

I have a form where the fields are validated after (ajax) submit - ok

4条回答
  •  温柔的废话
    2020-12-05 09:09

    Your particular problem is caused by

    
        javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL
        true
    
    

    and a bug (at least, an oversight) in HtmlBasicRenderer#getCurrentValue() of Mojarra:

    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;
    

    Normally, the submitted value is set to null when the UIInput component is successfully converted and validated. When JSF is about to redisplay the value, it first checks if the submitted value is not null before proceeding to redisplay the model value. However, with this context parameter, it is null instead of an empty string when it is invalid and thus it will always redisplay the original model value when you remove the initial value of a required field.

    To test it, set that context param value to false or remove it altogether. You'll see that it works as intended. However, it will bring back the disadvantage that your model values will be cluttered with empty strings on empty but non-required fields and you'll lose the advantage of using @NotNull annotation of JSR 303 bean validation.

    To fix this, you've to alter 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've already reported it to Mojarra guys as issue 2262.

提交回复
热议问题