JSF 2 facelets <f:metadata/> dans le modèle de page et

J'ai le modèle suivant (masterLayout.xhtml):

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:ui="http://java.sun.com/jsf/facelets">
    <f:view contentType="text/html">
        <ui:insert name="metadata"/>
        <h:head>
            <title><ui:insert name="windowTitle"/> | MySite</title>
        </h:head>

        <h:body>
            <div id="container">
                <div id="header">
                    <ui:insert name="header">
                        <ui:include src="/WEB-INF/templates/header.xhtml"/>
                    </ui:insert>
                </div>
                <div id="content">
                    <ui:insert name="content"/>
                </div>
                <div id="footer">
                    <ui:insert name="footer">
                        <ui:include src="/WEB-INF/templates/footer.xhtml"/>
                    </ui:insert>
                </div>
            </div>
        </h:body>
    </f:view>
</html>

et la page qui l'utilise (de recherche.xhtml):

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:f="http://java.sun.com/jsf/core">
    <h:head>
        <title></title>
    </h:head>
    <h:body>
        <ui:composition template="/WEB-INF/templates/masterLayout.xhtml">
            <ui:define name="metadata">
                <f:metadata>
                    <f:viewParam name="address" value="#{searchBean.address}"/>
                    <f:event type="preRenderView" listener="#{userSessionBean.preRenderViewCookieLogin(e)}"/>
                    <f:event type="preRenderView" listener="#{searchBean.preRenderView(e)}"/>
                </f:metadata>
            </ui:define>
            <ui:define name="windowTitle">#{searchBean.address}</ui:define>

            <ui:define name="content">

                <!-- Content goes here -->

            </ui:define>
        </ui:composition>
    </h:body>
</html>

Le problème est que je veux placer l'appel à userSessionBean.preRenderViewCookieLogin(e) dans le modèle parce qu'il y a de nombreuses autres pages. Cette méthode vérifie que l'utilisateur est connecté (en fonction de l'état de session) et, si non, vérifie qu'un cookie est disponible qui peut être utilisé pour connecter l'utilisateur et, si oui (et si en cours de validité), les journaux de l'utilisateur automatiquement. Le système fonctionne dans le code ci-dessus, mais quand j'essaie de le pousser dans le modèle, de mon point de vue, les paramètres ne sont plus ensemble.

Voici la version modifiée de la version ci-dessus, avec userSessionBean.preRenderViewCookieLogin(e) poussé jusqu'à la modèle.

masterLayout.xhtml:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:ui="http://java.sun.com/jsf/facelets">
    <f:view contentType="text/html">
        <f:metadata>
            <f:event type="preRenderView" listener="#{userSessionBean.preRenderViewCookieLogin(e)}"/>
            <ui:insert name="metadata"/>
        </f:metadata>
        <h:head>
            <title><ui:insert name="windowTitle"/> | MySite</title>
        </h:head>

        <h:body>
            <div id="container">
                <div id="header">
                    <ui:insert name="header">
                        <ui:include src="/WEB-INF/templates/header.xhtml"/>
                    </ui:insert>
                </div>
                <div id="content">
                    <ui:insert name="content"/>
                </div>
                <div id="footer">
                    <ui:insert name="footer">
                        <ui:include src="/WEB-INF/templates/footer.xhtml"/>
                    </ui:insert>
                </div>
            </div>
        </h:body>
    </f:view>
</html>

de recherche.xhtml

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:f="http://java.sun.com/jsf/core">
    <h:head>
        <title></title>
    </h:head>
    <h:body>
        <ui:composition template="/WEB-INF/templates/masterLayout.xhtml">
            <ui:define name="metadata">
                <f:viewParam name="address" value="#{searchBean.address}"/>
                <f:event type="preRenderView" listener="#{searchBean.preRenderView(e)}"/>
            </ui:define>
            <ui:define name="windowTitle">#{searchBean.address}</ui:define>

            <ui:define name="content">

                <!-- Content goes here -->

            </ui:define>
        </ui:composition>
    </h:body>
</html>

Avis que j'ai déplacé le <f:metadata/> balise pour le modèle. C'est le seul problème que la suppression userSessionBean.preRenderViewCookieLogin(e) ne fait aucune différence. J'ai aussi essayé une variation sur le code qui a travaillé, qui a été à juste déplacer userSessionBean.preRenderViewCookieLogin(e) dans le modèle, ce qui signifie qu'il ne peut pas être à l'intérieur de la <f:metadata/> tag. Dans ce cas, la méthode exécutée après que tous les paramètres de vue avaient été établies et searchBean.preRenderView(e) appelé. Je veux userSessionBean.preRenderViewCookieLogin(e) à être appelée avant tout de la page preRenderView(e) est appelé, et pas après. Et juste pour le fun j'ai essayé de mettre un <f:metadata/> autour de userSessionBean.preRenderViewCookieLogin(e), qui appelle cette méthode, mais n'a pas défini les paramètres d'affichage.

Donc, je voudrais savoir:

  1. Pourquoi est-ce qui se passe et est-il un moyen de le réparer?
  2. Est-il une meilleure façon de s'assurer de la même méthode est appelée à chaque page avant de quelque chose d'autre?

Edit:
Je viens d'essayer quelque chose d'autre - une phase de l'événement:
<f:view contentType="text/html" beforePhase="#{userSessionBean.beforePhase(e)}">
C'est dans masterLayout.xhtml. Il n'est pas appelée à tous; ce n'est pas n'importe quelle phase.

Edit:
Enlevé le e (damn vous NetBeans!):
<f:view contentType="text/html" beforePhase="#{userSessionBean.beforePhase}">
Ce n'est appelée avant que le rendu de la réponse de phase, ce qui bien sûr, signifie qu'il est appelé d'après le preRenderView événement est déclenché.

OriginalL'auteur Distortum | 2011-09-27