这似乎不正确。我正在清理我的代码,我只是注意到了这一点。每个ajax请求都会触发我的@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组件的idbinding属性的值绑定到视图作用域的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标签的问题。然而,这种特殊情况是棘手的。从理论上讲,您可以使用一个有价值的组件来解决此问题,例如接受一个集合,而不是 。我相信这是曾经作为功能请求发布到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



谢谢。使用 0”}> ...时遇到了这个问题,因此我修复了将替换为

–亚历山大·特苏里卡(Oleksandr Tsurika)
2015年4月20日在16:28