为什么这条线 [isLocalValueSet() ? getLocalValue(): ...] 而不是 [isLocalValueSet() ? getValue(): ...] 在 UIInput class 中?

Why this line [isLocalValueSet() ? getLocalValue(): ...] instead of [isLocalValueSet() ? getValue(): ...] in UIInput class?

我已经经历了this,但答案对我来说不是很清楚。所以问,

对于class UIInput的验证方法,我们有这个(只标记那些与问题相关的行)

public void validate(FacesContext context) {

     Object submittedValue = getSubmittedValue();           // LINE 958

     newValue = getConvertedValue(context, submittedValue); // LINE 976

     validateValue(context, newValue);                      // LINE 983

     if (isValid()) {                                       // LINE 987
            Object previous = getValue();
            setValue(newValue);                             // LINE 989
            setSubmittedValue(null);
     }
}

如果转换和验证都成功,则 isValid() returns true.

然后设置组件的 local 值 - setValue(newValue),由标志 setLocalValueSet(true)

指示

之后,submitted值设置为null - setSubmittedValue(null)

如果你看一下 UIInput 的这个 setValue(...) 方法的代码,它被覆盖了,

@Override
public void setValue(Object value) {
    super.setValue(value);
    // Mark the local value as set.
    setLocalValueSet(true);
}

所以从第 989 行开始,调用委托给上面的 setValue(...)。 如果你看看这个方法,

@Override
public Object getValue() {
    return isLocalValueSet() ? getLocalValue() : super.getValue();
}

如果本地值由 setValue(...) 设置,由标志 setLocalValueSet(true) 指示, 为什么要返回 getLocalValue()? 我的意思是,

isLocalValueSet() ? getLocalValue() : ....

为什么不是

isLocalValueSet() ? getValue() : ....

如上所示,我的困惑在于 getValue()getLocalValue() 方法。此外,在这种情况下 Object previous = getValue(); 将是 not null?

If the local value was set by setValue(...), indicated by the flag setLocalValueSet(true), why is this returning the getLocalValue()?

我认为阅读 ValueHolder 接口的 javadoc 很有帮助。

Object getLocalValue()

Return the local value of this UIComponent (if any), without evaluating any associated ValueExpression.

Object getValue()

Gets the value of this UIComponent. If validation failed, as indicated by FacesContext.isValidationFailed() returning true, always return the local value. Otherwise, first, consult the local value property of this component. If non-null return it. If null, see if we have a ValueExpression for the value property. If so, return the result of evaluating the property, otherwise return null.

void setValue(Object value)

Set the value of this UIComponent (if any).

注意我强调的是“没有”。

换句话说,getLocalValue()setValue()形成了一个真正的getter/setter对,基本上指的是组件自己的实例变量,而不是属性中指定的任何表达式后面的bean组件的 value 属性,例如 value="#{bean.value}".

getValue() 方法的实现方式是在验证未失败(尚未)且本地值为 null 时自动评估任何关联的 ValueExpression。当(转换后的)提交值实际上是 null 并且组件仍在忙于处理验证阶段并且模型值尚未更新时,这是不可取的。

简单地说,如果使用 getValue() 而不是 getLocalValue(),那么“用户删除(非必需)输入值”的情况将失败,因为 getValue() returns初始模型值。


Furthermore, in which case Object previous = getValue(); will be not null?

当模型中有初始值时。