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

Dre*_*w H 28 jsf constructor postconstruct jsf-2 view-scope

这似乎不对.我正在清理我的代码,我只是注意到了这一点.每个ajax请求都会触发构造函数和@PostConstruct我的@ViewScopedbean.即使是简单的数据库分页也会触发它.

知道@ViewScoped@RequestScoped任何请求都要重建并且不应该重建.只有在通过GET重新加载完整页面之后.

Bal*_*usC 51

换句话说,你的@ViewScopedbean表现得像一个@RequestScopedbean.它在每次回发请求时都是从头开始重新创建的.造成这种情况的原因有很多种,其中大多数原因归结为JSF状态中的相关JSF视图不再可用,而JSF状态又默认与HTTP会话相关联.

前提是您可以确保HTTP会话本身不是问题的根本原因,即当@SessionScoped工作绝对正常时,请查看以下可能原因列表.否则,如果HTTP会话本身也在每个请求上被删除并重新创建,那么您需要退后一步并查看会话cookie和服务器配置.与HTTP会话损坏相关的任何原因至少超出了JSF的上下文.

  1. 您正在使用Mojarra 2.1.17或更早版本,并且视图包含EL表达式,它将视图范围的bean属性绑定到在视图构建期间评估的标记属性.实例是JSTL <c:if>,<c:forEach>等或JSF <ui:include>,<x:someComponent id="#{...}",<x:someComponent binding="#{...}">等,这是由一个错误在钻嘴鱼科(引起问题1492).另请参阅为什么@PostConstruct回调每次都会触发,即使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>
    
    Run Code Online (Sandbox Code Playgroud)

    或者,当您只想要定位一组特定的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>
    
    Run Code Online (Sandbox Code Playgroud)

    值得一提的是,将JSF组件idbinding属性的值绑定到视图范围的bean属性是一种不好的做法.这些应该真正绑定到请求范围的bean属性,或者应该寻求替代方案.另请参见"绑定"属性如何在JSF中起作用?应该何时以及如何使用?

  2. 您正在使用Mojarra 2.2.0,只有该版本在维护视图范围方面存在(尚未知)错误,该视图范围已在2.2.1中修复,另请参见问题2912.解决方案是升级到更新的版本.

  3. @ViewScoped注释是从错误的包导入.JSF提供了两个@ViewScoped注释,一个来自javax.faces.bean用于注释的JSF托管bean的包@ManagedBean,另一个来自javax.faces.view用于注释的CDI托管bean的包@Named.当bean作用域注释与bean管理批注不匹配时,实际的bean作用域将成为bean管理框架的默认作用域,它@RequestScoped位于JSF托管bean和@DependentCDI托管bean中.

    您需要确保您具有以下任一构造,并且不要混用它们,另请参阅使用JSF 2.2时在每个回发请求上重新创建的@ViewScoped bean.

    import javax.faces.bean.ManagedBean;
    import javax.faces.bean.ViewScoped;
    
    @ManagedBean
    @ViewScoped
    public class CorrectJSFViewScopedBean implements Serializable {
    
    Run Code Online (Sandbox Code Playgroud)

    import javax.inject.Named;
    import javax.faces.view.ViewScoped;
    
    @Named
    @ViewScoped
    public class CorrectCDIViewScopedBean implements Serializable {
    
    Run Code Online (Sandbox Code Playgroud)
  4. 视图(意外地?)标记为瞬态通过<f:view transient="true">.这基本上打开了"无状态JSF",这是自Mojarra 2.1.19以来的新功能.因此,JSF视图根本不会保存在JSF状态中,并且逻辑结果是所有引用的视图范围bean都不能再与JSF视图关联.另请参见JSF中无状态的有用性?

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

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

  7. 当您使用PrimeFaces时<p:dialog>,请确保它<p:dialog>有自己的<h:form>并且它没有嵌套在另一个中<h:form>.另请参阅p:fileUpload里面的p:对话框丢失@ViewScoped值.

  8. 当您将PrimeFaces FileUploadFilter与PrettyFaces 结合使用时,请确保FileUploadFilter它还可以在PrettyFaces重写/转发的请求上运行.另请参见使用PrettyFaces调用FileUploadListener时重建的ViewScoped bean以及如何使用PrimeFaces p:fileUpload?从不调用Listener方法或者UploadedFile为null /抛出错误/不可用.

  9. 当您使用PrettyFaces时,一个配置错误的重写规则将CSS/JS /图像资源重定向到绑定到@ViewScopedbean 的JSF页面也会产生误导性行为.另请参阅CDI ViewScope和PrettyFaces:对@PostConstruct的多次调用(JSF 2.2).

  • @Danijel:只使用`rendered`属性?另请参见http://stackoverflow.com/a/4870557和http://stackoverflow.com/a/15947948.或者,只需升级到Mojarra 2.1.18或更新版本.从那时起它就被修复了. (3认同)

归档时间:

查看次数:

17684 次

最近记录:

7 年,7 月 前