JSF PROCESS_VALIDATIONS 和@RequestScoped 问题

JSF PROCESS_VALIDATIONS and @RequestScoped issue

考虑以下用例。我正在使用 @RequestScoped 支持 bean 开发 JSF 表单。另外,我用的是PrimeFaces,不过跟问题关系不大。

表单字段中的值通过复杂的业务逻辑相互关联。 IE。一个下拉列表中的值取决于另一个下拉列表中的值,或者一个字段的 enabled/disabled 状态取决于另一个字段中的值。 table 的内容取决于某些隐藏字段中的视图参数或值。

支持 bean 中的设置器将值写入数据模型构建器,获取器调用构建器的 build() 方法,该方法以某种预定义的顺序应用值和 returns immutable 数据模型.

@RequestScoped 意味着在回发时(无论是 AJAX 还是常规请求)表单的支持 bean 需要从 null 重建。它发生在 UPDATE_MODEL_VALUES 阶段。

当我们使用 selectOneMenu(JSF selectOneMenu 或 PrimeFaces selectOneMenu - 无关紧要)或 dataTable 时,问题就开始了。因为在 PROCESS_VALIDATIONS 阶段(发生在 UPDATE_MODEL_VALUES 之前)backing bean 仍然没有设置值。提到的组件无法通过内置验证,因为请求值不对应于 [仍然为空] 集合中的任何值(为 selectOneMenu 或 dataTable 或任何类似的内容提供服务)。

我想出的一个解决方案是使用支持 bean 的 @PostConstruct 方法,我们可以在其中手动读取必要的请求值并预填充所需的集合。但这个解决方案似乎远非干净和优雅。

此外,我尝试应用自定义虚拟验证器,但它似乎无法替代内置验证器,所以这不起作用。

在这种情况下,考虑到我想坚持使用 @RequestScoped,专家的建议是什么?

谢谢!

这正是 @ViewScoped 存在的原因。

如果您不想使用 JSF 的“自动”视图状态管理,最好在每次回发期间手动维护 @RequestScoped bean 的 @PostConstruct 中的视图状态通过 @ViewScoped。您最多可以通过 @ManagedProperty 注入参数。具有 validation/conversion 支持的 <f:viewParam> 远非有用,因为它运行“太晚了”。

如果您使用的是 CDI 托管 bean,JSF 实用程序库 OmniFaces has a CDI @Param 也支持验证和转换,这与 @ManagedProperty 相反。这可能会进一步减少 @PostConstruct 方法中的样板文件。

另请参阅:

  • How to choose the right bean scope?
  • What is the usefulness of statelessness in JSF?
  • ViewParam vs @ManagedProperty(value = "#{param.id}")