TCM*_*TCM 8 java jsf jstl facelets
我再次看到@PostConstruct每次都在触发,即使没有使用绑定属性.看到这段代码: -
<?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:ui="http://java.sun.com/jsf/facelets"
xmlns:c="http://java.sun.com/jsp/jstl/core">
<h:head>
<title>Facelet Title</title>
</h:head>
<h:body>
<h:form>
<c:forEach var="item" items="#{TestBean.listItems}">
<h:outputText value="#{item}"/>
</c:forEach>
<h:commandButton value="Click" actionListener="#{TestBean.actionListener}"/>
</h:form>
</h:body>
</html>
Run Code Online (Sandbox Code Playgroud)
这是JSF中最简单的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;
@ManagedBean(name="TestBean")
@ViewScoped
public class TestBean implements Serializable {
private List<String> listItems;
public List<String> getListItems() {
return listItems;
}
public void setListItems(List<String> listItems) {
this.listItems = listItems;
}
public TestBean() {
}
@PostConstruct
public void init(){
System.out.println("Post Construct fired!");
listItems = new ArrayList<String>();
listItems.add("Mango");
listItems.add("Apple");
listItems.add("Banana");
}
public void actionListener(){
System.out.println("Action Listener fired!");
}
}
Run Code Online (Sandbox Code Playgroud)
您是否看到任何应该导致postconstruct回调每次触发的行为?我认为JSF 2.0非常不稳定.如果每次@ViewScoped服务的目的都必须触发PostConstruct.为什么不使用@RequestScoped?我以为我在申请中犯了一些错误.但是当我在JSF中创建这个最简单的时候,我仍然会遇到这个错误.我不了解JSF的范围吗?或者他们没有正确测试?此外,如果你删除c:forEach并用ui:repeat替换它,那么它工作正常.
等待回复以确认它是否是错误或是故意阻止程序员使用jstl?
Bal*_*usC 13
这个问题与你之前回答的问题有相同的理由:为什么@PostConstruct回调每次都会触发,即使bean是@ViewScoped?JSF.
这确实是JSF2中的一个错误.这是一个鸡蛋问题.视图范围bean存储在JSF视图状态中.因此视图范围bean仅在还原视图阶段后可用.但是,JSTL标记在还原视图阶段运行,而视图范围Bean尚不可用.这会导致创建一个全新的视图范围bean实例,然后由实际视图范围bean替换,该实例存储在已恢复的JSF视图状态中.
这被报告为JSF问题1665和JSF规范isssue 787,它针对JSF 2.2修复并移植回Mojarra 2.1.18.因此,只需升级到Mojarra 2.1.18即可.
如果您无法升级,那么您最好的选择是在请求/会话/应用程序作用域上独占使用JSTL标记,或者寻找特定功能需求的替代方法.您可以替换已经发现的<c:forEach>with <ui:repeat>.