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}")
考虑以下用例。我正在使用 @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}")