5

如果我正确地将 BalusC 2006 年伟大的帖子http://balusc.blogspot.ch/2006/09/debug-jsf-lifecycle.html中包含的信息与 Optimus Prime 更早的帖子http://cagataycivici.wordpress.com/2005结合起来/12/28/jsf_component_s_value_local/我得到以下信息:

我的理解:

  1. 在 APPLY_REQUEST_VALUES 阶段,
    • 输入值被设置为 UI 组件的提交值属性(例如 inputComponent.setSubmittedValue ( "test"))。
  2. 在 PROCESS_VALIDATIONS 阶段,
    • 从 submitValue 属性(可能是inputComponent.getSubmittedValue ())中读取相同的值,并在必要时用于转换。
    • 如果转换成功或跳过,则将结果设置为组件的 value 属性(例如 inputComponent.setValue ( "test"))。
    • 此外,submittedValue 会立即再次被擦除(例如inputComponent.setSubmittedValue (null))
    • 从 UI 组件的 value 属性中读取(转换后的)值(大概是 inputComponent.getValue ())并进行验证。
    • 验证后,读取支持 bean/模型的存储值(例如 myBean.getInputValue ( ))并与新转换和验证的值进行比较。如果不同,将调用 valueChangeListener 方法。
  3. 在 UPDATE_MODEL_VALUES 阶段,
    • 新转换和验证的值最终存储在支持 bean 的属性字段中(例如 myBean.setInputValue ( "test"))。

问题:

  • 它是否正确?
  • 是否缺少一些东西来全面理解 POST 和将输入值保存在支持 bean 之间发生的事情?
  • 在输入组件上使用 immediate="true" 时,我们只是将这些事件转移到 APPLY_REQUEST_VALUES 阶段,还是我们改变的不仅仅是事件的时间/顺序?
4

1 回答 1

4

几乎正确。组件的本地值仅在转换验证成功时设置。之后,提交的值设置为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     }

至于组件immediate上的属性UIInput,是的,这只是将验证转移到应用请求值阶段。UIInput#processDecodes()另请参阅and的源代码,UIInput#processValidators()UIInput#isImmediate().

于 2013-03-28T21:01:35.360 回答