@PostConstruct callback fire,即使Bean是@viewScop的,为什么还要每次回电? JSF
-
04-10-2019 - |
题
我正在使用页面上的DataTable,并使用绑定属性将其绑定到我的背bean。这是我的代码: -
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.prime.com.tr/ui">
<h:head>
<title>Facelet Title</title>
</h:head>
<h:body>
<h:form prependId="false">
<h:dataTable var="item" value="#{testBean.stringCollection}" binding="#{testBean.dataTable}">
<h:column>
<h:outputText value="#{item}"/>
</h:column>
<h:column>
<h:commandButton value="Click" actionListener="#{testBean.action}"/>
</h:column>
</h:dataTable>
</h:form>
</h:body>
</html>
这是我的豆: -
package managedBeans;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.component.html.HtmlDataTable;
@ManagedBean(name="testBean")
@ViewScoped
public class testBean implements Serializable {
private List<String> stringCollection;
public List<String> getStringCollection() {
return stringCollection;
}
public void setStringCollection(List<String> stringCollection) {
this.stringCollection = stringCollection;
}
private HtmlDataTable dataTable;
public HtmlDataTable getDataTable() {
return dataTable;
}
public void setDataTable(HtmlDataTable dataTable) {
this.dataTable = dataTable;
}
@PostConstruct
public void init(){
System.out.println("Post Construct fired!!");
stringCollection = new ArrayList<String>();
stringCollection.add("a");
stringCollection.add("b");
stringCollection.add("c");
}
public void action(){
System.out.println("Clicked!!");
}
}
请告诉我为什么@PostConstruct每次点击按钮都会发射?只要我在同一页上,我的豆是@viewscop的,它应该只发射一次。此外,如果我删除绑定属性,那么一切都可以正常工作,@postConstruct回调仅发射一次。那么为什么每次使用绑定属性?我需要绑定属性,并希望执行初始化任务,例如从Web服务中获取数据,等等。我该怎么办?我应该在哪里写我的初始化任务?
解决方案
有趣的是,当您在视图范围的bean上使用组件绑定时,视图范围会断开。
我不确定这是否是JSF2中的错误,我必须首先阅读整个JSF2规范。到目前为止,您最好的选择是暂时删除组件绑定,并通过新的EL 2.2方法参数语法传递所选项目:
<h:dataTable var="item" value="#{testBean.stringCollection}">
<h:column>
<h:outputText value="#{item}"/>
</h:column>
<h:column>
<h:commandButton value="Click" action="#{testBean.action(item)}"/>
</h:column>
</h:dataTable>
也可以看看:
更新 (2012年12月):这确实是JSF2中的一个错误。这是一个鸡蛋的问题。视图示波器豆存储在JSF视图状态中。因此,仅在还原视图阶段之后可用视图范围的豆类。然而 binding
属性在还原视图阶段运行,而视图示波器尚不可用。这导致创建一个全新的视图范围范围的bean实例,然后将其替换为真实的视图范围示波器bean,该bean存储在已修复的JSF视图状态中。
据报道 JSF问题1492 和 JSF规格ISSSUE 787 将为JSF 2.2修复。在此之前,最好的选择是使用 binding
根据要求独家示范Bean,或为特定功能要求寻找其他方法。
更新 (2015年3月):JSF 2.2 FIX已退到Mojarra 2.1.18。因此,如果您仍在使用JSF 2.0/2.1,则最好至少升级到该版本。另请参阅AO JSF中的组件绑定是什么?何时首选使用? 和 JSF2 Facelets中的JSTL ...有意义吗?
其他提示
正如其他说的那样,我要说的是,最好的办法是放弃组件绑定(您在这里不需要)。
但是我会补充说,您可以通过使用类似参数来实现与试图以更面向对象的方式进行的相同的事情:
<h:commandButton value="Click" action="#{testBean.action(item)}"/>
...在您的Java代码中:
public void action(Item item){
System.out.println("Clicked!!" + item);
}
如果您有一个ViewScopep Bean,并且要保留在表单上输入的值或不希望爆发后射击,则应从操作方法中返回NULL。
如果您返回一些结果(例如无效),然后使用faces-config.xml将无效的结果指向同一页面,则可以重新创建ViewScoped Bean,因此它会导致邮政编码再次发射。
其他解决方案:
- 在请求范围bean中绑定可在请求范围内的HTMLDATATATATATATATATATATATATAT。
- 在视图范围bean中注入此请求范围bean。
JBOSS SEAM使用此解决方案将JSF组件绑定到对话范围组件。
Balusc的答案对我有很大帮助,我想说的是,我有Mojarra版本2.1.7的错误,我目前正在使用2.1.29-01于2015年1月发布,并且此错误是固定的,我的问题是约束tabview到ViewScoped Bean。有了这个版本,我没有那个错误,绑定和邮政编码正常工作。我使用JBOSS 5.2,我必须使用Mojarra 2.1.x,因此我希望这个答案能帮助其他情况下的其他人。
http://mvnrepository.com/artifact/com.sun.faces/jsf-api/2.1.29-01 http://mvnrepository.com/artifact/com.sun.faces/jsf-impl/2.1.29-01