如果我正确地将BalusC的2006年帖子http://balusc.blogspot.ch/2006/09/debug-jsf-lifecycle.html和擎天柱更早的帖子http://cagataycivici.wordpress.com/2005/12/28/jsf_component_s_value_local/中包含的信息结合起来,我得到以下内容:
我的理解:
- 在APPLY_REQUEST_VALUES阶段,
- 输入值被设置为UI组件的submittedValue属性(例如:inputComponent.setSubmittedValue("test"))。
- 在process_validation阶段,
- 从submittedValue属性中读取相同的值(假设是inputComponent.getSubmittedValue()),并在必要时用于转换。
- 如果转换成功或跳过,结果将被设置为组件的值属性(例如inputComponent.setValue("test"))。
- 同时,submittedValue被立即再次擦除(例如:inputComponent.setSubmittedValue(null))
- 从UI组件的value属性(假定为inputComponent.getValue())中读取(转换的)值并进行验证。 验证后,读取支持bean/模型的存储值(例如myBean.getInputValue()),并与新转换和验证的值进行比较。如果不同,则调用valueChangeListener方法。
- 在UPDATE_MODEL_VALUES阶段,
- 新转换和验证的值最终存储在后台bean的属性字段中(例如myBean.setInputValue("test"))。
问题:
- 正确吗?
- 对于完全理解POST和在后台bean中保存输入值之间发生了什么,是否缺少了一些东西? 使用Input Component上的immediate="true",我们仅仅是将这些事件转移到APPLY_REQUEST_VALUES阶段,还是我们改变的不仅仅是事件的时间/顺序?
基本正确。组件的本地值只有在和转换验证成功时才会设置。之后,提交的值设置为"null
"。您可以在UIInput#validate()
方法中以一种相当自文档化的方式找到验证阶段的整个过程(行号符合JSF 2.1 API):
934 public void validate(FacesContext context) {
935
936 if (context == null) {
937 throw new NullPointerException();
938 }
939
940 // Submitted value == null means "the component was not submitted
941 // at all".
942 Object submittedValue = getSubmittedValue();
943 if (submittedValue == null) {
944 return;
945 }
946
947 // If non-null, an instanceof String, and we're configured to treat
948 // zero-length Strings as null:
949 // call setSubmittedValue(null)
950 if ((considerEmptyStringNull(context)
951 && submittedValue instanceof String
952 && ((String) submittedValue).length() == 0)) {
953 setSubmittedValue(null);
954 submittedValue = null;
955 }
956
957 Object newValue = null;
958
959 try {
960 newValue = getConvertedValue(context, submittedValue);
961 }
962 catch (ConverterException ce) {
963 addConversionErrorMessage(context, ce);
964 setValid(false);
965 }
966
967 validateValue(context, newValue);
968
969 // If our value is valid, store the new value, erase the
970 // "submitted" value, and emit a ValueChangeEvent if appropriate
971 if (isValid()) {
972 Object previous = getValue();
973 setValue(newValue);
974 setSubmittedValue(null);
975 if (compareValues(previous, newValue)) {
976 queueEvent(new ValueChangeEvent(this, previous, newValue));
977 }
978 }
979
980 }
对于UIInput
组件上的immediate
属性,是的,这只是将验证转移到应用请求值阶段。参见UIInput#processDecodes()
和UIInput#processValidators()
的源代码,UIInput#isImmediate()
有一个检查