gpt4 book ai didi

jsf - 为什么 @PostConstruct 回调每次都会触发,即使 bean 是 @ViewScoped 的? JSF

转载 作者:行者123 更新时间:2023-12-03 08:49:09 28 4
gpt4 key购买 nike

我在页面上使用数据表并使用绑定(bind)属性将其绑定(bind)到我的支持 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>

这是我的 bean :-
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 都会触发?只要我在同一页面上,它就应该只触发一次,因为我的 bean 是@ViewScoped。此外,如果我删除绑定(bind)属性,那么一切正常,@PostConstruct 回调只触发一次。那为什么每次我使用绑定(bind)属性时?我需要绑定(bind)属性,并且只想执行一次初始化任务,例如从 web 服务获取数据等。我该怎么办?我应该在哪里写我的初始化任务?

最佳答案

有趣的是,当您在 View 范围的 bean 上使用组件绑定(bind)时, View 范围会中断。

我不确定这是否是 JSF2 中的错误,我必须先阅读整个 JSF2 规范。到目前为止,您最好的选择是暂时放弃组件绑定(bind)并通过新的 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>

也可以看看:
  • How can I pass selected row to commandLink inside dataTable?
  • Invoke direct methods or methods with arguments / variables / parameters in EL
  • Benefits and pitfalls of @ViewScoped


  • 更新 (2012 年 12 月):这确实是 JSF2 中的一个错误。这是一个鸡蛋问题。 View 范围的 bean 存储在 JSF View 状态中。因此 View 范围的 bean 仅在恢复 View 阶段后可用。但是, binding属性在恢复 View 阶段运行,而 View 范围的 bean 尚不可用。这会导致创建一个全新的 View 范围 bean 实例,然后将其替换为存储在恢复的 JSF View 状态中的真实 View 范围 bean。

    这报告为 JSF issue 1492JSF spec isssue 787这将在 JSF 2.2 中修复。在那之前,您最好的选择是使用 binding根据请求专门限定范围的 bean,或者为特定的功能需求寻找替代方法。

    更新 (2015 年 3 月):JSF 2.2 修复被反向移植到 Mojarra 2.1.18。因此,如果您仍在使用 JSF 2.0/2.1,您最好至少升级到该版本。另见 a.o. What is component binding in JSF? When it is preferred to be used?JSTL in JSF2 Facelets... makes sense?

    关于jsf - 为什么 @PostConstruct 回调每次都会触发,即使 bean 是 @ViewScoped 的? JSF,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2797231/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com