@PostConstruct
bean的构造函数和@ViewScoped
。即使是简单的数据库分页也会触发它。我知道
@ViewScoped
比@RequestScoped
长,因此不应在每次请求时都对其进行重构。只有在通过GET重新加载完整的页面之后。#1 楼
换句话说,您的@ViewScoped
bean的行为类似于@RequestScoped
bean。它已在每个回发请求中从头开始重新创建。造成这种情况的原因有很多,其中多数原因可以归结为:在JSF状态下,关联的JSF视图不再可用,而该状态又默认与HTTP会话相关联。您可以确保HTTP会话本身不是问题的根本原因,即当
@SessionScoped
绝对正常运行时,请遍历以下可能的原因列表。否则,如果HTTP会话本身也被删除并在每个单个请求上重新创建,那么您需要退后一步,查看会话cookie和服务器配置。与HTTP会话中断有关的任何原因至少都超出了JSF的范围。您正在使用Mojarra 2.1.17或更早的版本,并且该视图包含绑定视图的EL表达式将范围为Bean的bean属性赋予标签属性,该标签属性在视图构建期间进行评估。例如JSTL
<c:if>
,<c:forEach>
等或JSF <ui:include>
,<x:someComponent id="#{...}"
,<x:someComponent binding="#{...}">
等。这是由Mojarra中的错误(发行1496)引起的。另请参见为什么即使bean是@ ViewScoped,@ PostConstruct回调也会每次触发? JSF 此问题已在Mojarra 2.1.18版中修复。如果您不能升级到较新的版本,解决方法是禁用下面的部分状态保存,如
web.xml
所示,还请参见JSF2 Facelets中的JSTL ...有意义吗? <context-param>
<param-name>javax.faces.PARTIAL_STATE_SAVING</param-name>
<param-value>false</param-value>
</context-param>
或当您想要仅针对特定的一组JSF视图:
<context-param>
<param-name>javax.faces.FULL_STATE_SAVING_VIEW_IDS</param-name>
<param-value>/foo.xhtml;/bar.xhtml;/folder/baz.xhtml</param-value>
</context-param>
重要的是将JSF组件的
id
或binding
属性的值绑定到视图作用域的bean属性是一种不好的做法。那些应该确实绑定到请求范围的bean属性,或者应该寻求替代方法。另请参见“绑定”属性在JSF中如何工作?什么时候以及如何使用?您正在使用Mojarra 2.2.0,只有该版本在维护视图范围时存在一个(至今未知)错误,该错误已在2.2.1中修复,另请参见问题2916。解决方案是升级到较新版本。
从错误的包中导入了
@ViewScoped
批注。 JSF提供了两个@ViewScoped
批注,一个来自javax.faces.bean
包,用于由@ManagedBean
注释的JSF托管bean,另一个来自javax.faces.view
包,用于以@Named
注释的CDI托管bean。当bean作用域注释与bean管理注释不匹配时,实际的bean作用域将成为bean管理框架的默认作用域,在JSF受管bean中为@RequestScoped
,在CDI受管bean中为@Dependent
。您需要确保您具有以下两种构造中的一种,并且不要混合使用,请参见使用JSF 2.2时在每个回发请求上重新创建的@ViewScoped bean。
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
@ManagedBean
@ViewScoped
public class CorrectJSFViewScopedBean implements Serializable {
import javax.inject.Named;
import javax.faces.view.ViewScoped;
@Named
@ViewScoped
public class CorrectCDIViewScopedBean implements Serializable {
通过
<f:view transient="true">
(偶然地?)将该视图标记为瞬态。这基本上打开了“无状态JSF”,这是自Mojarra 2.1.19之后的新功能。因此,根本不会将JSF视图完全保存为JSF状态,并且逻辑上的结果是,所有引用的视图范围的Bean都无法再与JSF视图关联。另请参见JSF中无状态的用途是什么?该Web应用程序配置了
com.sun.faces.enableRestoreView11Compatibility
上下文参数,该上下文参数设置为true
,这是一种错误尝试“避免” ViewExpiredException
的方式。使用此上下文参数,将永远不会抛出ViewExpiredException
,但是将仅从头开始重新创建视图(以及所有关联的视图作用域Bean)。但是,如果在每个请求上都发生这种情况,则此方法实际上隐藏了另一个问题:视图过早过期。这表明在维护JSF视图状态和/或HTTP会话时可能存在问题。如何正确解决/配置该问题,请转至javax.faces.application.ViewExpiredException:无法恢复视图。Web应用程序的运行时类路径被多个不同版本的JSF API或与impl相关的类所污染。这会导致JSF视图状态的标识符/标记损坏/不匹配。您需要确保在webapp的
/WEB-INF/lib
中没有多个JSF API JAR文件。如果使用的是Maven,请确保将服务器提供的库标记为<scope>provided</scope>
。另请参见我们的JSF Wiki页面中的“安装JSF”部分,以及以下相关问题的答案:如何通过Maven正确安装和配置JSF库?。当您使用PrimeFaces时
<p:dialog>
,然后确保<p:dialog>
有自己的<h:form>
,并且没有嵌套在另一个<h:form>
中。另请参见p:dialog中的p:fileUpload丢失@ViewScoped值。当您将PrimeFaces
FileUploadFilter
与PrettyFaces结合使用时,请确保FileUploadFilter
也可以在经重写/转发的PrettyFaces上运行要求。另请参见当使用PrettyFaces调用FileUploadListener和如何使用PrimeFaces p:fileUpload时重建的ViewScoped bean。永远不会调用侦听器方法,或者UploadedFile为null /引发错误/无法使用。绑定到@ViewScoped
bean的JSF页面也会产生误导性行为。另请参见CDI ViewScope和PrettyFaces:多次调用@PostConstruct(JSF 2.2)。
评论
没错我在网页上添加了一个使用c:foreach的功能。难怪我以前没有注意到它。问题是ui:repeat在我的情况下不起作用。 primefaces.prime.com.tr/forum/viewtopic.php?f=3&t=59部分状态保存是否可以与c:for一起使用?
–提请H
2011年4月4日17:55
不幸的是,不,禁用部分状态保存不能解决JSTL标签的问题。然而,这种特殊情况是棘手的。从理论上讲,您可以使用一个有价值的组件来解决此问题,例如
接受一个集合,而不是
0”}> ...时遇到了这个问题,因此我修复了将替换为
。我相信这是曾经作为功能请求发布到PrimeFaces的,不确定Cagatay做了什么。
– BalusC
2011年4月4日在18:07
PARTIAL_STATE_SAVING改变了我的生活
– Mert inan
2012年11月15日12:35
@Danijel:只是使用渲染属性?另请参阅stackoverflow.com/a/4870557和stackoverflow.com/a/15947948。或者,只需升级到Mojarra 2.1.18或更高版本。此后已修复。
– BalusC
13年5月15日在13:59
谢谢。使用
–亚历山大·特苏里卡(Oleksandr Tsurika)
2015年4月20日在16:28