【问题标题】:CDI bean List in datatable is null on submit from JSF从 JSF 提交时,数据表中的 CDI bean 列表为空
【发布时间】:2012-11-05 17:50:25
【问题描述】:

请注意:这个问题是关于 CDI 范围的,因为我们在应用程序中使用的是 CDI 范围,而不是 JSF 范围。

1)RequestScoped(企业上下文)中的Controller Bean(TestController.java)被称为index_cut.xhtml,当我们第一次来到这个页面时。

2) 在“加载”按钮上,我们加载以下方法来填充 sapFinancialPeriodList,该方法工作正常并显示数据

3)更改页面内容并提交后,sapFinancialPeriodList在以下方法中显示为NULL——

有什么建议吗?

【问题讨论】:

  • 在第 3 步提交的表单帐户基本上发送了一个全新的 HTTP 请求。并且您的 bean 是请求范围的。你现在看到了吗...?
  • @BalusC:我们也尝试过 ConversationScoped。我看到了请求的重点。你有什么建议?

标签: jsf-2 cdi


【解决方案1】:

您的 bean 是请求范围的,并且您仅在操作时加载数据模型,而不是在(后)构造时加载。当加载数据的操作完成后的 HTTP 响应时,该 bean 将被丢弃。随后的请求将获得一个全新的 bean 实例,所有属性都设置为默认值。但是,由于在(后)构建期间没有保留相同的数据模型,因此它保持为空。

在 JSF2 中,您可以使用 @ViewScoped 来解决这个问题。这样,只要您通过回发(返回 nullvoid)与同一个视图交互,bean 就会一直存在。

在 CDI 中,您需要使用 @ConversationScoped 解决此问题,而这又需要一些额外的 @Inject Conversation 样板,并在适当的时候完成 begin()end() 调用。具体示例,另见What scope to use in JSF 2.0 for Wizard pattern?

另一种方法是通过命令链接/按钮中的<f:param>将负责创建数据模型的参数传递给后续请求,如下所示

<h:commandButton value="save" ...>
    <f:param name="period" value="#{bean.period}" />
</h:commandButton>

然后在请求范围 bean 的(后)构造函数中重新创建完全相同的数据模型,如下所示

String period = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("period");
List<SapFinancialPeriod> sapFinancialPeriodList = someservice.list(period);

(顺便说一句,如果您使用标准 JSF,使用 @ManagedProperty 解决上述问题会更好;据我所知,CDI 没有注释可以让您将 HTTP 请求参数设置为bean 属性)

另见:


与具体问题无关,即将推出的 JSF 2.2 使用新的 "Faces Flow" 特性以及新的 @FlowScoped 注释和新的 xmlns:j="http://java.sun.com/jsf/flow" 标记以更好的方式解决了这个功能需求。

【讨论】:

  • 不错的答案。我可以建议查看 ViewAccessScoped 而不是使用 ConversationScoped 您可以在下一个版本中从 Deltaspike 或现在从 myfaces codi 获得它。
  • Reqarding注入http请求参数。我觉得没有答案足够干净,所以我用它做了一个问答。 stackoverflow.com/questions/13239975/…
  • @BalusC:它适用于会话范围 - 但我看到的奇怪的事情是,如果我保留 RequestScoped 并使用 PostConstruct 中数据库中的原始值重新加载 bean提交,那么 bean 就能够保存并显示屏幕上更改的值。不使用 f:param。这是 ArrayList 特有的——所以我尝试在 Postconstruct 中为 Submit 创建一个空的 ArrayList,但它不会从 submitdata() 的屏幕中获取新值。它只会替换 ArrayList 中的任何现有值,前提是在 Postconstruct 中创建了一个这样的 ArrayList。
  • 提交的和本地的输入值存储在UI组件树状态中(它本身基本上在视图范围内)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-20
  • 1970-01-01
相关资源
最近更新 更多