Tiens, allez, c’est Noël après tout : encore un tutoriel technique de derrière les fagots (Noël – cheminée – fagots… tout le monde suit je pense).
Les règles de navigation de JSF 2 sont ma foi très pratiques pour découpler l’implémentation physique des vues de la logique “métier”. Vos méthodes d’action peuvent renvoyer un mot-clef, l’outcome, interprété par le NavigationHandler à partir de déclarations externalisées dans le fichier faces-config.xml standard. Exemple, pour rappel :
La logique ci-dessus indique, vous le voyez, que lorsque le résultat de l’action est “success” vous serez redirigé vers la vue “next”, tandis que vous seriez redirigé vers la vue “errors” si le résultat était “error”. Ainsi votre action est découplée à la fois de la réalité “physique” de l’implémentation des vues, et de la logique de navigation. En effet, il sera possible de modifier l’emplacement des vues visées et d’opter pour des redirections différentes selon que l’action sera appelée depuis un emplacement ou un autre (si *doSomething* était appelé depuis *next.xhtml*, alors *to-view-id* pourrait pointer vers *end.xhtml* pour l’*outcome* “success”, par exemple). Bref.Si vous utilisez PrimeFaces Mobile, vous allez définir des vues multiples, internes aux vues JSF classiques. Sous forme de pages. Cela peut prendre la forme suivante :
Vous constatez que PrimeFaces Mobile emploie une syntaxe particulière d’*outcome*, avec un préfixe “#” (commandLink) ou “pm:” (commandButton). Pour que la boucle soit bouclée, les méthodes d’action doivent retourner des *outcomes* préfixés par “pm:”, et le tour sera joué. Tout ceci grâce à la classe **MobileNavigationHandler** introduite par l’API qui fait comme ceci : Malheureusement, et c’est là que je voulais en venir, les règles de navigation ne sont pas prises en compte par cette API. Vous voyez ci-dessus que seul l’*outcome* est considéré, et que lorsque le préfixe est détecté alors les règles de navigation sont purement et simplement ignorées. C’est *ben plate*, comme on dit à Montréal. Concrètement, il n’est pas possible d’écrire ceci nativement : Personnellement, je trouve ça navrant. Parce que cela nous force potentiellement à surcharger ou (pire) à recoder des *beans*, juste pour renvoyer les bons *outcomes*. C’est franchement la *loose* quand on veut avoir une couche vue *web* ET une couche vue *mobile*, sans toucher à la couche des *managed beans* (ce qui est la moindre des choses à mon avis). Mais au lieu de râler et de me lamenter, j’ai cherché une solution de contournement. Et ben j’ai trouvé (c’est Noël après tout, non ?). Voilà, c’est cadeau : Vous remarquerez que nous n’étendons pas la classe MobileNavigationHandler, ce serait contraire au pattern Délégation ici en oeuvre. Cependant, nous avons une dépendance à MobileUtils. Après tout, “it’s all about PrimeFaces Mobile” ; cette classe n’a pas d’intérêt sans lui, c’est donc justifié. Il ne reste plus qu’à enregistrer notre gestionnaire de navigation pour l’application dans faces-config.xml, nos méthodes d’action pourront continuer à renvoyer leurs *outcomes* agnostiques, ce sont les règles de navigation qui continueront à décider sereinement de la marche à suivre. Ce sera plus tant mieux !Et Bonne Année à tous !