@ViewScoped在每个回发请求上调用@PostConstruct

这看起来不正确。 我正在做一些清理我的代码,我只是注意到了这一点。 每个Ajax请求都会触发我的@ViewScoped bean的构造函数和@PostConstruct 。 即使是一个简单的数据库分页也是如此。

我知道 @ViewScoped@RequestScoped更长,并且不应该在每个请求中重build。 只有在通过GET重新加载完成页面之后。

换句话说,你的@ViewScoped bean的行为就像一个@RequestScoped bean。 每个回发请求都从头开始重新创build。 有很多可能的原因,其中大部分原因归结为相关的JSF视图在JSF状态中不再可用,而JSF状态又是默认与HTTP会话相关联的。

  1. 您正在使用Mojarra 2.1.17或更高版本,并且该视图包含EL视图,该视图将视图范围的bean属性绑定到在视图构build时间期间评估的标记属性。 示例是JSTL <c:if><c:forEach>等或JSF <ui:include><x:someComponent id="#{...}"<x:someComponent binding="#{...}">这是由于Mojarra( 问题1492 )中的一个错误造成的。 另请参见为什么@PostConstructcallback触发,即使bean是@ViewScoped? 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属性的值binding到视图范围的bean属性是一个不好的做法。 这些应该真的绑定到一个请求范围的bean属性,或者应该寻找替代方法。 另请参见JSF中的“绑定”属性如何工作? 何时以及如何使用?

  2. 您正在使用Mojarra 2.2.0,只有该版本在维护已经在2.2.1中已经修复的视图范围时有一个(但是未知的)错误,参见问题2912 。 解决scheme是升级到更新的版本。

  3. @ViewScoped注释是从错误的包中导入的。 JSF提供了两个@ViewScoped注释,一个来自javax.faces.bean包,用于@ManagedBean注解的JSF托pipebean,另一个来自javax.faces.view包,用于包含用@Named注释的CDI托pipebean。 当bean范围标注与beanpipe理标注不匹配时,实际的bean范围将成为beanpipe理框架的默认范围,即JSF托pipebean中的@RequestScoped和CDI托pipebean中的@Dependent

    您需要确保您具有以下任一结构并且不要混合使用,另请参阅使用JSF 2.2时在每个回发请求上重新创build的@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 { 
  4. 视图是(意外?)通过<f:view transient="true">标记为瞬态的。 这基本上打开了自Mojarra 2.1.19以来新的“无状态的JSF”。 因此,JSF视图根本不会保存在JSF状态中,而逻辑上的后果就是所有引用的视图范围的bean都不能再与JSF视图相关联。 另请参见JSF中无状态的用处是什么?

  5. Web应用程序configuration了com.sun.faces.enableRestoreView11Compatibility上下文参数设置为true ,以避免ViewExpiredException的错误尝试。 有了这个上下文参数, ViewExpiredException永远不会被抛出,但视图(以及所有关联的视图范围的bean)将从头开始重新创build。 但是,如果每次请求都发生这种情况,那么这种方法实际上隐藏了另一个问题:视图过期太快。 这表明在维护JSF视图状态和/或HTTP会话时可能存在问题。 如何正确地解决/configuration,头向javax.faces.application.ViewExpiredException:视图无法恢复 。

  6. Web应用程序的运行时类path受到多个不同版本的JSF API或impl相关类的污染。 这会导致JSF视图状态的标识符/标记损坏/不匹配。 您需要确保在webapp的/WEB-INF/lib没有多个JSF API JAR文件。 如果您使用的是Maven,请确保您将服务器提供的库标记为<scope>provided</scope> 。 另请参见我们的JSF wiki页面中的 “安装JSF”部分以及相关问题的答案: 如何通过Maven正确安装和configurationJSF库? 。

  7. 在使用PrimeFaces <p:dialog> ,确保<p:dialog>具有自己的<h:form> ,并且它不嵌套在另一个<h:form> 。 参见p:fileUpload里面的p:对话框丢失@ViewScoped值 。

  8. 当您将PrimeFaces FileUploadFilter与PrettyFaces结合使用时,请确保FileUploadFilter也在PrettyFaces重写/转发的请求上运行。 另请参见当使用PrettyFaces调用FileUploadListener时 如何 重buildViewScoped bean以及如何使用PrimeFaces p:fileUpload? Listener方法永远不会被调用或者UploadedFile为null 。

  9. 在使用PrettyFaces时,将CSS / JS / image资源redirect到绑定到@ViewScoped bean的JSF页面上的configuration错误的重写规则也会@ViewScoped错误的行为。 另请参见CDI ViewScope和PrettyFaces:多次调用@PostConstruct(JSF 2.2) 。