PreRenderView incrementally called on every postback

谁说我不能喝 提交于 2019-11-30 09:42:33

I can reproduce it. This is caused by the presence of /WEB-INF/beans.xml and implicitly thus CDI. It even occurs when you switch back to standard JSF annotations while keeping the beans.xml file. This is already reported as both issue 1771 and issue 2162. However, due to absence of a concrete WAR file reproducing the issue and low votes, the Mojarra developers didn't bother to look closer at it.

I have reported it once again as issue 2719. The problem can be reproduced with a smaller example:

<!DOCTYPE html>
<html lang="en"
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:ui="http://java.sun.com/jsf/facelets"
>
    <f:metadata>
        <f:event type="preRenderView" listener="#{bean.preRenderView}" />
    </f:metadata>
    <h:head>
        <title>preRenderView fail</title>
    </h:head>
    <h:body>
        <p>On initial request, you'll see the listener being invoked twice instead of only once.</p>
        <p>On every postback by the below button, you'll see the listener being invoked once more.</p>
        <h:form>
            <h:commandButton value="submit" />
        </h:form>
        <p>Note however that this increments every time you issue the postback.</p>
        <p>If you remove <code>/WEB-INF/beans.xml</code> and redeploy, then the issue will disappear.</p>
    </h:body>
</html>

and

package com.example;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;

@ManagedBean
@RequestScoped
public class Bean {

    public void preRenderView() {
        System.out.println("preRenderView called");
    }

}

A missing resource may also cause the listener to be called twice. I'm using MyFaces 2.2 here:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:ui="http://java.sun.com/jsf/facelets">

<f:metadata>
    <f:event type="preRenderView" listener="#{testController.update()}" />
</f:metadata>

<h:head>
    <script type="text/javascript" src="#{resource['/js/missing.js']}" />
    <title>Test</title>
</h:head>

<h:body>
    <p>TestController.update() is called twice.</p>
</h:body>

</html>

Obviously, you shouldn't include any missing or obsolete resources in the first place. But let's say you have (by mistake) and your listener gets called twice on and on, you have no chance to find the actual cause of that problem. JSF shouldn't do this.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!