IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JSF Java Discussion :

Créer une redirection dans mon application


Sujet :

JSF Java

  1. #1
    Rédacteur
    Avatar de romaintaz
    Homme Profil pro
    Java craftsman
    Inscrit en
    Juillet 2005
    Messages
    3 790
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Java craftsman
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2005
    Messages : 3 790
    Points : 7 275
    Points
    7 275
    Par défaut Créer une redirection dans mon application
    Bonjour,

    J'ai une application web au sein de laquelle les utilisateurs peuvent acceder directement à certaines pages (par exemple une page de visualisation d'un item, ou encore une page d'édition).
    Afin de réaliser ceci, je fournis une URL particulière. Cette URL est accessible à l'extérieur de mon appli web, comme par exemple au sein d'un email ou d'une autre appli-web.

    L'url ressemble à quelque chose de ce genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    http://myserver/my-app/forward.jsf?action=XXX&actionParam=YYY
    où :

    • action représente un identifiant symbolisant la page vers laquelle l'utilisateur va être redirigé. On peut considérer cela comme le from-outcome d'une règle de navigation de JSF.
    • actionParam est un paramètre pour l'action précédente (généralement un ID).


    Je vais par exemple avoir ce genre d'URL :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    http://myserver/my-app/forward.jsf?action=viewItem&actionParam=1234
    http://myserver/my-app/forward.jsf?action=editItem&actionParam=1234
    Du côté Java, j'ai un bean qui va réaliser certains tests de sécurité (savoir si l'utilisateur a le droit de voir / éditer l'item en question par exemple). Ensuite, il redirige l'utilisateur vers la bonne page, par ex. edit.xhtml, view.xhtml ou access-denied.xhtml si l'utilisateur n'est pas censé voir cette page.

    Mon implementation actuelle

    Aujourd'hui, la façon de faire est très basique : Quand un utilisateur clique sur l'URL, la page XHTML suivante est appelée :

    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <html>
        <body>
            <form id="forwardForm">
                <h:inputHidden id="myAction" binding="#{forwardBean.hiddenAction}"/>
                <h:inputHidden id="myParam" binding="#{forwardBean.hiddenActionParam}"/>
                <h:commandButton id="forwardBtn" actionListener="#{forwardBean.doForward}" style="display: none;"/>
                <script type="text/javascript">
                    document.getElementById('forwardForm:forwardBtn').click();
                </script>
            </form>
        </body>
    </html>


    On peut le voir, je binde 2 <h:inputHidden> dans mon bean Java. Ils vont être utilisés pour stocker la valeur de action et actionParam, en les récupérant depuis les paramètres de la requête :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("actiontParam");
    Je fournis également une action doForward qui va être immédiatement appelée quand la page est créée, ce qui va avoir comme conséquence de redirigé à nouveau l'utilisateur sur la bonne page cette fois-ci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    public void doForward(ActionEvent evt) {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        String redirect = // define the navigation rule that must be used in order to redirect the user to the adequate page...
        NavigationHandler myNav = facesContext.getApplication().getNavigationHandler();
        myNav.handleNavigation(facesContext, null, redirect);
    }
    Cette solution fonctionne, mais me pose 2 soucis :

    • Je n'aime pas cette façon de faire, je suis sûr que l'on peut trouver quelque chose de plus propre.
    • Nous devons bientôt gérer le BlackBerry, et le Javascript est tout simplement interdit (oui, le BB supporte le JS, mais là n'est pas la question).

    Il me faut donc considérer une refactorisation de cette fonctionnalité de redirection. Comment dois-je aborder la chose ?

    Je précise une chose : dans mon doForward, je vais rediriger l'utilisateur vers une page donnée, cette page étant identifiée via son from-outcome dans le fichier faces-config.xml. Autrement dit, cette redirection se base sur un contexte JSF qui doit donc être existant.
    La solution d'opter pour une Servlet ne me parait pas forcément une bonne idée donc..

    Infos Techniques

    Java 1.6, JSF 1.2, Facelets, Richfaces 3.3
    Nous sommes tous semblables, alors acceptons nos différences !
    --------------------------------------------------------------
    Liens : Blog | Page DVP | Twitter
    Articles : Hudson | Sonar | Outils de builds Java Maven 3 | Play! 1 | TeamCity| CitConf 2009
    Critiques : Apache Maven

  2. #2
    Rédacteur

    Profil pro
    Inscrit en
    Juin 2003
    Messages
    4 184
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 4 184
    Points : 5 059
    Points
    5 059
    Par défaut
    ça me rappel quelque chose .. ah oui un truc qui s'appelle Struts..

    Pourquoi tu ne redéfinis pas le phase listener dans lequel tu récupère l'url, le viewId.. .

  3. #3
    Rédacteur
    Avatar de romaintaz
    Homme Profil pro
    Java craftsman
    Inscrit en
    Juillet 2005
    Messages
    3 790
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Java craftsman
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2005
    Messages : 3 790
    Points : 7 275
    Points
    7 275
    Par défaut
    Bah en fait je trouve ça un peu barbare / intrusif de mettre un PhaseListener rien que pour ça, qui va donc checker ce genre de chose à chaque requête reçue par le serveur. Mais je suis d'accord que ce pourrait être une solution possible...

    En fait, ce qu'il me faudrait, c'est pouvoir dire, dans ma doForward() un truc du genre "ok mon bichon*, maintenant que tu as quasiment fini ton cycle de vie JSF, bah tu vas tout recommencer, mais cette fois-ci tu vas refaire avec une autre vue".


    * oui je suis intime avec JSF
    Nous sommes tous semblables, alors acceptons nos différences !
    --------------------------------------------------------------
    Liens : Blog | Page DVP | Twitter
    Articles : Hudson | Sonar | Outils de builds Java Maven 3 | Play! 1 | TeamCity| CitConf 2009
    Critiques : Apache Maven

  4. #4
    Rédacteur

    Profil pro
    Inscrit en
    Juin 2003
    Messages
    4 184
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 4 184
    Points : 5 059
    Points
    5 059
    Par défaut
    tu peux aussi utiliser le viewHandler..
    Sinon faire comme ce que tu fais et jouer avec des variables de sessions.

  5. #5
    Rédacteur
    Avatar de romaintaz
    Homme Profil pro
    Java craftsman
    Inscrit en
    Juillet 2005
    Messages
    3 790
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Java craftsman
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2005
    Messages : 3 790
    Points : 7 275
    Points
    7 275
    Par défaut
    Bon, j'ai réussit à me dépatouiller, mais ma solution me plait toujours qu'à moitié...

    Mon doForward fait ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
        private void applyForward() {
            FacesContext facesContext = FacesContext.getCurrentInstance();
            // Find where to redirect the user.
            String redirect = getTheFromOutCome();
     
            // Change the Navigation context.
            NavigationHandler myNav = facesContext.getApplication().getNavigationHandler();
            myNav.handleNavigation(facesContext, null, redirect);
     
            // Update the user
            UIViewRoot vr = facesContext.getViewRoot();
            if (vr != null) {
                String url = facesContext.getExternalContext().getRequestContextPath();
                url = url + "/" + vr.getViewId().replace(".xhtml", ".jsf");
                Object obj = facesContext.getExternalContext().getResponse();
                if (obj instanceof HttpServletResponse) {
                    HttpServletResponse response = (HttpServletResponse) obj;
                    try {
                        response.sendRedirect(response.encodeURL(url));
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    En gros, je chope via le ViewRoot l'URL de la page à afficher, je replace son extension .xhtml en .jsf (c'est définit comme ça dans mon web.xml), et ensuite je redirige mon ami l'utilisateur vers sa page.

    Ca a l'air de marcher, mais bon, c'est quand même la solution delamorkitu (c).
    Nous sommes tous semblables, alors acceptons nos différences !
    --------------------------------------------------------------
    Liens : Blog | Page DVP | Twitter
    Articles : Hudson | Sonar | Outils de builds Java Maven 3 | Play! 1 | TeamCity| CitConf 2009
    Critiques : Apache Maven

  6. #6
    Rédacteur
    Avatar de romaintaz
    Homme Profil pro
    Java craftsman
    Inscrit en
    Juillet 2005
    Messages
    3 790
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Java craftsman
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2005
    Messages : 3 790
    Points : 7 275
    Points
    7 275
    Par défaut
    Bon, a priori, il y a 2 façons de faire.
    Dans tous les cas, j'ai ce code Java dans mon bean :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
        public void navigate() {
            FacesContext context = FacesContext.getCurrentInstance();
            // Retrieve request parameters value.
            Map<String, String> map = context.getExternalContext().getRequestParameterMap();
            String action = map.get("action");
            String actionParam = map.get("actionParam");
            // Get the from-outcome regarding action and actionParam.
            String redirect = getRedirectionPage(action, actionParam);
            context.getApplication().getNavigationHandler().handleNavigation(context, null, redirect);
        }
    A noter qu'il est important que mon navigation-case soit une redirection (sinon ça ne marche pas) :

    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
            <navigation-case>
                <from-outcome>somePage</from-outcome>
                <to-view-id>/pages/somePage.xhtml</to-view-id>
                <redirect/>
            </navigation-case>

    Solution #1

    Définir une page toute simple, et utiliser le beforePhase du composant <f:view> :

    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    <html xmlns:f="http://java.sun.com/jsf/core">
        <f:view beforePhase="#{forwardBean.navigate}"/>
    </html>

    Noter que dans ce cas, la signature de la méthode navigate de mon bean change, afin d'accepter un PhaseEvent en argument.

    C'est finalement assez proche de ce que l'on peut faire avec un PhaseListener...

    Cependant, pour une raison que j'ignore, ça ne marche pas chez moi...

    Solution #2

    On simplifie encore les choses :

    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    <html>
    #{forwardBean}
    </html>

    En gros, ce code fait juste une référence au bean afin que ce dernier soit instancié (il est en scope="request"). Ensuite, au choix on annote la méthode navigate() avec @PostConstruct ou encore on la définit dans init-method de sa configuration Spring (ce qui est mon cas).
    Cette page ne sert donc que de prétexte à l'appel de cette méthode, qui va ensuite réaliser la navigation...
    Nous sommes tous semblables, alors acceptons nos différences !
    --------------------------------------------------------------
    Liens : Blog | Page DVP | Twitter
    Articles : Hudson | Sonar | Outils de builds Java Maven 3 | Play! 1 | TeamCity| CitConf 2009
    Critiques : Apache Maven

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Créer un dossier dans mon application web J2EE
    Par gebtun dans le forum Général Java
    Réponses: 1
    Dernier message: 18/04/2013, 12h19
  2. [WP8] Lire une vidéo dans mon application
    Par rolandl dans le forum Windows Phone
    Réponses: 10
    Dernier message: 20/12/2012, 18h03
  3. [WD10] intégrer une animation dans mon application
    Par zannoubia dans le forum WinDev
    Réponses: 2
    Dernier message: 20/04/2010, 12h05
  4. Afficher une OrdImage dans mon application JAVA
    Par anas.eh dans le forum Oracle
    Réponses: 4
    Dernier message: 23/11/2007, 16h02
  5. importation d'un fonction d'une dll dans mon application
    Par jeannot27 dans le forum C++Builder
    Réponses: 7
    Dernier message: 11/07/2005, 15h35

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo