请注意:这个问题与CDI范围有关,因为我们在应用程序中使用CDI范围而不是JSF范围。
1)当我们第一次来到这个页面时,在RequestScoped(企业上下文)中的Controller Bean(TestController.java)被称为index_cut.xhtml。
2)在“加载”按钮上,我们加载以下方法来填充sapFinancialPeriodList,它可以正常工作并显示数据
3)更改页面上的内容并提交后,sapFinancialPeriodList
在以下方法中显示为NULL -
有什么建议吗?
答案 0 :(得分:2)
您的bean是请求作用域,您只在操作上加载数据模型而不是在(post)构造上加载。当完成加载数据的操作之后的HTTP响应时,bean就会被吞噬。后续请求将获得bean的全新实例,并将所有属性设置为default。但是,由于在(post)构造期间未保留相同的数据模型,因此它仍为空。
在JSF2中,您可以使用@ViewScoped
解决此问题。这样,只要您通过回发(返回null
或void
)与相同的视图进行交互,bean就会存在。
在CDI中,您需要使用@ConversationScoped
解决此问题,@Inject Conversation
需要一些额外的begin()
样板,并在适当的时刻完成end()
和<f:param>
次呼叫。有关具体示例,另请参阅What scope to use in JSF 2.0 for Wizard pattern?。
另一种方法是通过命令链接/按钮中的<h:commandButton value="save" ...>
<f:param name="period" value="#{bean.period}" />
</h:commandButton>
将负责创建数据模型的参数传递给后续请求,如下所示
String period = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("period");
List<SapFinancialPeriod> sapFinancialPeriodList = someservice.list(period);
然后在请求范围bean的(post)构造函数中重新创建完全相同的数据模型,如下所示
@ManagedProperty
(如果使用标准JSF,上面的方法更好用@FlowScoped
来解决;据我所知,CDI没有一个注释,可以让你设置一个HTTP请求参数作为bean属性)
无关,即将推出的JSF 2.2使用新的"Faces Flow"功能和新的xmlns:j="http://java.sun.com/jsf/flow"
注释以及新的{更好地解决了这一功能需求{1}}代码。