Monitoring du serveur Jafar

Dimension: px
Commencer à balayer dès la page:

Download "Monitoring du serveur Jafar"

Transcription

1 . Monitoring du serveur Jafar Travail de n d'études présenté par Gildas Cuisinier en vue de l'obtention du grade de Bachelier en Informatique Industrielle Année académique

2 Remerciements Je remercie tout d'abord la société Manex, qui a eu la gentillesse de m'accueillir et de me guider dans mon stage, ainsi que dans la réalisation de ce T.F.E. Je pense tout particulièrement à Vincent Keunen, qui m'a parrainé au sein de la société, et à Jacques Militello, mon guide durant ces quelques mois. Merci également à ma superviseur, Laurence Herbiet, pour son aide et sa disponibilité. Je remercie enn tous ceux qui ont relu ce T.F.E. et qui m'ont prodigué leurs conseils avisés.

3 Table des matières I Introduction 1 1 Introduction 2 2 Présentation de l'entreprise Manex Personnel Domaines de prédilection Outils et technologies Coordonnées Produits Cahier des Charges Objectif général Principaux points étudiés Cahier des charges de l'application Outils et Frameworks Objectifs Présentation des outils Intellij Idea Subversion JBoss Spring Hibernate Jasper Report ii

4 TABLE DES MATIÈRES II Notions théoriques 11 5 Rappels Généraux Java Introduction Java : présentation générale Java : orienté Objet Java : portabilité Techniques de programmation en Java Sérialisation JavaBean Génériques Java Web Conteneur, Servlet et JSP Balises personnalisées Expression Language XML XML par l'exemple Traiter un chier XML Spring Framework Présentation générale Pour rappel, Spring est Comment fonctionne Spring? Bean Factory / Application Context Le chier de conguration Injection de dépendances Petit exemple pratique Spring Web MVC? Que veut dire MVC? Spring : le dispatcher Spring : les Contrôleurs Spring : les modèles et les Vues Hibernate Présentation générale iii

5 TABLE DES MATIÈRES 7.2 Avantages et inconvénients Guide d'utilisation Lier Hibernate avec une base de données Mapping des objets Le mapping des associations Génération de schémas Conclusion Jafar Présentation générale Adaptation des audits Architecture du serveur Jafar Le client Le serveur Jafar Schéma de la base de données serveur Objectifs du stage III Développement de l'application 51 9 Module 1 : Créer la zone admin Objectif Analyse Eléments théoriques Validateur Spring Pratique Section : rejouer les chiers XML Section : construire les chiers XML Section : réinitialiser les Synchro Assignments Module 2 : Tracer les téléchargements Objectif Eléments théoriques Hibernate DAO/Service Pratique Création d'un objet de stockage iv

6 TABLE DES MATIÈRES Création du mapping Hibernate Création d'un DAO Hibernate Création d'un Service Création de l'interface Web Module 3 : Ajouter des fonctionnalités Objectif Analyse Eléments théoriques JFreeChart Pratique Création d'une surclasse pour la génération de graphique Création d'une tâche planiée Module 4 : Amélioration du design Objectif Analyse Eléments théoriques Tiles Tiles avec Spring Pratique Module 5 : Multilinguisme Objectif Analyse Eléments théoriques Spring et i18n JMX/MBean Pratique Gestion des traductions en mémoire Intégration avec Spring : Interface MessageSource Module 6 : Amélioration des entrées ID Objectif Eléments théoriques Ajax Analyse v

7 TABLE DES MATIÈRES ère possibilité : 2 champs distincts ème possibilité : Combo Box ème Possibilité : Ajax Pratique Préparation des données XML Du côté HTML Désactivation de l'autocomplétion interne Module 7 : Achage des chiers de trace Objectif Eléments théoriques Log4J Analyse Gestion des chiers log Achage d'un chier de log Pratique Traitement d'un chier Log Traitements diérés IV Conclusion Conclusion 97 V Annexes 98 Screenshots i Code 16.1 Exemple Spring xi xi Bibliographie Glossaire xii xiii vi

8 Première partie Introduction 1

9 Chapitre 1 Introduction "Intranet. Méthode conviviale de surveillance des salariés." Marie-Anne Dujarier A l'heure actuelle, la surveillance est omniprésente dans notre société et dans nos moeurs. Un bien? Un mal? Tout dépend du contexte et du point de vue. Il sut d'allumer notre télévision pour remarquer que les nouvelles émissions sont axées sur la téléréalité. D'aucuns diront que c'est plutôt malsain. Mais force est de constater que ces émissions remportent un franc succès. Si nous sortons faire des courses, on nous propose des cartes de délité, qui permettent de mieux cibler la publicité en fonction de notre consommation. Au niveau informatique, la surveillance ( des utilisateurs, des services, des serveurs, du réseau ) est plus qu'importante. Elle permet de prévoir des pannes, de contre-carrer des attaques de pirates, de détecter les risques d'infection du système. Qui n'a jamais été tenté de lire un provenant d'un utilisateur inconnu délivrant un logiciel gratuit et soi-disant extraordinaire? Une fois celui-ci ouvert, son ordinateur est infecté, voire tout un réseau! Le sujet de ce mémoire va dans le sens d'une telle surveillance. La société Manex a développé un serveur qui centralise des données fournies par un nombre important de clients. Mais, jusqu'à présent, aucune surveillance n'existait, que ce soit au niveau des actions des utilisateurs ou au niveau de l'accroissement de la taille de la base de données. Le jour de mon arrivée chez Manex, j'ai plongé dans le projet passionnant du développement d'un module Web de monitoring de leur serveur. Celui-ci propose une interface simple, qui permet de voir la croissance du nombre d'objets dans la base de données, mais aussi de connaître les dernières actions d'un utilisateur ainsi que les erreurs apparues durant celles-ci. Un beau projet, un beau sujet pour un TFE. Vous y trouverez tout d'abord une présentation de Jafar, ainsi qu'une explication de la base de l'utilisation des frameworks Spring et Hibernate. Ensuite, vous entrerez dans le vif du sujet en suivant les diérentes étapes du développement des modules du projet. Bonne lecture! Gildas Cuisinier 2 Haute Ecole Rennequin Sualem

10 Chapitre 2 Présentation de l'entreprise Sommaire 2.1 Manex Personnel Domaines de prédilection Outils et technologies Coordonnées Produits Inter Business Automated Transport System Java Advanced Facilities for Audit and Reporting ( Jafar ) Manex La société Manex a été fondée en 1986 et propose des services de consultance et de développement pour l'implémentation de solutions réseaux et logicielles Personnel Cette société est dirigée par Vincent Keunen et est présidée par Nicolas Keunen. En plus des trois informaticiens qui y travaillent à plein temps, la société Manex travaille avec plusieurs indépendants. À cette équipe s'ajoute une assistante de direction Domaines de prédilection Les systèmes Internet : site web transactionnels, applications web, connexions de bases de données, systèmes de messagerie, échanges Business-to-Businnes,... Gildas Cuisinier 3 Haute Ecole Rennequin Sualem

11 Présentation de l'entreprise Les systèmes de sécurité signatures électroniques,... : cryptographie, infrastructure Clés privées-clés publiques, certicats, Les systèmes mobiles : Palm, ipaq, J2ME, Gsm, Sms, Outils et technologies La société Manex s'est spécialisée dans le domaine Java et développe, grâce à ce langage, aussi bien des applications classiques que des applications Web. L'utilisation de ce langage n'est pas anodin. En eet, grâce à la machine virtuelle de java, les applications pourront être utilisées aussi bien sur un ordinateur équipé d'un système d'exploitation Microsoft, Linux/Unix ou bien encore Mac. De plus, la société Manex favorise l'opensource en utilisant des produits tels que Jboss, Hibernate ou bien encore Jasper Report. Elle maîtrise aussi les protocoles tels que : HTTP : le protocole utilisé pour les communications web ; SOAP : le protocole d'échanges utilisé pour la communication avec un service Web ; LDAP : le protocole de communication avec des annuaires ; SMTP/POP/IMAP : les protocoles utilisés pour le transfert du courrier électronique ; Coordonnées Rue Wagner, 93 & 127 BE-4100 Boncelles, Belgique Tel. : +32 (0) Fax. : +32 (0) Mail : Web : Produits Inter Business Automated Transport System Ibats est un système de messagerie Internet sécurisée, automatisée et ouverte. Sécurisée, car il utilise une infrastructure clés publiques - clés privées, qui apporte : * l'authenticité à la fois de l'émetteur et du récepteur ; * la condentialité, du fait que toute communication est cryptée et ne pourra être comprise que par le destinataire ; * l'intégrité du message, car si une modication ou altération du message se produit lors du transfert, alors il sera illisible par le récepteur, et donc tout message interprété correctement est obligatoirement identique à celui que l'émetteur a transmis ; * la non-répudiation, car par le système de signature électronique, le message a été signé grâce à la clé privée, mais sera vérié par la clé publique associée. Donc, si la signature est vériée par la clé publique de l'émetteur que possède le récepteur, il peut prouver l'origine du message ; Gildas Cuisinier 4 Haute Ecole Rennequin Sualem

12 Présentation de l'entreprise Automatisée * tout document déposé dans le répertoire d'envoi sera envoyé automatiquement, selon une fréquence déterminée ; * le système gère les éventuels conits lors de la réception des documents ; * Ibats se met automatiquement à jour via le réseau. Ouverte car : * gestion des formats : Ibats possède un convertisseur qui adapte les formats de chiers entre l'émetteur et le récepteur ; * portabilité : grâce à la machine virtuelle Java, Ibats fonctionne sur les divers systèmes d'exploitation ( Windows, Unix, Mac, AS400 ) ; * standard : Ibats fonctionne sur les standards Internet tel que IMAP, SMTP, LDAP ; * complémentaire : il ne remplace pas votre logiciel de messagerie actuelle, mais le complète. La technologie qui est au coeur d'ibats est utilisée aujourd'hui par les deux principales messageries médicales de Belgique et couvre près de utilisateurs. Au niveau international, Ibats est en cours d'implémentation dans plusieurs pays. Site web du produit : Java Advanced Facilities for Audit and Reporting ( Jafar ) Jafar 1 est la réponse à une demande de Idewe, leader dans le secteur de la médecine du travail en Belgique. En eet, avant l'arrivée de Jafar, les observations des auditeurs étaient inscrites sur papier, et une numérisation de cette méthode s'avérait nécessaire. C'est alors que Manex a développé un produit appelé Jaws ( Java Workstation ), adaptable à divers appareils, capable de centraliser et de traiter les données collectées, et de générer des rapports sur base de celles-ci. An de trouver de nouveaux débouchés, Manex a développé un nouveau logiciel, qui reprend les mêmes fonctionnalités que Jaws, mais qui en élargit le domaine d'activité. Ce nouveau logiciel est Jafar. Fonctionnalités Faire des audits et recueillir des données en ce qui concerne un champ d'activité. Générer instantanément des rapports en fonction de ces audits. Synchroniser les données recueillies avec un serveur central. Site web du produit : 1 Du fait de l'objet de ce TFE, une présentation plus précise du fonctionnement de Jafar se trouve au chapitre 8 Gildas Cuisinier 5 Haute Ecole Rennequin Sualem

13 Chapitre 3 Cahier des Charges Sommaire 3.1 Objectif général Principaux points étudiés Cahier des charges de l'application Outils et Frameworks Objectifs Objectif général Il s'agit de développer une application web pour la surveillance du serveur Jafar (jafar.biz). 3.2 Principaux points étudiés Etude du serveur Jafar. Etude du framework Spring. Etude du framework Hibernate. 3.3 Cahier des charges de l'application L'application consiste en un site Web de monitoring du serveur Jafar, qui possèdera comme fonctionnalités : l'analyse des chiers log envoyés par les clients Jafar, an d'y détecter d'éventuelles erreurs et les signaler au client ; la visualisation des chiers de données au format Xml qui servent à la synchronisation entre les clients et le serveur ; un mécanisme pour "rejouer" l'insertion de ces chiers Xml dans une base de données ; la génération de graphiques ; la génération de rapports. 3.4 Outils et Frameworks Intellij Idea, un environnement de programmation Java professionnel ; Java et Java Server Page ; Langage Xml ; Gildas Cuisinier 6 Haute Ecole Rennequin Sualem

14 Cahier des Charges Framework Spring ; Framework Hibernate, qui permet de sauver des objets java dans une base de données relationnelle ; Postgres, une base de données relationnelle ; JasperReport, un outil Open Source de génération de rapports. 3.5 Objectifs Comme il sera expliqué plus en détail au chapitre 8, le serveur Jafar est le centre de transitions de données ( principalement sous forme de chier XML ), et ce par un grand nombre d'utilisateurs diérents. L'objectif de mon stage est d'intégrer un système de traçage, d'analyser les actions des utilisateurs, et d'acher ces informations de manière simple et compréhensible. Par exemple, pour l'administrateur d'un serveur Jafar, il sera possible de : savoir quels chiers ont été envoyés, et par qui ; savoir quels chiers ont été téléchargés par un utilisateur, ou bien à une date donnée ; de savoir qui a synchronisé ses informations ou bien au contraire, qui ne l'a pas fait depuis une date ou une période donnée ; de vérier la cohérence des informations attribuées à un utilisateur, ou de lui attribuer de nouvelles informations ; d'avoir une idée rapide de l'état d'une base de données ou bien de l'évolution de celle-ci sur une période donnée. Gildas Cuisinier 7 Haute Ecole Rennequin Sualem

15 Chapitre 4 Présentation des outils Sommaire 4.1 Intellij Idea Subversion JBoss Spring Hibernate Jasper Report Intellij Idea IntelliJ Idea est un environnement complet de développement pour la programmation de Java, reconnu par les principaux développeurs en java comme le meilleur IDE sur le marché. Il allie à la fois une simplicité d'utilisation avec une interface conviviale avec tous les outils qu'un développeur utilise fréquemment, tels que : refactoring ; intégration avec Ant ; intégration avec Tomcat ; création de fenêtre GUI très simple. De plus, de nombreuses extensions sont disponibles pour combler les manques de l'installation de base. Site ociel : 4.2 Subversion Subversion est un logiciel de contrôle de version, il permet à plusieurs programmeurs de travailler sur un même projet en parrallèle. Gildas Cuisinier 8 Haute Ecole Rennequin Sualem

16 Présentation des outils Le concept de Subversion ( appellé souvent SVN ), tout comme CVS, est de stocker une version du projet sur un dépôt centralisé, tandis que les programmeurs possèdent une copie de celui-ci. Dès qu'un de ces programmeurs a terminé son travail sur une partie du projet, il va soumettre les modications sur la version du dépôt. De temps en temps, les autres programmeurs feront une mise à jour du projet, ce qui va récupérer la version actuelle sur le dépôt, et intégrer les changements sur leur copie locale, automatiquement. Dans le cas où deux programmeurs eectuent des modications sur la même portion d'un même chier, lors de la mise à jour, subversion va détecter un conit, ce qui nécessitera une intervention humaine an de savoir comment il doit eectuer la mise à jour ( quelles lignes doit-il garder? fusionner? supprimer? ). Ainsi, chacun peut travailler de son côté, tout en restant à jour dans les modications faites par les autres programmeurs. Site ociel : 4.3 JBoss JBoss est le serveur J2EE Open Source le plus populaire. Avec plus de 4 millions de téléchargements, c'est l'un des plus gros succès de SourceForge.net. Quand on parle de JBoss, il faut bien diérencier JBoss, le projet Open Source soutenu par environ 100 développeurs et JBoss Group, une entreprise qui ore des services de grande qualité autour du projet JBoss, comme la documentation, formations, supports... De nombreuses personnes de cette entreprise travaillent sur le projet Open Source. JBoss est un serveur très léger implémentant l'ensemble des spécications J2EE. Site ociel : 4.4 Spring Spring est eectivement un conteneur dit léger, c'est-à-dire une infrastructure similaire à un serveur d'application J2EE. Il prend en charge la création d'objets et leur mise en relation par l'intermédiaire d'un chier de conguration qui décrit les objets à fabriquer et les relations de dépendance entre ces objets. Une présentation plus complète de Spring se trouve au chapitre 6. Site ociel : Gildas Cuisinier 9 Haute Ecole Rennequin Sualem

17 Présentation des outils 4.5 Hibernate Hibernate est un framework de mapping objet/relationnel pour le monde Java. Le terme mapping objet/relationnel décrit la technique utilisée pour faire le lien entre un objet en terme de classe, et sa représentation dans une base de données relationnelle ( telles que Postgres, Mysql,... ) Le but d'un tel framework est de faire gagner du temps aux programmeurs, car la sauvegarde, le chargement, la recherche d'objets dans une base relationnelle peut devenir très complexe. Grâce à Hibernate, ces problèmes sont résolus, il sura de décrire dans un chier de mapping, quelles sont les propriétés d'un objet qu'il faut sauver, quelles sont les relations qu'un objet possède avec un autre. Lorsque ce chier est correctement créé, Hibernate eectue tout le travail, et peut même créer la base de données si nécessaire. Pour ce qui est de la recherche, Hibernate possède un langage propre : Hibernate Query Language, ou HQL. Une explication plus détaillée du fonctionnement de Hibernate se trouve au chapitre 7. Site ociel : 4.6 Jasper Report Jasper Report est un logiciel de génération de rapports Open Source qui permet d'acher des rapports sur un écran, pour l'impression ou dans des chiers de type PDF, HTML, XML ou autres. Ecrit totalement en java, il est complètement portable et peut être intégré à toute application java, même J2EE ou des applications WEB. Le concept est de créer un modèle de documents sous forme d'un chier XML ( mais il existe des logiciels tels qu' ireport qui permettent de créer ces modèles graphiquement ), que l'on remplira par programmation pour ensuite générer le rapport nal. Site ociel : Gildas Cuisinier 10 Haute Ecole Rennequin Sualem

18 Deuxième partie Notions théoriques 11

19 Chapitre 5 Rappels Généraux Sommaire 5.1 Java Introduction Java : présentation générale Historique des JDK Les diérentes plateformes Java : orienté Objet Java : portabilité Techniques de programmation en Java Sérialisation JavaBean Génériques Java Web Conteneur, Servlet et JSP Conteneur Web Servlet JSP Balises personnalisées Expression Language NullPointerException ArrayOutOfBoundException Exemples : Comparaison Scriptlet <=> Expression Language XML XML par l'exemple Traiter un chier XML SAX DOM Java Introduction Java est un langage de programmation très en vogue, en grosse partie grâce aux applets que l'on peut voir sur le net. Java n'est pas uniquement cela, et le but de cette section est de présenter brièvement les particularités de ce langage. Gildas Cuisinier 12 Haute Ecole Rennequin Sualem

20 Rappels Généraux Vous comprendrez ensuite pourquoi le langage Java est dit très sécurisé, ou encore pourquoi il est portable. Vous comprendrez aussi ce qu'est la machine virtuelle java, ce qu'est une servlet ou bien encore ce qu'on appelle du bytecode Java : présentation générale Les débuts de Java remontent à 1991, quand un petit groupe d'employés de Sun Microsystem 1 est placé sur un projet baptisé 'Green', voué à la réalisation d'applications électroniques commerciales. Leur première mission fut de créer un appareil capable de contrôler plusieurs équipements électroniques. A cette n, ils ont créé un langage, le langage Oak. Le nom Oak, malheureusement trop proche d'une autre marque, fut rebaptisé en 1995, à l'occasion du salon SunWorld, et prendra le nom de Java. La première version du kit de développement Java fut disponible en 1996, et est utilisable gratuitement. Historique des JDK JSK 1.0 sorti en 1996 JSK 1.1 sorti en 1997 JSK 1.2 sorti en 1998, appellé Java 2 JSK 1.3 sorti en 2000, JSK 1.4 sorti en 2002, JSK 1.5 sorti en 2004, dit Java 5 JSK 1.6 sorti en 2006, prévu pour n 2006/début 2007, nom de code Mustang Les diérentes plateformes L'environnement Java est divisé en plusieurs plateformes qui se diérencient principalement par les composants qu'elles contiennent et qui sont destinées à un secteur de développement plus spécique. J2SE : destiné aux applications pour poste de travail, elle contient entre autre la partie interface graphique du monde java ; J2EE : destiné pour les applications serveur ; J2ME : destiné à la programmation des mobiles, tels que les Gsm et les pda ; JavaCard : destiné à la programmation des cartes à puces Java : orienté Objet La première caractéristique de Java est qu'il est orienté objet. L'orienté objet est une méthode de programmation qui permet de regrouper dans une entité logique ( une classe ) un ensemble de données ( des propriétés ) et des fonctions ( des méthodes ) qui traiteront ces données. L'intérêt de ce type de programmation est de rendre un code réutilisable. En eet, par exemple, si pour une application vous avez dû développer une classe qui gère des utilisateurs, et que plus tard vous devez faire une seconde application qui utilise les mêmes utilisateurs, vous n'aurez pas à réécrire cette partie, car il sura de l'intégrer directement dans votre nouvelle application. 1 Gildas Cuisinier 13 Haute Ecole Rennequin Sualem

21 Rappels Généraux De plus, une propriété de la programmation orientée objet est l'héritage. Derrière ce mot se cache le fait de hiérarchiser des classes. Autrement dit, si pour la nouvelle application, votre classe utilisateur ne sut plus, car de nouvelles propriétés apparaissent, au lieu de tout reprogrammer, il sura de créer une nouvelle classe, qui héritera de la première, et de créer dans cette classe lle les nouvelles propriétés et nouvelles méthodes. Les méthodes et propriétés de la classe mère ( ou de base ) sont directement intégrées dans la classe lle. Une autre particuliarité de la programmation orientée objet est l'encapsulation, qui divise la manière de voir un objet en deux : L'interface : les méthodes qu'il fournit, de manière générale ; L'implémentation : comment sont développées les méthodes d'un point de vue technique. L'intérêt est qu'un développeur qui utilise un objet d'un autre développeur n'a pas besoin de savoir comment il est fait, mais uniquement les services qu'il fournit. Imaginons un objet, utilisé pour l'authentication. Il possède une méthode qui prend en paramètre un nom d'utilisateur et un mot de passe. Cette méthode vérie l'existence d'un couple utilisateur / mot de passe correct. Pour le développeur qui utilise cet objet, il importe peu que cette vérication soit faite via un chier, une base de données ou par un autre moyen, pour lui seul le résultat compte Java : portabilité Un des intérêts de Java est qu'une fois compilé, le chier pourra être exécuté sur n'importe quelle machine, qu'elle soit de type Windows, Unix, Mac OS, et ce malgré leur format d'exécutable complètement diérent. Pour rappel, cette portabilité est due à la machine Virtuelle Java. En eet, lors d'une compilation d'un programme Java, on n'obtient pas un exécutable mais du bytecode. Ce bytecode n'est pas lié à un système d'exploitation mais à la machine virtuelle. C'est elle qui permet d'interpréter ce bytecode java, et d'exécuter le programme. C'est grâce au fait qu'il existe une machine virtuelle Java adaptée à chaque système d'exploitation qu'un programme java est portable. Fig. 5.1 Machine Virtuelle Gildas Cuisinier 14 Haute Ecole Rennequin Sualem

22 Rappels Généraux 5.2 Techniques de programmation en Java Cette partie va présenter quelques points intéressants sur la programmation en Java, tels que les apports utiles de Java 5 ou encore, expliquer ce qu'est un JavaBean Sérialisation L'intérêt de la sérialisation est de permettre de sauver l'état d'un objet qui se trouve en mémoire vive, dans un chier disque. Cela permettra ainsi de récupérer l'objet lors d'une utilisation ultérieure du programme. Mais, de manière plus générale, la sérialisation n'est pas limitée à un stockage des objets dans un chier, mais en réalité elle envoie cet objet sur un ux, que ce soit vers un chier, un ux réseau ou un ux vers un autre programme, ce qui peut faciliter le transfert d'objets entre deux applications Java. Pour rappel, pour être sérialisable, une classe doit simplement implémenter l'interface Serializable JavaBean Un JavaBean est déni par Sun Microsystems comme un composant logiciel réutilisable, qui peut être manipulé visuellement par un utilitaire. Mais pratiquement, un JavaBean est une classe, qui possède quelques caractéristiques : Sérialisable : elle doit être sérialisable. Constructeur par défaut : elle doit posséder un constructeur par défaut, c'est-à-dire un constructeur sans argument. Propriété : elle possède au moins une propriété. Si les deux premiers points sont assez parlants d'eux-mêmes, une petite explication sur le terme propriété est nécessaire. Une propriété est une caractéristique d'un objet, une information qui peut être soit récupérée, soit spéciée, soit les deux. Pour comprendre, faisons une petite comparaison. Imaginez une voiture, elle possède entre autres les caractéristiques suivantes : une couleur, qui peut être "`vue"', mais que l'on peut changer ; une marque, qui est xée, mais que l'on peut connaître. Si cette voiture était un JavaBean, on dirait que la couleur est une propriété en lecture-écriture, tandis que la marque est une propriété accessible uniquement en lecture. Au niveau programmation, il existe aussi des propriétés accessibles uniquement en écriture. Mais comment cela se traduit-il dans le code? Si une propriété que l'on nommera 'Couleur' doit être en lecture, alors, dans le code de la classe, il existera une méthode : public Color getcouleur(); Si la propriété doit être aussi accessible en écriture, il existera alors une méthode : public void setcouleur(); Gildas Cuisinier 15 Haute Ecole Rennequin Sualem

23 Rappels Généraux Génériques Pour les habitués de la programmation C++, les génériques sont en quelque sorte l'équivalent Java des Templates. Ils ont été introduits dans Java depuis la version 5. En fait, cela permet de programmer des conteneurs d'objets, sans spécier durant la programmation de ce conteneur, le type d'objets qu'il contiendra. Auparavant, s'il était question de développer un conteneur, deux moyens étaient possibles : 1. Soit une variante du conteneur était créée pour chaque type que l'on souhaitait pouvoir stocker, par exemple un conteneur d'entiers, un conteneur de chaînes de caractères, etc Soit un conteneur d'objet quelconque ( de type Object ) était utilisé. Le risque de voir n'importe quoi y être stocké existait, car aucune vérication n'était réalisée. Depuis les génériques, il sut de programmer une classe, en disant qu'elle contiendra des objets de type <T>. Exemple : public class MonConteneur<T> { void ajouter(t nouveau); T[] toutrecuperer(); } Dès lors, ce n'est qu'au moment de la déclaration que le type de données qu'il contiendra sera déni : MonConteneur<String> cont1 = new MonConteneur<String>(); cont1.ajouter("test1"); cont1.ajouter("test2"); String[] cont1.toutrecuperer(); Les connaisseurs du C++ y verront une ressemblance avec les Templates. Gildas Cuisinier 16 Haute Ecole Rennequin Sualem

24 Rappels Généraux 5.3 Java Web Cette section consiste en un rappel sur les éléments utilisés pour le développement Web en java Conteneur, Servlet et JSP Conteneur Web Un point spécique à la programmation Web en Java est la nécessité d'un programme qui va contenir ses applications. C'est lui qui va gérer la vie des servlets, qui va compiler les Jsp, qui va passer les requêtes HTTP à celles-ci et récupérer le résultat pour le renvoyer au client. Ce programme est appelé un conteneur. Pour déployer ( c'est-à-dire installer ) une application web dans un tel conteneur, il faut créer une archive WAR ( Web ARchive ) qui contiendra : des chiers HTML, JSP, images et répertoires publics ; un répertoire WEB-INF, qui ne sera pas visible publiquement mais qui contiendra typiquement : * un chier web.xml qui congurera les servlets ; * les classes et servlets ( /WEB-INF/classes ) ; * les librairies nécessaires à l'application ( /WEB-INF/lib). Servlet Les servlets sont les éléments de base de la programmation web en Java, ce sont des classes qui seront instanciées par le conteneur web, et liées à une URL via le chier web.xml. Lors d'un appel de cette URL, le conteneur Web va créer un thread qui va récupérer l'unique instance de cette classe, et lui passer la requête HTTP via les méthodes de base des servlets. Ce sont ces méthodes de traitement des requêtes qu'il faut redénir pour eectuer ce qui est désiré. Le résultat de ce traitement ( qui, en général, sera du code HTML, mais pas obligatoirement ) sera récupéré par le conteneur web et renvoyé dans une réponse HTTP au client. Le point important, lors de la programmation de servlets, est de ne pas oublier qu'une servlet est instanciée une seule fois, et que toutes les requêtes sont traitées par cette unique instance. Donc il faut être attentif, car il est parfois nécessaire de créer des zones critiques ( via des blocs synchronisés, qu'un seul thread peut exécuter à la fois ). En contre-partie, la mémoire est mieux utilisée : il ne faut pas recréer et initialiser plusieurs fois le même objet. JSP Bien que les servlets à elles seules pourraient très bien sure à la création d'un site web, les JSP ont leur utilité. En eet, une servlet est du code pur, et il n'est pas facile de créer une page HTML correcte directement dans le code de celle-ci. Plus particulièrement pour un infographiste qui ne connaît peut-être rien au monde Java. D'où l'utilité des JSP! En eet, le code source d'une JSP ressemble à du code HTML dans lequel sont ajoutées des commandes Java. Rien n'empêche un infographiste de créer un design en HTML, et que le programmeur Java ajoute Gildas Cuisinier 17 Haute Ecole Rennequin Sualem

25 Rappels Généraux par après le code Java nécessaire dans cette page. C'est un premier pas dans la collaboration entre graphiste et développeur Balises personnalisées Un deuxième pas vers cette collaboration : les balises personnalisées. Elles cachent encore plus le code Java dans une page JSP. Autrement dit, là où il était nécessaire au développeur de venir ajouter dans la JSP les commandes pour acher les informations provenant d'une base de données, dorénavant, même le graphiste pourra s'en occuper. En eet, il sura au développeur de créer une balise <affichedata table="livres"/> qui eectuera ce travail. Pour le graphiste, il lui sut de mettre cette balise là où les informations doivent se trouver pour que cela s'ache. L'intérêt est de bien séparer ainsi la présentation des données Expression Language Jusqu'ici, on a remplacé une bonne partie des scriptlets grâce aux balises personnalisées. Cependant, il est parfois dicile, voire impossible de les utiliser. Par exemple, si nous avons une liste d'utilisateurs ( qui possèdent un nom, un prénom, une adresse ), et que nous souhaitons acher ceux-ci en fournissant un moyen d'envoyer un à ceux-ci, il n'existe pas de balise propre à cette utilisation. Donc nous allons devoir créer une balise d'itération sur la liste, qui renverra un utilisateur, et nous devrons jouer avec d'autres balises pour acher les valeurs des propriétés de cet utilisateur... Si vous avez du mal à comprendre le sens de cette phrase, imaginez la complexité de programmation pour un résultat aussi simple... C'est là qu'interviennent les Expression Language, souvent nommées EL. Derrière elles se cache un système qui simplie énormément l'achage dans des pages JSP. Grâce à elles, l'exemple ci-dessus ressemblerait à ceci : <c : f o r e a c h items=" m a l i s t e " var="oneuser"> <a href=" mailto : ${ OneUser. }">${ OneUser.Nom} ${ OneUser. Prenom} ( ${ OneUser. }</a> </ c : f o r e a c h> Mais n'est-ce pas exactement ce qui a été dit plus haut?! Oui et non. Une balise qui boucle sur une liste est bel et bien utilisée, mais c'est une balise standard, elle renvoie un objet quelconque, et non pas une instance d'un Utilisateur. De plus, il n'est dit nulle part qu'on utilise une liste d'utilisateur. Grâce aux EL ( les expressions entre $<expression> ), il n'est plus utile de dire sur quoi on travaille, ce sont elles qui font la correspondance via l'introspection ( le fait d'aller voir les méthodes, propriétés, etc... qu'un objet possède ). Par exemple, ${OneUser. } veut dire, va voir dans l'objet OneUser s'il existe une propriété accessible en lecture ( donc est-ce que oneuser possède une méthode get ()? ), si oui récupère la valeur et ache-là. Gildas Cuisinier 18 Haute Ecole Rennequin Sualem

26 Rappels Généraux Magnique, n'est-ce pas? Ce n'est pas tout. Ici, la méthode get renvoie une chaîne de caractères, mais il est possible qu'une méthode renvoie un autre objet. Dans un tel cas, si celui-ci possède des propriétés, les EL permettent de descendre jusqu'à celles-ci. Par exemple, imaginons un objet Maison, qui possède un objet Chambre, qui lui-même contient un objet Lit. Si l'on désire récupérer le modèle de ce lit, cela donne ${Maison.Chambre.Lit.Modele}. Simple, non? Mais ce n'est pas tout. Et s'il y a plusieurs chambres? Lesquelles sont stockées dans un tableau associatif ( de type HashMap par exemple ), avec comme clé le nom du propriétaire? Et bien c'est tout aussi simple! ${Maison.Chambre["Gildas"].Lit.Modele} achera l'information à propos du lit situé dans la chambre de Gildas. Et à ces bases, s'ajoutent des méthodes sur les EL, qui permettent de faire des tests, des transformations sur les chaînes de caractères. De plus, il existe des objets EL implicites, tels que 'sessionscope', qui est l'équivalent de l'objet session en JSP, et qui permet de récupérer les informations stockées dans la session. Il en existe d'autres pour récupérer les valeurs passées en paramètre, les variables d'application, les variables de cookies,... Un point important aussi, c'est que les EL gèrent deux classes d'exceptions : NullPointerException Soit ${Maison.Chambre["Gildas"].Lit.Modele}, qui correspondrait à ce code java : Maison.getChambre("Gildas"').getLit().getModele. Il se peut tout à fait que Maison, ou la chambre, ou le lit soit une référence nulle, dans ce cas, un NullPointerException serait lancé mais les EL les gèrent et renvoient simplement la valeur null dans ce cas. De plus, lors de l'achage dans la page JSP, toutes les valeurs null sont remplacées par des chaînes vides, an de ne pas acher le texte null à l'utilisateur. ArrayOutOfBoundException De la même manière, l'accès à un index incorrect d'un élément d'un tableau ou d'une liste ne provoquera pas d'exception mais renverra une valeur null. Gildas Cuisinier 19 Haute Ecole Rennequin Sualem

27 Rappels Généraux Exemples : Comparaison Scriptlet <=> Expression Language An d'être plus explicite sur l'utilité des EL, un petit exemple : Vous venez de vous authentier sur un site qui fournit une page permettant de modier votre prol. Celle-ci va récupérer les informations de la session pour pré-remplir les champs du formulaire. Voici la visualisation du code source de cette page, selon l'ancienne méthode ( scriptlet ) et selon la nouvelle ( EL ) : Version Scriptlet page import="packagenames. " %> <% P r o f i l p = ( P r o f i l ) s e s s i o n. g e t A t t r i b u t e ( " p r o f i l " ) ; String name = n u l l ; String = n u l l ; String l i n e 1 = n u l l ; String l i n e 2 = n u l l ; String zipcode = n u l l ; String c i t y = n u l l ; i f ( p!= n u l l ) { name = p. getname ( ) ; = p. get ( ) ; Address address = p. getaddress ( ) ; i f ( address!= n u l l ) { l i n e 1 = address. getline1 ( ) ; l i n e 2 = address. getline2 ( ) ; zipcode = address. getzipcode ( ) ; c i t y = address. getcity ( ) ; } } i f ( name==n u l l ) name = "" ; i f ( ==n u l l ) = "" ; i f ( l i n e 1==n u l l ) l i n e 1 = "" ; i f ( l i n e 2==n u l l ) l i n e 2 = "" ; i f ( zipcode==n u l l ) zipcode = "" ; i f ( c i t y==n u l l ) c i t y = "" ; %> <form action="/monaction" method=" post "> Nom :<br/> <input type=" text " name="name" value="<%=name%>"/> <br/> <br/> <input type=" text " name=" " value="<%= %>"/> <br/> <f i e l d s e t> <legend>adresse</legend> Rue :<br/> <input type=" t e x t " name=" l i n e 1 " value="<%=l i n e 1%>"/> <br/> <input type=" t e x t " name=" l i n e 2 " value="<%=l i n e 2%>"/> <br/> <br/> Code Postal :<br/> <input type=" text " name=" zipcode " value="<%=zipcode%>" /> <br/> V i l l e :<br/> <input type=" text " name=" v i l l e " value="<%=c i t y%>"/> <br/> </ f i e l d s e t> </form> Version EL <form action="/monaction" method=" post "> Nom :<br/> <input type=" text " name="name" value="${ s e s s i o n S c o p e [ ' p r o f i l ' ]. name}"/><br/> <br/> <input type=" text " name=" " value="${ s e s s i o n S c o p e [ ' p r o f i l ' ]. }"/><br/> <f i e l d s e t> <legend>adresse</legend> Rue :<br/> <input type=" t e x t " name=" l i n e 1 " value="${ s e s s i o n S c o p e [ ' p r o f i l ' ]. address. l i n e 1 }"/ ><br/> <input type=" t e x t " name=" l i n e 2 " value="${ s e s s i o n S c o p e [ ' p r o f i l ' ]. address. l i n e 2 }"/>< br/> <br/> Code Postal :<br/> <input type=" text " name=" zipcode " value="${ s e s s i o n S c o p e [ ' p r o f i l ' ]. address. zipcode }"/ ><br/> V i l l e :<br/> <input type=" t e x t " name=" v i l l e " value="${ s e s s i o n S c o p e [ ' p r o f i l ' ]. address. c i t y }"/>< br/> </ f i e l d s e t> </form> On remarque immédiatement que le codage en EL est plus court, plus clair, tout en étant aussi performant. Gildas Cuisinier 20 Haute Ecole Rennequin Sualem

28 Rappels Généraux 5.4 XML XML par l'exemple Le format XML est un standard pour le transport de données de tout type, sous forme d'un chier texte. Cependant, il possède quelques règles. <?xml version=" 1. 0 " encoding="iso "?> < l i v r e version="1" > <auteur> <nom>c u i s i n i e r</nom> <prenom>gildas</prenom> </ auteur> < t i t r e>mon premier l i v r e</ t i t r e> <! Un commentaire > <sommaire /> <c h a p i t r e t i t r e=" Chapitre 1"> <paragraphe>mon premier l i v r e en XML, c ' e s t fun! J ' adore </ paragraphe> <paragraphe>et l a s u i t e du l i v r e e s t i c i </ paragraphe> </ c h a p i t r e> <c h a p i t r e t i t r e=" Chapitre2 "> <paragraphe>je s u i s seulement en t r a i n de l ' é c r i r e </paragraphe> </c h a p i t r e > </ l i v r e > Comme on peut le voir dans ce chier simple : il doit y avoir une et une seule balise racine ( ici <livre> ) ; une balise ouverte doit être fermée * soit via une balise fermante ( <livre> => </livre>, <chapitre> => </chapitre> ) ; * soit directement ( <sommaire /> ) ; une balise peut contenir soit : * du texte ou des données directement ( par exemple ici, la balise <nom> ) ; * d'autres balises ( exemple : <chapitre> ) ; * soit rien du tout ( <sommaire />" ) ; une balise peut avoir des attributs ( <chapitre titre="chapitre 1"> ) ; il peut y avoir des commentaires dans le chier XML, compris entre <! et > ; une balise ouverte doit être fermée au même niveau ( par exemple <balise1><balise2></balise1></balise2> est incorrect ) Traiter un chier XML Pour traiter un chier XML, il existe deux techniques pour lire et récupérer les informations. SAX La première est SAX, Simple Api for XML. Celle-ci se base sur un système producteur/consommateur. Sans rentrer dans les détails, il y a un processus qui lit le chier XML et dès qu'il a lu entièrement une balise, il produit un événement "`ouverture balise"', "`fermeture balise"', etc.. Gildas Cuisinier 21 Haute Ecole Rennequin Sualem

29 Rappels Généraux C'est au consommateur de gérer les diérents événements an d'eectuer les traitements nécessaires. L'avantage de cette technique est qu'elle est très rapide, et qu'elle ne consomme pas énormément de mémoire. Par contre, elle ne permet pas de récupérer les informations par la suite, et ne permet pas de modier les informations, ni même de créer un chier XML. DOM L'autre technique est DOM, Document Object Model. DOM quant à lui va lire le document XML et le stocker en mémoire sous la forme d'un arbre. Dès que le traitement est ni, il est tout à fait possible de voyager dans les noeuds de l'arbre, les modier ou les supprimer. L'avantage est que, dès la n du traitement, tout le document est facilement accessible en lecture et écriture, mais l'inconvénient est que cette méthode est beaucoup plus lourde en mémoire et en temps. Gildas Cuisinier 22 Haute Ecole Rennequin Sualem

30 Chapitre 6 Spring Framework Sommaire 6.1 Présentation générale Pour rappel, Spring est Comment fonctionne Spring? Bean Factory / Application Context ApplicationContext Le chier de conguration Structure Injection de dépendances Injection par accesseurs Injection par constructeurs Que choisir? Petit exemple pratique La classe Utilisateur L'interface d'enregistrement d'un utilisateur Enregistrement dans un chier Enregistrement dans une base de données Le service Le chier de conguration Utilisation Spring Web MVC? Que veut dire MVC? Modèle Vue Contrôleur Spring : le dispatcher Spring : les Contrôleurs Déclarer un contrôleur Lier le contrôleur à une adresse Spring : les modèles et les Vues Exemple Gildas Cuisinier 23 Haute Ecole Rennequin Sualem

31 Spring Framework 6.1 Présentation générale Pour rappel, Spring est... Le principal avantage de Spring est l'ioc. IoC est l'acronyme de Inversion of Control, l'inversion du contrôle en français, ou encore l'injection de dépendances. Derrière ces termes se cache le fait que si un objet a besoin d'un autre objet, il ne va pas l'instancier lui-même, mais il va lui être fourni par un conteneur. Un cas pratique sera expliqué plus loin dans ce chapitre, mais un exemple pourrait éclaicir cette idée. Imaginons un objet A qui nécessite un autre objet B fournissant un accès à une base de données. Sans l'injection de dépendances, on aurait le choix de : soit de créer un objet B par new ObjetB(), et d'ensuite paramétrer celui-ci an d'eectuer ensuite la connexion ; soit d'utiliser une méthode Factory pour récupérer une instance unique ( qu'on appellera Singleton ), déjà paramétrée, et d'utiliser la connexion existante, ce qui permet de ne pas devoir re-paramétrer à chaque utilisation. Cela fonctionnera, mais si des modications futures sont nécessaires, il faudra modier le code à plusieurs endroits, ce qui peut être une perte de temps conséquente dans de gros projets. C'est là qu'intervient l'utilité de l'injection de dépendances! Lorsqu'on programme avec Spring, il est courant ( mais non obligatoire techniquement parlant ) de diviser l'objet B en deux parties. une interface : qui dénira les méthodes publiques ; une implémentation : une classe qui implémentera ces méthodes. Où est l'intérêt? En fait, notre objet A contiendra une variable privée du type de l'interface, qui ne sera pas initialisée, mais qui pourra être dénie via un accesseur. Gildas Cuisinier 24 Haute Ecole Rennequin Sualem

32 Spring Framework 1 public class ClasseA { 2 3 // r e f e r e n c e v e r s l o b j e t B v i a son i n t e r f a c e 4 private I n t e r f a c e B s e r v i c e B ; 5 6 // Accesseur u t i l i s e par Spring pour i n j e c t e r l a r e f e r e n c e 7 public void s e t S e r v i c e B ( I n t e r f a c e B r e f e r e n c e ) { 8 this. s e r v i c e B = r e f e r e n c e ; 9 } // Code u t i l i s a n t l e s methodes de l i n t e r f a c e B } Dans le code de l'objet A, une interface sera utilisée pour l'accès à la base de données. Le reste de la magie se situe dans le chier de conguration de Spring qui, dans la dénition de l'objet B, contiendra une propriété qui correspond à l'accesseur déni pour l'interface de B. Donc, durant l'exécution, dès qu'on récupérera un objet A via Spring, ce dernier va lui fournir directement un Objet B. L'intérêt réside dans le fait que l'objet A n'est pas directement lié à un autre objet. Premièrement, parce qu'il utilise une interface, autrement dit des services, sans avoir de contexte de type de base de données, de chiers, ou autres. Et deuxièmement, parce qu'il n'instancie pas lui-même un objet qui implémente cette interface, mais celui-ci lui est fourni, et donc l'objet A est totalement indépendant du type de l'objet B. Donc si plus tard, on ne désire plus utiliser de base de données, mais un autre moyen qui fournit les mêmes services, il sura par exemple de créer une nouvelle classe B2, qui implémentera toujours la même interface que B. Ensuite, on devra modier le chier de conguration de Spring pour qu'il ne fournisse plus un objet B mais un objet B2 lors de la création d'un objet A. 6.2 Comment fonctionne Spring? Le fonctionnement de Spring est basé sur un chier de conguration Xml, dans lequel sont dénies toutes les classes, ainsi que leurs dépendances Bean Factory / Application Context Le Bean Factory représente en fait le conteneur permettant l'inversion de contrôle ( Pattern Factory ). C'est lui qui permet la conguration et la liaison des objets par Injection de dépendances, et assure aussi la gestion des objets. Typiquement, une classe qui implémente cette interface sera utilisée : XmlBeanFactory, qui va utiliser un chier Xml comme source de conguration. Pour cela, il va lire le chier XML et utiliser l'introspection pour accéder aux propriétés des objets, et ainsi congurer les objets selon les informations lues dans le chier de conguration XML. Gildas Cuisinier 25 Haute Ecole Rennequin Sualem

33 Spring Framework Exemple d'utilisation : 1 // I n s t a n t i c a t i o n du Bean Factory q u i u t i l i s e r a l e f i c h i e r 2 // s r c / r e s s o u r c e / beans. xml comme c o n f i g u r a t i o n 3 4 Resource r e s = new FileSystemResource ( " s r c / r e s s o u r c e s / beans. xml" ) ; 5 XmlBeanFactory f a c t o r y = new XmlBeanFactory ( r e s ) ; 6 7 // Récuperation d ' un o b j e t 8 9 MonObjet t e s t = ( MonObjet ) f a c t o r y. getbean ( "monobjet" ) ; // U t i l i s a t i o n normal de l ' o b j e t t e s t t e s t. methode1 ( ) ; t e s t. methode2 ( ) ; ApplicationContext Spring possède une extension de Bean Factory plus avancée, appelée Application Context. Tout ce que fait le Bean Factory, l'application Context le fait! Mais il ajoute des fonctionnalités comme : le support de MessageSource, qui est une interface utilisée pour récupérer des messages selon la langue du système d'exploitation ( ce qui permet de rendre un programme multilingue facilement) ; la propagation des événements ; la possibilité d'avoir une hiérarchie d'applicationcontext ( un ApplicationContext possède une méthode setparent(applicationcontext parent) ), et de récupérer un Bean déni soit dans l'applicationcontext en lui-même, soit dans toute la hiérarchie Le chier de conguration Structure <beans> <d e s c r i p t i o n> P e t i t e d e s c r i p t i o n de ce que c o n t i e n t l e f i c h i e r de c o n f i g u r a t i o n </ d e s c r i p t i o n> <import s o u r c e=" a u t r e f i c h i e r. xml"/> <bean i d="monbeana" c l a s s=" monpackage. monbeana"/> <bean i d="accesdb" c l a s s="monpackage. monbeanb"> <property name=" u r l " value=" j d b c : m y s q l : // l o c a l h o s t /mabase"/> <property name=" username " value=" logindb "/> <property name=" password " value=" monpassword" /> </ bean> <bean i d=" testdb " c l a s s="monpackage. monbeanc"> <property name=" DBConnection" r e f=" accesdb"/> </ bean> </ beans> Gildas Cuisinier 26 Haute Ecole Rennequin Sualem

34 Spring Framework Comme on peut le voir, un chier de conguration se compose de : une ( ou aucune ) description pour expliquer ce que contient le chier de conguration ; des ( ou aucun) imports, qui vont insérer un autre chier de conguration ( ce qui permet de classer les Beans dans diérents chiers ) ; des Beans ( ou aucun ) qui : * possèderont un nom unique ( attribut name ) ; * possèderont une classe ( attribut class ) ; * pourront posséder des propriétés Injection de dépendances Comme dit précédement, l'injection de dépendances consiste à insérer les dépendances d'un objet lors de l'exécution du code et non lors de la programmation. Mais il faut savoir qu'il existe deux grands types d'injections et les deux cas sont gérés par Spring. Injection par accesseurs Dans ce cas, on utilise les propriétés ( les getxxxx / setxxxx ) d'un objet pour lui fournir les informations. Dans le chier de conguration, cela donne : <bean name=" t e s t " c l a s s="... "> <! I n j e c t i o n par a c c e s s e u r ( s e t S t r i n g ( S t r i n g v a l u e ) ) > <property name=" s t r i n g " value=" t e s t " /> <! I n j e c t i o n par a c c e s s e u r ( setmonbean ( MonBean r e f e r e n c e ) ) RQ : i l f a u t un bean de c l a s s e "MonBean", avec l e nom "monbean" dans l e f i c h i e r de c o n f i g u r a t i o n > <property name="monbean" value="monbean" /> </ bean> Injection par constructeurs Dans ce cas, les informations sont passées au constructeur de la classe. Au niveau du chier xml : <bean c l a s s=" beans. BeanViaConstructor " i d=" BeanViaConstructor "> <! I n j e c t i o n par c o n s t r u c t e u r : > p u b l i c BeanViaConstructor ( S t r i n g param1, MonBean param2 ) ; <c o n s t r u c t o r arg index="0" type=" java. lang. S t r i n g "> <value>valeur de t e s t</ value> </ c o n s t r u c t o r arg> <c o n s t r u c t o r arg index="1"> <r e f l o c a l="monbean"> </ c o n s t r u c t o r arg> </ bean> Gildas Cuisinier 27 Haute Ecole Rennequin Sualem

35 Spring Framework Que choisir? L'utilisation de l'injection par accesseurs est souvent préférée à celle par constructeurs, car elle possède quelques atouts : il n'est pas toujours nécessaire de redénir des propriétés, par exemple dans le cas où les valeurs par défaut sont celles que l'on désire ; s'il y a de nombreuses propriétés, il sut d'avoir un accesseur par propriété, tandis qu'avec la méthode des constructeurs, il faudrait créer X variantes du constructeur, ce qui peut devenir incompréhensible ; à l'exécution, les propriétés sont visibles grâce à l'introspection, tandis qu'une fois compilé, le constructeur perd les informations sur le "`nom"' des paramètres ; les propriétés sont héritées d'une classe mère à une classe lle, ce qui n'est pas vrai pour les constructeurs ;... De son côté, il est parfois intéressant d'utiliser l'injection de dépendances par constructeurs, si par exemple on désire que TOUS les paramètres soient fournis OBLIGATOIREMENT Petit exemple pratique Voyons un petit exemple de programmation avec Spring. Objectif : pouvoir fournir un service pour enregistrer un utilisateur. La classe Utilisateur Tout d'abord, une première classe simple, qui contient un nom et un mot de passe et qui représente un utilisateur : 1 public class User implements S e r i a l i z a b l e { 2 3 private S t r i n g _username ; 4 private S t r i n g _password ; 5 6 public User ( S t r i n g username, S t r i n g password ) { 7 _username = username ; 8 _password = password ; 9 } public S t r i n g getusername ( ) { 12 return _username ; 13 } public void setusername ( S t r i n g username ) { 16 _username = username ; 17 } public S t r i n g getpassword ( ) { 20 return _password ; 21 } public void setpassword ( S t r i n g password ) { 24 _password = password ; 25 } } Rien de spécial à première vue, si ce n'est qu'on a spécié que la classe devra être sérialisable. Gildas Cuisinier 28 Haute Ecole Rennequin Sualem

36 Spring Framework L'interface d'enregistrement d'un utilisateur De sorte à ne pas restreindre la possibilité d'enregistrement d'un utilisateur, une interface spécie quelle(s) méthode(s) existe(nt) pour travailler sur les utilisateurs. 1 public interface SaveUser { 2 3 public void save ( User u s e r ) ; 4 } Enregistrement dans un chier Ensuite, créons une première classe d'enregistrement d'un utilisateur, qui stockera celui-ci sous forme sérialisée dans un chier. 1 public class S a v e F i l e implements SaveUser { 2 3 public void save ( User u s e r ) { 4 5 F i l e f = new F i l e ( u s e r. getusername ( ) + ". usr " ) ; 6 7 try { 8 ObjectOutputStream oos = new ObjectOutputStream (new FileOutputStream ( f ) ) ; 9 oos. w r i t e O b j e c t ( u s e r ) ; 10 oos. c l o s e ( ) ; } catch ( Exception e ) { 13 e. printstacktrace ( ) ; 14 } 15 } 16 } Enregistrement dans une base de données Créons ensuite une classe qui stockera un utilisateur dans une base de données. 1 public class SaveDB implements SaveUser { 2 3 private S t r i n g _connectionstring ; 4 private S t r i n g _driver ; 5 6 public void s e t C o n n e c t i o n S t r i n g ( S t r i n g c o n n e c t i o n S t r i n g ) { 7 _connectionstring = c o n n e c t i o n S t r i n g ; 8 } 9 public void s e t D r i v e r ( S t r i n g d r i v e r ) { 10 _driver = d r i v e r ; 11 } 12 public void save ( User u s e r ) { 13 try { 14 Class. forname ( _driver ) ; Connection dbconn = DriverManager. getconnection ( _ connectionstring ) ; 17 PreparedStatement cmd = dbconn. preparestatement ( "INSERT INTO u s e r s VALUES (?,?) " ) ; cmd. s e t S t r i n g ( 1, u s e r. getusername ( ) ) ; 20 cmd. s e t S t r i n g ( 2, u s e r. getpassword ( ) ) ; 21 cmd. execute ( ) ; } 24 catch ( Exception e ) { } 25 } 26 } Gildas Cuisinier 29 Haute Ecole Rennequin Sualem

37 Spring Framework Il s'agit d'une classe un peu plus complexe. Au lieu de spécier, dans le code source, le driver à utiliser ainsi que la chaîne de connexion, on peut voir l'apparition de deux variables privées, associées à deux propriétés. L'intérêt est qu'ainsi, si l'on change de base de données, il n'est pas forcément nécessaire de tout recompiler. Le service Créons ensuite un service, qui encapsulera les classes précédentes. 1 public class S a v e S e r v i c e { 2 3 private SaveUser _saveuser ; 4 5 public SaveUser getsaveuser ( ) { 6 return _saveuser ; 7 } 8 9 public void setsaveuser ( SaveUser saveuser ) { 10 _saveuser = saveuser ; 11 } public void E n r e g i s t r e r U t i l i s a t e u r ( User User ) 14 { 15 _saveuser. save ( User ) ; 16 } 17 } Encore une fois, il n'y a pas une utilisation directe de la classe d'enregistrement par chier ou par base de données, mais il y a une variable privée du type de l'interface commune des deux, et liée à une propriété. Le chier de conguration Il faut ensuite lier toutes ces classes ensemble grâce au chier de conguration de Spring. Gildas Cuisinier 30 Haute Ecole Rennequin Sualem

38 Spring Framework <?xml version=" 1. 0 " encoding="utf 8"?> <!DOCTYPE beans PUBLIC " //SPRING//DTD BEAN//EN" " h t t p : //www. springframework. org / dtd / spring beans. dtd "> <beans> <! Sauver un u t i l i s a t e u r dans une base de donnees > <bean i d=" saveuserindb " c l a s s=" e x empletfe. impl. SaveDB"> <property name=" c o n n e c t i o n S t r i n g " value=" j d b c : m y s q l : // l o c a l h o s t /mabase"/> <property name=" d r i v e r " value=" org. mysql. Driver "/> </ bean> <! Sauver un u t i l i s a t e u r dans un f i c h i e r > <bean i d=" s a v e U s e r I n F i l e " c l a s s=" exempletfe. impl. S a v e F i l e " /> <! S e r v i c e pour e n r e g i s t r e r l e s u t i l i s a t e u r s > <bean i d=" u s e r S e r v i c e " c l a s s=" exempletfe. impl. S a v e S e r v i c e " > <! On e n r e g i s t r e dans un f i c h i e r > <property name=" saveuser " r e f=" s a v e U s e r I n F i l e " /> <! Pour e n r e g i s t r e r dans une base de donnees <property name=" saveuser " r e f=" saveuserindb " /> > </ bean> </ beans> On peut voir l'injection de dépendances : conguration de la connexion à la base de données pour le bean SaveUserByDB ; injection d'un Bean de sauvegarde d'utilisateur dans le service, soit l'un soit l'autre. Utilisation Le petit programme de test : 1 public class Main { 2 3 public static void main ( S t r i n g... a r g s ) { 4 5 ClassPathXmlApplicationContext appcontext = new ClassPathXmlApplicationContext ( " r e s s o u r c e s / exemple. xml" ) ; 6 BeanFactory f a c t o r y = ( BeanFactory ) appcontext ; 7 8 User u s e r = new User ( " g i l d a s ", " stagemanex " ) ; 9 S a v e S e r v i c e s e r v i c e U s e r = ( S a v e S e r v i c e ) f a c t o r y. getbean ( " u s e r S e r v i c e " ) ; 10 s e r v i c e U s e r. E n r e g i s t r e r U t i l i s a t e u r ( u s e r ) ; } 13 } Il est facile de constater que c'est tout à fait transparent pour l'utilisation nale, le programme nal ne sait pas où est stocké l'utilisateur, tout passe par le service. Maintenant, si l'on désire changer, il sut de modier le chier de conguration Xml, soit : en changeant les informations de connexion à la base de données ; en modiant le Bean à utiliser dans le service. Aucune recompilation n'est nécessaire. Gildas Cuisinier 31 Haute Ecole Rennequin Sualem

39 Spring Framework 6.3 Spring Web MVC? Que veut dire MVC? MVC est un modèle de conception qui impose la séparation entre les données, les traitements et la présentation. C'est pour cette raison que l'application est divisée en trois composants fondamentaux : le modèle, la vue et le contrôleur. Chacun de ces composants tient un rôle bien déni. Modèle Le modèle représente le comportement de l'application : traitements des données, interractions avec les bases de données, et intégration de celles-ci à la vue. Vue La vue correspond à l'interface avec laquelle les utilisateurs interragissent. Elle n'eectue aucune requête sur les bases de données et autres, mais reçoit des informations brutes des modèles, et s'occupe de la mise en page de ces informations. Au niveau Web, la vue est principalement conçue en HTML, mais peut être aussi bien en Flash. Contrôleur Pour nir, le contrôleur interprète les requêtes de l'utilisateur et appelle le couple modèle/vue an de répondre à la requête. Ainsi, lorsque l'utilisateur clique sur un lien ou soumet un formulaire HTML, le contrôleur ne produit rien et n'eectue aucun traitement. Il intercepte la requête et détermine quels modèles et quelles vues doivent êtres utilisés Spring : le dispatcher Comme dans le modèle MVC de base en Java, le rôle de dispatcher est attribué à une servlet. C'està-dire que les requêtes HTTP reçues seront transférées au bon contrôleur selon l'adresse demandée. Il faut donc déclarer une servlet, et la lier à une ou plusieurs adresses : <s e r v l e t> <s e r v l e t name>d i s p a t c h e r</ s e r v l e t name> <s e r v l e t c l a s s>org. springframework. web. s e r v l e t. D i s p a t c h e r S e r v l e t</ s e r v l e t c l a s s> <load on s t a r t u p>1</ load on s t a r t u p> </ s e r v l e t> <s e r v l e t mapping> <s e r v l e t name>d i s p a t c h e r</ s e r v l e t name> <url p a t t e r n>. form</ url p a t t e r n> </ s e r v l e t mapping> <s e r v l e t mapping> <s e r v l e t name>dasys</ s e r v l e t name> <url p a t t e r n>. htm</ url p a t t e r n> </ s e r v l e t mapping> Une servlet Dispatcher est déclarée, associée à la classe de la servlet fournie par Spring, et liée aux adresses nissant par html ou form. Gildas Cuisinier 32 Haute Ecole Rennequin Sualem

40 Spring Framework Le nom de la servlet est très important, car il va être employé pour savoir quel chier de conguration doit être utilisé. Dans notre cas, les Beans de Spring doivent être dénis dans un chier nommé dispatcher-servlet.xml, et doivent être situés dans le répertoire WEB-INF/ Spring : les Contrôleurs Un contrôleur pour Spring est une simple classe qui implémente l'interface Controller, avec son unique méthode : ModelAndView handlerequest( HttpServletRequest request, HttpServletResponse response) throws Exception; Cependant, Spring fournit des classes qui orent des services facilitant le développement de sites Web. Le deux principales sont : SimpleFormController, qui permet de faire des liaisons entre un objet et un formulaire HTML, tout en ajoutant la possiblité de faire des vérications sur les données fournies lors de l'envoi du formulaire. Ceci permet de vérier la validité des données ; MultiActionController, qui permet d'avoir plusieurs actions dans un seul contrôleur, et d'utiliser l'une ou l'autre action selon un paramètre fourni dans la requête HTTP. Au niveau du chier de conguration, il y a plusieurs choses à faire : Déclarer un contrôleur Tout d'abord, il faut créer une référence du Bean dans le chier de conguration <bean i d=" moncontrolleur " c l a s s=" monpackage. moncontrolleur "> <property name="commandname" value="command" > <property name=" commandclass" value=" monpackage. monobjetcommand" > <property name=" formview" value="admin/ download/ downloadselect " > <property name=" v a l i d a t o r "> <bean c l a s s=" monpackage. monvalidateur "> </ bean> </ property> </ bean> Ici, on a déclaré un contrôleur qui hérite de SimpleFormControler, et on lui attribue la classe qui recevra les données du formulaire, ainsi que la classe qui vériera les informations. On dénit aussi la vue qu'il doit utiliser. Lier le contrôleur à une adresse Jusqu'ici, le Bean est déclaré, mais il est impossible de le voir fonctionner : il n'est pas lié à une adresse. Pour cela, il faut créer un nouveau Bean, nommé handlermapping, qui va lier des Beans à une adresse. Gildas Cuisinier 33 Haute Ecole Rennequin Sualem

41 Spring Framework <bean i d=" handlermapping " c l a s s=" org. springframework. web. s e r v l e t. handler. SimpleUrlHandlerMapping "> <property name=" mappings"> <props> <prop key="/ moncontroller. form ">moncontrolleur</ prop> <prop key="/ deuxiemecontroller. form ">showsaselectcontroller</ prop> </ props> </ property> </ bean> Dans ce cas, on associe le Bean moncontrolleur à l'adresse : Spring : les modèles et les Vues Au niveau des vues, rien d'extraordinaire, ce sont des JSP qui reçoivent les informations à acher via les attributs de page. La spécicité de Spring est de lier la vue et le modèle au niveau du contrôleur. En eet, il apparaît que ce que renvoie l'unique méthode de l'interface Controller est un objet de type ModelAndView. Et si l'on regarde la JavaDoc : 1 ModelAndView ( S t r i n g viewname, Map model ) ; Le premier paramètre correspond à la page vue logique ( dans un premier temps, simplement le chemin vers la page JSP ), et le second à une Map des données à passer à la JSP. La Map peut contenir des Beans, une collection, ou simplement une chaîne de caractères, et la page JSP pourra les utiliser directement via les expression language. Exemple Soit un contrôleur qui va acher l'heure actuelle, ainsi que la langue actuelle. p u b l i c c l a s s ExempleController implements C o n t r o l l e r { p u b l i c ModelAndView h a n d l e R e q u e s t I n t e r n a l ( HttpServletRequest request, HttpServletResponse r e s p o n s e ) throws Exception { Map map = new HashMap ( ) ; map. put ( " date ", new Date ( ) ) ; map. put ( " langue ", new Locale ( ). getlanguage ( ) ) ; } } r e t u r n new ModelAndVue ( " t e s t. j s p ", map) ; Et la page JSP "`test.jsp"' : <html> <body> La date e s t ${ date } <br>la Langue e s t ${ langue } </ body> </ html> Gildas Cuisinier 34 Haute Ecole Rennequin Sualem

42 Chapitre 7 Hibernate Sommaire 7.1 Présentation générale Avantages et inconvénients Guide d'utilisation Lier Hibernate avec une base de données Le chier Hibernate.properties Le chier Hibernate.cfg.xml Mapping des objets Le mapping des associations Relation un à un Relation un à plusieurs Relation plusieurs à plusieurs Remarque sur les relations Génération de schémas Génération via Ant Conclusion Présentation générale Hibernate est un framework de mapping Objet/Relationnel. Autrement dit, c'est un framework qui va permettre de sauver des objets Java dans une base de données relationnelle, en gardant les relations qu'il possède avec d'autres objets. En quelque sorte, c'est une surcouche à JDBC qui ajoute une notion d'objet. Mais pour fonctionner, il ne sut pas de placer Hibernate dans notre application : une conguration est nécessaire. Hibernate permet aussi de générer la base de données qui sera utilisée au stockage. Ce chapitre présentera quelques-unes des fonctionnalités d'hibernate. Gildas Cuisinier 35 Haute Ecole Rennequin Sualem

43 Hibernate 7.2 Avantages et inconvénients Avantages : les objets métiers sont plus faciles à manipuler ; peu de dépendances avec une base de données, il sut de modier le chier de conguration pour passer d'une base Oracle à Postgres par exemple ; gain de temps assez important dans la génération du code si l'on utilise les outils intégrés : * XDoclet/Annotations : grâce à XDoclet, il est possible de générer le chier de conguration automatiquement si l'on utilise des annotations dans le code ; * hbm2ddl : permet la génération des tables en utilisant le chier de mapping ; * hbm2java : permet la génération des classes Java vides selon le chier de mapping ; * middlegen : permet la génération du chier de mapping au départ d'un chier DDL. Le principal inconvénient est la prise en main assez dicile au début. De plus, Hibernate n'est pas forcément adaptée à des projets importants où les performances doivent être optimales. 7.3 Guide d'utilisation Lier Hibernate avec une base de données Il existe deux moyens de lier Hibernate avec une base de données : soit via un chier properties, soit via un chier de conguration xml. Ces deux chiers contiendront les paramètres qui spécient le type de base de données, les informations de connexions, etc.. Les diérentes propriétés qui reviennent assez souvent sont : Propriétés hibernate.connection.driver class hibernate.connection.url hibernate.connection.username hibernate.connection.password hibernate.dialect hibernate.show_sql Descriptions Classe du driver JDBC Chaîne de connexion JDBC Utilisateur de la base de données Mot de passe de la base de données Le nom de la classe du dialect Hibernate Active ou désactive l'achage des requêtes SQL pour débugage Le Dialect est obligatoire car il permet d'optimiser Hibernate selon le type de base, par l'utilisation de séquences ou d'une génération de clés primaires propre à la base. De plus, il dénira les valeurs correctes pour certaines autres propriétés, ce qui évite de devoir le faire manuellement. Le chier Hibernate.properties Le premier moyen de fournir ces informations à Hibernate est un simple chier properties, donc au format clé=valeur qui doit être placé dans le CLASSPATH du projet ( /WEB-INF/classes pour un projet web ). Le chier Hibernate.cfg.xml Ce chier a la même utilité qu'hibernate.properties sauf que sa syntaxe est de l'xml. Il est à noter que si les deux chiers sont présents, c'est le format XML qui supplante les informations du chier properties. Gildas Cuisinier 36 Haute Ecole Rennequin Sualem

44 Hibernate Mapping des objets Le chier de mapping permet de lier la base de données avec les objets persistants et est au format XML. Exemple simple : <?xml version=" 1. 0 "?> <!DOCTYPE hibernate mapping PUBLIC " // Hibernate / Hibernate Mapping DTD 3. 0//EN" " h t t p : // h i b e r n a t e. s o u r c e f o r g e. net / hibernate mapping 3.0. dtd "> <hibernate mapping> <c l a s s name="mon. package. Exemple1" t a b l e="exemple"> <i d name=" i d " type=" long " colunm=" objid " unsaved value=" n u l l " > <g e n e r a t o r c l a s s=" sequence "> <param name=" sequence ">exemple_sequence</param> </ g e n e r a t o r> </ i d> <property name="name" type=" s t r i n g " column=" d e s c r i p t i o n " /> </ c l a s s> </ hibernate mapping> Déchirons ce chier : Un élément class, représentant une classe qui doit être mappée. Il possède des attributs : name, qui représente la classe dans son package ; table, qui spécie le nom de la table dans laquelle doivent être sauvés les objets. Si ce n'est pas spécié, alors Hibernate utilise la table du même nom que la classe. Et un élément class contient aussi au moins un élément ID et peut posséder plusieurs éléments Property. L' élément ID représente la clé primaire d'un objet, un identiant unique, et lui aussi possède des attributs : id, qui représente la propriété ( en sens JavaBean ) de la classe qui doit être utilisée comme identiant ; type, qui représente le type Hibernate de cette propriété ( peut valoir "string", "long", "int",.. ou le nom d'une classe Sérialisable ) ; column, qui spécie le nom de la colonne de la table qui doit être utilisée pour la clé primaire. Il possède aussi un élément enfant de type Generator. Un élément Generator, de la classe. L'attribut Class de cet élément peut valoir : représentant la manière de générer l'identiant unique pour les instances sequence, alors il utilise une séquence dans DB2, PostgreSQL, Oracle, SAP DB, McKoi ou un générateur dans Interbase ; increment, alors il génère des identiants du type long, short ou int qui sont uniques seulement lorsqu'aucun autre processus n'insère de données dans la même table ; native, alors il utilise la méthode la plus adaptée à la base de données précisée en tant que dialect ; assigned, alors Hibernate laisse l'application spécier l'identiant avant de le sauver dans la base ; L'élément Property représente les propriétés, les valeurs d'un objet. Il possède un attribut name qui spécie la propriété ( toujours au sens JavaBean ) de la classe, un attribut type qui dénit le type Gildas Cuisinier 37 Haute Ecole Rennequin Sualem

45 Hibernate Hibernate et un attribut column qui désigne le nom de la colonne dans la table Le mapping des associations Un des intérêts d'hibernate, c'est qu'il ne se contente pas de stocker simplement des objets dans une base de données, mais qu'il permet de garder les liaisons qui existent entre diérents objets. Et bien sûr, il existe plusieurs types de relations. Relation un à un Les associations un à un représentent le fait qu'une instance d'un objet correspond au maximum à une instance d'un autre objet. Par exemple, le fait qu'un utilisateur possède un mot de passe donnera, au niveau de la conguration Hibernate : <hibernate mapping> <c l a s s name="my. User " t a b l e=" u t i l i s a t e u r "> <! D e s c r i p t i o n de l a c l e primaire > <i d name=" i d " type=" long " colunm=" userid " unsaved value=" n u l l " > <g e n e r a t o r c l a s s=" sequence "> <param name=" sequence ">u t i l i s a t e u r _ s e q u e n c e</param> </ g e n e r a t o r> </ i d> <! P r o p r i e t e simple > <property name="nom" type=" s t r i n g " /> <property name="prenom" type=" s t r i n g " /> <! R e l a t i o n un à un > <one to one name=" password " c l a s s="my. User " cascade=" save update, p e r s i s t " /> </ c l a s s> <c l a s s name="my. Password " t a b l e=" password "> <! D e s c r i p t i o n de l a c l e primaire > <i d name=" i d " type=" long " colunm=" passwordid " unsaved value=" n u l l " > <g e n e r a t o r c l a s s=" sequence "> <param name=" sequence ">password_sequence</param> </ g e n e r a t o r> </ i d> <! P r o p r i e t e simple > <property name=" cyphertext " type=" s t r i n g " /> <! R e l a t i o n un à un > <one to one name=" u s e r " c l a s s="my. User " cascade=" save update, p e r s i s t " /> </ c l a s s> </ hibernate mapping> Donc, la relation est dénie grâce au tag <one-to-one>, qui nécessite au moins l'attribut name qui représente encore une fois le nom de la propriété. Il existe d'autres attributs optionnels tels que 1 : class : spécie le nom de la classe associée. Par défaut, Hibernate utilisera la réexion pour trouver une classe qui correspond ; cascade : spécie quelles actions seront réalisées en cascade sur les objets liés. ( Par exemple, une suppression du parent, supprimera l'enfant ou non ). 1 Cette liste n'est pas exhaustive Gildas Cuisinier 38 Haute Ecole Rennequin Sualem

46 Hibernate Relation un à plusieurs Il se peut aussi qu'un objet soit associé à plusieurs instances d'un autre type. Dans ce cas, on parle d'association un à plusieurs. Exemple : un utilisateur peut avoir plusieurs téléphones : <hibernate mapping> <c l a s s name="my. User " t a b l e=" u s e r "> <! D e s c r i p t i o n de l a c l e primaire > <i d name=" i d " type=" long " colunm=" userid " unsaved value=" n u l l " > <g e n e r a t o r c l a s s=" sequence "> <param name=" sequence ">u t i l i s a t e u r _ s e q u e n c e</param> </ g e n e r a t o r> </ i d> <! P r o p r i e t e simple > <property name="nom" type=" s t r i n g " /> <property name="prenom" type=" s t r i n g " /> <! Un u t i l i s a t e u r peut a v o i r p l u s i e u r s t e l e p h o n e > <s e t name=" phones "> <key column=" u s e r I d " not n u l l=" t r u e "/> <one to many c l a s s="my. Phone"/> </ s e t> </ c l a s s> <c l a s s name="my. Phone" t a b l e="phone"> <! D e s c r i p t i o n de l a c l e primaire > <i d name=" i d " type=" long " colunm="phoneid" unsaved value=" n u l l " > <g e n e r a t o r c l a s s=" sequence "> <param name=" sequence ">phone_sequence</param> </ g e n e r a t o r> </ i d> </ c l a s s> </ hibernate mapping> Dans ce cas, une explication est nécessaire. Tout d'abord, le tag <Set> représente une propriété d'un Bean de type java.util.set. Autrement dit, au niveau de la programmation du Bean, les diérents téléphones seront accessibles via un Set. Et ce Set sera accessible de l'extérieur par la propriété phones 2. La relation, quant à elle, est dénie via le tag <one-to-many>, qui spécie le type de la classe associée. Reste le tag <Key>,qui spécie le nom du champ, de la table qui stocke les téléphones, qui représente la clé étrangère vers un utilisateur. 2 autrement dit : void setphones(set lestelephones ) / Set getphones() Gildas Cuisinier 39 Haute Ecole Rennequin Sualem

47 Hibernate Relation plusieurs à plusieurs La dernière association qui sera présentée dans ce T.F.E. est la relation plusieurs à plusieurs. Pour rappel, dans la modélisation Merise, ce type de relation était réalisé par la création d'une nouvelle table qui associe les clés primaires des deux tables. Hibernate suit également ce modèle. Par exemple, pour Hibernate, si un utilisateur peut être membre de plusieurs groupes, et qu'un groupe peut contenir plusieurs utilisateurs, cela donnerait : <hibernate mapping> <c l a s s name="my. User " t a b l e=" u s e r "> <! D e s c r i p t i o n de l a c l e primaire > <i d name=" i d " type=" long " colunm=" userid " unsaved value=" n u l l " > <g e n e r a t o r c l a s s=" sequence "> <param name=" sequence ">u t i l i s a t e u r _ s e q u e n c e</param> </ g e n e r a t o r> </ i d> <! P r o p r i e t e simple > <property name="nom" type=" s t r i n g " /> <property name="prenom" type=" s t r i n g " /> <! Un u t i l i s a t e u r peut f a i r e p a r t i de p l u s i e u r s groupes > <s e t name=" groupes " t a b l e="usergroup" > <key column=" u s e r I d " /> <many to many column=" groupid " c l a s s="my. Group"/> </ s e t> </ c l a s s> <c l a s s name="my. Group" > <! D e s c r i p t i o n de l a c l e primaire > <i d name=" i d " type=" long " colunm="phoneid" unsaved value=" n u l l " > <g e n e r a t o r c l a s s=" sequence "> <param name=" sequence ">phone_sequence</param> </ g e n e r a t o r> </ i d> <! Un groupe peut a v o i r p l u s i e u r s u t i l i s a t e u r s > <s e t name=" u s e r s " t a b l e="usergroup" > <key column=" groupid " /> <many to many column=" u s e r I d " c l a s s="my. User "/> </ s e t> </ c l a s s> </ hibernate mapping> Pour chacune des deux classes apparait un Set, correspondant soit aux "Utilisateurs" d'un groupe, ou bien aux groupes dont fait partie un utilisateur. Première diérence par rapport au Set d' "un à plusieurs"' : il possède un nouvel attribut table qui représente la troisième table dont on vient de parler. Cet attribut doit donc bien sûr être identique pour les deux classes. Ensuite, la relation est spéciée par le tag <many-to-many>, qui possède deux attributs : class : spécie toujours le type de la classe associée ; column : spécie le nom de la clé étrangère de la classe associée dans la table de liaison ; Gildas Cuisinier 40 Haute Ecole Rennequin Sualem

48 Hibernate Ensuite, encore une fois, le tag <key> spécie le nom qu'aura la clé étrangère pour la classe courante dans la table de liaison. Autrement dit, si dans une classe l'attribut column du tag key vaut "ABC", dans la classe associée, l'attribut column du tag <many-to-many> devra valoir lui aussi "ABC". Remarque sur les relations Il n'a été présenté dans ce T.F.E. qu'une partie des relations que fournit Hibernate, car la présentation complète d'hibernate pourrait être en elle-même un sujet de mémoire. Mais à titre d'information, Hibernate permet de sauver les relations d'héritage. De plus, il permet de faire la diérence entre les relations unidirectionnelles et bidirectionnelles. Dans les exemples précédents, la relation groupes/utilisateurs était bidirectionnelle, car un groupe connaît ses utilisateurs, et un utilisateur connaît tous ses groupes. Par contre, les deux autres relations présentées sont unidirectionnelles, car un utilisateur connaît ses téléphones, mais un téléphone ne sait pas à qui il appartient. Mais il serait tout à fait possible de garder ce "lien" si on le désirait Génération de schémas Un autre intérêt d'hibernate est de pouvoir générer automatiquement le code SQL en se basant sur le chier de mapping, voire même se connecter directement à la base de données an de la créer. C'est particulièrement utile en phase de développement, cela permet de ne pas rééchir à comment modier le schéma dès qu'on ajoute des éléments. Et donc, il y a un gain de temps pendant les tests. Il est parfois utile de retravailler ce schéma dès qu'on atteint un niveau de production : des solutions basées sur des triggers, ou des éléments plus techniques peuvent être intéressants. Génération via Ant Un des moyens pour générer le schéma avec Hibernate est d'utiliser une tâche pour Ant 3 fournie avec Hibernate. 3 Ant est un outil, comparable au Make du C, permettant de créer et exécuter des tâches ( compilation, archivage, déployement,.. ) répétitives Gildas Cuisinier 41 Haute Ecole Rennequin Sualem

49 Hibernate Un exemple éventuel de script : <t a r g e t name=" i n i t db"> <path i d=" h i b e r n a t e c l a s s p a t h "> < f i l e s e t d i r=" l i b r a i r i e /"> <i n c l u d e name=". j a r "/> </ f i l e s e t> < f i l e s e t f i l e ="${ monapplication. j a r }"/> </ path> <t a s k d e f name=" schemaexport " classname=" org. h i b e r n a t e. t o o l. hbm2ddl. SchemaExportTask" c l a s s p a t h r e f=" h i b e r n a t e c l a s s p a t h "/> <schemaexport p r o p e r t i e s=".. / r e s s o u r c e / h i b e r n a t e / l o c a l d b. p r o p e r t i e s " t e x t="no" output=".. / s r c / h i b e r n a t e / i n t e r n a l. s q l "> < f i l e s e t d i r=".. / s r c / h i b e r n a t e "> <i n c l u d e name=".hbm. xml"/> </ f i l e s e t> </ schemaexport> </ t a r g e t> 1. Tout d'abord il faut créer un classpath, qui contiendra les librairies d'hibernate ( et ses dépendances ), mais aussi les sources de l'application ( sous forme de Jar ou de.class ) ; 2. Ensuite, il faut importer la tâche ant, via le tag <taskdef> ; 3. Pour nir, utiliser cette tâche <schemaexport> avec les paramètres suivants : properties qui est le chemin vers un chier de conguration Hibernate au format properties ; text : * s'il est positionné à true, seul le code SQL sera généré ; * s'il est positionné à false, Hibernate se connectera à la base pour créer le schéma ; output, est le chemin vers le chier dans lequel le code SQL doit être enregistré ; delimiter, dénit le caractère qui sera utilisé pour séparer les diérentes commandes SQL Conclusion Dans ce chapitre, les bases de l'api Hibernate ont été présentées, permettant d'ores et déjà de travailler avec la persistance des objets, tout en générant la base de données. D'autres outils sont inclus dans Hibernate tels qu'une intégration de XDoclet (qui permet de ne plus utiliser un chier de mapping, et de le remplacer par des tags du style javadoc directement dans les classes ) ou encore une gestion des transactions. Pour plus d'informations à ce sujet, je vous conseille le livre Professional Hibernate, de la collection WRox, ou encore la documentation ocielle 4, très bien faite et qui plus est, existe en version française. 4 Gildas Cuisinier 42 Haute Ecole Rennequin Sualem

50 Chapitre 8 Jafar Sommaire 8.1 Présentation générale Adaptation des audits Encodage de l'audit Génération de rapports Synchronisation avec le serveur central Architecture du serveur Jafar Le client Le serveur Jafar Schéma de la base de données serveur Table Jawsers Table Auditables Table ACS ( Auditable Components ) Table Encounters Table ProposedACS Table SynchroAssigments Objectifs du stage Présentation générale Adaptation des audits Jafar étant développé de manière à être générique, l'adaptation à un domaine spécique passe par la dénition de celui-ci via des chiers Xml, en utilisant un langage AuditML déni par Manex. Celui-ci est assez intuitif et n'oblige pas de connaissances approfondies de l'informatique pour être manipulé. Il existe plusieurs types de chiers XML pour dénir le domaine de l'application : les dictionnaires, qui dénissent les règles métiers du domaine ( en AuditML ) ; les GUI, qui dénissent l'apparence de l'interface utilisateur ( Combobox, Textbox, etc.. ), avec la syntaxe de conguration de Spring ; les chiers d'i18n, qui permettent d'utiliser les deux types précédents dans diérents langages ( en AuditML ). Gildas Cuisinier 43 Haute Ecole Rennequin Sualem

51 Jafar Exemple d'un dictionnaire en AuditML : <?xml version=" 1. 0 " encoding="utf 8"?> <d i c t i o n a r y x m l n s : x s i=" h t t p : //www. w3. org /2001/XMLSchema i n s t a n c e " xsi:nonamespaceschemalocation=" http: //www. auditml. org /schema/ d i c t i o n a r y. xsd "> <head> <d e f a u l t Q u a l i f i e r s> <lastelements x s i : t y p e=" t e x t " id="note"> <marker name=" note "/> </ lastelements> </ d e f a u l t Q u a l i f i e r s> <s e l e c t i o n L i s t s> <s e l e c t i o n L i s t id="sl. 1. Status "> <item>ok</ item> <item>pas OK</ item> <item>absent</ item> <item>reporté</ item> </ s e l e c t i o n L i s t> <s e l e c t i o n L i s t id="sl.language"> <item>nederlands</ item> <item>francais</ item> <item>deutsch</ item> <item>english</ item> </ s e l e c t i o n L i s t> </ s e l e c t i o n L i s t s> </ head> <body> <s e t id=" t0. admin"> <mac x s i : t y p e=" i n t e g e r " id="companyidewepk"> <c o n s t r a i n t>\d {6,7}</ c o n s t r a i n t> </mac> <mac x s i : t y p e=" s t r i n g " id="companyname"/> <mac x s i : t y p e=" s t r i n g " id="companyname2"/> <mac x s i : t y p e=" s t r i n g " id="companymail"> <c o n s t r a i n t><! + \. [ a z ]+ ] ]></ c o n s t r a i n t> </mac> <mac x s i : t y p e=" s t r i n g " id="companycountry"/> <mac x s i : t y p e=" i n t e g e r " id=" companyvisitorcode "/> <mac x s i : t y p e=" fastcode " lncdatabase="idewenacebel" id=" companysectortype"> < q u a l i f i e r s> <mac x s i : t y p e=" fastcodeengine " id=" companysectortypefastcodeengine "> <marker name=" fastcodeengine "/> <marker name=" displayinoverview "/> </mac> </ q u a l i f i e r s> </mac> <mac x s i : t y p e=" s t r i n g " id=" companyinactivitycode "/> <mac x s i : t y p e=" i n t e g e r " id="companyheadofficenumber"/> </ s e t> <s e t id=" t0. planning "> <mac x s i : t y p e=" s t r i n g " id=" visitedname "/> <mac x s i : t y p e=" s t r i n g " id=" examscheduling "/> <mac x s i : t y p e=" s t r i n g " id=" visitonrequest "/> </ s e t> <s e t id=" t0. i n f o "> <mac x s i : t y p e=" t e x t " id="companyinfodoc"/> </ s e t> </body> </ d i c t i o n a r y> Encodage de l'audit En se basant sur les chiers précédents, le client Jafar va créer une interface permettant d'entrer correctement les informations nécessaires. Autrement dit, les listes de choix, des éléments à cocher, des boîtes de textes... vont être générés dynamiquement. Génération de rapports Ensuite, selon les informations encodées, le client Jafar va créer automatiquement le rapport de l'audit. Synchronisation avec le serveur central Ensuite, les données collectées seront renvoyées vers le serveur central, qui s'occupera de garder l'historique des audits, ainsi que le planning des audits à eectuer. Gildas Cuisinier 44 Haute Ecole Rennequin Sualem

52 Jafar Fig. 8.1 Schéma d'utilisation de Jafar 1. Création du domaine de l'audit en AuditML. 2. Encodage de l'audit. 3. Génération de rapports. 4. Synchronisation avec le serveur Jafar. Gildas Cuisinier 45 Haute Ecole Rennequin Sualem

53 Jafar 8.2 Architecture du serveur Jafar Fig. 8.2 Architecture existante Le client D'un côté, nous avons un utilisateur du client Jafar qui peut : planier des rendez-vous pour un audit ; entrer des informations sur des sociétés ou des travailleurs ; voir son planning de rendez-vous ; encoder des résultats. Pour ce faire, le client Jafar possède une base de données interne. Celle-ci utilise Apache Derby, qui est une base de données complètement implémentée en Java, qui n'oblige pas d'installer un système de gestion de base de données externe Le serveur Jafar De l'autre côté, nous avons le serveur. Il stocke lui aussi les données, mais en quantité nettement plus importante, dès lors un système de base de données Derby devient insusant. Jafar peut utiliser une base de données Oracle RDB ou bien Postgres pour les données métiers, mais il est évolutif, et peut être adapté assez facilement à n'importe quel système de base de données. Durant la synchronisation avec le client, des chiers XML contenant les informations d'audit sont récupérées, ainsi que des chiers Log du client Jafar, tandis que des chiers XML contenant les informations sur le planning, les sociétés et autres sont envoyés au client. Les chiers XML reçus par le serveur seront analysés an d'eectuer les mises à jour dans la base de données, et seront ensuite stockés dans un répertoire an de garder une trace de la synchronisation. Les chiers de Log reçus, quant à eux, seront simplement stockés dans un répertoire. Gildas Cuisinier 46 Haute Ecole Rennequin Sualem

54 Jafar Schéma de la base de données serveur Fig. 8.3 Schéma de la base de données Jafar Table Jawsers Elle représente les utilisateurs de Jafar, ceux qui encodent les audits, génèrent les rapports, synchronisent les données avec le serveur. Exemple : Fig. 8.4 Exemple d'utilisateurs Table Auditables Cette table représente les "`cibles"' d'un audit, autrement dit, une société ou un travailleur. La diérence entre ces deux types est stockée dans l'attribut "`mactype"', qui vaudra t0 dans le cas d'une société, et t1 dans le cas d'un travailleur. De plus, un travailleur étant employé par une société, l'attribut "`parentid"' sera une référence vers celle-ci. Gildas Cuisinier 47 Haute Ecole Rennequin Sualem

55 Jafar Exemple : Fig. 8.5 Exemple d'auditables Table ACS ( Auditable Components ) Cette table représente les éléments que pourront contenir les informations qui caractérisent un audit sur une cible spécique. Par exemple, si l'on fait un audit sur une société, les informations nécessaires pour un audit pourraient être : le nom du responsable de la sécurité ( un champ texte ) ; la présence d'extincteurs ( un bouton à cocher ) ; l'état du matériel ( un champ de sélection : Bon état / Limite / À remplacer rapidement ). Et ces "`champs"' sont représentés dans la table ACS. Il faut cependant faire une distinction entre les ACS et les qualiers : Les ACS sont des informations liées directement à une auditable, elle peuvent être de type simple ( valeur texte, champs de sélection, etc ), mais elles peuvent être plus complexes, par exemple un employé peut avoir eu un emploi précédent. Les informations de cet emploi sont multiples : nom de l'employeur précédent ; date de début de l'emploi ; date de n de l'emploi. Dans ce cas, l'information liée à l'auditable est un AC "emploi précédent", qui possède des sousinformations stockées elles aussi dans la table ACS et appelées Qualiers. Ces sous-informations, liées donc à un AC et non plus à une auditable, sont appelées des Qualiers. Fig. 8.6 Exemple d'ac et de Qualiers Table Encounters Cette table contient le planning des audits passés et futurs des clients. Il lie un client ( attribut encounterer ) à faire un audit d'une société ou d'un travailleur ( attribut auditable ) sur un certain nombre de critères ( proposedmaciadlist ). Gildas Cuisinier 48 Haute Ecole Rennequin Sualem

56 Jafar Table ProposedACS Cette table contient les tâches proposées pour un audit. En eet, la table ACS contient tous les critères possibles pour un audit, or, il n'est pas forcément utile et nécessaire de revérier tous les critères à chaque audit. An de permettre de choisir seulement une partie des critères, il fallait pouvoir stocker la liste de ceux-ci, et c'est le rôle de cette table. Table SynchroAssigments Elle représente les informations assignées à un utilisateur, par un administrateur, an qu'elles lui soient obligatoirement transmises lors de la prochaine synchronisation Objectifs du stage La plus grosse partie ajoutée est bien entendu la partie web, basée sur le framework Spring MVC : des contrôleurs ; diérents services et DAOs ; diérents frameworks externes : * Tiles pour l'utilisation de Templates Web ; * JfreeChart pour la génération de Rapports ; * Hibernate pour l'implémentation des DAOs. Une seconde partie vient s'intercaler dans la synchronisation, elle comprend : le traitement des chiers de log reçus durant la synchronisation ; le traçage de la synchronisation. Ces informations sont stockées dans une base de données, mais diérente de la base de données métiers. Cette nouvelle base interne utilise Postgres, et ne contiendra que les informations propres au module de monitoring. Une dernière partie concerne le stockage d'informations d'état de la base de données. Cela signie que des données statistiques sur le nombre d'éléments métiers ( Auditables, ACs,... ) seront stockées périodiquement dans la base de données interne. Gildas Cuisinier 49 Haute Ecole Rennequin Sualem

57 Jafar Fig. 8.7 Architecture existante Fig. 8.8 Architecture après le développement du module de monitoring Gildas Cuisinier 50 Haute Ecole Rennequin Sualem

58 Troisième partie Développement de l'application 51

59 Chapitre 9 Module 1 : Créer la zone admin Sommaire 9.1 Objectif Analyse Eléments théoriques Validateur Spring Pratique Section : rejouer les chiers XML Schéma FileSystemXML ReplayCommand ReplayValidator ReplayController ReplayDeleagor Section : construire les chiers XML SynchroAssignmentService DownloadController DownloadDelegator Section : réinitialiser les Synchro Assignments Objectif Ce module est le point de départ de l'application Web à développer. Il consiste en fait à mettre en place l'architecture de base de la zone d'administration du serveur Jafar. Elle consiste en : une section pour acher les données envoyées par un utilisateur, et les données rejouées, soit une en particulier, soit toutes les données en une fois ; une section pour acher les données téléchargeables pour un utilisateur ; une section pour réinitialiser les dates de synchronisation des Synchro Assignments pour un utilisateur. Le tout est accessible via un menu qui permettra de naviguer vers ces sections. 9.2 Analyse Pour cette première partie, il n'y a pas eu énormément de choix à faire, si ce n'est lors du développement de la zone d'administration, celui d'utiliser du CSS pour la mise en forme. Gildas Cuisinier 52 Haute Ecole Rennequin Sualem

60 Module 1 : Créer la zone admin L'utilisation de tableaux simples pour la mise en forme n'est pas une bonne solution, car malgré la simplicité, les modications sont diciles par la suite. Par contre, grâce à l'utilisation du CSS, il sut de spécier des zones, et la mise en forme dépend des feuilles de style. Dès lors, lorsque mon design sera repris par un infographiste, il sera plus facile pour lui de travailler, et de reprendre ses modications pour les appliquer au site. 9.3 Eléments théoriques Validateur Spring Lorsque des données sont entrées dans un formulaire web, il est souvent intéressant de pouvoir vérier ces entrées, et de fournir un message d'erreur lorsqu'elles sont erronées, incorrectes ou absentes. Cela est souvent visible, par exemple sur une page d'inscription à un site, où il existe des champs obligatoires tels que le nom, l'adresse de référence, et un nom d'utilisateur. Si par exemple, des valeurs ne sont pas spéciées pour de tels champs, un message d'erreur apparaît, nous informant de ce manque d'information, ou, pour le cas du nom d'utilisateur de l'existence d'un utilisateur du même nom. Il serait possible de vérier ces informations dans le contrôleur et de renvoyer vers une page d'erreurs, mais Spring fournit un autre moyen plus ecace : les validateurs. Les validateurs fonctionnent seulement avec certains contrôleurs, ceux qui héritent de AbstractCommandController, ce qui est le cas du SimpleFormController. Un validateur est en fait une classe qui implémente l'interface Validator, qui fournit deux méthodes : public boolean supports(class aclass), qui dénit sur quelle(s) classe(s) d'objets Command le validateur eectue la validation ; public void validate(object object, Errors errors), qui est la méthode qui eectuera la validation. Un petit mot sur la méthode validate. Le premier paramètre object est en réalité l'objet Command sur lequel on travaille. Pour les cas simples, un validateur ne valide qu'un seul type de commande, donc on peut simplement faire un casting vers le type de l'objet Command. Dès lors, on pourra utiliser les propriétés pour connaître les valeurs fournies et faire des vérications. Une erreur détectée devra être indiquée à Spring, et pour cela, on utilise le 2ème paramètre, de type org.springframework.validation.errors. Cette classe possède une méthode : void rejectvalue(string eld, String errorcode, String defaultmessage), où : * eld représente le champ de l'objet command en erreur ; * errorcode représente le code d'erreur qui sera utilisé pour récupérer le message d'erreur selon la langue du client. Elle peut être null, dans ce cas, le message renvoyé sera le message par défaut ; * defaultmessage, représente le message par défaut qui sera aché soit lorsqu'il n'existe pas de message dans la langue voulue, soit parce que errorcode a été positionné à null ; Dès qu'une erreur a été spéciée, Spring n'appellera pas la méthode du contrôleur qui traite la requête, mais réachera le formulaire, avec les messages d'erreurs, si bien sûr la page JSP le permet. Gildas Cuisinier 53 Haute Ecole Rennequin Sualem

61 Module 1 : Créer la zone admin Pour cela, il sut de l'indiquer dans le tag <spring :bind> : <s p r i n g : b i n d path="command. username "> <input type=" t e x t " name="${ s t a t u s. e x p r e s s i o n }" value="${ s t a t u s. value }"/> <! A f f i c h a g e du message d ' e r r e u r en rouge s i b e s o i n > <b><f o n t c o l o r ="red"><c : o u t value ="${ s t a t u s. errormessage}"/></font ></b> </s p r i n g : b i n d > 9.4 Pratique Section : rejouer les chiers XML Schéma Fig. 9.1 Diagramme d'utilisation du rejouement de chier XML Au niveau web, cette section possède deux pages : un formulaire du choix de l'utilisateur et des dates ; une page qui ache les résultats selon le choix. Elle possède cinq classes Java : FileSystemXML, qui représente les chiers XML pour un utilisateur donné et une période donnée ; ReplayController, qui est le contrôleur du formulaire de choix. Il va récupérer la liste des chiers, et les envoyer à la 2ème vue/page pour permettre à l'utilisateur de choisir quel chier "`rejouer"' ; ReplayCommand, qui représente l'objet Command du formulaire du choix de l'utilisateur ; ReplayValidator, c'est le validateur associé au contrôleur et à l'objet Command. Il va vérier l'existence de l'utilisateur entré, ainsi que le format des dates ; ReplayDelegator, c'est la classe qui va permettre de rejouer le (les) chier(s) sélectionné(s) par l'utilisateur. Gildas Cuisinier 54 Haute Ecole Rennequin Sualem

62 Module 1 : Créer la zone admin FileSystemXML La base de cette classe existait déjà. Au départ, la base permettait de récupérer la liste des chiers pour un utilisateur donné. Le constructeur de cette classe prenait en paramètre l'utilisateur en question, et allait vérier l'existence d'un répertoire du nom de cet utilisateur dans celui où sont stockés les chiers uploadés par les utilisateurs. Et s'il existait, il parcourait les sous-répertoires pour ajouter les informations sur les chiers dans une liste. En premier, il fallait modier cette classe an de pouvoir faire une recherche basée sur une période de temps. Du fait de l'organisation des répertoires / chiers, ce ne fut pas spécialement dicile car le format des chemins suit : <Répertoire de Base>/<User>/<Date d'upload>/<datasync> Dès lors, avant d'ajouter un chier dans la liste, il sut de vérier que la date d'upload est comprise dans la période. ReplayCommand L'objet ReplayCommand ne fait que stocker les entrées d'un utilisateur, et dans ces cas-ci : l'identiant Utilisateur ; la date à partir de laquelle commencer la recherche. Elle peut être égale à null ; la date à laquelle doit se nir le ltre de la recherche. Elle peut être égal à null. ReplayValidator C'est le validateur de l'objet ReplayCommand, chargé de vérier : si l'identiant utilisateur n'est pas null ; si l'identiant utilisateur existe vraiment ; dans le cas où la date de début n'est pas nulle, si le format est correct ; dans le cas où la date de n n'est pas nulle, si le format est correct. Vérication de l'utilisateur. autre classe : UserMBean. Pour vérier qu'un utilisateur existe, le validateur a besoin d'une En fait, ce Bean contient en cache tous les utilisateurs existants, et propose une méthode User get- ByUserId(String id). Il sut de vérier que le résultat de cet appel avec comme paramètre l'entrée fournie ne renvoit pas nulle. Si tel était le cas, les informations fournies par le formulaire ne seraient pas correctes et il faudrait acher une erreur. Vérication de la date. Le validateur contient une instance de SimpleDateFormat, qui permet d'analyser une chaîne de caractères pour récupérer une instance de Date. Et cette méthode lance une exception ParseException dans le cas où la date n'est pas correctement formatée, en renvoyant une erreur à Spring dans le bloc catch. Gildas Cuisinier 55 Haute Ecole Rennequin Sualem

63 Module 1 : Créer la zone admin ReplayController Il ne fait que récupérer un objet ReplayCommand, et en extrait les informations sur l'utilisateur ainsi que sur les dates. Du fait que l'objet Command est au préalable passé par le validateur, on est sûr et certain que les informations sont correctes. Il n'a plus qu'à utiliser un FileSystemXML pour récupérer la liste des chiers, et les fournir à la vue. ReplayDeleagor La base de cette classe m'était déjà fournie, elle permettait de rejouer un seul chier à la fois. Elle possède une méthode interne replay, qui prend comme paramètre un chier et l'identiant de l'utilisateur associé à ce chier. An de permettre de rejouer tous les chiers sélectionnés par une recherche, une méthode replayall a dû être ajoutée. Cette méthode récupérait l'identiant et les deux dates fournies dans la recherche. Il me susait, via un objet FileSystemXML, de récupérer la liste des chiers, et de lancer la méthode replay, avec chaque chier Section : construire les chiers XML Cette section est assez identique à la précédente, hormis le Délégateur qui, au lieu de rejouer des chiers, permet de récupérer un chier XML par téléchargement. En ce qui concerne les classes : SynchroAssignmentService, qui est une classe qui ore des services sur les Synchro ; DownloadController, le contrôleur qui permet d'acher les chiers disponibles pour un utilisateur ; DownloadCommand, qui représente l'objet Command du formulaire du choix de l'utilisateur ; DownloadValidator, qui ore dans ce cas précis une vérication de l'existence d'un utilisateur ; DownloadDelegator, qui va récupérer le chier à télécharger et le fournir au client via un téléchargement. SynchroAssignmentService Ce service est en fait la classe qui encapsule un DAO, et qui permet d'ajouter une notion transactionnelle à ses accès. Elle se compose d'une interface et d'une implémentation. Elle propose des méthodes telles que : int delete(string id) ; List<SynchroAssignmentEntry> getallbyuserid(string userid) ; SynchroAssignmentEntry getbyid(string id) ;... En réalité, ces méthodes vont appeler les méthodes équivalentes du DAO. Gildas Cuisinier 56 Haute Ecole Rennequin Sualem

64 Module 1 : Créer la zone admin DownloadController Ce contrôleur va simplement récupérer la liste des chiers disponibles pour un utilisateur, et ce, grâce au service de Synchro Assignements. DownloadDelegator Ce contrôleur contient une méthode : public ModelAndView download(httpservletrequest request, HttpServletResponse response) ; Cette méthode va faire appel à un autre service, déja existant, qui permet de récupérer les chiers sous format de documents XML. Dès lors, il sut d'utiliser un framework XML qui permet d'analyser un tel chier, et de l'écrire sur un ux, qui dans ce cas sera le ux de sortie de l'objet HttpServletResponse. Cependant, an de permettre le téléchargement, et non l'achage du chier XML dans le navigateur, il faut spécier le type de données qui seront renvoyées par le biais de : response.setcontenttype("text/xml") ; response.setheader("content-disposition", "attachment; filename=" + f.getname()) ; Ainsi, le chier sera considéré par tous les navigateurs comme un chier à télécharger et non à acher directement comme une page Web Section : réinitialiser les Synchro Assignments Cette partie consiste en une page unique, qui sera à la fois la page qui ache le formulaire, ainsi que celle qui ache le résultat de l'opération. Au niveau des classes, il y en a uniquement trois : un contrôleur, un objet command et un validateur. Les deux dernières ont exactement les même rôles que dans les sections précédentes. Le contrôleur, de son côté, possède une référence vers un service de Synchro Assignments, qui comprend une méthode qui réinitialise ceux-ci en fonction d'un utilisateur. Il renvoie à la vue, une information sur le nombre d'éléments qui ont été modiés par cette requête. Au niveau de la vue, donc de la page JSP, il existe une petite diérence par rapport au précédent formulaire : il y a du code javascript qui demande une conrmation avant de procéder au transfert du formulaire. Une sécurité existe donc pour ne pas eacer des informations par inadvertance. Gildas Cuisinier 57 Haute Ecole Rennequin Sualem

65 Chapitre 10 Module 2 : Tracer les téléchargements Sommaire 10.1 Objectif Eléments théoriques Hibernate DAO/Service La couche DAO La couche Service Pratique Création d'un objet de stockage Création du mapping Hibernate Création d'un DAO Hibernate Création d'une Interface Création de l'implémentation Hibernate Conguration du DAO dans Spring Création d'un Service Création d'une Interface Création de l'implémentation Conguration du Service dans Spring Création de l'interface Web Objectif L'objectif de ce module est de pouvoir tracer les téléchargements d'un utilisateur, et de stocker ce traçage dans une base de données, grâce à Hibernate. Il faudra ensuite pouvoir acher ces chiers de trace pour un utilisateur Eléments théoriques Hibernate Hibernate est un framework qui permet de faciliter l'enregistrement d'objets, ainsi que leurs relations, dans une base de données relationnelle. ( Voir le chapitre 7 ) Gildas Cuisinier 58 Haute Ecole Rennequin Sualem

66 Module 2 : Tracer les téléchargements DAO/Service La couche DAO Lorsque l'on développe une application, et que l'on doit sauver des informations de manière persistante, le choix du type de stockage est assez courant : base de données relationnelle ; base de données Objet ; chier XML ; ldap ;... À la vue de cette liste, on peut déjà voir que les méthodes d'accès sont complétement diérentes. De plus, pour les bases de données, on pourrait encore subdiviser, car on peut y accéder directement via JDBC, ou en utilisant des frameworks tels qu'hibernate. Et même lors d'accès JDBC, les requêtes SQL peuvent être complètement diérentes selon le type de base ( Oracle, Mysql, Postgres,.. ) Des programmeurs qui ne penseront pas à la maintenance d'un projet vont sûrement faire des accès directement selon le type de stockage qui aura été choisi. C'est malheureusement assez mal pensé, car en cas de problème, il faudra parcourir tout le code pour trouver les endroits où les accès sont faits, pour corriger. De plus, si pour une raison ou une autre il fallait changer de type de stockage, cela devient périlleux. D'où tout l'intérêt du pattern DAO. Le DAO est en fait une couche d'accès au stockage et consiste en : une interface, qui contient les méthodes d'accès ( stockage d'un utilisateur, recherche de tous les utilisateurs commençant par une chaîne spéciée en paramètre,... ) une ou plusieurs implémentations, une implémentation par "`type de stockage"', cette implémentation va donc eectuer les accès spéciques. En pratique, cela veut dire qu'il va y avoir, par exemple : une implémentation du DAO pour Hibernate, qui va eectuer les lectures/écritures en utilisant l'api Hibernate ; Gildas Cuisinier 59 Haute Ecole Rennequin Sualem

67 Module 2 : Tracer les téléchargements une implémentation du DAO pour XML, et qui va faire des lectures/écritures de chiers XML ; une implémentation du DAO pour JDBC Mysql, et qui va faire des accès via JDBC mais avec des requêtes SQL optimisées pour Mysql ; une implémentation du DAO pour JDBC Oracle, et qui va faire des accès via JDBC mais avec des requêtes SQL optimisées pour Oracle. Et au niveau du programme, une classe Factory va récupérer une implémentation d'un certain type. Note : Si Spring est utilisé, il n'y a pas besoin de classe Factory, grâce à l'injection de dépendances. La couche Service L'intérêt de la couche Service est qu'elle va servir à gérer les transactions. Mais pourquoi ne pas utiliser les transactions au niveau DAO? Tout simplement parce qu'un DAO est spécique à une seule classe métier. Or, lors d'une transaction, il est possible de travailler sur plusieurs classes métiers d'un coup. Dès lors, si l'on travaille sur les DAO pour la transaction, il se peut qu'une transaction passe, et que la deuxième ne passe pas, mais la première ayant réussi, elle sera présente dans la base. Il y aura donc une incohérence. Ce problème est résolu grâce au Service : soit tout se passe bien et tout est sauvé dans la base de données ( via les DAO ), soit il y a une erreur, et toute la transaction est annulée Pratique Création d'un objet de stockage Lors du début de l'application, les informations à propos du traçage étaient simplement gardées en mémoire, et uniquement dans la méthode de téléchargement, autrement dit, une fois qu'un chier était téléchargé, les données de traçage étaient perdues. Ces informations consistaient principalement à connaître les moments d'entrée et de sortie des diérentes étapes du téléchargement. Ce qui permettait de savoir en plus le temps qu'il fallait pour eectuer ces étapes. Outre ces informations de trace, il faut aussi sauvegarder les informations sur le type de données téléchargées, et bien sûr, l'information sur la personne qui a téléchargé le chier. L'objet qui représente cela sera donc un simple objet qui contiendra plusieurs paires de champs de type entier long, dont la nomenclature sera : long xxxxxstart, pour le moment de début de l'étape xxxxx long xxxxxstop, pour le moment où cette étape nit. Ainsi que plusieurs champs représentant le type de données et l'utilisateur. Vu que ces champs sont privés, il faut aussi des accesseurs an de modier ou lire ces derniers. Ces accesseurs sont spéciés dans une interface DownloadTracking, tandis que l'objet qui implémente cette interface est nommé DownloadTrackingImpl Gildas Cuisinier 60 Haute Ecole Rennequin Sualem

68 Module 2 : Tracer les téléchargements Création du mapping Hibernate L'objet n'ayant pas de relation avec d'autres, le mapping Hibernate est très simple, voici un extrait : <c l a s s name="be. manex. j a f a r. s e r v e r. i n t e r n a l m o d e l. impl. DownloadTrackingImpl " t a b l e=" trackinglog "> <i d name=" i d " column=" dbid " type=" long " unsaved value=" n u l l "> <g e n e r a t o r c l a s s=" sequence "> <param name=" sequence ">downloadlogs_dbid_seq</param> </ g e n e r a t o r> </ i d> <property name=" dataid " type=" s t r i n g " not n u l l=" t r u e "/> <property name=" backupxmlresponsestart" type=" long " not n u l l=" t r u e "/> <property name=" backupxmlresponsestop" type=" long " not n u l l=" t r u e "/> <property name="backupxmlstart" type=" long " not n u l l=" t r u e "/> [... ] <property name=" x m l S e r v i c e S t a r t " type=" long " not n u l l=" t r u e "/> <property name=" xmlservicestop " type=" long " not n u l l=" t r u e "/> </ c l a s s> Ce code est extrait d'un chier internal-hibernate-mapping-postgres.hbm.xml, qui représente le mapping de la base de données interne ( qui est diérente de la base de données qui contient les ACS, Auditables, etc.. ). En utilisant la génération du schéma par Hibernate, on obtient : Fig Génération de la table de traçage par Hibernate Création d'un DAO Hibernate Création d'une Interface Tout d'abord, il faut créer une interface qui dénit les méthodes qui seront accessibles pour tout objet qui possèdera une référence vers ce DAO. 1 public interface DownloadTrackingDao { 2 void add ( DownloadTracking downloadlog ) ; 3 void update ( DownloadTracking downloadlog ) ; 4 List <DownloadTracking> g e t A l l ( ) ; 5 6 List <DownloadTracking> findbyuserid ( S t r i n g u s e r I d ) ; 7 L i s t <DownloadTracking> findbydate ( Date date ) ; 8 List <DownloadTracking> findbydate ( Date s t a r t, Date end ) ; 9 List <DownloadTracking> findbyperiod ( Date s t a r t, Date end ) ; 10 } Les méthodes add, update ainsi que getall sont assez courantes dans les DAO. Gildas Cuisinier 61 Haute Ecole Rennequin Sualem

69 Module 2 : Tracer les téléchargements Remarques : il serait d'ailleurs intéressant de créer une interface GenericDao qui utiliserait les génériques de java contenant ces méthodes. Les autres méthodes de cette interface sont plus spéciques aux objets de trace, elles permettent de faire une recherche par utilisateur, par date ou encore par période. Création de l'implémentation Hibernate Lors de la création d'un DAO Hibernate, dans un contexte autre que Spring, il faudrait gérer directement les sessions et/ou les sources de données. Mais Spring fournit une classe de base HibernateDaoSupport, qui s'occupe déjà de cette gestion ( mais qu'il faudra tout de même paramétrer via l'injection de dépendances ), et donc la classe que l'on développe n'a plus qu'à s'occuper de la logique métier pure. Dès lors, les méthodes de la classe que l'on développe ont une structure semblable : 1 public void add ( DownloadTracking downloadlog ) { 2 final S e s s i o n s e s s i o n ; 3 4 try { 5 s e s s i o n = g e t S e s s i o n ( ) ; 6 7 / 8 Code metier q u i t r a v a i l l e sur l a s e s s i o n 9 / 10 } catch ( HibernateException ex ) { 11 throw S e s s i o n F a c t o r y U t i l s. converthibernateaccessexception ( ex ) ; 12 } 13 } Il sut de récupérer la session par la méthode getsession() ( dénie dans HibernateDaoSupport ) et d'encapsuler les accès à cette session dans un bloc try/catch qui utilisera la méthode SessionFactoryUtils.convert qui en fait va renvoyer une exception propre à Spring dans le contexte des DAO. C'est-à-dire que les exceptions qui seront lancées par Hibernate ( du type HibernateException ) seront transformées en une exception équivalente mais propre au package org.springframework.dao, qui est donc plus générique. Ce qui permet ainsi de cacher l'utilisation d'hibernate pour les couches supérieures, qui ne devront s'occuper que d'exceptions standards. Conguration du DAO dans Spring <bean i d=" downloadtrackingdaotarget " c l a s s="be. manex. j a f a r. s e r v e r. i n t e r n a l m o d e l. h i b e r n a t e. dao. DownloadTrackingDaoImpl "> <property name=" s e s s i o n F a c t o r y " r e f=" i n t e r n a l S y n c h r o S e s s i o n F a c t o r y "/> </ bean> <bean i d=" i n t e r n a l S y n c h r o S e s s i o n F a c t o r y " c l a s s=" org. springframework. j n d i. JndiObjectFactoryBean "> <property name="jndiname" value=" j a v a : / h i b e r n a t e / H i b e r n a t e S e s s i o n F a c t o r y J a f a r S e r v e r I n t e r n a l "/> </ bean> On peut voir que ce n'est qu'au niveau de Spring que l'on voit apparaître la notion de sessionfactory. Dans ce cas, l'instance de sessionfactory est récupérée via JNDI. Cette instance est créée lors du déploiement de l'application, mais cette fois au niveau de JBoss, dans le chier de conguration Jboss-Service.xml : Gildas Cuisinier 62 Haute Ecole Rennequin Sualem

70 Module 2 : Tracer les téléchargements <mbean code=" org. h i b e r n a t e. jmx. H i b e r n a t e S e r v i c e " name="manex. j c a : s e r v i c e=h i b e r n a t e S e s s i o n F a c t o r y J a f a r S e r v e r I n t e r n a l "> <depends>j b o s s. j c a : s e r v i c e=rardeployer</ depends> <a t t r i b u t e name="jndiname">j a v a : / h i b e r n a t e / H i b e r n a t e S e s s i o n F a c t o r y J a f a r S e r v e r I n t e r n a l</ a t t r i b u t e> <a t t r i b u t e name=" Datasource ">j a v a : / Internal_Jafar_Server_Datasource</ a t t r i b u t e> <a t t r i b u t e name=" D i a l e c t ">org. h i b e r n a t e. d i a l e c t. PostgreSQLDialect</ a t t r i b u t e> <a t t r i b u t e name=" T r a n s a c t i o n S t r a t e g y ">org. h i b e r n a t e. t r a n s a c t i o n. JTATransactionFactory</ a t t r i b u t e> <a t t r i b u t e name=" TransactionManagerLookupStrategy "> org. h i b e r n a t e. t r a n s a c t i o n. JBossTransactionManagerLookup</ a t t r i b u t e> <a t t r i b u t e name=" CacheProviderClass ">org. h i b e r n a t e. cache. HashtableCacheProvider</ a t t r i b u t e> <a t t r i b u t e name=" ShowSqlEnabled ">t r u e</ a t t r i b u t e> <a t t r i b u t e name="mapresources ">i n t e r n a l hibernate mapping p o s t g r e s. hbm. xml</ a t t r i b u t e> </mbean> L'intérêt de le déclarer au niveau de JBoss, en tant que MBean, est qu'il sera possible de le congurer via un Manager JMX. Par exemple, l'interface web jmx-console que Jboss fournit Création d'un Service Création d'une Interface Tout comme le DAO, un service est accessible via son interface, la première étape est d'en créer ( readonly = f a l s e ) p u b l i c i n t e r f a c e MonitorDownloadService { } p u b l i c void save ( DownloadTracking t r a c k ) ; p u b l i c void update ( DownloadTracking t r a c k ) ; p u b l i c void d e l e t e ( DownloadTracking t r a c k ) ; p u b l i c L i s t<downloadtracking> l i s t A l l ( ) ; p u b l i c L i s t<downloadtracking> findbyuserid ( S t r i n g u s e r i d ) ; p u b l i c L i s t<downloadtracking> findbydate ( Date date ) ; p u b l i c L i s t<downloadtracking> findbydate ( Date s t a r t, Date end ) ; p u b l i c L i s t<downloadtracking> findbyperiod ( Date s t a r t, Date end ) ; On note l'apparition d'une annotation java = false) Cette annotation veut dire que toutes les méthodes de cette interface seront considérées comme transactionelles. Dans notre cas, c'est obligatoire. En eet, Hibernate fonctionne de telle manière qu'il faut faire un commit pour que les écritures/modications se fassent au niveau de la base de données. Or, on a vu qu'au niveau du DAO, on n'utilisait pas directement les transactions, donc il faut bien qu'elles apparaissent quelque part. Mais où? Dans ce cas précis, l'annotation "`Transactional"' est une partie de la réponse. En eet, le fait d'annoter de cette manière ne rend pas la méthode directement transactionnelle, mais sert à la marquer an d'informer à Spring qu'il devra la rendre transactionnelle. Création de l'implémentation Dans le cas de l'implémentation du Service, rien de spécial à dire. Il possèdera une référence vers le DAO, et ne fera qu'appeler les méthodes de celui-ci. Gildas Cuisinier 63 Haute Ecole Rennequin Sualem

71 Module 2 : Tracer les téléchargements Conguration du Service dans Spring <bean i d=" monitordownloadservicetarget " c l a s s="be. manex. j a f a r. s e r v e r. i n t e r n a l m o d e l. s e r v i c e s. impl. MonitorDownloadServiceImpl "> <property name=" downloadtrackingdao " r e f=" downloadtrackingdaotarget "/> </ bean> <bean i d=" monitordownloadservice " c l a s s=" org. springframework. t r a n s a c t i o n. i n t e r c e p t o r. TransactionProxyFactoryBean "> <property name=" transactionmanager " r e f=" txmanager"/> <property name=" p r o x y I n t e r f a c e s " value="be. manex. j a f a r. s e r v e r. i n t e r n a l m o d e l. s e r v i c e s. MonitorDownloadService " /> <property name=" t a r g e t " r e f=" monitordownloadservicetarget "/> <property name=" t r a n s a c t i o n A t t r i b u t e S o u r c e "> <bean c l a s s=" org. springframework. t r a n s a c t i o n. annotation. AnnotationTransactionAttributeSource "/> </ property> </ bean> <bean i d="txmanager" c l a s s=" org. springframework. orm. h i b e r n a t e 3. HibernateTransactionManager "> <property name=" s e s s i o n F a c t o r y " r e f=" i n t e r n a l S y n c h r o S e s s i o n F a c t o r y "/> </ bean> Comme on peut le voir, au niveau du service, il n'y a pas qu'un acteur mais trois. monitordownloadservicetarget. Ce Bean est la classe du Service que l'on a développé, tout à fait standard, et dans lequel on injecte la référence vers le DAO. monitordownloadservice. Ce Bean est la référence que l'on va fournir à tous les autres Beans qui auront besoin du Service précédemment cité. En fait, c'est un proxy, c'est-à-dire une classe qui va fournir exactement les mêmes méthodes qu'une classe ciblée ( target ) et qui sera une implémentation d'une interface ou plusieurs ( proxyinterfaces ). txmanager. En plus de spécier la classe qu'il doit rendre transactionnelle, le proxy nécessite un composant de gestion de transactions propre à la base de données utilisée. En eet, une transaction Hibernate n'est pas gérée de la même manière qu'une transaction au niveau JDBC. Mais quel est l'intérêt? En fait, ce proxy ne va pas simplement appeler les méthodes de la classe qu'il remplace. En plus, pour les méthodes qui sont marquées comme transactionelles ( via ), il va s'occuper des transactions. C'est donc grâce aux annotations et à ce proxy qu'une classe non-transactionnelle peut le devenir. Remarque : l'utilisation des annotations n'est apparue qu'avec la version 5 de Java. Avant celle-ci, on dénissait directement dans Spring quelles méthodes devenaient transationnelles, ainsi que leur mode de transaction Création de l'interface Web Au niveau de l'interface Web, il y aura trois manières d'acher des traces : soit les traces d'un utilisateur donné ; soit la trace de tous les utilisateurs pour un jour donné entre deux heures spéciées ; soit la trace de tous les utilisateurs pour une période donnée. Gildas Cuisinier 64 Haute Ecole Rennequin Sualem

72 Module 2 : Tracer les téléchargements Comme précédement, il y aura un objet command, qui va être validé par un validateur. La seule diérence de ce validateur par rapport aux autres est qu'il va eectuer une vérication diérente selon le type d'entrée fournie. Au niveau du contrôleur, il contiendra une référence vers le service, et selon le type d'entrée, appellera l'une ou l'autre méthode du Service. Gildas Cuisinier 65 Haute Ecole Rennequin Sualem

73 Chapitre 11 Module 3 : Ajouter des fonctionnalités Sommaire 11.1 Objectif Analyse Eléments théoriques JFreeChart Exemple simple d'utilisation de JFreeChart Pratique Création d'une surclasse pour la génération de graphique Création d'une tâche planiée Création de l'objet qui eectue la tâche Création du wrapper pour s'intégrer au Framework Plannication de la tâche Création du Manager de Plannication Objectif Ce module consiste à améliorer la section d'achage des traces de téléchargements et la section de gestion des synchro Assignments et à ajouter une nouvelle section pour acher les statistiques des données dans la base de données. Rechercher des traces de téléchargements, c'est permettre une recherche sur une période donnée pour tout utilisateur. En ce qui concerne la gestion des Synchro Assignments, cette section possède plusieurs fonctionnalités : une page pour réinitialiser, donc la page existante ; une recherche des SA pour un utilisateur donné pour ensuite pouvoir : * en supprimer ; * faire une vérication des liens entre les SA et les données sur lesquelles elle pointent ; une page pour ajouter une synchro Assignment pour un utilisateur. Gildas Cuisinier 66 Haute Ecole Rennequin Sualem

74 Module 3 : Ajouter des fonctionnalités 11.2 Analyse 11.3 Eléments théoriques JFreeChart Dans de nombreuses applications, il est nécessaire de disposer de graphiques statistiques sur les données de son domaine d'application. Dans la plupart des cas, ces graphiques reposent sur diérents modes de représentations typiques : histogrammes, camemberts, courbes de répartition, et graphiques d'évolution n'en sont que quelques exemples. Or, créer de tels graphiques manuellement est assez pénible. La solution à ce problème est JFreeChart qui est sans doute, dans le monde Java, l'outil de génération de graphiques le plus connu et le plus réputé, pour diverses raisons : d'abord, en tant que librairie Open-Source, JFreeChart bénécie d'un avantage important face à ses concurrents : sa gratuité ; JFreeChart est un outil facile à utiliser et à intégrer dans une application, qu'elle soit installable, ou utilisée depuis un navigateur web. Exemple de graphique généré par JfreeChart : Fig Graphique généré par JFreeChart Gildas Cuisinier 67 Haute Ecole Rennequin Sualem

75 Module 3 : Ajouter des fonctionnalités Exemple simple d'utilisation de JFreeChart // Creation d un DataSet s p e c i f i q u e au graphique en camenberg D e faultpiedataset p i e D a t a s e t = new DefaultPieDataset ( ) ; // Ajout des i n f o r m a t i o n s p i e D a t a s e t. setvalue ( " Java ", new I n t e g e r ( 7 5 ) ) ; p i e D a t a s e t. setvalue ( ". net ", new I n t e g e r ( 2 5 ) ) ; // Creation du graphique JFreeChart chart = ChartFactory. c r e a t e P i e C h a r t ( "Exemple de graphique ", // T i t l e piedataset, // Dataset t r u e // Show legend ) ; // Creation d ' un png FileOutputStream out = new FileOutputStream (" graphique. png ") ; C h a r t U t i l i t i e s. writechartaspng ( out, chart, _width, _height ) ; Lorsqu'on l'on crée un graphique, il faut tout d'abord créer un DataSet spécique au type de graphique que l'on souhaite générer : PieDataset dans le cas d'un graphique en camembert ; CategoryDataset dans le cas d'un graphique en histogramme ; TimeSeriesCollection dans le cas d'un graphique temporel ;... Ensuite, il faut remplir ce DataSet avec les informations souhaitées, et les méthodes pour insérer des nouvelles données sont diérentes selon le type du DataSet. La génération en elle-même du graphique est réalisée grâce aux méthodes statiques de la classe Chart- Factory. Celle-ci contient une méthode par type de graphique disponible. Elle prend en paramètre le DataSet, mais aussi le titre et d'autres informations sur la présentation du graphique. Et pour nir, en utilisant la classe ChartUtilities, il est possible de sauver le graphique dans un chier sous forme de JPG ou de PNG Pratique Les nouvelles fonctions des synchro Assignments ne sont que des modications de ce qui a été fait précédemment, en y ajoutant des méthodes de recherche dans les DAOs/Service. Il n'est donc pas utile d'expliquer d'avantage cette partie. Au niveau de la génération de graphiques, il y a deux points intéressants à noter Création d'une surclasse pour la génération de graphique Tout d'abord, lors de l'achage de graphiques, il est intéressant de pouvoir avoir deux vues diérentes sur les mêmes données. Malheureusement, le type de DataSet et les méthodes de création ne sont pas identiques entre les diérents types de graphiques. An de pouvoir simplement générer un graphique de type camembert et histogramme avec les mêmes données, il a été utile de créer une nouvelle classe qui encapsule le graphique. Gildas Cuisinier 68 Haute Ecole Rennequin Sualem

76 Module 3 : Ajouter des fonctionnalités Elle possède deux constructeurs : private mxchart(httpservletrequest req) ; private mxchart(httpservletrequest req, String title, int w, int h). Le premier paramètre est de type HttpRequest, an de permettre à la classe de récupérer les informations passées en paramètre an de savoir quel type de graphique est désiré. Les trois autres paramètres sont le titre du graphique, ainsi que sa largeur et sa hauteur. Tous ceux-ci sont aussi paramétrables via des accesseurs. Le deuxième constructeur ne fait qu'appeler le premier constructeur, après quoi il congure le titre et la taille. Au niveau du constructeur, le type de graphique demandé sera récupéré via la méthode getparameter() de HttpServletRequest, ce qui permettra d'instancier le bon Dataset. La classe possède une méthode void adddata(comparable key, double value), qui ne fera qu'appeler les méthodes propres au type de Dataset instancié : setvalue dans le cas d'un DefaultPieDataset ; addvalue dans le cas d'un DefaultCategoryDataset. Ensuite une dernière méthode writeaspng(outputstream outstream) va générer le graphique et l'écrire sur le ux de sortie fourni en paramètre. Dès lors, si l'on désire permettre la création d'un type de graphiques diérent, il sut de modier cette classe pour la gérer, et d'ajouter le paramètre correct dans l'adresse du graphique, pour que le bon type de graphique soit généré Création d'une tâche planiée An de pouvoir créer un historique de l'état de la base de données, il faut posséder une base d'état de celle-ci à intervalles réguliers. Il faut donc créer une tâche, qui serait, par exemple, exécutée toutes les heures, et qui enregistrerait dans une table l'heure à laquelle la tâche s'est exécutée ainsi que le nombre d'auditables, d'acs, etc... à cet instant précis. Spring permet la création de telles tâches facilement. Création de l'objet qui eectue la tâche Que ce soit au niveau de la programmation ou de la conguration de Spring, rien de nouveau. La classe nécessite juste les services qui permettent de récupérer l'état de la base ( AuditableService, ACService, etc.. ). Ceux-ci sont insérés via injection de dépendances de manière tout à fait classique. L'objet en lui-même est un simple POJO, et ne doit donc pas implémenter d'interface spécique. <! 1. Création de l o b j e t q u i r e p r e s e n t e l a tache > <bean i d=" dbsnapshotobject " c l a s s="be. manex. j a f a r. s e r v e r. s c h e d u l e r. DatabaseSnapshot "> <property name=" h e l p e r " r e f="summaryhelper"/> <property name=" s t a t i s t i c S e r v i c e " r e f=" s t a t i s t i c S e r v i c e " /> </ bean> Création du wrapper pour s'intégrer au Framework Vu que l'objet est un simple POJO, il faut bien qu'un autre objet fasse la liaison entre le framework et notre objet. Gildas Cuisinier 69 Haute Ecole Rennequin Sualem

77 Module 3 : Ajouter des fonctionnalités Ceci se fait simplement via des classes du framework Spring et toute la conguration est dans le chier XML. <! 1. Création de l o b j e t q u i r e p r e s e n t e l a tache > <bean i d=" dbsnapshotobject " c l a s s="be. manex. j a f a r. s e r v e r. s c h e d u l e r. DatabaseSnapshot "> <property name=" h e l p e r " r e f="summaryhelper"/> <property name=" s t a t i s t i c S e r v i c e " r e f=" s t a t i s t i c S e r v i c e " /> </ bean> <! 2. Lier notre o b j e t au framework > <bean i d=" jobdbsnapshot " c l a s s=" org. springframework. s c h e d u l i n g. quartz. MethodInvokingJobDetailFactoryBean "> <property name=" t a r g e t O b j e c t " r e f=" dbsnapshotobject "/> <property name=" targetmethod " value=" execute "/> </ bean> Simple, il sut de créer un Bean de la classe MethodInvokingJobDetailFactoryBean, et d'injecter la référence vers notre objet, ainsi que le nom de la méthode à exécuter. Plannication de la tâche Ensuite vient la plannication proprement dite. Encore une fois, tout est fourni avec Spring, et il sut de le congurer correctement : <! 1. Création de l o b j e t q u i r e p r e s e n t e l a tache > <bean i d=" dbsnapshotobject " c l a s s="be. manex. j a f a r. s e r v e r. s c h e d u l e r. DatabaseSnapshot "> <property name=" h e l p e r " r e f="summaryhelper"/> <property name=" s t a t i s t i c S e r v i c e " r e f=" s t a t i s t i c S e r v i c e " /> </ bean> <! 2. Lier notre o b j e t au framework > <bean i d=" jobdbsnapshot " c l a s s=" org. springframework. s c h e d u l i n g. quartz. MethodInvokingJobDetailFactoryBean "> <property name=" t a r g e t O b j e c t " r e f=" dbsnapshotobject "/> <property name=" targetmethod " value=" execute "/> </ bean> <! 3. P l a n n i f i c a t i o n de l a tache > <bean i d=" triggerdbsnapshot " c l a s s=" org. springframework. s c h e d u l i n g. quartz. CronTriggerBean "> <property name=" j o b D e t a i l " r e f=" jobdbsnapshot "/> <property name=" cronexpression " value="0 0?"/> </ bean> Dans ce cas, une classe permettant de spécier la plannication avec une syntaxe similaire au bien connu Crontab de Linux a été utilisée. Il sut de spécier le job que l'on désire exécuter ainsi que sa fréquence/période (dans notre cas, c'est toutes les heures piles). Gildas Cuisinier 70 Haute Ecole Rennequin Sualem

78 Module 3 : Ajouter des fonctionnalités Création du Manager de Plannication Il reste à dénir, toujours dans le chier de conguration de Spring, le Manager, c'est-à-dire celui qui va gérer toutes les tâches à eectuer. <bean c l a s s=" org. springframework. s c h e d u l i n g. quartz. SchedulerFactoryBean "> <property name=" autostartup " value=" t r u e "/> <property name=" t r i g g e r s "> < l i s t> <r e f l o c a l=" l o g A n a l y s e r T r i g g e r " /> <r e f l o c a l=" triggerdbsnapshot " /> </ l i s t> </ property> </ bean> Gildas Cuisinier 71 Haute Ecole Rennequin Sualem

79 Chapitre 12 Module 4 : Amélioration du design Sommaire 12.1 Objectif Analyse Eléments théoriques Tiles Templates Exemple : Le modèle Exemple : Une page Tiles avec Spring Exemple Conguration de Spring Pratique Objectif Jusqu'ici, le design de l'application Web était sommaire : un titre ; un menu ; une zone de contenu. Cela susait pour les tests en interne, mais n'était pas assez convivial pour la future utilisation en production. De plus, outre le menu qui est stocké dans un chier mis à part, le design était présent dans toutes les pages de contenu. Autrement dit, si l'on désirait modier le design, cela revenait à modier tous les chiers... un peu complexe lorsqu'il y a un certain nombre de pages. Ce module consiste donc à intégrer un design créé par un infographiste, et à créer une séparation entre celui-ci et les pages de contenu, en utilisant un système de modèles 12.2 Analyse Lors de la prise en main d'un design par un infographiste, il est facile de constater que modier toutes les pages d'un site est impensable. Une modication mineure équivaudrait à modier une vingtaine de pages, voire plus. L'intérêt d'un système de Modèle ( ou templates en anglais ) est alors fort intéressant. Gildas Cuisinier 72 Haute Ecole Rennequin Sualem

80 Module 4 : Amélioration du design De rapides recherches sur Internet renvoient le plus souvent vers le framework Tiles, qui plus est, possède une bonne intégration avec Spring Eléments théoriques Tiles Templates Un template (ou en francais modèle) est une page JSP qui utilise une bibliothèque de balises personnalisées pour décrire l'aspect graphique de la page. Le modèle agit comme une dénition de l'apparence des diérentes pages d'une application web, sans pour autant spécier le contenu de ces mêmes pages. Le contenu est inséré dans le template lors de l'exécution. Ainsi, une ou plusieurs pages peuvent utiliser le même modèle, assurant l'uniformité de la présentation. Lors d'une modication du modèle, l'intérêt est que toutes les pages liées à celui-ci sont modiées, ce qui permet un gain de temps. Gildas Cuisinier 73 Haute Ecole Rennequin Sualem

81 Module 4 : Amélioration du design Exemple : Le modèle <! <!DOCTYPE html PUBLIC " //W3C//DTD XHTML 1. 0 T r a n s i t i o n a l //EN" " http : / /www. w3. org /TR/ xhtml1 /DTD/xhtml1 t r a n s i t i o n a l. dtd "> > t a g l i b p r e f i x=" t i l e s " u r i=" http : / / j a k a r t a. apache. org / s t r u t s / tags t i l e s " %> <html> <head> <t i t l e>< t i l e s : g e t AsString name=" t i t l e " i g n o r e=" t r u e "/></ t i t l e> <base href="${ initparam. hrefbase }"/> <link href=" s t y l e. c s s " rel=" s t y l e s h e e t " type=" t e x t / c s s "/> </head> <body> <div id=" p a g e T i t l e "> <h1>< t i l e s : g e t AsString name=" t i t l e " </ div> i g n o r e=" t r u e "/></h1> <div id="menu"> < t i l e s : i n s e r t a t t r i b u t e="menu"/> </ div> <div id=" content "> < t i l e s : i n s e r t a t t r i b u t e=" content "/> </ div> </ div> </body></html> Dans cet exemple de modèle, on peut voir des balises de type : tiles :insert : qui dénit une zone que l'on doit remplir par du contenu ; tiles :getasstring : qui dénit une zone qui sera remplacée par une simple chaîne de caractères. Chacun de ces 'emplacements' possède un identiant ( ou un nom ) qui servira pour spécier quel emplacement correspond à quel contenu. De plus, certains possèdent un attribut ignore="true", ce qui signie que si l'on ne dénit pas de contenu pour ces emplacements, il n'y aura pas d'erreur, et donc que cela sera simplement remplacé par une chaîne vide. Dans le cas contraire, une exception sera lancée. Exemple : Une page t a g l i b p r e f i x=" t i l e s " u r i=" http : / / j a k a r t a. apache. org / s t r u t s / tags t i l e s " %> < t i l e s : i n s e r t page="/ j s p /model. j s p " f l u s h=" t r u e "> < t i l e s : put name=" t i t l e " value=" T i l e s exemple 1" /> < t i l e s : put name="menu" value="/ j s p / content /menu. j s p " /> < t i l e s : put name=" content " value="/ j s p / content / page1. j s p " /> </ t i l e s : i n s e r t> Du côté de la page, on peut voir les balises : tiles :insert mais qui prend cette fois un attribut page pour spécier la page de modèle, et qui contient des balises ; tiles :put qui spécie, pour un emplacement nommé, ce qu'il doit contenir. Gildas Cuisinier 74 Haute Ecole Rennequin Sualem

82 Module 4 : Amélioration du design Tiles avec Spring Il y a déjà un mieux, mais un nombre important de JSP existent à l'heure actuelle. Car pour chaque page, il y a à la fois une page spécique au contenu ainsi qu'une jsp qui lie le modèle avec le contenu. Quand il commence a y avoir beaucoup de pages, il y a de quoi s'y perdre! Et cela devient dicile de savoir quelle page correspond à quoi. Heureusement, Tiles propose une manière de dénir plus facilement les liens entre les pages de contenu et le modèle plus facilement, via un chier de conguration XML. Exemple <?xml version=" 1. 0 " encoding="iso "?> <t i l e s d e f i n i t i o n s> <! D e f i n i t i o n d une page d e r r e u r > <d e f i n i t i o n name=" e r r o r " page="/web INF/ j s p / d e s i g n. j s p "> <put name="menu" value="" type=" s t r i n g "/> <put name=" t i t l e " value=" Error " type=" s t r i n g "/> <put name=" content " value="the page does not e x i s t "/> </ d e f i n i t i o n> <! Remplissage de base du d e s i g n avec l e menu e t un t i t r e commum > <d e f i n i t i o n name=" d e f a u l t " page="/web INF/ j s p / d e s i g n. j s p "> <put name="menu" value="/web INF/ j s p /admin/menu. j s p "/> <put name=" t i t l e " value="mon s i t e Web" type=" s t r i n g "/> </ d e f i n i t i o n> <! D e f i n i t i o n de page1 e t page2, en h e r i t a n t de default > <d e f i n i t i o n name=" page1 " extends=" d e f a u l t "> <put name=" content " value="/web INF/ j s p / contenu / page1. j s p "/> </ d e f i n i t i o n> <d e f i n i t i o n name=" page2 " extends=" d e f a u l t "> <put name=" content " value="/web INF/ j s p / contenu / page2. j s p "/> </ d e f i n i t i o n> <t i l e s d e f i n i t i o n s> Dans cet exemple, on dénit trois vues logiques La vue "error", qui utilise le modèle design.jsp, et qui spécie la valeur des trois parties du modèle via des chaînes de caractères ; Les vues "page1" et "page2", qui héritent de la vue "`default"' et qui ne font que dénir ce que contiendra la partie "`content"', les deux autres parties étant remplies directement via la vue mère "`default"'. Ce mécanisme remplace en fait les jsp servant à la liaison entre le modèle et les pages JSP de contenu propre. Mais maintenant, il faut informer Spring qu'il doit utiliser les vues de Tiles. Conguration de Spring Il faut ajouter un Bean dans la conguration : Gildas Cuisinier 75 Haute Ecole Rennequin Sualem

83 Module 4 : Amélioration du design <bean i d=" t i l e s R e s o l v e r " c l a s s=" org. springframework. web. s e r v l e t. view. t i l e s. T i l e s C o n f i g u r e r "> <property name=" d e f i n i t i o n s "> < l i s t> <value>/web INF/ t i l e s / t i l e s. xml</ value> </ l i s t> </ property> </ bean> Comme on peut le voir, on spécie à ce Bean le chemin vers le chier de conguration Tiles. Ensuite, il sut de remplacer le résolveur de vue par défaut, par celui de Tiles : <bean i d=" viewresolver " c l a s s=" org. springframework. web. s e r v l e t. view. I nternalresourceviewresolver "> <! Plus d u t i l i t e i c i <property name=" p r e f i x " value="/web INF/ j s p /"/> <property name=" s u f f i x " value=". j s p "/> <property name=" viewclass " value=" org. springframework. web. s e r v l e t. view. JstlView "/> > <! On u t i l i s e l e r e s o l v e r de T i l e s > <property name=" viewclass "> <value>org. springframework. web. s e r v l e t. view. t i l e s. T i l e s J s t l V i e w</ value> </ property> </ bean> 12.4 Pratique La première chose à faire pour passer d'un design statique à un design utilisant Tiles, est de diviser celui-ci en diérentes zones. Dans notre cas, les zones qui risqueraient de changer d'une page à l'autre sont : le menu, qui pourrait être diérent que l'on se trouve dans la zone admin ou dans la zone publique ; le contenu, qui changerait, lui, à chaque page. La jsp nale du design ressemble à : 1 <head> 2 <t i t l e ><t i l e s : getasstring name=" t i t l e " i g n o r e=" t r u e "/></ t i t l e > 3 <base h r e f="${ initparam. hrefbase }"/> 4 <l i n k h r e f=" s t y l e. c s s " r e l=" s t y l e s h e e t " type=" t e x t / c s s "/> 5 <s c r i p t type=" t e x t / j a v a s c r i p t " s r c=" j s / s c r i p t. j s " /> 6 <s c r i p t type=" t e x t / j a v a s c r i p t " s r c=" j s / n i c e t i t l e. j s "></s c r i p t > 7 <s c r i p t type=" t e x t / j a v a s c r i p t " s r c=" j s / completion_ajax. j s "></s c r i p t > 8 <s c r i p t type=" t e x t / j a v a s c r i p t " s r c=" j s / t a b l e _ r e s i z e. j s "></s c r i p t > 9 </head> <body> 12 <div i d="mainb"> 13 <div i d=" p a g e T i t l e "> 14 <div i d=" p i c t "></div> 15 <h1><t i l e s : g e t A s S tring name=" t i t l e " i g n o r e=" t r u e "/></h1> 16 </div> 17 <div i d="menu"> 18 < t i l e s : i n s e r t a t t r i b u t e="menu"/> 19 </div> 20 <div i d=" content "> 21 < t i l e s : i n s e r t a t t r i b u t e=" content "/> 22 </div> 23 <div i d=" bottom"> 24 <p>j a f a r : : by <a h r e f=" http : / /www. manex. be">manex</a></p> 25 </div> 26 </div> 27 </body></html> Gildas Cuisinier 76 Haute Ecole Rennequin Sualem

84 Module 4 : Amélioration du design Quant au menu il sera une succession de <li>, de <ul> et de <A>, qui seront mises en forme par la feuille de style CSS. Les pages de contenus sont liées grâce au chier de conguration de Tiles : Gildas Cuisinier 77 Haute Ecole Rennequin Sualem

85 Chapitre 13 Module 5 : Multilinguisme Sommaire 13.1 Objectif Analyse Eléments théoriques Spring et i18n Exemple avec les RessourceBundle JMX/MBean Pratique Gestion des traductions en mémoire Chaîne de responsabilité de traduction Intégration avec Spring : Interface MessageSource Utilisation dans les JSP Objectif Le serveur Jafar étant développé dans plusieurs langues, il faut pouvoir naviguer sur le site en plusieurs langues. Or, il est inconcevable de créer plusieurs fois le même site, dans plusieurs langues. Ce module consiste donc à créer et utiliser un système qui permettra l'achage de la page dans la langue de l'utilisateur Analyse Dans Java, il existe une manière toute faite pour gérer l'internationalisation : ce sont les Resource- Bundles. Les textes sont stockés dans diérents chiers properties, un pour chaque langue. Cela fonctionne plutôt bien mais c'est fort limité, car les chiers sont stockés dans les chiers Jar de l'application et dès lors, il est impossible de les modier durant l'exécution. Il faut absolument recréer une archive et redéployer l'application. Pour notre application, il était plus intéressant de stocker les valeurs dans une base de données, qui serait modiable durant l'exécution. Mais comme il n'existe aucun moyen permettant de lier l'i18n 1 avec une base de données, le développement de celui-ci est donc à faire. 1 internationalisation Gildas Cuisinier 78 Haute Ecole Rennequin Sualem

86 Module 5 : Multilinguisme 13.3 Eléments théoriques Spring et i18n Pour l'internationalisation, lors du déployement, Spring va regarder dans le chier de conguration s'il existe un Bean nommé "messagesource". Si oui, il faut que celui-ci implémente l'interface de même nom. Dès lors, lorsqu'on appellera les méthodes d'i18n 2 dans des pages Web, Spring va passer par ce Bean pour tenter de traduire le message. Exemple avec les RessourceBundle Conguration de Spring Si l'on utilise la méthode standard, il existe un Bean tout fait qui le permet. Sa conguration ressemble à : <bean i d=" messagesource " c l a s s=" org. springframework. context. support. ResourceBundleMessageSource "> <property name="basename"><value>r e s s o u r c e s / i18n / messages</ value></ property> </ bean> Dans ce cas-ci, cela signie qu'il existe des chiers de langues dans le répertoire ressource/i18n, et dont le nom de base est messages. Autrement dit, s'il faut que le site soit compatible en français, anglais et italien, il doit exister : ressources/i18n/messages_en.properties, qui correspond au chier pour l'anglais ; ressources/i18n/messages_fr.properties, qui correspond au chier pour le français ; ressources/i18n/messages_it.properties, qui correspond au chier pour l'italien. Ces chiers sont au format des chiers properties, donc pour rappel : 1 2 s i t e. t i t r e=mon premier s i t e m u l t i l i n g u e 3 s i t e. bonjour=bonjour 4 s i t e. menu. l i e n 1=A c c u e i l 5 s i t e. menu. l i e n 2=Mon CV Donc à la forme, clé = texte. Utilisation dans les JSP. Dans la page JSP, il sut d'importer la librairie de tags de la JSTL via la commande taglib prex="fmt"uri="http://java.sun.com/jsp/jstl/fmt"%> Il est alors facile de placer du texte ainsi internationalisé via la balise fmt :message qui prend pour paramètre la clé du texte JMX/MBean Sans expliquer les détails de JMX, l'intérêt de celui-ci, dans le contexte JBoss, est qu'il permet de déclarer des Bean administrables au niveau même de JBoss. Ainsi il sera possible, si le nom de référence est connu, de récupérer une instance dans n'importe quel programme. Par Bean Administrable, il est sous-entendu le fait qu'il existe dans JBoss une console JMX, qui permet de voir les Bean dénis comme MBean, et d'appeler les méthodes spéciées dans l'interface de celui-ci. Ce qui revient à paramètrer le Bean alors qu'il est déjà en cours d'utilisation. 2 internationalisation Gildas Cuisinier 79 Haute Ecole Rennequin Sualem

87 Module 5 : Multilinguisme Quelques exemples où les MBean sont intéressants : Logging : car cela permet de spécier le niveau d'écoute de log que l'on désire ; Connexion DB : car cela permet de spécier les informations de connections ; Transaction : pour spécier le niveau de transactions ;... Dans notre cas, cela permettra de recharger les traductions sans avoir à recharger toute l'application Pratique Le but de ce module est donc de créer une classe qui : permettra à Spring de l'utiliser en tant que source de message i18n 3 ; permettra d'être rechargée à chaud, via une interface JMX. En pratique, cela veut dire qu'elle doit implémenter l'interface MessageSource ( de Spring ), et qu'elle doit posséder une interface propre an de spécier quelles méthodes seront disponibles via JMX. Au niveau de la traduction proprement dite, il y a plusieurs acteurs : une interface Language ( et son implémentation LanguageImpl ) qui contiendra les quatre traductions pour une clé donnée ; un Service et son DAO pour stocker et recharger toutes les instances de Language ; une chaîne de responsabilité qui s'occupera de faire les traductions. Ce qui donne schématiquement ceci : Fig Diagramme des classes d'i18n 3 internationalisation Gildas Cuisinier 80 Haute Ecole Rennequin Sualem

88 Module 5 : Multilinguisme Gestion des traductions en mémoire An de limiter les accès à la base de données, toutes les correspondances clé <=> traduction seront sauvées dans une Map de traduction ( Map<Language> ). Ce chargement se fera grâce à la méthode "`load"' qui utilisera le service de Langue ( LanguageService ) an de récupérer la liste complète des traductions, et créer la Map avec les informations contenues dans celle-ci. De plus, comme il sera expliqué juste après, chaque maillon de la chaîne de responsabilité contient une référence vers la Map de traductions. Or, lors de l'appel de cette méthode Load, la référence mise à jour ne sera plus la même que celle que les maillons connaissent. Les diérents maillons seront donc avertis de ce changement via une propriété liée. Chaîne de responsabilité de traduction An de rendre le système évolutif au niveau du nombre de langues supporté, on va créer une chaîne de responsabilité. Mais qu'est-ce que cela signie? En fait, cela veut dire que lorsqu'on va programmer le Bean I18n, il ne va pas gérer lui-même la traduction, mais il va posséder une référence vers le premier élément d'une chaîne qui est spécialisée dans la traduction. Elle est composée de plusieurs maillons, chaînés les uns aux autres, et chacun d'entre eux va pouvoir traduire une langue bien spécique. Chaque maillon de la chaîne possède trois méthodes : String translate(locale locale, String totransalate, Object[] params) ; private boolean isforme(locale locale) ; String dotranslate(string totransalate, Object[] params) ; Fig Chaine de responsabilité Lorsque le Bean i18n reçoit une demande de traduction pour un code donné, il reçoit en même temps la locale souhaitée, et pour résoudre cette traduction, il appelle la méthode translate de la racine de la chaîne de responsabilité. On rentre donc dans cette méthode qui consiste en un aiguillage. Gildas Cuisinier 81 Haute Ecole Rennequin Sualem

89 Module 5 : Multilinguisme La locale passée en paramètre est celle que connait le maillon courant ( c'est-à-dire que isforme renvoie "`vrai"' ), dès lors la méthode dotranslate du maillon courant est appelée. Sinon, il regarde s'il possède un maillon suivant. Si la réponse est négative, il renvoie un message informant qu'il n'existe pas de traduction pour cette clé. Si la réponse est positive, il appelle la méthode translate de celui-ci ( qui appelera le maillon suivant s'il ne peut pas le gérer, etc.. ). Avec cette approche, il sura d'ajouter un maillon si une langue doit être ajoutée Intégration avec Spring : Interface MessageSource L'interface MessageSource est assez simple, elle contient trois méthodes qui seront appellées par Spring dans des contextes légèrement diérents. String getmessage(string code, Object[] args, String defaultmessage, Locale locale), cette méthode sera appelée par Spring lors d'appels i18n possédant non seulement le code mais aussi un message par défaut. Remarque : le second paramètre est un tableau d'arguments. En eet, la chaîne correspondante à une clé peut posséder des zones "vides" qui devront être remplies uniquement lors de l'appel grâce au paramètre. public String getmessage(string code, Object[] args, Locale locale), cette méthode est exactement la même que la précédente, mis à part le fait que, si un code n'existe pas, une exception sera lancée au lieu de renvoyer un message par défaut. String getmessage(messagesourceresolvable messagesourceresolvable, Locale locale), méthode est appelée, par exemple, dans le contexte des messages d'erreurs des validateurs. Le code, les arguments ainsi que le message par défaut sont encapsulés dans l'interface MessageSourceResolvable. En pratique, ces diérentes méthodes ne vont faire qu'appeler la méthode translate de la chaîne de responsabilité citée plus haut. Au niveau de la conguration de Spring : <bean i d=" messagesource " c l a s s="be. manex. j a f a r. s e r v e r. jmx. I18N. I18N" i n i t method=" load "> <property name=" l a n g u a g e S e r v i c e " r e f=" l a n g u a g e S e r v i c e " /> </ bean> On dénit une méthode qui sera lancée lors de l'initialisation du Bean ( init-method ) an de charger les traductions en mémoire. Remarque : dans le cas présent, le maillonage de la chaîne se fait via une méthode afterpropertiesset(), qui fait de l'interface InitializingBean propre à Spring, et qui est appelée après le paramètrage du Bean via l'injection. Ce n'est pas adapté pour l'évolubilité des langues car il faudrait aussi modier le Bean i18n pour ajouter à la main le nouveau maillon. An de rendre cela nettement plus propre, il faudrait créer le maillon directement via la conguration de Spring. cette Gildas Cuisinier 82 Haute Ecole Rennequin Sualem

90 Module 5 : Multilinguisme Utilisation dans les JSP Grâce à ce système, il est possible d'utiliser notre classe de manière tout à fait transparente, et donc d'utiliser le tag : <fmt:message key="${key}" /> Cependant, an de permettre au traducteur de travailler facilement sur les traductions, il serait intéressant de fournir un moyen de modier ces textes en ligne. En eet, avec le système actuel, il est nécessaire d'aller dans la base de données et de modier les textes à la main. C'est assez génant, et de plus, on perd le contexte du texte, et il devient dicile de traduire correctement. Créer un système identique à la balise fmt :message serait une solution, mais celle-ci comporterait deux modes : mode d'achage, qui ne ferait qu'appeler directement fmt :message ; mode d'édition, qui en plus d'acher le résultat de fmt :message, rajouterait un lien "`Edit"' qui acherait une fenêtre d'édition de cette clé. Pour cela, il nous faut : un contrôleur, an d'acher le formulaire de modication, ainsi qu'eectuer les mises à jour des textes ; un nouveau tag qui remplacera les appels à fmt :message. Au niveau du contrôleur, rien de nouveau, il possèdera une référence vers un service de Langue ( LanguageService ) an de récupérer les valeurs courantes et de mettre à jour les modications dans la base de données. Au niveau du tag, voici le code : t a g l i b p r e f i x="fmt" u r i=" h t t p : // java. sun. com/ j s p / j s t l /fmt" %> t a g l i b p r e f i x=" c " u r i=" h t t p : // java. sun. com/ j s p / j s t l / c o r e " %> tag body content=" s c r i p t l e s s " %> a t t r i b u t e name=" key " r e q u i r e d=" t r u e " type=" java. lang. S t r i n g " %> a t t r i b u t e name="admin" r e q u i r e d=" f a l s e " type=" java. lang. Boolean " %> <c : c h o o s e> <c:when t e s t=" $ {! empty admin}"> <fmt:message key="${ key }"/><a h r e f=" j a v a s c r i p t : openeditmessage ( ' $ { key } ' ) ">[ e d i t ]</a> </ c:when> <c : o t h e r w i s e> <fmt:message key="${ key }"/> </ c : o t h e r w i s e> </ c : c h o o s e> Soit il existe un attribut admin ( dans n'importe quelle portée, tant qu'il existe ), alors la traduction sera faite par fmt :message en ajoutant le lien vers le contrôleur ; soit il n'en existe pas, et c'est un simple appel de fmt :message. Dans cette première version, il n'y a pas beaucoup de sécurité, n'importe qui connaissant le "code" peut accéder à l'édition. Cependant, il sura de modier le chier message.tag, en ajoutant des conditions, pour augmenter la sécurité. Gildas Cuisinier 83 Haute Ecole Rennequin Sualem

91 Chapitre 14 Module 6 : Amélioration des entrées ID Sommaire 14.1 Objectif Eléments théoriques Ajax Objectif Comment? Analyse ère possibilité : 2 champs distincts ème possibilité : Combo Box ème Possibilité : Ajax Pratique Préparation des données XML Du côté HTML Désactivation de l'autocomplétion interne Création de l'objet XmlHttpRequest Traitement des appels Ajax Création d'un Tag Objectif Dans le site, il faut parfois entrer le user ID d'un utilisateur pour acher ou rechercher des informations le concernant. Or, cet identiant est un nombre, et il n'est pas simple de retenir forcément tous ces codes. Le but de ce module est de donner un moyen plus convivial pour l'entrée de cet identiant Eléments théoriques Ajax Ajax ( ou Asynchronous JavaScript And XML ) est un acronyme désignant un ensemble technologique qui se base sur : HTML/CSS : pour la présentation des informations ; Javascript et DOM : pour interagir dynamiquement avec l'information présentée ; XML et XMLHttpRequest : pour échanger et manipuler les données de manière asynchrone avec le serveur web. Gildas Cuisinier 84 Haute Ecole Rennequin Sualem

92 Module 6 : Amélioration des entrées ID Objectif Le but d'ajax est de mieux répartir le travail d'un site web en matière de ressources. Avant Ajax, même si plusieurs pages avaient le même design mais sans acher les mêmes informations, on rechargeait toute la page à chaque changement d'informations. Un exemple, lors de choix d'une catégorie d'articles, on rechargeait toute la page pour changer les articles à acher. Lors de chaque requête, une grosse partie des informations était redondante, c'était un gaspillage de bande passante réseaux, et de temps de traitements du côté du serveur. Ajax résoud cela, en permettant de modier partiellement la page achée par le navigateur pour la mettre à jour sans avoir à la recharger complètement. Comment? Prenons l'exemple d'un formulaire de recherche de scéances d'un cinéma en Belgique, qui contient : une combobox permettant de choisir une province ; une liste, au départ vide, qui contiendra la liste des cinémas selon la province choisie ; Le formulaire HTML ainsi que les 2 champs possèderont un identiant, permettant de les retrouver avec Javascript via DOM. 1. L'utilisateur va choisir une province, par exemple Liège. 2. Un évènement javascript va se produire, et appelle une méthode surchoix() par exemple, qui va : (a) récupérer la valeur du choix de l'utilisateur en javascript/dom( via l'identiant du combo- Box ) ; (b) créer un objet XMLHttpRequest propre au navigateur du client ; (c) spécier quelle méthode doit être appelée lorsque les données seront reçues ; (d) envoyer une requête HTTP avec des arguments ( exemple http ://www.monsite.be/ajax.form?category=3 ). 3. Du côté serveur, on reçoit donc une simple requête HTTP et que l'on traite : ici on va récupérer la liste des cinémas dans la province de Liège ; 4. La servlet va renvoyer le résultat sous forme de XML en dénissant un cinéma par un nom et un id (<cinema><nom>kinepolis></nom><id>45</id></cinema> ) 5. Retour du côté client, la méthode spéciée en 2.c va être appellée, celle-ci va : (a) traiter les données Xml ; (b) récupérer la liste HTML pour la remplir correctement avec les bonnes informations. 6. L'utilisateur voit la liste des cinémas et va pouvoir sélectionner celui de son choix. Gildas Cuisinier 85 Haute Ecole Rennequin Sualem

93 Module 6 : Amélioration des entrées ID 14.3 Analyse Jusqu'ici, le choix d'un utilisateur se faisait directement via son identiant, un nombre, ce qui n'est pas fort parlant et peut être dicile à retenir. Pour simplier, il y avait plusieurs choix ère possibilité : 2 champs distincts Il aurait été possible de créer 2 champs, un pour entrer l'identiant, et un pour rentrer un nom d'utilisateur. Ceci aurait permis de rentrer directement soit l'id ( si on le connait ), soit un nom. Il est inintéressant d'utiliser celle-ci pour plusieurs raisons : si l'on remplit les deux entrées, sur laquelle devont nous eectuer le choix? Lors de l'entrée d'un nom, impossible de savoir s'il n'y a aucune personne de ce nom, ou si l'on a mal orthographié celui-ci. Obligation d'implémenter une méthode de recherche par nom pour chaque contrôleur. Au nal, cela compliquait l'interface graphique ainsi que le fonctionnement interne ème possibilité : Combo Box Une deuxième manière aurait été de créer une Combo Box que l'on remplirait avec tous les utilisateurs, avec leur nom aché à la place du code identiant. Cette solution n'était pas non plus parfaite car : vu qu'il y a plusieurs centaines d'utilisateurs, la Combo Box risquerait d'être immense, et donc peu pratique ; si l'on connait l'identiant, impossible de le rentrer directement. Encore une fois, cette solution, bien que ne compliquant pas le fonctionnement interne de l'application, n'est pas adaptée pour l'utilisateur ème Possibilité : Ajax La 3ème solution, celle mise en pratique, est d'utiliser Ajax pour faire de l'autocomplétion. C'est-à-dire que dès qu'un utilisateur va rentrer quelque chose au clavier, il va y avoir une requête Ajax pour récupérer tout ce qui peut concorder avec cette entrée. Intérêts : on peut faire une autocomplétion sur le nom OU sur l'identiant ; ne gène pas l'entrée d'un identiant directement ; permet de voir les entrées qui correspondent, et ainsi choisir facilement la bonne ; aucun changement à l'infrastructure des contrôleurs actuels Pratique Préparation des données XML An de travailler en Ajax pour l'autocomplétion, il est nécessaire de fournir les informations sous forme de chiers xml. Gildas Cuisinier 86 Haute Ecole Rennequin Sualem

94 Module 6 : Amélioration des entrées ID Dans notre cas, le chier XML aura le format suivant : <u s e r s> <u s e r> <i d>105</ i d> <name>nom du c l i e n t 105</name> </ u s e r> <u s e r> <i d>106</ i d> <name>nom du c l i e n t 106</name> </ u s e r> </ u s e r s> Les données concernant les informations des utilisateurs peuvent être récupérées au moyen des méthodes de UserCacheMBean : Collection<User> getall(), qui permet de récupérer la liste complète des utilisateurs ; User getbyuserid(string userid), qui permet de récupérer une instance d'un utilisateur par son identiant. Ainsi que les méthodes de la classe User : String getlastname(), qui permet de récupérer le nom de famille ; String getfirstname(), qui permet de récupérer le prénom de l'utilisateur ; Lors de l'appel du contrôleur, un paramètre start est fourni, et la recherche des utilisateurs pouvant correspondre à une entrée va se faire grâce à ce paramètre. Le contrôleur va récupérer la liste des utilisateurs via une méthode privée : private void filluserlist(string pattern, List<String> result) ; le premier paramètre est la chaîne qui doit être contenue soit dans le nom, le prénom ou l'identiant de l'utilisateur ; le second est la liste dans laquelle seront stockés les identiants des utilisateurs qui correspondent à la recherche. Ensuite, le contrôleur va appeler la méthode private String getuserslistxml(list<string> listusers), qui se charge de créer une chaîne comprennant la liste en format XML. Remarque : vu la simplicité du format XML souhaité, il n'était pas utile d'utiliser un moteur DOM pour la création du document. Cela aurait demandé beaucoup de ressources pour peu de choses. Et pour nir, le contrôleur renvoie la réponse au client, en spéciant bien que le format renvoyé est de l'xml et non un chier HTML Du côté HTML Désactivation de l'autocomplétion interne Dans plusieurs navigateurs récents, il existe une autocomplétion interne, qui se base sur les entrées précédentes. Si cette fonction s'avère fort pratique dans la plupart des cas, elle va gêner l'achage de notre autocomplétion. Il y a un moyen simple an de spécier au navigateur qu'il ne doit pas fournir sa propre autocomplétion pour un champ. Il sut de lui ajouter un attribut autocomplete=off Gildas Cuisinier 87 Haute Ecole Rennequin Sualem

95 Module 6 : Amélioration des entrées ID Création de l'objet XmlHttpRequest Du fait de la non-existance d'un standard au niveau des objets XmlHttpRequest, il était nécessaire de créer une méthode qui fournirait le bon objet selon le type du navigateur du client. 1 f u n c t i o n getxmlhttp( ) { 2 var xhr=null ; 3 i f ( window. XMLHttpRequest ) // F i r e f o x e t a u t r e s 4 xhr = new XMLHttpRequest ( ) ; 5 else i f ( window. ActiveXObject ) { // I n t e r n e t Explorer 6 try { 7 xhr = new ActiveXObject ( "Msxml2.XMLHTTP" ) ; 8 } catch ( e ) { 9 try { 10 xhr = new ActiveXObject ( " M i c r o s o f t.xmlhttp" ) ; 11 } catch ( e1 ) { 12 xhr = null ; 13 } 14 } 15 } 16 else { // XMLHttpRequest non supporté par l e n a v i g a t e u r 17 a l e r t ( " Votre n a v i g a t e u r ne supporte pas l e s o b j e t s XMLHTTPRequest... " ) ; 18 } 19 return xhr ; 20 } Traitement des appels Ajax f u n c t i o n c a l l S u g g e s t i o n s ( v a l e u r ) { i f ( _xmlhttp&&_xmlhttp. readystate!=0) { _xmlhttp. abort ( ) } _xmlhttp=getxmlhttp( ) ; i f ( _xmlhttp ) { // appel à l ' u r l d i s t a n t e _xmlhttp. open ("GET", _adresserecherche+"?method=u s e r s&s t a r t="+valeur, t r u e ) ; _xmlhttp. onreadystatechange=f u n c t i o n ( ) { i f ( _xmlhttp. readystate==4&&_xmlhttp. responsexml ) { var l i s t e = t r a i t e X m l S u g g e s t i o n s ( _xmlhttp. responsexml ) showautocompletiondiv ( valeur, l i s t e ) } } ; // envoi de l a r e q u e t e _xmlhttp. send ( n u l l ) } } En ce qui concerne l'appel Ajax proprement dit, il est divisé en deux méthodes : traitexmlsuggestions(xmldocument), qui va transformer le document XML récupéré via Ajax en un tableau, plus facilement utilisable pour les traitements ; showautocompletiondiv(valeur,liste), qui permet de créer le <DIV> à acher ( qui va traiter les événements de la souris et du clavier ) an de rendre l'autocomplétion visible et utilisable. Gildas Cuisinier 88 Haute Ecole Rennequin Sualem

96 Module 6 : Amélioration des entrées ID Création d'un Tag Du fait que l'autocomplétion sera réutilisée dans divers endroits de notre application, la création d'un tag était intéressante. t a g l i b p r e f i x="fmt" u r i=" h t t p : // java. sun. com/ j s p / j s t l /fmt" %> t a g l i b p r e f i x=" c " u r i=" h t t p : // java. sun. com/ j s p / j s t l / c o r e " %> t a g l i b p r e f i x=" s p r i n g " u r i=" h t t p : //www. springframework. org / t a g s " %> tag body content=" s c r i p t l e s s " %> a t t r i b u t e name=" path " r e q u i r e d=" t r u e " type=" java. lang. S t r i n g " d e s c r i p t i o n="the path o f command to Bind" %> <s p r i n g : b i n d path="${ path }"> <input type=" t e x t " i d=" u s e r I d " name="${ s t a t u s. e x p r e s s i o n }" value="${ s t a t u s. value }" autocomplete=" o f f "/> <b><f o n t c o l o r=" red "><c : o u t value="${ s t a t u s. errormessage }"/></ f o n t></b> </ s p r i n g : b i n d> Gildas Cuisinier 89 Haute Ecole Rennequin Sualem

97 Chapitre 15 Module 7 : Affichage des fichiers de trace Sommaire 15.1 Objectif Eléments théoriques Log4J Utilisation Conguration Analyse Gestion des chiers log Achage d'un chier de log Pratique Traitement d'un chier Log LogRecord Log4JParser Traitements diérés STATE TO PROCESS STATE PROCESSING STATE DONE Objectif Lors de la synchronisation avec un client, l'application de celui-ci renvoie au serveur des chiers de trace créés par le framework log4j. Le but de ce module est de permettre d'analyser automatiquement ces chiers, et de stocker dans une base de données le nombre d'erreurs fatales, d'alertes, d'informations de trace et de débugages qu'il possède. De plus, il fournira une interface web permettant l'achage du chier de log tout en laissant à l'utilisateur la possibilité de choisir quels niveaux de trace il désire acher. Gildas Cuisinier 90 Haute Ecole Rennequin Sualem

98 Module 7 : Affichage des fichiers de trace 15.2 Eléments théoriques Log4J Log4J est une API de journalisation 1 très répandue dans le monde Java. Dans ses fonctionnalités principales, on note : qu'il possède plusieurs niveaux de trace, dans l'ordre décroissant de gravité : 1. FATAL, utilisé pour journaliser une erreur grave pouvant mener à l'arrêt prématuré de l'application : 2. ERROR, utilisé pour journaliser une erreur qui n'empêche cependant pas l'application de fonctionner ; 3. WARN utilisé pour journaliser un avertissement. Il peut s'agir par exemple d'une incohérence dans la conguration, l'application peut continuer à fonctionner mais pas forcément de la façon attendue ; 4. INFO, utilisé pour journaliser des messages à caractère informatif (nom des chiers, etc.) ; 5. DEBUG utilisé pour générer des messages pouvant être utiles au débogage ; 6. TRACE 2 utilisé pour générer des messages pouvant être utiles lors du développement. qu'il permet de spécier plusieurs destinations à qui envoyer les traces, qui peuvent être : * des chiers ; * une base de données ; * une console ; * un courrier ; *... qu'il permet de spécier pour chaque destination un niveau de log. ( Autrement dit, il est possible d'envoyer uniquement les logs de type FATAL par et de stocker les autres dans un chier ) ; qu'il possède plusieurs layouts, qui sont utilisés pour mettre en format les événements de trace : * SimpleLayout, qui journalise les événements au format Niveau - Message[Retour à la ligne] ; * PatternLayout, qui permet de spécier manuellement le format que l'on désire ; * XMLLayout, qui stocke les événements sous format d'un chier XML. Utilisation Au niveau de la programmation, on récupère une instance du logger dans la classe qui souhaite créer des événements par : private static final Logger logger = Logger.getLogger(MaClasse.class); Et la création d'une trace se fait par les méthodes : void fatal(object message) ; void error(object message) ; void warn(object message) ; void info(object message) ; 1 de génération de chier de trace, de log 2 Ce niveau a été ajouté dans l'api uniquement dans le package fourni par JBoss Gildas Cuisinier 91 Haute Ecole Rennequin Sualem

99 Module 7 : Affichage des fichiers de trace void debug(object message) ; void trace(object message) ; Conguration La conguration des destinations, ainsi que des niveaux que l'on écoute se fait soit par un chier log4j.properties, soit par un chier log4j.xml. Voici un exemple simple de log4j.xml qui : envoie toutes les traces des classes du package mon.package, dont le niveau est supérieur ou égal à DEBUG, dans un chier debug.log ; envoie toutes les traces de toutes les classes, dont le niveau est égal ou supérieur à ERROR, sur la console. <?xml version=" 1. 0 " encoding="utf 8"?> <!DOCTYPE l o g 4 j : c o n f i g u r a t i o n SYSTEM " l o g 4 j. dtd "> <l o g 4 j : c o n f i g u r a t i o n x m l n s : l o g 4 j=" h t t p : // j a k a r t a. apache. org / l o g 4 j /"> <appender name=" ConsoleAppender " c l a s s=" org. apache. l o g 4 j. ConsoleAppender "> <l a y o u t c l a s s=" org. apache. l o g 4 j. SimpleLayout "/> </ appender> <appender name=" FileAppendar " c l a s s=" org. apache. l o g 4 j. FileAppender "> <param name=" F i l e " value="debug. l o g " /> <l a y o u t c l a s s=" org. apache. l o g 4 j. PatternLayout "> <param name=" ConversionPattern " value="%r %p %t %c %m%n"/> </ l a y o u t> </ appender> <c a t e g o r y name="mon. package "> <p r i o r i t y value="debug"> <appender r e f r e f=" FileAppender "/> <r o o t> <p r i o r i t y value =" e r r o r " /> <appender r e f r e f=" ConsoleAppender "/> </ r o o t> </ l o g 4 j : c o n f i g u r a t i o n> 15.3 Analyse Gestion des chiers log Jusqu'ici, lors de la synchronisation avec un client, les chiers de log sont simplement stockés et aucun traitement n'est eectué sur ceux-ci. Bien qu'il soit tout à fait possible de travailler directement sur le système de chiers pour récupérer les chiers propres à un client, cette méthode n'est pas assez performante. En eet, il y aurait énormément d'accès disque lors d'une simple recherche, et vu que le nombre de clients ( ainsi que le nombre de chiers par client ) peut devenir important, le temps de la recherche risque d'être assez conséquent. Ceci est d'autant plus vrai si l'on ajoute des critères de date dans la recherche. En outre, si l'on travaille directement sur les chiers, la seule information connue sera la taille du chier. Or, il se peut tout à fait qu'un chier de log soit assez important au niveau de la taille mais qu'il ne contienne que des informations de faible importance. Gildas Cuisinier 92 Haute Ecole Rennequin Sualem

100 Module 7 : Affichage des fichiers de trace Il serait donc intéressant d'avoir des informations supplémentaires sur le nombre d'erreurs fatales, de warning, d'informations, de debug, an de pouvoir cibler par exemple, uniquement les chiers contenant beaucoup de problèmes importants. Pour ce faire, lors de la synchronisation, ces informations seront stockées dans une base de données Achage d'un chier de log Après avoir choisi un chier de log, il est traité et aché sur une page. Cependant, si celui-ci contient plusieurs milliers de lignes, il est assez lourd de tout charger. Il faut donc pouvoir diviser l'achage du chier en plusieurs pages. De plus, il serait intéressant de pouvoir sélectionner uniquement certains niveaux à acher. Il serait possible de recharger la page complètement, mais il est plus intéressant d'utiliser Ajax pour ne réacher que les nouvelles lignes. De plus, grâce à cette méthode, il est tout à fait possible d'acher un message durant le chargement des nouvelles données an de faire patienter l'utilisateur Pratique Traitement d'un chier Log La partie concernant le traitement d'un chier de log comporte deux classes : un analyseur ; une classe correspondant à une ligne de log. LogRecord C'est une classe simple, elle ne fait que représenter une ligne, et comprend donc : un champ LineNumber, qui représente le numéro de ligne dans le chier de log ; un champ Date, qui est la date de l'émission de l'événement de log ; un champ Level, qui représente le niveau de log de la ligne ( FATAL, ERROR, WARN, INFO, DEBUG, TRACE ) ; un champ ClassName, qui est le nom de la classe qui a émis l'événement de log ; un champ Message, qui est le texte de l'événement de log ; un champ StackTrace, qui est la stacktrace dans le cas où l'événement est une exception lancée. Log4JParser Cette classe représente à la fois le processus qui va traiter le chier de log pour en récupérer les informations, et la classe qui contiendra les lignes sous forme de LogRecord. Pour charger un chier de log dans un analyseur de ce type, il faut utiliser la méthode : public void read(string absolutefilepath) Cette méthode va ouvrir le chier spécié en paramètre, et lire ligne après ligne ce chier. Selon le format de la ligne lue, il fera la diérence entre un message de log simple, ou bien une ligne de la stacktrace, et réagira diérement pour créer une liste de LogRecord. Gildas Cuisinier 93 Haute Ecole Rennequin Sualem

101 Module 7 : Affichage des fichiers de trace En plus de la liste des records, cette classe possède six autres listes qui contiendront les index des lignes correspondant aux 6 niveaux de log, an de permettre de récupérer rapidement les éléments d'un niveau particulier Traitements diérés Comme il a été dit plus tôt, les chiers de log sont envoyés lors de la synchronisation. Cependant le traitement ne se fera pas durant ce processus. Lors de la synchronisation, la seule opération est de copier le chier reçu au bon endroit, et d'ajouter une entrée dans la base de données. Les objets stockés dans la base de données ont cette structure-ci : Fig Structure d'un objet représentant un chier de Log dans la base de données un champ userid qui représente l'utilisateur qui a envoyé le chier ; un champ date pour spécier le jour de l'envoi du chier ; un champ File, qui représente le chemin où est stocké physiquement le chier de log ; des champs Error, Fatal, Warn, Info, Debug et Trace, qui représentent le nombre de lignes que contient le chier pour chaque niveau de log. Reste le champ state qui peut valoir soit : STATE TO PROCESS STATE PROCESSING STATE DONE STATE TO PROCESS C'est l'état qu'aura cette classe lors de son insertion dans la base de données par le processus de synchronisation. Dans cet état, seules les informations sur l'utilisateur ainsi que la date sont connues. STATE PROCESSING C'est l'état qu'aura l'objet lorsqu'il sera pris en compte par le processus de traitements. En pratique, périodiquement ( toutes les heures, mais cela reste paramétrable ), un processus sera lancé. Celui-ci va récupérer tous les objets en état STATE TO PROCESS et pour chacun d'eux faire un traitement sur le chier de log pour en récupérer le nombre des lignes de type FATAL, ERROR, WARN, INFO, DEBUG et TRACE. Durant le traitement d'un objet par ce processus, celui-ci est dans l'état STATE PROCESSING Gildas Cuisinier 94 Haute Ecole Rennequin Sualem

102 Module 7 : Affichage des fichiers de trace STATE DONE Lors que le processus a ni de traiter un chier de Log, il sauve dans la base de données le résultat du traitement et marque cet objet dans l'état STATE DONE. Ce chier sera dès lors disponible dans la liste des chiers de log dans l'interface Web ( qui ne permet de voir que ceux étant dans l'état STATE DONE ). Gildas Cuisinier 95 Haute Ecole Rennequin Sualem

103 Quatrième partie Conclusion 96

104 Chapitre 16 Conclusion Le développement de ce module fut un projet très intéressant et motivant, et ce, à plusieurs niveaux. Tout d'abord, ce projet constituait pour moi une première approche du monde du travail. Un module réalisé en équipe pluridisciplinaire, qui a regroupé programmeurs, infographiste et assistante de direction. Peu à peu, le travail s'est enrichi des compétences particulières de chacun. Parfois même, le regard extérieur des autres membres ont fait évoluer ma manière de travailler. Être intégré à une équipe, c'est apprendre à mettre des priorités dans son travail : les autres ont besoin de certaines parties pour avancer! Au niveau technique, je n'ai pas éprouvé de grandes dicultés à exécuter ce que l'on me demandait. J'ai eu l'opportunité de bien me documenter, j'ai ainsi pu appréhender de nouveaux Frameworks tels qu'hibernate, mais surtout Spring, omniprésent dans le développement, tant au niveau de la gestion Web qu'au niveau de la gestion des données. J'ai également étudié la Programmation Orienté Aspect, qui permet, entre autre, d'ajouter des fonctionnalités à une classe sans avoir à en modier le code. Ensuite, participer à l'élaboration de ce projet m'a permis de travailler de manière plus professionnelle, en le divisant correctement en couches, en diérenciant les accès aux données, les interfaces utilisateurs,... an de le rendre modulaire. A l'heure actuelle, ma participation au projet est partiellement intégrée : il faut encore résoudre certains problèmes propres à l'utilisation en production ( base de données spécique à une entreprise qui va utiliser le programme Jafar ). Dû à des changements prévus dans l'architecture de Jafar, une partie du module ( le traçage ) n'a pas été intégré. Par la suite, elle sera retravaillée an de pouvoir l'adapter à la nouvelle architecture. La réalisation de ce module était, à mon sens, nécessaire dans le contexte de travail de la société Manex : maintenant, les clients vont pouvoir, entre autres, observer la croissance de leur base de données, et parcourir les informations de celle-ci. A l'avenir, on pourrait envisager un module d'authentication Web, pour ne permettre qu'aux administrateurs identiés d'accèder à l'interface Web du module. Ce qui serait un gage supplémentaire de sécurité. Parallèlement à cette authentication, il serait possible de fournir aux utilisateurs du client Jafar une interface web simpliée, équivalente au client Jafar. Mais ceci est un autre projet... Gildas Cuisinier 97 Haute Ecole Rennequin Sualem

105 Cinquième partie Annexes 98

106 Screenshots Fig Version française du formulaire de sélection d'un utilisateur i

107 Screenshots Fig Version française du formulaire de sélection d'un utilisateur Fig Autocomplétion ajax de l'id utilisateur ii

108 Screenshots Fig Erreur achée lors de l'introduction d'un mauvais utilisateur Fig Liste des chiers envoyé par un utilisateur iii

109 Screenshots Fig Formulaire de sélection d'un utilisateur Fig Liste des chiers téléchargeables pour un utilisateur iv

110 Screenshots Fig Page d'information sur les Synchro Assignments d'un utilisateur Fig Formulaire de selection des traces d'un utilisateur v

111 Screenshots Fig Détail d'un auditable Fig Page d'informations statistiques vi

112 Screenshots Fig Page d'informations statistiques Fig Formulaire de sélection des traces vii

113 Screenshots Fig Liste des chiers de trace disponible pour un utilisateur Fig Interface d'achage d'un chier de trace viii

114 Screenshots Fig Interface d'achage d'un chier de trace ( suite ) Fig Mode d'edition i18n ix

Compte-rendu de projet de Système de gestion de base de données

Compte-rendu de projet de Système de gestion de base de données Compte-rendu de projet de Système de gestion de base de données Création et utilisation d'un index de jointure LAMBERT VELLER Sylvain M1 STIC Université de Bourgogne 2010-2011 Reponsable : Mr Thierry Grison

Plus en détail

Les architectures N-tiers

Les architectures N-tiers Les architectures N-tiers 1 SOMMAIRE DU COURS XML ET LES ARCHITECTURES N-TIER Introduction aux architectures N-tier Serveurs d applications Déploiement d applications J2EE Tiers applicatif : servlets Tiers

Plus en détail

JAVA PROGRAMMATION. Programme. 1. Java, HTML et World Wide Web

JAVA PROGRAMMATION. Programme. 1. Java, HTML et World Wide Web PROGRAMMATION PUBLIC Professionnels informatiques qui souhaitent développer des applications et «applets» Java DUREE 4 jours 28 heures OBJECTIF Créer divers «applets» à intégrer dans un site Web dynamique,

Plus en détail

Programmation orientée objet et interfaces web en PHP

Programmation orientée objet et interfaces web en PHP Programmation orientée objet et interfaces web en PHP La programmation objet avec PHP5 Bases de données et interfaces web Fonctionnement des sessions Nicolas Moyroud Cemagref - UMR TETIS 26 Juin 2008 Programmation

Plus en détail

Avant-propos 1. Avant-propos...3 2. Organisation du guide...3 3. À qui s'adresse ce guide?...4

Avant-propos 1. Avant-propos...3 2. Organisation du guide...3 3. À qui s'adresse ce guide?...4 Les exemples cités tout au long de cet ouvrage sont téléchargeables à l'adresse suivante : http://www.editions-eni.fr. Saisissez la référence ENI de l'ouvrage EP5EJAV dans la zone de recherche et validez.

Plus en détail

Documentation technique

Documentation technique MEEVY Documentation technique Juillet 200 MEEVY a pour but de fournir aux artistes des outils pour promouvoir leur musique sur internet et proposer à l auditeur une plateforme de musique en ligne gratuite

Plus en détail

Java EE Approfondi - Cours 2. Cours de 2 e année ingénieur Spécialisation «Génie Informatique»

Java EE Approfondi - Cours 2. Cours de 2 e année ingénieur Spécialisation «Génie Informatique» Java EE Approfondi - Cours 2 Cours de 2 e année ingénieur Spécialisation «Génie Informatique» Présentation Lier l'orienté objet et la base de données relationnelle peut être lourd et consommateur en temps.

Plus en détail

Dr. Djamel Benmerzoug. Email : djamel.benmerzoug@univ-constantine2.dz

Dr. Djamel Benmerzoug. Email : djamel.benmerzoug@univ-constantine2.dz Master 2 SITW Les services Web Dr. Djamel Benmerzoug Email : djamel.benmerzoug@univ-constantine2.dz Maitre de Conférences A, Département TLSI Faculté des NTIC Université Constantine 2 Abdelhamid Mehri

Plus en détail

Plan. Environnement Client/Serveur. Cours 6 Rappels Java (suite) Appel de méthode à distance. Utilité. static

Plan. Environnement Client/Serveur. Cours 6 Rappels Java (suite) Appel de méthode à distance. Utilité. static Plan Environnement Client/Serveur Cours 6 Rappels Java (suite) Appel de méthode à distance kn@lri.fr http://www.lri.fr/~kn 1 Rappels sur les systèmes d'exploitations / Communication par mémoire partagée

Plus en détail

TP4-5 : Authentication Java

TP4-5 : Authentication Java TP4-5 : Authentication Java V. Danjean V. Marangozova-Martin Résumé Le but de ce TP est double : se familiariser avec le mécanisme classique d'authentication en Java ; apprendre à utiliser la documentation

Plus en détail

Formation Webase 5. Formation Webase 5. Ses secrets, de l architecture MVC à l application Web. Adrien Grand Centrale Réseaux

Formation Webase 5. Formation Webase 5. Ses secrets, de l architecture MVC à l application Web. Adrien Grand <jpountz@via.ecp.fr> Centrale Réseaux Formation Webase 5 Ses secrets, de l architecture MVC à l application Web Adrien Grand Centrale Réseaux Sommaire 1 Obtenir des informations sur Webase 5 2 Composants de Webase 5 Un

Plus en détail

Les entrées/sorties Java (sérialisation, accès aux chiers et connexion réseau)

Les entrées/sorties Java (sérialisation, accès aux chiers et connexion réseau) Année 2008-2009 Les entrées/sorties Java (sérialisation, accès aux chiers et connexion réseau) Nicolas Baudru mél : nicolas.baudru@esil.univmed.fr page web : nicolas.baudru.perso.esil.univmed.fr 1 Introduction

Plus en détail

Sauvegardes sous Windows c 2003 serveur

Sauvegardes sous Windows c 2003 serveur Sauvegardes sous Windows c 2003 serveur Louis-Maurice De Sousa ~ Fabrice Lemoine ~ Jackie Daon 27 mars 2006 Table des matières 1 Introduction 3 2 NTbackup 3 2.1 La sauvegarde...........................

Plus en détail

Bypass et filtre sur les requêtes destinées à la servlet W4

Bypass et filtre sur les requêtes destinées à la servlet W4 Note technique W4 Engine Bypass et filtre sur les requêtes destinées à la servlet W4 Cette note technique décrit le filtre de contrôle du bypass de la servlet W4. Versions de W4 Engine concernées : 5.0

Plus en détail

Formation développement Java, Spring et Hibernate

Formation développement Java, Spring et Hibernate L institut de formation continue des professionnels du Web Formation développement Java, Spring et Hibernate Référence formation : Durée : Prix conseillé : DJSH 10 jours (70 heures) 4 500 HT (hors promotion

Plus en détail

Institut Supérieure Aux Etudes Technologiques De Nabeul. Département Informatique

Institut Supérieure Aux Etudes Technologiques De Nabeul. Département Informatique Institut Supérieure Aux Etudes Technologiques De Nabeul Département Informatique Support de Programmation Java Préparé par Mlle Imene Sghaier 2006-2007 Chapitre 1 Introduction au langage de programmation

Plus en détail

1 Introduction à Apache Maven

1 Introduction à Apache Maven IUT Bordeaux 1 - Département Informatique Semestre 4 JEE 20112012 TP JEE (0) Introduction à MAVEN 1 Introduction à Apache Maven Les projets Java (surtout JEE) ont la particularité de dépendre de beaucoup

Plus en détail

Sauf mention contraire, le contenu de cet ouvrage est publié sous la licence : Creative Commons BY-NC-SA 2.0 La copie de cet ouvrage est autorisée

Sauf mention contraire, le contenu de cet ouvrage est publié sous la licence : Creative Commons BY-NC-SA 2.0 La copie de cet ouvrage est autorisée Sauf mention contraire, le contenu de cet ouvrage est publié sous la licence : Creative Commons BY-NC-SA 2.0 La copie de cet ouvrage est autorisée sous réserve du respect des conditions de la licence Texte

Plus en détail

Plan. Environnement Client/Serveur. Cours 7 JavaServer Pages (1) JSP. Programmation Web coté serveur

Plan. Environnement Client/Serveur. Cours 7 JavaServer Pages (1) JSP. Programmation Web coté serveur Plan Environnement Client/Serveur Cours 7 JavaServer Pages (1) kn@lri.fr 7.1 Principe 7.2 Rappels HTTP 7.3 Le serveur web Tomcat Programmation Web coté serveur JSP 2/28 (rappel) génération de pages-web

Plus en détail

Interactions audio sur le site web du LIA Documentation Technique

Interactions audio sur le site web du LIA Documentation Technique 2007 Interactions audio sur le site web du LIA Documentation Technique Projet 13 - IUP Avignon Master1 TAIM 28/05/2007 2 Projet 13 : Interactions audio sur le site web du LIA Sommaire Composants de l'application...

Plus en détail

Les formations. Développeur Logiciel. ENI Ecole Informatique

Les formations. Développeur Logiciel. ENI Ecole Informatique page 1/5 Titre professionnel : Reconnu par l Etat de niveau III (Bac), inscrit au RNCP (arrêté du 12/10/07, J.O. n 246 du 23/10/07) (32 semaines) Unité 1 : Structurer une application 6 semaines Module

Plus en détail

Table des matières. TP JEE (2) Logic metier et Entreprise Java Beans. IUT Bordeaux 1 - Département Informatique

Table des matières. TP JEE (2) Logic metier et Entreprise Java Beans. IUT Bordeaux 1 - Département Informatique IUT Bordeaux 1 - Département Informatique Semestre 4 JEE 20112012 TP JEE (2) Logic metier et Entreprise Java Beans Les EJB (Enterprise JavaBeans) 3.0 permettent de découpler la logique de présentation

Plus en détail

TP 6 : Java Server Pages et Tomcat.

TP 6 : Java Server Pages et Tomcat. TP 6 : Java Server Pages et Tomcat. Christophe Gravier, Frédérique Laforest, Julien Subercaze Télécom Saint-Étienne Université Jean Monnet {pnom.nom}@univ-st-etienne.fr FI2_INFO4 20122013 1 / 24 Plan Objectifs

Plus en détail

Configuration d'un annuaire LDAP

Configuration d'un annuaire LDAP Le serveur Icewarp Configuration d'un annuaire LDAP Version 10.3 Juillet 2011 Icewarp France / DARNIS Informatique i Sommaire Configuration d'un annuaire LDAP 1 Introduction... 1 Qu'est-ce que LDAP?...

Plus en détail

Cahier de charges (Source : "Java EE - Guide de développement d'applications web en Java" par Jérôme Lafosse) Module. Site Web dynamique JSP / Servlet

Cahier de charges (Source : Java EE - Guide de développement d'applications web en Java par Jérôme Lafosse) Module. Site Web dynamique JSP / Servlet Cahier de charges (Source : "Java EE - Guide de développement d'applications web en Java" par Jérôme Lafosse) Module Site Web dynamique JSP / Servlet Sujet : betaboutique Soutenance le 04 / 01 /2013 &

Plus en détail

MANUEL D' UTILISATION

MANUEL D' UTILISATION MANUEL D' UTILISATION Table des matières Présentation...2 Introduction...2 Matériel nécessaire...2 Logiciel nécessaire...3 Partie A : Installation et Mise en oeuvre du matériel et logiciel...4 Partie B

Plus en détail

Quelques patterns pour la persistance des objets avec DAO DAO. Principe de base. Utilité des DTOs. Le modèle de conception DTO (Data Transfer Object)

Quelques patterns pour la persistance des objets avec DAO DAO. Principe de base. Utilité des DTOs. Le modèle de conception DTO (Data Transfer Object) Quelques patterns pour la persistance des objets avec DAO Ce cours présente des modèles de conception utilisés pour effectuer la persistance des objets Université de Nice Sophia-Antipolis Version 1.4 30/8/07

Plus en détail

Avant de programmer en Java DOS Set Path=C:\JDK\bin Path=C:\JDK\bin C:\JDK\bin Set Path=%Path%;C:\JDK\bin C:\JDK\bin C:\JDK\

Avant de programmer en Java DOS Set Path=C:\JDK\bin Path=C:\JDK\bin C:\JDK\bin Set Path=%Path%;C:\JDK\bin C:\JDK\bin C:\JDK\ Exercices corrigés de programmation OO Java Préparés par : Mlle Imene Sghaier Année Académique : 2006-2007 Premiers Pas I. Avant de programmer en Java Le JDK de Sun (Java Development Kit) est l outil essentiel

Plus en détail

Chapitre 1 : Introduction aux bases de données

Chapitre 1 : Introduction aux bases de données Chapitre 1 : Introduction aux bases de données Les Bases de Données occupent aujourd'hui une place de plus en plus importante dans les systèmes informatiques. Les Systèmes de Gestion de Bases de Données

Plus en détail

SOMMAIRE. Utilisation des profils itinérants. Chapitre 1 Mise en place 2

SOMMAIRE. Utilisation des profils itinérants. Chapitre 1 Mise en place 2 Page 1 sur 21 SOMMAIRE Chapitre 1 Mise en place 2 1.1 Qu est ce que c est 2 1.2 Quelques recommandations 3 1.3 La sécurité? 4 1.4 Comment le configurer? 5 1.5 Comment obtenir les droits sur le profil?

Plus en détail

TP JEE Développement Web en Java. Dans ce TP nous commencerons la programmation JEE par le premier niveau d une application JEE : l application web.

TP JEE Développement Web en Java. Dans ce TP nous commencerons la programmation JEE par le premier niveau d une application JEE : l application web. ASTRIUM - Toulouse JEE Formation 2013 TP JEE Développement Web en Java Dans ce TP nous commencerons la programmation JEE par le premier niveau d une application JEE : l application web. Figure 1 Architecture

Plus en détail

Scub Foundation. Socle technique Java Open Source http://www.scub-foundation.org

Scub Foundation. Socle technique Java Open Source http://www.scub-foundation.org Scub Foundation Socle technique Java Open Source http://www.scub-foundation.org Présentation de Scub Présentation de Scub Scub est une société de service en informatique qui a pour but de fournir du conseil

Plus en détail

Pourquoi ai-je besoin de recompiler apache? Comment recompiler apache? Comment récupérer les entêtes eid en PHP?

Pourquoi ai-je besoin de recompiler apache? Comment recompiler apache? Comment récupérer les entêtes eid en PHP? 1 Généralité Qu'elle est l'architecture générale d'une application eid en ligne? Client / PC-SC / Reverse Proxy / Serveur applicatif TODO gure architecture JPG A quel niveau se fait/font la/les vérication(s)

Plus en détail

LES ACCES ODBC AVEC LE SYSTEME SAS

LES ACCES ODBC AVEC LE SYSTEME SAS LES ACCES ODBC AVEC LE SYSTEME SAS I. Présentation II. SAS/ACCESS to ODBC III. Driver ODBC SAS IV. Driver ODBC SAS Universel V. Version 8 VI. Références I. Présentation Introduction ODBC, qui signifie

Plus en détail

Explication des statistiques

Explication des statistiques Explication des statistiques Sources : http://www.eolas.fr/8-conseil/65-interpreter-vos-statistiques-webalizer.htm http://support.sherweb.com/faqdetails.php?idarticle=68 Un site web est un ensemble de

Plus en détail

Utiliser Access ou Excel pour gérer vos données

Utiliser Access ou Excel pour gérer vos données Page 1 of 5 Microsoft Office Access Utiliser Access ou Excel pour gérer vos données S'applique à : Microsoft Office Access 2007 Masquer tout Les programmes de feuilles de calcul automatisées, tels que

Plus en détail

24/11/2011. Cours EJB/J2EE Copyright Michel Buffa. Plan du cours. EJB : les fondamentaux. Enterprise Java Bean. Enterprise Java Bean.

24/11/2011. Cours EJB/J2EE Copyright Michel Buffa. Plan du cours. EJB : les fondamentaux. Enterprise Java Bean. Enterprise Java Bean. Plan du cours 2 Introduction générale : fondamentaux : les fondamentaux Michel Buffa (buffa@unice.fr), UNSA 2002, modifié par Richard Grin (version 1.1, 21/11/11), avec emprunts aux supports de Maxime

Plus en détail

Pour signifier qu'une classe fille hérite d'une classe mère, on utilise le mot clé extends class fille extends mère

Pour signifier qu'une classe fille hérite d'une classe mère, on utilise le mot clé extends class fille extends mère L'héritage et le polymorphisme en Java Pour signifier qu'une classe fille hérite d'une classe mère, on utilise le mot clé extends class fille extends mère En java, toutes les classes sont dérivée de la

Plus en détail

TPC#9 : Client & Serveur!

TPC#9 : Client & Serveur! TPC#9 : Client & Serveur! Table des matières 1 Structure du rendu 1 2 Introduction 2 3 Sockets et Threads 2 3.1 Les sockets............................................ 2 3.1.1 Cours et exemples....................................

Plus en détail

Chapitre 4 Les Servlets. 1. Qu'est-ce qu'une Servlet? 1.1 Présentation. 1.2 Requêtes HTTP

Chapitre 4 Les Servlets. 1. Qu'est-ce qu'une Servlet? 1.1 Présentation. 1.2 Requêtes HTTP 210 Les Servlets 1. Qu'est-ce qu'une Servlet? 1.1 Présentation Les Servlets sont la base de la programmation Java EE. La conception d'un site Web dynamique en Java repose sur ces éléments. Une Servlet

Plus en détail

Un serveur FTP chez soi Tutoriel pour Filezilla FTP server

Un serveur FTP chez soi Tutoriel pour Filezilla FTP server Space-OperaRécitsLogicielsCréationsBlogForum Un serveur FTP chez soi Tutoriel pour Filezilla FTP server DynDNS : Pourquoi et comment? Téléchargement et installation de Filezilla Server Configuration réseau

Plus en détail

Télécom Nancy Année 2013-2014

Télécom Nancy Année 2013-2014 Télécom Nancy Année 2013-2014 Rapport 1A Ajout du langage C dans la Programmer's Learning Machine GIANNINI Valentin Loria 615, rue du Jardin Botanique 54600, Villers-Lès-Nancy Maître de stage : QUINSON

Plus en détail

Programmation concurrente en java

Programmation concurrente en java Programmation concurrente en java M. Belguidoum Université Mentouri de Constantine Département Informatique M. Belguidoum (UMC) Programmation concurrente 1 / 29 Plan 1 Introduction 2 Création d'un thread

Plus en détail

Java - TP3. Nicolas Baudru, Carine Guivier-Curien, Laurent Vallet. Année 2008-2009

Java - TP3. Nicolas Baudru, Carine Guivier-Curien, Laurent Vallet. Année 2008-2009 Java - TP3 Nicolas Baudru, Carine Guivier-Curien, Laurent Vallet Année 2008-2009 Le but de ce TD est d'écrire une application client/serveur de type msn : 1. Des clients se connectent à un serveur 2. Un

Plus en détail

Création d un WebService. Tp WinDev Numéro 13

Création d un WebService. Tp WinDev Numéro 13 Tp WinDev Numéro 13 Objectifs : Création d un WebService Paramétrage d un serveur Web, Création du Service Web, Création du client consommateur, Approche XML, SOAP Outils : Un serveur d application Ce

Plus en détail

Site Web de paris sportifs

Site Web de paris sportifs Conception Nom HENAUD Benoît Numéro d auditeur 05-39166 Version V1.1 Date de mise à jour 15/05/2008 1/18 Table des matières 1. Objectif du document... 3 2. Architecture... 4 2.1. Contraintes techniques...

Plus en détail

Unité de formation 1 : Structurer une application. Durée : 3 semaines

Unité de formation 1 : Structurer une application. Durée : 3 semaines PROGRAMME «DEVELOPPEUR LOGICIEL» Titre professionnel : «Développeur Logiciel» Inscrit au RNCP de niveau III (Bac+2) (JO du 23 Octobre 2007) (32 semaines) Unité de formation 1 : Structurer une application

Plus en détail

Manuel d'utilisation d'apimail V3

Manuel d'utilisation d'apimail V3 Manuel d'utilisation d'apimail V3 I Préambule Page 3 II Présentation Page 4 III Mise en route Configuration Page 5 Messagerie Serveur smtp Serveur pop Compte pop Mot de passe Adresse mail Laisser les messages

Plus en détail

Types d applications pour la persistance. Outils de développement. Base de données préexistante? 3 modèles. Variantes avec passerelles

Types d applications pour la persistance. Outils de développement. Base de données préexistante? 3 modèles. Variantes avec passerelles Types d applications pour la persistance Université de Nice Sophia-Antipolis Version 0.9 28/8/07 Richard Grin Toutes les applications n ont pas une complexité qui nécessite une architecture n- tiers Ce

Plus en détail

Comment utiliser mon compte alumni?

Comment utiliser mon compte alumni? Ce document dispose d une version PDF sur le site public du CI Comment utiliser mon compte alumni? Elena Fascilla, le 23/06/2010 Sommaire 1. Introduction... 2 2. Avant de commencer... 2 2.1 Connexion...

Plus en détail

Active Directory Sommaire :

Active Directory Sommaire : Active Directory Sommaire : Définition Ce qu'il permet A quoi sert-il? Principe de fonctionnement Structure Hiérarchie Schéma Qu'est ce qu'un service d'annuaire? Qu'elle est son intérêt? L'installation

Plus en détail

JAVA. (Java-sans objet) (Dernière édition) Programme de formation. et (Java - Hibernate &Spring) France, Belgique, Suisse, Roumanie - Canada

JAVA. (Java-sans objet) (Dernière édition) Programme de formation. et (Java - Hibernate &Spring) France, Belgique, Suisse, Roumanie - Canada JAVA (Java-sans objet) et (Java - Hibernate &Spring) (Dernière édition) Programme de formation Microsoft Partner France, Belgique, Suisse, Roumanie - Canada WWW.SASGROUPE.COM Formez vos salariés pour optimiser

Plus en détail

Plugin Payment-OnLine

Plugin Payment-OnLine Plugin Payment-OnLine Le plugin "Payment-Online" est un plugin technique dont l'objectif est de faciliter l'utilisation du paiement en ligne dans des applications Lutèce. Il se compose d'une librairie

Plus en détail

Rapport Gestion de projet

Rapport Gestion de projet IN56 Printemps 2008 Rapport Gestion de projet Binôme : Alexandre HAFFNER Nicolas MONNERET Enseignant : Nathanaël COTTIN Sommaire Description du projet... 2 Fonctionnalités... 2 Navigation... 4 Description

Plus en détail

TD4 : Wikis, Servlets & Projet

TD4 : Wikis, Servlets & Projet Université Bordeaux 1 T.D. License 3 Informatique 2007 2008 TD4 : Wikis, Servlets & Projet L objet de cette séance est de vous familiariser avec les sockets et les servlets, et d introduire le projet.

Plus en détail

Compte Rendu d intégration d application

Compte Rendu d intégration d application ISMA 3EME ANNEE Compte Rendu d intégration d application Compte Rendu Final Maxime ESCOURBIAC Jean-Christophe SEPTIER 19/12/2011 Table des matières Table des matières... 1 Introduction... 3 1. Le SGBD:...

Plus en détail

Installation du Serveur - Windows Server 2003

Installation du Serveur - Windows Server 2003 Installation du Serveur - Windows Server 2003 Nous allons commencer par l installation du serveur afin de remplir les conditions nécessaires et préparer celui-ci à l installation des services : Active

Plus en détail

Java pour le Web. Cours Java - F. Michel

Java pour le Web. Cours Java - F. Michel Java pour le Web Cours Java - F. Michel Introduction à JEE 6 (ex J2EE) Historique Qu'est-ce que JEE JEE : Java Entreprise Edition (ex J2EE) 1. Une technologie outils liés au langage Java + des spécifications

Plus en détail

Le service FTP. M.BOUABID, 04-2015 Page 1 sur 5

Le service FTP. M.BOUABID, 04-2015 Page 1 sur 5 Le service FTP 1) Présentation du protocole FTP Le File Transfer Protocol (protocole de transfert de fichiers), ou FTP, est un protocole de communication destiné à l échange informatique de fichiers sur

Plus en détail

Vue d'ensemble de Document Distributor

Vue d'ensemble de Document Distributor Pour afficher ou télécharger cette publication ou d'autres publications Lexmark Document Solutions, cliquez ici. Vue d'ensemble de Document Distributor Le logiciel Lexmark Document Distributor fournit

Plus en détail

RMI le langage Java XII-1 JMF

RMI le langage Java XII-1 JMF Remote Method Invocation (RMI) XII-1 Introduction RMI est un ensemble de classes permettant de manipuler des objets sur des machines distantes (objets distants) de manière similaire aux objets sur la machine

Plus en détail

Documentation de CMS-gen

Documentation de CMS-gen Table des matières GÉNÉRALITÉ... 1 LA ZONE D'ADMINISTRATION... 2 LOGIN SUR LA ZONE D ADMINISTRATION... 2 EDITION DU CONTENU EN LIGNE... 3 LE MODE EDITION... 3 PUBLICATION... 3 SUPPRIMER DES MODIFICATIONS...

Plus en détail

JDOM. Manipulation de XML avec JDOM et Java. A. Belaïd http://cynober.developpez.com/tutoriel/java/xml/jdom/

JDOM. Manipulation de XML avec JDOM et Java. A. Belaïd http://cynober.developpez.com/tutoriel/java/xml/jdom/ JDOM Manipulation de XML avec JDOM et Java 1 JDOM C est quoi? JDOM est une API du langage Java Permet de manipuler des donnés XML plus simplement qu'avec les API classiques Son utilisation est pratique

Plus en détail

PLAN PROJET. Binôme ou monôme (B/M): M. : abdlhaqmilan@gmail.com GSM : 00212640108250. : Gestion d'une agence de location de voiture.

PLAN PROJET. Binôme ou monôme (B/M): M. : abdlhaqmilan@gmail.com GSM : 00212640108250. : Gestion d'une agence de location de voiture. Développement d une application JAVA EE PLAN PROJET Binôme ou monôme (B/M): M Nom & Prénom : AZRAGUE Abdelhaq Email : abdlhaqmilan@gmail.com GSM : 00212640108250 Organisme Scolaire : Gestion d'une agence

Plus en détail

Le stockage local de données en HTML5

Le stockage local de données en HTML5 Le stockage local HTML5, pourquoi faire? Dans une optique de réduction des couts de maintenance, de déploiement, beaucoup d'entreprises ont fait le choix de migrer leurs applicatifs (comptables, commerciales,

Plus en détail

Applications Web. Cours 2: Introduction J2EE Servlets et JSP. Khaled Khelif

Applications Web. Cours 2: Introduction J2EE Servlets et JSP. Khaled Khelif Applications Web Cours 2: Introduction J2EE Servlets et JSP Khaled Khelif 1 Rappel Web statique vs. Web dynamique Principe des applications web Protocole HTTP : requêtes en mode texte Développement d applications

Plus en détail

Initiation au mail. Sommaire : 1. Qu'est-ce qu'un mail?...3 2. Deux types d'outils pour consulter ses mails...4

Initiation au mail. Sommaire : 1. Qu'est-ce qu'un mail?...3 2. Deux types d'outils pour consulter ses mails...4 Initiation au mail Sommaire : 1. Qu'est-ce qu'un mail?...3 2. Deux types d'outils pour consulter ses mails...4 2.1. Les logiciels de gestion de mail...4 2.2. Les webmails...5 3. Se connecter au webmail...6

Plus en détail

Projet Système Distribué : Implémentation d'un serveur générateur de certicats. BEUQUE Eric, CORNEVAUX Sébastien, MOUTENET Cyril 13 janvier 2009

Projet Système Distribué : Implémentation d'un serveur générateur de certicats. BEUQUE Eric, CORNEVAUX Sébastien, MOUTENET Cyril 13 janvier 2009 Projet Système Distribué : Implémentation d'un serveur générateur de certicats BEUQUE Eric, CORNEVAUX Sébastien, MOUTENET Cyril 13 janvier 2009 1 Table des matières 1 Sujet 3 2 Analyse 4 3 Création clé

Plus en détail

SERVEUR DE MESSAGERIE

SERVEUR DE MESSAGERIE CRÉEZ VOTRE SERVEUR DE MESSAGERIE avec: version 4.3-B248 Sommaire PREAMBULE et REMERCIEMENTS Page 2 INTRODUCTION Page 2 AVERTISSEMENT Page 3 INSTALLATION Page 3 CONFIGURATION Page 12 CLIENT DE MESAGERIE

Plus en détail

Sage CRM. 7.2 Guide de Portail Client

Sage CRM. 7.2 Guide de Portail Client Sage CRM 7.2 Guide de Portail Client Copyright 2013 Sage Technologies Limited, éditeur de ce produit. Tous droits réservés. Il est interdit de copier, photocopier, reproduire, traduire, copier sur microfilm,

Plus en détail

Architecture N-Tier. Ces données peuvent être saisies interactivement via l interface ou lues depuis un disque. Application

Architecture N-Tier. Ces données peuvent être saisies interactivement via l interface ou lues depuis un disque. Application Architecture Multi-Tier Traditionnellement une application informatique est un programme exécutable sur une machine qui représente la logique de traitement des données manipulées par l application. Ces

Plus en détail

SIO-65291 Page 1 de 5. Applications Web dynamiques. Prof. : Dzenan Ridjanovic Assistant : Vincent Dussault

SIO-65291 Page 1 de 5. Applications Web dynamiques. Prof. : Dzenan Ridjanovic Assistant : Vincent Dussault SIO-65291 Page 1 de 5 1- Objectifs généraux Applications Web dynamiques Prof. : Dzenan Ridjanovic Assistant : Vincent Dussault acquérir les principes et concepts fondamentaux dans le domaine d'applications

Plus en détail

La Programmation Web avec PHP

La Programmation Web avec PHP Nouvelle page 1 La Programmation Web avec PHP Qu'est-ce que php? Menu Qu'est ce que php? Les scripts PHP Installation de PHP Configuration d'un serveur IIS Mohamed SIDIR PHP est un langage de script HTML,

Plus en détail

JAVA Première approche

JAVA Première approche Année 2008-2009 JAVA Première approche Nicolas Baudru mél : nicolas.baudru@esil.univmed.fr page web : nicolas.baudru.perso.esil.univmed.fr 1 Qu'est ce que Java? C'est le nom d'une technologie mise au point

Plus en détail

Traitement et navigation

Traitement et navigation 12 Traitement et navigation Au chapitre précédent, nous avons vu comment créer des pages web avec différentes technologies (HTML, JSP, JSTL, etc.) en insistant sur le fait que JSF est la spécification

Plus en détail

SCOoffice Mail Connector for Microsoft Outlook. Guide d'installation Outlook 2002

SCOoffice Mail Connector for Microsoft Outlook. Guide d'installation Outlook 2002 SCOoffice Mail Connector for Microsoft Outlook Guide d'installation Outlook 2002 Rév 1.1 4 décembre 2002 SCOoffice Mail Connector for Microsoft Outlook Guide d'installation - Outlook XP Introduction Ce

Plus en détail

Installer et Utiliser MSDE 2000 Utilisation de MS SQL Server 2000 Desktop Engine

Installer et Utiliser MSDE 2000 Utilisation de MS SQL Server 2000 Desktop Engine Installer et Utiliser MSDE 2000 Utilisation de MS SQL Server 2000 Desktop Engine Le produit de développement de Microsoft pour les bases de données le plus proche de SQL Server 2000 est : Microsoft SQL

Plus en détail

Extension SSO Java. Cette note technique décrit la configuration et la mise en œuvre du filtre de custom SSO Java.

Extension SSO Java. Cette note technique décrit la configuration et la mise en œuvre du filtre de custom SSO Java. Note technique W4 Engine Extension SSO Java Cette note technique décrit la configuration et la mise en œuvre du filtre de custom SSO Java. 1 Présentation 3 2 Custom SSO Java 4 3 Bilan 10 Sommaire Référence

Plus en détail

Créer le modèle multidimensionnel

Créer le modèle multidimensionnel 231 Chapitre 6 Créer le modèle multidimensionnel 1. Présentation de SSAS multidimensionnel Créer le modèle multidimensionnel SSAS (SQL Server Analysis Services) multidimensionnel est un serveur de bases

Plus en détail

LISE 3. Template pour les mails. Version 1.0 du 13/04/2010. Etat : Validé

LISE 3. Template pour les mails. Version 1.0 du 13/04/2010. Etat : Validé Template pour les mails Version 1.0 du 13/04/2010 Etat : Validé SUIVI DES MODIFICATIONS Version Rédaction Description Vérification Date 1.0 A. Lesuffleur création du document 13/04/10 Document validé dans

Plus en détail

Mémento professeur du réseau pédagogique

Mémento professeur du réseau pédagogique Mémento professeur du réseau pédagogique 1. Accéder au réseau pédagogique Il suffit quand on vous demande votre nom d utilisateur et votre mot de passe de renseigner ceux-ci. Votre nom d utilisateur est

Plus en détail

Java Licence professionnelle CISI 2009-2010

Java Licence professionnelle CISI 2009-2010 Java Licence professionnelle CISI 2009-2010 Cours 10 : Type générique (c) http://manu.e3b.org/java/tutoriels/avance/generique.pdf 1 Introduction La programmation générique - nouveauté la plus significative

Plus en détail

18/05/2010 JSF : Java server faces

18/05/2010 JSF : Java server faces 18/05/2010 JSF : Java server faces Groupe JAXB - JSF TABLE DES MATIÈRES OBJECTIF...2 VERSION... ERREUR! SIGNET NON DEFINI. MISE EN ŒUVRE...2 UTILISATION...4 Génération des classes à partir d un schéma...

Plus en détail

Tutoriel de UWE. Traduction du tutoriel du site ociel. traduit et mis en page par Ludovic Dubois. ludovic.dubois89 (at) gmail.com

Tutoriel de UWE. Traduction du tutoriel du site ociel. traduit et mis en page par Ludovic Dubois. ludovic.dubois89 (at) gmail.com Tutoriel de UWE Traduction du tutoriel du site ociel Images du logiciel MagicDraw traduit et mis en page par Ludovic Dubois ludovic.dubois89 (at) gmail.com Décembre 2009 - Version 2.0 Table des matières

Plus en détail

Le client/serveur repose sur une communication d égal à égal entre les applications.

Le client/serveur repose sur une communication d égal à égal entre les applications. Table des matières LES PRINCIPES DE BASE... 1 Présentation distribuée-revamping...2 Présentation distante...3 Traitements distribués...3 données distantes-rd...4 données distribuées-rda distribué...4 L'ARCHITECTURE

Plus en détail

Programme «Analyste Programmeur» Diplôme d état : «Développeur Informatique» Homologué au niveau III (Bac+2) (JO N 176 du 1 août 2003) (34 semaines)

Programme «Analyste Programmeur» Diplôme d état : «Développeur Informatique» Homologué au niveau III (Bac+2) (JO N 176 du 1 août 2003) (34 semaines) Programme «Analyste Programmeur» Diplôme d état : «Développeur Informatique» Homologué au niveau III (Bac+2) (JO N 176 du 1 août 2003) (34 semaines) Module 1 : Programmer une application informatique Durée

Plus en détail

AJAX est l'acronyme d'asynchronous JavaScript And XML, autrement dit JavaScript Et XML Asynchrones.

AJAX est l'acronyme d'asynchronous JavaScript And XML, autrement dit JavaScript Et XML Asynchrones. Le concept d'ajax Introduction AJAX est l'acronyme d'asynchronous JavaScript And XML, autrement dit JavaScript Et XML Asynchrones. AJAX n'est ni une technologie ni un langage de programmation ; AJAX est

Plus en détail

Mise en œuvre des serveurs d application

Mise en œuvre des serveurs d application Nancy-Université Mise en œuvre des serveurs d application UE 203d Master 1 IST-IE Printemps 2008 Master 1 IST-IE : Mise en œuvre des serveurs d application 1/54 Ces transparents, ainsi que les énoncés

Plus en détail

RAPPORT DE CONCEPTION UML :

RAPPORT DE CONCEPTION UML : Carlo Abi Chahine Sylvain Archenault Yves Houpert Martine Wang RAPPORT DE CONCEPTION UML : Bamboo Ch@t Projet GM4 Juin 2006 Table des matières 1 Introduction 2 2 Présentation du logiciel 3 2.1 Précisions

Plus en détail

1 Mise en forme des SELECT

1 Mise en forme des SELECT Table des matières Utilitaire SQL*PLUS 1 Mise en forme des SELECT 1 2 Commandes utilitaires de SQL*PLUS 2 2.1 Éditeur de la machine hôte.................... 2 2.2 Commande RUN, commande /.................

Plus en détail

Service WEB, BDD MySQL, PHP et réplication Heartbeat. Conditions requises : Dans ce TP, il est nécessaire d'avoir une machine Debian sous ProxMox

Service WEB, BDD MySQL, PHP et réplication Heartbeat. Conditions requises : Dans ce TP, il est nécessaire d'avoir une machine Debian sous ProxMox Version utilisée pour la Debian : 7.7 Conditions requises : Dans ce TP, il est nécessaire d'avoir une machine Debian sous ProxMox Caractéristiques de bases : Un service web (ou service de la toile) est

Plus en détail

Applications Web dynamiques SIO-21970

Applications Web dynamiques SIO-21970 Faculté des sciences de l'administration Systèmes d'information organisationnels Université Laval Automne 2003 Applications Web dynamiques SIO-21970 Professeur: Dzenan Ridjanovic Bureau: 2519 Téléphone:

Plus en détail

Programmabilité du réseau avec l'infrastructure axée sur les applications (ACI) de Cisco

Programmabilité du réseau avec l'infrastructure axée sur les applications (ACI) de Cisco Livre blanc Programmabilité du réseau avec l'infrastructure axée sur les applications (ACI) de Cisco Présentation Ce document examine la prise en charge de la programmabilité sur l'infrastructure axée

Plus en détail

Préparation à l installation d Active Directory

Préparation à l installation d Active Directory Laboratoire 03 Étape 1 : Installation d Active Directory et du service DNS Noter que vous ne pourrez pas réaliser ce laboratoire sans avoir fait le précédent laboratoire. Avant de commencer, le professeur

Plus en détail

Application web de gestion de comptes en banques

Application web de gestion de comptes en banques Application web de gestion de comptes en banques Objectif Réaliser une application Web permettant à un client de gérer ses comptes en banque Diagramme de cas d'utilisation 1 Les cas d'utilisation Connexion

Plus en détail

CQP Développeur Nouvelles Technologies (DNT)

CQP Développeur Nouvelles Technologies (DNT) ORGANISME REFERENCE STAGE : 26572 20 rue de l Arcade 75 008 PARIS CONTACT Couverture géographique : M. Frédéric DIOLEZ Bordeaux, Rouen, Lyon, Toulouse, Marseille Tél. : 09 88 66 17 40 Nantes, Lille, Strasbourg,

Plus en détail

Conseil, Etudes et Edition de logiciels NORMES & CONVENTIONS DE DEVELOPPEMENT JAVA ET SQL

Conseil, Etudes et Edition de logiciels NORMES & CONVENTIONS DE DEVELOPPEMENT JAVA ET SQL Conseil, Etudes et Edition de logiciels NORMES & CONVENTIONS DE DEVELOPPEMENT JAVA ET SQL Table des matières Système d'exploitation... 3 Environnement de développement intégré... 3 Le workspace... 3 Le

Plus en détail

Atelier 2. Étape 1 : Installation de Active Directory, installation du service DNS et installation du service WINS Durée approximative : 40 minutes

Atelier 2. Étape 1 : Installation de Active Directory, installation du service DNS et installation du service WINS Durée approximative : 40 minutes Atelier 2 Installation d Active Directory Installation du service DNS Installation du Service WINS Création d'un compte d'ordinateur Jonction d'un ordinateur à un domaine Création d usagers. Étape 1 :

Plus en détail

Cours en ligne Développement Java pour le web

Cours en ligne Développement Java pour le web Cours en ligne Développement Java pour le web We TrainFrance info@wetrainfrance Programme général du cours Développement Java pour le web Module 1 - Programmation J2ee A) Bases de programmation Java Unité

Plus en détail

2 Grad Info Soir Langage C++ Juin 2007. Projet BANQUE

2 Grad Info Soir Langage C++ Juin 2007. Projet BANQUE 2 Grad Info Soir Langage C++ Juin 2007 Projet BANQUE 1. Explications L'examen comprend un projet à réaliser à domicile et à documenter : - structure des données, - objets utilisés, - relations de dépendance

Plus en détail