调试JSF生命周期 - 每个阶段到底发生了什么

时间:2014-02-20 16:45:08

标签: jsf jsf-2 lifecycle phase immediate-attribute

我决定全力挖掘JSF 2.0,因为我的项目需要深入了解它。我正在阅读JSF Lifecyle Debug,这是一篇关于JSF生命周期的精彩而精彩的文章。在阅读本文时,我有以下混淆。

  1. 如果是初始请求,则在Restore View Phase中创建一个空视图,并发生直接Render Response Phase。此时没有可以保存的州。那么render response phase实际发生了什么?我在运行这个例子时感到很困惑。

  2. 文章指出,检索到的输入值在inputComponent.setSubmittedValue()阶段的Apply Request Values中设置。如果验证和转换通过,则会在inputComponent.setValue(value)中设置值并运行inputComponent.setSubmittedValue(null)。在同一篇文章中指出,现在如果在下一个回发请求中,值被更改,则将其与提交的值进行比较,该值在每个帖子上始终为空,将调用v alue change listener。这意味着,如果,我们不更改值,因为submittedValue将为null,将始终调用valueChangeListener?我对此声明感到困惑。有人可以详细说明这个吗?

  3. 文章说明immediate属性的用法。如果在输入组件上设置了immediate属性,则跳过理想情况Process Validation Phase,但所有转换和验证都在Apply Request Values中进行。我的观点是,当转换和验证发生时,跳过第三阶段的优势是什么?

  4. 术语检索值的含义是什么?

  5. 我想知道,如果让我们说视图上有五个字段。 JSF是否列出了这些值的一些集合,Apply Request ValuesProcess Validations阶段逐个迭代它们?

  6. 在本文的最后一点,它指出何时使用immediate属性。根据我的理解,如果在输入组件和命令组件中都设置了immediate属性,它将跳过从没有immediate的任何属性的Apply Request Values to Invoke Application的阶段。那么最后一个语句在登录表单中是什么意思是“忘记密码”按钮,其中包含必需的即时用户名字段和必需但非直接的密码字段。

  7. 我知道这些是非常基本的混淆,但这些主题的明确性肯定有助于提高JSF知识。

1 个答案:

答案 0 :(得分:14)

  

1:渲染响应阶段实际发生了什么?

UIViewRoot#encodeAll()开始为客户端生成HTML输出。您可以通过右键单击web浏览器中的查看源来查看结果(因此不能通过右键单击webbrowser中的 Inspect Element ,因为这只会显示webbrowser的HTML DOM树基于原始HTML源代码和之后的所有JavaScript事件构建。


  

2:将其与提交的值进行比较,每次回发后该值始终为空

不,它被保留为实例变量。 JSF不会调用getSubmittedValue()来比较它。


  

3:我的观点是,仍然在进行转换和验证时,跳过第三阶段的优势是什么?

Okay, when should I use the immediate attribute?下的文章底部回答了这个问题。简而言之:优先验证。如果immediate="true"的组件在转换/验证时失败,则不会转换/验证没有immediate="true"的组件。


  

4:术语检索值的含义是什么?

最终用户提交的“原始”值(最终用户在输入表单中输入的确切输入值)。这通常是String。如果您熟悉servlet,那么很容易理解它与request.getParameter()获得的值完全相同。


  

5: JSF是否列出了这些值的一些集合,并且Apply Request Values和Process Validations阶段逐个迭代它们?

几乎。该集合已经存在于JSF组件树的风格中。因此,JSF基本上迭代树结构,从FacesContext#getUIViewRoot()开始。


  

6:那么最后一个语句在登录表单中是什么意思是“忘记密码”按钮,其中包含必需的即时用户名字段和必需但非直接的密码字段。

通过这种方式,您可以重复使用“忘记密码”案例的登录表单。如果您提交“登录”按钮,那么显然必须验证用户名和密码字段。但是,如果您提交“忘记密码”按钮,则不应验证密码字段。


尽管如此,您可能会发现以下JSF阶段/生命周期备忘单也很有用,可以快速参考:

  
      
  • fc = FacesContext
  •   
  • vh = ViewHandler
  •   
  • in = UIInput
  •   
  • rq = HttpServletRequest
  •   
  • id = in.getClientId(fc);
  •   
     

1 RESTORE_VIEW

String viewId = rq.getServletPath();
fc.setViewRoot(vh.createView(fc, viewId));
     

2 APPLY_REQUEST_VALUES

in.setSubmittedValue(rq.getParameter(id));
     

3 PROCESS_VALIDATIONS

Object value = in.getSubmittedValue();
try {
   value = in.getConvertedValue(fc, value);
   for (Validator v : in.getValidators())
      v.validate(fc, in, value);
   }
   in.setSubmittedValue(null);
   in.setValue(value);
} catch (ConverterException | ValidatorException e) {
   fc.addMessage(id, e.getFacesMessage());
   fc.validationFailed(); // Skips phases 4+5.
   in.setValid(false);
}
     

4 UPDATE_MODEL_VALUES

bean.setProperty(in.getValue());
     

5 INVOKE_APPLICATION

bean.submit();
     

6 RENDER_RESPONSE

vh.renderView(fc, fc.getViewRoot());

另见: