JSTL c:forEach导致@ViewScoped bean在每个请求上调用@PostConstruct
我再次看到@PostConstruct每次都在触发,即使没有使用绑定属性。 看到这段代码: –
Facelet Title
这是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 listItems; public List getListItems() { return listItems; } public void setListItems(List listItems) { this.listItems = listItems; } public TestBean() { } @PostConstruct public void init(){ System.out.println("Post Construct fired!"); listItems = new ArrayList(); listItems.add("Mango"); listItems.add("Apple"); listItems.add("Banana"); } public void actionListener(){ System.out.println("Action Listener fired!"); } }
您是否看到任何应该导致postconstruct回调每次都触发的行为? 我认为JSF 2.0非常不稳定。 如果每次@ViewScoped服务的目的都必须触发PostConstruct。 为什么不只使用@RequestScoped? 我以为我在申请中犯了一些错误。 但是当我在JSF中创建这个最简单的时候,我仍然会遇到这个错误。 我不理解JSF的范围? 或者他们没有正确测试? 此外,如果你删除c:forEach并用ui:repeat替换它,那么它工作正常。
等待回复以确认它是否是错误或是故意阻止程序员使用jstl?
这个问题与你之前回答的问题有相同的理由: 为什么@PostConstruct回调每次都会触发,即使bean是@ViewScoped? JSF 。
这确实是JSF2中的一个错误。 这是一个鸡蛋问题。 视图范围的bean存储在JSF视图状态中。 因此,视图范围bean仅在还原视图阶段后可用。 但是,JSTL标记在还原视图阶段运行,而视图范围bean尚不可用。 这会导致创建一个全新的视图范围的bean实例,然后由实际的视图范围bean替换,该bean存储在恢复的JSF视图状态中。
这被报告为JSF问题1665和JSF规范isssue 787 ,它已针对JSF 2.2修复并移植回Mojarra 2.1.18。 所以,只需升级到Mojarra 2.1.18即可。
如果您无法升级,那么最好的办法是在请求/会话/应用程序作用域上使用JSTL标记,或者寻找特定function需求的替代方法。 您可以使用
替换
,如您所知。
也可以看看:
- JSF 2.0中的通信 –
@ViewScoped
在taghandler中失败 - JSF2 Facelets中的JSTL有意义吗?