我已经完成了this,但答案对我来说并不是很清楚。因此问,
对于类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()
返回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);
}
所以从LINE 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
?
答案 0 :(得分:2)
如果本地值是由setValue(...)设置的,由标志setLocalValueSet(true)指示,为什么这会返回getLocalValue()?
我认为阅读ValueHolder
界面的javadoc很有帮助。
Object getLocalValue()
返回此
UIComponent
(如果有)的本地值,不用评估任何关联的ValueExpression
。
Object getValue()
获取此
UIComponent
的值。如果验证失败,如FacesContext.isValidationFailed()
返回true
所示,则始终返回本地值。否则,首先,请参阅此组件的本地值属性。如果非 -null
返回它。如果null
,请查看我们是否为值属性ValueExpression
。如果是,则返回评估属性的结果,否则返回null
。
void setValue(Object value)
设置此
UIComponent
的值(如果有)。
注意我强调"没有"。
换句话说,getLocalValue()
和setValue()
形成一个真正的getter / setter对,基本上是指组件自己的实例变量,而不是组件中指定的任何表达式后面的bean属性。 s value
属性,例如value="#{bean.value}"
。
getValue()
方法的实现方式是,当验证失败(尚未)且本地值为ValueExpression
时,它会自动评估任何关联的null
。当(转换的)提交的值实际为null
并且组件仍然忙于处理验证阶段并且模型值尚未更新时,这是不希望的。
简单地说,如果使用getValue()
而不是getLocalValue()
,那么用例#34;用户删除(非必需)输入值"会失败,因为getValue()
会返回初始模型值。
此外,在这种情况下,Object previous = getValue();将不为空?
当模型中有初始值时。