Au cœur des différentes architectures Web  (WebForms, Apache Struts, XSL/XML, HTML ...)

 


Cet article s’intéresse aux différentes manières de traiter les problématiques de présentation. La première partie introduit les diverses facettes de cette couche logicielle ; les deux suivantes présentent les solutions proposées respectivement par la plateforme J2EE (à travers les frameworks de présentation du type Struts) et la plateforme .NET (à travers le framework des WebForms). Enfin, toujours dans un souci de comparaison, nous aborderons une architecture de présentation basée entièrement sur XML et XSL et nous tenterons de peser avantages et inconvénients de chaque solution.

Le thème abordé ici est bien entendu très vaste, et nous ne saurions prétendre à l’exhaustivité. Aussi, après avoir planté le décor de la couche de présentation, nous nous intéresserons particulièrement à la manière dont les erreurs de saisie sont traitées dans les différents frameworks (et nous aborderons brièvement les sujets connexes, qui sont énoncés dans la première section de cet article).

Problématiques majeures de la couche de présentation

1.    Restitution d’informations, présentation de services, multi-canal

La principale responsabilité de la couche de présentation est bien entendu de permettre à l’utilisateur de visualiser informations (textes, graphiques, multimedia) et services dans l’équipement dont il dispose.

Cette activité de « rendu » soulève des questions variées :

·        L’ergonomie : doit-on utiliser du texte, des couleurs, des métaphores graphiques ou sonores

·        Le multi-canal : l’utilisateur souhaite consulter les mêmes informations ou accéder aux mêmes services à travers le Web, le Wap, le téléphone vocal traditionnel, un assistant personnel (PDA)…

·        L’internationalisation (i18n) : le service ou les informations doivent s’adapter aux habitudes linguistiques et culturelles de l’usager. Or, cela tombe bien, la plupart des outils et protocoles permettent la configuration et l’exploitation de la « langue préférée » et du pays de l’utilisateur. Cette information est capitale pour que le service traduise ses libellés dans la bonne langue, qu’il adapte le sens de lecture (français, arabe, chinois), ainsi que les métaphores (couleurs, icônes, sons…)

·        La personnalisation : l’idéal, pour répondre au mieux aux utilisateurs, est de leur donner la possibilité de raffiner eux-mêmes les options de rendu (voire de contenu et de navigation, cf ci-après). Par exemple, la plupart des moteurs de recherche permettent de redéfinir le nombre de réponses attendues par l’utilisateur à chacune de ses requêtes. Cela peut également aller jusqu’à la modification de la charte graphique (ou du « thème », du « skin ») de notre système.

2.    Navigation à travers les différentes fonctionnalités

Cette responsabilité de la couche de présentation est très liée aux aspects précédents. La question est ici de savoir quel cheminement, quel synoptique de navigation dans les informations et services nous proposons aux utilisateurs.

Et bien entendu, comment faire en sorte de bien isoler cet aspect de celui du rendu ! En effet, comme on peut souhaiter modifier une charte graphique sans vouloir toucher à l’enchaînement des pages, on pourrait également désirer modifier la navigation dans un site indépendamment de la présentation (typiquement, certaines options de navigation ne sont accessibles qu’à certains utilisateurs disposant des bonnes accréditations. Exemple : les services protégés, les pages d’administration).

Il faut pouvoir décrire la navigation indépendamment de la présentation, et pouvoir, dans l’idéal, y inclure un minimum d’intelligence (accréditations, parcours « orienté » dans un site marchand, parcours « découverte » pour un type ciblé d’utilisateur…)

3.    Aide à la correction de saisie pour l’utilisateur

« Ce service refuse de fonctionner, et je ne parviens pas à savoir pourquoi ! »

« Cela fait quatre fois que l’on me demande de saisir les mêmes informations, pour la simple raison que j’ai fait une erreur de frappe dans ma date de naissance ou dans l’orthographe de mon lieu de naissance ! C’est un peu fort ! »

Ces utilisateurs vont forcément rechigner à utiliser notre service, ou aller voir ailleurs ! Pour éviter une telle situation, facilitons-leur la tâche : si, dans un questionnaire (formulaire) quelconque, ils saisissent dix informations et se trompent sur une ou deux d’entre elles, il serait de bon ton de :

·        Mémoriser les entrées correctes,

·        Inviter l’utilisateur à ne modifier que celles qui sont erronées,

·        Indiquer pour cela quelle information ne convient pas, et pour quelle raison,

De cette manière, pas de fatalité ni de défaitisme dans l’esprit de nos usagers.

4.    Interactivité, réactivité

L’informatique est une science qui a quelques décennies d’histoire. Les utilisateurs ont donc eu le temps de s’habituer à certaines caractéristiques, en termes d’ergonomie, de fonctionnalités, mais aussi d’utilisabilité et de temps de réponse.

Les nouveaux services (Web, Wap, nomadisme…) ont une offre fonctionnelle très riche. Leur utilisabilité est perfectible, mais un peu de discipline et certaines pratiques (cf thèmes abordés dans les sections précédentes) devraient répondre à ce besoin.

En termes d’interactivité, certains utilisateurs (de gros systèmes en particulier) ont l’habitude de temps de réponse du système assez courts. Mieux, certains ont tellement l’habitude de leurs logiciels (agences de voyage, banques, assurances) qu’ils connaissent les « écrans » et leur enchaînement par cœur, ce qui accélère énormément leur saisie (dans ce genre de système, le logiciel client mémorise toutes les frappes de touches, on peut donc taper des caractères qui apparaîtront seulement dans l’écran suivant : l’utilisateur avancé n’est jamais en attente du système).

Il faudra concevoir une architecture permettant à nos systèmes d’être aussi réactifs que les systèmes connus de certains utilisateurs, tout en assurant les fonctionnalités et l’ergonomie qui font le succès des nouvelles technologies. Typiquement, certaines informations peuvent être préparées de manière asynchrone, et être immédiatement disponibles lors de leur demande par l’utilisateur. Un site permettant la pagination des résultats d’une requête peut, par exemple, tirer parti de la probabilité que l’utilisateur demande la « prochaine » page ou la « précédente » pour préparer ces informations alors que l’utilisateur prend connaissance de la page « courante » (dans un thread asynchrone côté serveur).

Solution Java (J2EE) : Apache Struts

Struts est un framework Open Source (voir ressources) qui répond à la plupart des besoins fondamentaux que nous avons abordés précédemment, en utilisant Servlets et JSP. Il cristallise les meilleures pratiques de conception orientée objet appliquées au développement de sites Web, en s’appuyant énormément sur la notion de Design Pattern. D’autres frameworks adoptent des approches voisines, en ajoutant souvent des outils d’aide à la configuration (description graphique de la navigation, internationalisation optimisée, cache de pages dynamiques…).

Nous nous proposons dans cette section d’examiner l’architecture typique d’un site basé sur Struts, ainsi que le déroulement d’une séquence utilisateur.

Dans un souci de séparation des responsabilités, Struts nous invite tout d’abord à appliquer le modèle MVC (Model-View-Controller) :

·        Contrôleur : une servlet (fournie par Struts et très configurable) est responsable de traiter toutes les requêtes de l’utilisateur.

·        Modèle : des composants JavaBeans représentent l’espace de travail en mémoire, stockent les informations de la requête de l’utilisateur, et sont un point d’entrée vers les services métier ou les données du système

·        Vue : toute présentation dynamique passe par l’utilisation des JSP. Les JSP sont complètement passives, et se bornent à présenter l’espace de travail stocké en mémoire par les JavaBeans, lorsque la servlet leur en donne l’ordre.

Le synoptique de traitement d’une requête utilisateur est donc le suivant :

 

 

 

 

 

 

 


Lorsque le client formule une requête, il s’adresse systématiquement à la servlet contrôleur, qui est unique (elle constitue la Façade de notre système). Celle-ci analyse la requête du client, et l’oriente vers un traitement adéquat. Le résultat du traitement produit généralement des informations, volatiles, stockées sous la forme de JavaBeans. La servlet passe ensuite la main à une page JSP chargée de réaliser le rendu des JavaBeans dans le langage de présentation adéquat (typiquement, HTML dans cet article). Mais cela pourrait bien sûr être WML, VoiceXML, SVG…. Les JSP ont donc dans Struts les responsabilités de restitution, d’internationalisation, de multi-canal, et de personnalisation.

Voyons ensuite comment Struts propose de traiter l’aide à la correction des erreurs de l’utilisateur dans un formulaire. Il suffit pour cela d’associer une classe Java (un « FormBean ») dont les attributs reflètent les champs du formulaire. Cette classe disposera également d’une méthode d’auto-validation, ainsi que d’un attribut (une table d’association) permettant de mémoriser les erreurs de chaque champ.

 

           

 

Struts s’appuiera sur notre classe pour déterminer si les saisies de l’utilisateur sont correctes (validation de surface, éventuellement complétée par une vérification d’existence lorsqu’il s’agit d’informations référençant des données métier : numéro de produit, etc…) : à la réception de la requête du client, la servlet de Struts positionne les propriétés du FormBean aux valeurs saisies par l’utilisateur, et demande au Bean de se valider. S’il est valide, on passera à l’étape suivante dans la navigation du site. Si ce n’est pas le cas, la servlet réoriente l’utilisateur vers la JSP qui avait généré son formulaire, et demande à cette dernière de réafficher le même formulaire, tout en

·        Affichant, face à chaque champ, les messages d’erreurs correspondants (messages que stocke le Bean, souvenez-vous)

·        Positionnant les valeurs des champs saisis précédemment à leurs anciennes valeurs (attributs du Bean)

Le FormBean a donc deux rôles, celui de la validation de surface et de l’indication des erreurs, et celui de mémorisation des valeurs précédemment saisies par l’utilisateur (on peut donc voir ici l’application du pattern Memento).

Reprenons graphiquement le déroulement des événements : le client se connecte une première fois et demande à accéder au formulaire d’une fonctionnalité particulière.

 

 

 

 

 

 

 


Après avoir rempli le formulaire, le client le soumet. Malheureusement, il a commis une erreur lors de la saisie. Donc on lui re-présente son formulaire pré-rempli, en lui indiquant les erreurs commises.

 

 

 

 

 

 

 

 


Une fois les erreurs corrigées, le client soumet à nouveau le formulaire. Pour peu qu’il n’ait pas fait d’erreur, cette fois-ci, sa requête va franchir l’étape de validation et déclencher une action sur le système (cf ci-après).

 

 

 

 

 

 

 


Jusqu’ici, nous avons passé sous silence le mécanisme permettant à la servlet de savoir quel FormBean était associé à chaque requête utilisateur ; poussons donc plus avant le raisonnement. En réalité, le FormBean ne répond qu’à une partie du problème, car l’utilisateur ne souhaite pas seulement valider ses entrées, mais également (c’est son objectif) exécuter des actions sur le système à travers son interface web (achat en ligne, recherche d’informations…). Donc il y aura lieu d’associer au FormBean une « fonctionnalité » (qui bien entendu ne sera déclenchée que si le FormBean valide les saisies de l’utilisateur). Celle-ci pourrait être une méthode du Bean, mais dans un souci de séparation des responsabilités, nous allons l’externaliser dans une classe distincte, que nous appellerons de manière générale une « commande » (vous reconnaîtrez à nouveau un Design Pattern célèbre).

Dans le framework Struts, c’est toujours la servlet contrôleur qui joue le rôle de « routeur » de requêtes client. Le client qui s’adresse au système va demander à exécuter une action particulière (« s’authentifier », « rechercher une info »…) ; cela se concrétise par un paramètre HTTP envoyé du client à la servlet contrôleur : http://……/controleur?action=authentifier.

·        Sur réception de cette requête, la servlet recherche (dans un fichier de correspondances) le FormBean associé à cette requête, positionne ses attributs aux valeurs saisies par l’utilisateur, et demande au Bean de se valider

·        Si la validation échoue (l’utilisateur s’est trompé sur au moins un des champs du formulaire, ou bien il a tenté d’accéder directement à l’exécution du service sans passer par le formulaire et donc les champs ne sont pas renseignés), le contrôleur passe immédiatement la main à la page JSP responsable de présenter (à nouveau) le formulaire d’accès au service. Ce formulaire est enrichi des anciennes valeurs saisies par l’utilisateur lors de sa précédente requête (les TagLibs de Struts rendent ceci automatique), ainsi que des messages d’erreur qui vont inviter l’utilisateur à corriger certains champs de ce formulaire. Cette boucle de « rétro-action » (client-servlet contrôleur-Bean-JSP-client) est sans fin, jusqu’à ce que le client saisisse des informations valables.

·        Lorsque la validation se passe bien, la servlet contrôleur décide d’aller plus loin et d’exécuter la « commande » associée au bean et à la requête client. Cette classe est responsable de rendre le service souhaité, et part du principe que les données d’entrée sont correctes (puisqu’elles ont été validées par le FormBean).

 

 

 

 

 

 

 

 


Pour finir, Struts propose un certain nombre de « TagLibs », des balises spécifiques supplémentaires permettant de bâtir aisément les aspects répétitifs de la couche de présentation (dans les JSP) tels que les tableaux, listes…

Ces balises permettent également l’internationalisation automatique des pages. Les JSP installées dans Struts ont tout intérêt à utiliser ces TagLibs qui traduisent automatiquement des libellés abstraits (texte qui doit apparaître dans les pages Web) en un texte concret dans la langue préférée de l’utilisateur. Cette information linguistique est obtenue de manière transparente, car elle est portée par toute requête HTTP (plus précisément, par le header « accept-langage »).

 

Que manque-t-il à Stuts ?

Struts est un framework assez complet, et propose une architecture purement objet, truffée de Design Patterns. Un site reposant sur cet outil est de ce fait très extensible et aisément maintenable. La prise en main initiale peut toutefois paraître un peu ardue, en particulier aux personnes qui ne sont pas familières des Patterns.

On peut regretter, toutefois, que Struts ne permette de façon standard que de valider les saisies utilisateur côté serveur. En effet, une partie de cette validation gagnerait à être réalisée côté client : un champ non rempli, un format de date non respecté, peut être détecté immédiatement, et donc améliorer la réactivité du système. Cette validation côté client diminuerait également le nombre de requête incorrectes, et donc le nombre de hits sur le serveur.

Il manque également à Struts les notions de pagination, sous la forme de TagLibs supplémentaires par exemple, ainsi que les optimisations du type « thread d’accès aux données proactif ». Cette optimisation consiste, dans un système de pagination (moteur de recherche par exemple), à créer un thread actif dans la session d’un utilisateur, chargé de maintenir un tableau « assez rempli » de réponses à la requête de l’utilisateur. Lorsque l’utilisateur passe à la page suivante, la couche de présentation (ici, une JSP) pourrait très bien travailler sur un tableau en mémoire dans la session ; le résultat serait donc immédiat et l’utilisateur l’obtiendrait en un temps record. Puis, lorsque les données du tableau sont pratiquement toutes consommées (si le prochain accès risque de causer un manque de données), le thread proactif décide spontanément de ré-exécuter la requête utilisateur sur l’engin de stockage et de charger en session les prochaines données. L’utilisateur n’est donc jamais en attente à cause d’un accès base de données puisque ces accès se font lors de la « période de réflexion », ou de lecture, de l’utilisateur.

Enfin, le principal reproche que l’on peut faire à la partie « vue » de Struts est l’utilisation abusive de TagLibs. En effet, une page qui tire parti au maximum des balises étendues de Struts devient complètement illisible pour une personne ne connaissant que le langage HTML. En voulant trop extraire le code des pages JSP, Struts est tombé dans cette aberration qui fait qu’un designer Web ne peut plus vraiment concevoir les pages de rendu : il doit apprendre les balises Struts, ou communiquer énormément avec une personne plus technique. Un outil graphique qui comprendrait à la fois le langage HTML et les TagLibs Struts serait bienvenu, mais cela n’est pour l’instant que de la prospective. Donc le problème risque de persister un moment.

Solution Microsoft (.NET) : WebForms

WebForms aborde la couche de présentation d’une manière originale, atypique par rapport aux « bonnes pratiques de conception objet » que l’on peut rencontrer dans la plupart des frameworks Java.

En effet, le développement de sites Web basés sur les WebForms s’approche davantage de la programmation d’interfaces graphiques typiques (Formulaires Visual Basic par exemple) que de la programmation Web classique (traitement d’une requête, génération de la prochaine page).

Les WebForms sont des composants actifs proposés par l’environnement ASP.NET que l’on peut ajouter à un environnement de conception de page Web de manière graphique, comme si l’on concevait une interface client lourd VB ou C#. Ces éléments peuvent être classés de la manière suivante :

·        les éléments classiques que l’on peut trouver dans un formulaire HTML (bouton, label, zone de texte, combo box, radio, check…)

·        les composants utiles, mais plus complexes à créer dans le monde Web (calendrier graphique HTML, bannière publicitaire dynamique)

·        les outils de « contrainte » permettant de valider les informations saisies par l’utilisateur.

La bonne surprise, lorsqu’on prend en main ce framework, vient du fait qu’il ne repose en rien sur des composants « contrôles ActiveX », qui posent d’énormes problèmes de déploiement et de sécurité. Non, les WebForms sont des composants exécutés côté serveur Web (IIS en l’occurrence), et génèrent des pages 100% standard contenant à la fois HTML et JavaScript. Cela va même plus loin : les WebForms détectent le type de navigateur qui se connecte, et génèrent une page (HTML + JavaScript) compréhensible par ce navigateur en procédant aux adaptations nécessaires (balises non supportées, etc…). Donc ce framework fait preuve d’une grande ouverture vis-à-vis de ses clients Web en s’adaptant à celui-ci. Cette précision étant donnée, reprenons notre étude de la couche de présentation, cette fois en utilisant les WebForms.


 


La création de pages Web avec Visual Studio .NET est très simple, et l’on peut aisément passer du mode texte HTML à un mode graphique très convivial. Mais l’innovation réside dans la manière dont les WebForms nous proposent de traiter les différents événements générés par l’utilisateur (soumission d’un formulaire, click sur un bouton…) : il suffit de double-cliquer sur un composant actif de notre page dans le mode conception pour se retrouver dans une méthode « callback », un gestionnaire d’événement (cette pratique rappellera des souvenirs aux développeurs d’IHM VisualBasic). Par exemple, la réaction à un click bouton sera décrite dans une méthode du type :

Private Sub Button1_Click(ByVal sender As System.Object,

ByVal e As System.EventArgs) Handles Button1.Click

              ‘ Votre code “callback” apparaît ici

              ‘ et sera exécuté côté serveur

        End Sub

 

Cela vous semble obscur, ou magique ? Décortiquons ensemble le fonctionnement de ce mécanisme. Chaque page ASP.NET peut contenir du code HTML, des WebForms, ainsi qu’une référence à une classe VB.NET ou C# que l’on qualifie de « CodeBehind ». Cette classe renferme un ensemble de méthode, et la page ASP.NET peut :

·        soit invoquer une méthode de cette classe CodeBehind pour simplifier sa tâche (un calcul un peu complexe gagne à être implémenté dans le CodeBehind et invoqué par une instruction de Script dans la page ASP.NET)

·        soit router les événements qu’elle reçoit (qui proviennent des utilisateurs, par le biais de leurs navigateurs Web) vers les méthodes adéquates

Typiquement, l’événement « click bouton 1 » généré par l’utilisateur se transforme en une requête HTTP à destination de la page ASP.NET contenant le bouton en question. La page reçoit cette requête, l’interprète et comprend qu’il s’agit d’un événement click sur le bouton numéro 1, et invoque donc la méthode « Button1_Click » sur la classe CodeBehind.

Cette pratique est à la fois simple (un simple double click permet d’installer notre code gestionnaire d’événement), et assez propre ; le code de gestion ne se trouve pas dans la page ASP, mais dans la classe CodeBehind : les responsabilités de traitement et de présentation sont donc assez bien séparées.

 

 

 

 


Mais continuons notre évaluation du framework WebForms par rapport aux responsabilités génériques afférentes à la couche de présentation. En particulier, comment gérer le contrôle des saisies utilisateur en WebForms ? Eh bien c’est déconcertant de simplicité : il suffit de glisser-déposer, en mode conception, un « composant de validation » sur la page ASP.NET. Il existe un panel assez complet de WebForms de validation : RequiredFieldValidator, CompareValidator, RangeValidator, RegularExpressionValidator et CustomValidator. Chaque instance de composant de validation possède un attribut qui indique sur quel champ de formulaire doit s’opérer la validation, ainsi qu’un message d’erreur qui s’affiche lorsque la validation échoue. Au niveau de l’exécution, les choses sont simples :

·        lorsqu’une ASP.NET génère une page HTML, l’utilisateur est invité à en remplir les champs, et à soumettre la page (à la même ASP.NET)

·        sur réception d’une requête, l’ASP.NET exécute immédiatement tous les composants de validation. Si le moindre problème est détecté (champ non rempli, etc…), la page Web est reconstruite pratiquement à l’identique, à ceci près que les messages d’erreur des composants de validation deviennent visibles. L’utilisateur est donc invité à nouveau à saisir les informations du formulaire. Comme dans Struts, les champs précédemment saisis par l’utilisateur et qui n’ont pas généré d’erreur de validation sont automatiquement remplis (aux mêmes valeurs) par les WebForms.

·        enfin, si la page soumise par l’utilisateur est correcte au sens des contraintes de validation (et dans ce cas uniquement), tous les événements sont déclenchés dans la classe CodeBehind. Cela permet de réagir très simplement à une modification de texte dans une TextBox (événement du type « TextBox1_TextChanged »), un click sur un bouton, un changement d’état d’un bouton Radio ou CheckBox… exactement comme on a l’habitude de le faire dans un développement de client lourd type VisualBasic.

Le gros avantage des WebForms, comparé à un framework Java type Struts, réside dans la possibilité de concevoir graphiquement nos pages Web. En effet, VisualStudio.NET est capable de rendre graphiquement à la fois les balises HTML et les WebForms, ce qui est impossible (pour l’instant) avec les TagLibs JSP (sauf à utiliser des TagLibs propriétaires à un éditeur d’environnement de développement Java, ce qui n’est probablement pas une bonne idée).

 

 

 

 

 

 

 

 

 


Une autre avancée non négligeable avec les WebForms : la validation des champs de formulaire peut se faire côté client et côté serveur. Les composants de validation automatique sont en effet capables de générer du code JScript afin d’exécuter côté client une partie de la validation des saisies utilisateur. Pour l’instant, cette génération de code ne fonctionne que si le client est Internet Explorer, version 4.0 ou supérieures. Mais on peut gager que les WebForms génèreront bientôt d’autres scripts de validation côté client (en JavaScript pour Opéra, Mozilla, Netscape…).

Dans tous les cas, même si la validation côté client se passe bien, tout le code de validation sera ré-exécuté côté serveur. Ceci est rendu indispensable pour des raisons évidentes de sécurité, mais pose également le problème de duplication de code et de sémantique de validation : une expression régulière exécutée par l’interpréteur JScript côté client n’a pas exactement la même sémantique que dans le framework .NET (donc dans les langages C# et VB.NET), d’où quelques petites divergences. Attention, donc.

Que manque-t-il aux WebForms ?

Le premier regret concernant les WebForms vient du fait que ce framework ne permet pas de séparer la navigation de la présentation d’un site. Contrairement à Struts qui propose un élément de réponse (partiel) avec son fichier de configuration « struts-config.xml » dans lequel on indique vers quelle page router l’utilisateur en cas de succès ou d’échec d’une commande (ou « action »), les WebForms incitent l’utilisateur à valider un formulaire dans la page ASP.NET qui l’a généré (grâce aux composants de validation côté serveur), et à traiter la commande correspondant à ce formulaire dans la classe CodeBehind. Cette architecture a l’avantage d’être très simple, et donc facile à appréhender. Struts de son côté impose à toutes les requêtes de l’utilisateur de pointer vers la Servlet contrôleur (qui redirige la requête client vers la bonne commande côté serveur), ce qui diminue le couplage entre pages Web (liens hypertextes, attributs « action » des formulaires) et les commandes à déclencher côté serveur. L’architecture WebForms convient donc tout à fait aux petits et moyens sites (pour lesquelles la facilité de prise en main est souvent plus importante que le découplage), mais pose des problèmes de maintenabilité à grande échelle. Par exemple, comment vérifier l’authentification de l’utilisateur qui tente d’accéder à une page ? Faut-il

·        dupliquer du code qui teste cela dans chaque page ASP.NET ?

·        créer un Contrôle personnalisé et l’inclure dans chaque ASP.NET ?

·        faire hériter la classe CodeBehind de fonctionnalités techniques ? (attention à l’héritage simple) ?

·        utiliser des attributs (Aspect Programming) de la classe CodeBehind pour forcer l’authentification ?

Dans tous les cas précités, il existe une dépendance forte entre la présentation et le code applicatif ou technique. Alors qu’en suivant la logique de Struts, comme toutes les requêtes passent nécessairement par la servlet Contrôleur, toute la logique d’authentification peut être centralisée : la servlet est une façade (elle masque le reste du système), un singleton (elle est unique), et peut tirer parti de décorateurs pour implémenter les aspects techniques supplémentaires (authentification, compression automatique de toutes les pages HTML générées dynamiquement, logs personnalisés, analyse de la navigation et des centres d’intérêt des utilisateurs…)

On peut également déplorer que les WebForms ne proposent pas de contrôle gérant automatiquement l’internationalisation des messages textuels apparaissant dans les pages HTML. Bien sûr, il suffit de créer son propre contrôle qui joue avec un assembly satellite (fichier de ressource qui contient par exemple la traduction de messages « logiques » en phrases ou mots « physiques », c’est-à-dire traduits dans un langage particulier). Ce contrôle générique s’appuierait, comme dans les TagLibs de Struts, sur le header HTTP accept-langage pour choisir le bon fichier assembly et donc traduire automatiquement une page Web dans la langue préférée de l’utilisateur. On peut gager que Microsoft inclura rapidement ce genre de bonne pratique au framework (somme toute très jeune) des WebForms.

D’autres reproches, mais qui sont plus du niveau du détail technique que de celui de l’architecture :

·        Attention à l’utilisation des composants complexes tels que le calendrier, la grille de données (DataGrid)… car ceux-ci génèrent une présentation HTML dont tous les liens pointent sur des fonctions JavaScript (pagination dans une DataGrid, mois suivant dans un calendrier). Ceci est très regrettable, car si un client désactive JavaScript dans son navigateur (ou si son firewall éradique automatiquement le code JavaScript des pages HTML téléchargées), ces composants deviennent complètement inutilisables.
Moralité, si l’on n’est pas certain de la configuration des postes clients (donc en particulier si l’on est sur Internet), la recommandation est de redévelopper ses propres composants pour ce genre de fonctionnalité avancée.

·        La pratique par défaut de l’environnement de conception graphique de VisualStudio.NET pour les pages ASP.NET est de positionner tous les composants de manière absolue. Cela donne bien sûr une facilité de conception déconcertante, comme dans une application graphique classique ; mais cela repose le problème des tailles d’écran des postes clients, du redimensionnement dynamique (de plus, les pages s’en trouvent alourdies)…  Il vaut mieux entrer complètement dans la philosophie du langage HTML et adopter un positionnement relatif (passez donc en FlowLayout au lieu de GridLayout dans vos pages ASP.NET).

Solution alternative ou complémentaire XML-XSL

En guise d’ouverture vers d’autres techniques nous pouvons examiner brièvement XML et XSL, qui offrent l’avantage de la neutralité : les architectures basées sur ces outils peuvent être implémentés à la fois dans la plate-forme J2EE et .NET. Nous ne présentons pas de framework particulier dans ce domaine (même si Cocoon est un outil intéressant dans le monde Java) pour deux raisons :

·        tout d’abord pour bien montrer que XML et XSL sont agnostiques aux langages et outils, ils sont compatibles avec les mondes J2EE, .NET, mais aussi Python…

·        parce que les frameworks existants sur le marché ne répondent que partiellement aux problématiques de présentation que nous avons abordées dans cet article.

Tout d’abord, intéressons-nous à la publication d’informations à partir de XML-XSL. Il est très simple, si l’on dispose d’un document XML, de produire une présentation adaptée grâce à une feuille de styles XSL. Produire un document (X)HTML, WML, SVG (image vectorielle), X3D, VoiceXML, ou même PDF est assez simple lorsqu’on connaît le langage XSL bien sûr. Les aspects publication et multi-canal sont donc bien gérés par ce couple d’outils.

 

 

 

 

 

 

 

 


Comme on le voit dans le diagramme précédent, cette architecture offre l’avantage d’une séparation très nette des responsabilités de production de contenu (à partir d’une base de données, d’un annuaire, ou de toute autre source d’informations) et de mise en forme dans un langage adapté à l’équipement de l’utilisateur. La contre-partie est bien sûr qu’il faut que la source d’informations soit compatible XML (SQL Server 2000, Oracle, WebServices, Annuaires compatibles DSML…), ou qu’il faut développer un connecteur spécifique pour une source non-compatible (ce qui peut impliquer une déperdition de performances).

Avec XML et XSL, qu’en est-il de la validation de surface ? Struts reporte cette validation dans des classes Java (FormBeans), les WebForms dans les composants de validation automatique (RegularExpressionsValidator). XML, lui, est parfaitement adapté à la validation de surface grâce aux XML Schémas (qui permettent de vérifier qu’un document respecte une certaine structure, que les informations respectent un certain typage…). Mais voilà : les requêtes HTTP ne sont pas (encore) formulées en XML. Il faut donc qu’un composant (Servlet/JSP ou ASP.NET/CodeBehind) se charge de produire un document XML à partir des requêtes HTTP. Cela ne pose aucun problème vue la structure élémentaire de ces requêtes (généralement, des paires nom-valeur) ; il faut simplement faire attention à l’encodage de requêtes « à compartiments » (multipart). Valider une requête est donc automatique, il suffit d’avoir décrit en XML Schéma les contraintes que nous voulons poser sur les types des différents champs de formulaire.

 

 

 

 

 

 

 

 

 

 

 


Toutefois, le framework ne serait probablement pas écrit entièrement en XML : même si l’on peut décrire des algorithmes complexes et des invocations de fonctions en XSL, il est probablement plus simple, plus concis et plus efficace de le faire en un langage de programmation plus évolué comme C#, Java ou VB.NET. Il faut donc que notre contrôleur (qui traite les requêtes HTTP) soit capable de déclencher soit une méthode d’une classe, soit une transformation XSL (soit les deux, en série, voire un pipeline de traitements et de transformations).

Mais comment gérer l’aspect « internationalisation » en XML ? Eh bien comme d’habitude : par le biais de fichiers de ressources. Au lieu de fichiers « properties » (Java) ou « satellite assemblies » (.NET), utilisons des fichiers… XML qui stockeraient la traduction de messages abstraits en langage naturel. Il suffit ensuite de réaliser la fusion d’un document de présentation qui mentionne ces messages abstraits (en XHTML par exemple) grâce à XSL.

 

 

 

 

 

 

 

 

 

 


Que penser d’une architecture XML-XSL ?

Cette architecture est séduisante, elle répartit bien les responsabilités (contenu, données), facilité l'aggrégation de données ou de services, l'internationalisation, et la validation des saisies utilisateur se fait dans un langage complètement intégré à XML (Schémas).

Toutefois, on peut douter (pour le moment) des performances de ce type de solution. Les processeurs XSL ne sont pas encore arrivés au niveau de performance des JVM ou CLR, mais ce n'est pas le plus inquiétant. Le pire vient probablement du nombre d'encodage / parsing / décodage des informations circulant en XML, ainsi que de leur forte occupation mémoire.

Enfin, pour la couche de publication pure, on manque aujourd'hui cruellement d'outils professionnels et matures permettant un développement graphique de la présentation " souhaitée " et générant la couche XML-XSL sous-jacente (avec la possibilité, comme en HTML aujourd'hui, de raffiner soi-même les feuilles de style pour un besoin spécifique, ou pour améliorer leurs performances). Pour rappel, une feuille XSL ressemble au code suivant :

 

Par contre, un système à forte connotation multi-canal (pour la couche d'accès) ou avec de fortes contraintes d'intégration (pour la couche d'informations ou de services) a tout à gagner à utiliser XML. Ce langage induit en effet un couplage faible et une malléabilité impressionnante.

Conclusion

La plupart des frameworks de présentation et de navigation Java implémentent les Design Patterns MVC (Model-View-Contoller), Memento, Commande, Décorateur, et la pratique des « form beans ». Grâce à l’extensibilité du langage des JSP (taglibs), les pages peuvent être aisément internationalisées.

Le principal reproche que l’on peut faire à ces outils est leur technicité : leur courbe d’apprentissage est vraisemblablement assez longue, sauf bien entendu pour les adeptes des Design Patterns.

Les WebForms proposent un regard nouveau, et invitent à voir le développement Web comme celui des interfaces graphiques traditionnelles. Le mode événementiel est probablement plus simple à appréhender, car plus classique, que les autres outils de développement Web….

A nouveau, la critique facile serait de dire que cet outil n’offre pas une maintenabilité suffisante pour un site de grande envergure. D’un autre côté, la possibilité de concevoir graphiquement même des pages dynamiques (WebForms dans VisualStudio.NET) compense la relative faiblesse d’architecture et le couplage un peu plus fort que ce qu’offre un framework basé sur le MVC.

XML et XSL apportent une réponse différente, une séparation nette et propre du contenu du rendu des informations. L’avantage de ces outils est leur ouverture, leur flexibilité, l’aspect multi-canal poussé à l’extrême. Enfin, XML et XSL sont agnostiques aux langages et plate-formes, ils s’accommodent tant de J2EE que de .NET. Inconvénients : la maîtrise des subtilités de XSL, les performances de processeurs XSL actuels, l’immaturité de l’offre d’outils graphiques pour la conception de feuilles XSL.

Il vous reste donc à déterminer à quels aspects vous souhaitez donner une priorité, et à vous lancer dans l’utilisation d’un de ces passionnants frameworks… et à les enrichir bien entendu !

 

Auteur : Thomas GIL

Copyright : DotNetGuru Ó 2002

 

Ressources

Apache Struts (http://jakarta.apache.org/)

Apache Cocoon (http://xml.apache.org/)

Microsoft WebForms (http://msdn.microsoft.com/msdnmag/issues/01/05/WebForms/WebForms.asp)