JSF 生命周期和自定义组件

2022-09-02 12:54:29

在 JSF 中开发自定义组件时,我很难理解一些事情。出于这些问题的目的,您可以假设所有自定义控件都使用值绑定/表达式(而不是文本绑定),但我也对它们的解释感兴趣。

  1. 在哪里设置值绑定的值?这应该发生在解码中吗?还是应该解码做其他事情,然后在编码中设置值开始?
  2. 从值绑定读取 - 何时从值绑定读取数据与从提交值读取数据并将其放入值绑定?
  3. 表单上的操作侦听器何时调用与所有这些相关的操作侦听器?JSF生命周期页面都提到了在各个步骤发生的事件,但是当只调用一个命令按钮的简单侦听器时,我并不完全清楚

我尝试了几种组合,但最终总是很难找到错误,我相信这些错误来自对事件生命周期的基本误解。


答案 1

JSF 规范中有一个非常好的图表,显示了请求生命周期 - 这对于理解这些东西至关重要。

步骤如下:

  • 恢复视图。将重建 UIComponent 树。
  • 应用请求值。可编辑的组件应该实现可编辑值持有者。此阶段遍历组件树并调用 processDecodes 方法。如果组件不像 UIData 那样复杂,则除了调用自己的解码方法外,它不会执行太多操作。解码方法除了找到其呈现器并调用其解码方法(将自身作为参数传递)之外,没有做太多事情。渲染器的工作是获取任何提交的值并通过 setSubmittedValue 进行设置。
  • 流程验证。此阶段调用进程验证器,后者将调用验证验证方法采用提交的值,使用任何转换器转换它,使用任何验证器验证它,并(假设数据通过这些测试)调用 setValue。这会将值存储为局部变量。虽然此局部变量不为 null,但对于任何对 getValue 的调用,它将返回它,而不是值绑定中的值。
  • 更新模型值。此阶段调用进程更新。在输入组件中,这将调用 updateModel,它将获取 ValueExpression 并调用它来设置模型上的值。
  • 调用应用程序。按钮事件侦听器等将在此处调用(如果内存可用,导航也是如此)。
  • 呈现响应。树通过呈现器呈现并保存状态。
  • 如果这些阶段中的任何一个失败(例如,值无效),则生命周期将跳到“渲染响应”。
  • 在大多数这些阶段之后,可以触发各种事件,并根据需要调用侦听器(例如进程验证后的值更改侦听器)。

这是事件的简化版本。有关更多详细信息,请参阅规范。

我会质疑你为什么要写自己的UIComponent。这是一项不平凡的任务,需要深入了解 JSF 体系结构才能正确完成。如果需要自定义控件,最好创建一个具体的控件,该控件使用等效的呈现器扩展现有的 UIComponent(如 HtmlInputText 所做的那样)。

如果污染不是问题,那么Apache MyFaces的形式就有一个开源的JSF实现。


答案 2

操作侦听器(如 CommandButton 的侦听器)在调用应用程序阶段调用,该阶段是最终呈现响应阶段之前的最后一个阶段。这在 JSF 生命周期 - 图 1 中所示。


推荐