什么时候在 UIComponent 上调用 setValue 和 setSubmittedValue?

Chr*_*ris 5 lifecycle jsf components

如果我正确地将 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 组件的 submitValue 属性(例如inputComponent.setSubmittedValue ("test"))。
  2. 在 PROCESS_VALIDATIONS 阶段,
    • 从 submitValue 属性(大概是inputComponent.getSubmittedValue ())中读取相同的值,并在必要时用于转换。
    • 如果转换成功或跳过,则结果被设定为分量的值属性(例如inputComponent。的setValue(“测试”))。
    • 此外,submittedValue 会立即再次被擦除(例如inputComponent.setSubmittedValue (null))
    • (转换后的)值是从 UI 组件(大概是 inputComponent.getValue ())的 value 属性中读取并验证的。
    • 在验证后,支持bean /模型的存储的值被读出(例如为myBean。getInputValue())中,用新转换和验证值进行比较。如果不同,将调用 valueChangeListener 方法。
  3. 在 UPDATE_MODEL_VALUES 阶段,
    • 新转换的和验证值被最终存储在背衬bean的属性字段(例如为myBean。setInputValue(“测试”))。

问题:

  • 这样对吗?
  • 要完全理解 POST 和在支持 bean 中保存输入值之间发生的事情,是否缺少一些东西?
  • 输入组件上的immediate =“true”,我们只是将这些事件转移到APPLY_REQUEST_VALUES阶段,还是我们改变的不仅仅是事件的时间/顺序?

Bal*_*usC 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     }
Run Code Online (Sandbox Code Playgroud)

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