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 au système L'utilisateur fourni son code client (entier, identifiant unique) et son mot de passe Si le ces informations sont correctes il est accède à une page listant l'ensemble de ses comptes Sinon, il reste sur la page de login et un message d'erreur est affiché Lister ses comptes L'utilisateur est connecté La liste des comptes accessibles au client apparaît Pour chaque compte on a : Le numéro du compte (entier identifiant) L'intitulé (livret A, compte Dépôt,.) Le nom du titulaire du compte Le solde du compte 2
Les cas d'utilisation Effectuer un transfert L'utilisateur est connecté L'utilisateur sélectionne un compte de départ, un compte d'arrivée L'utilisateur fournit le montant à transférer L'utilisateur demande le transfert (possible que si les données nécessaires au transfert ont été fournies) Le transfert est effectué Il n'est possible que si le montant du transfert respecte le débit maximum autorisé et le découvert maximum autorisé pour le compte à débiter. En cas d'impossibilité un message le signale à l'utilisateur Deconnexion L'utilisateur quitte le système, il doit repasser par la phase de connexion pour lister ses comptes où effectuer un virement 3 Interface et fonctionnement de l'application Page d'accueil Retour à la page de login en indiquant la cause de l'échec 1 Page liste des comptes Permet de sélectionner le compte source et le compte destination et le montant du transfert 1 2 Page pour effectuer un transfert Page affichage des résultats du transfert Réalisation du transfert échec Authentification de l'utilisateur ok Affiche la liste des comptes accessibles par le client Déconnexion 2 L'utilisateur n'a plus accès à l'application à moins de repasser par la phase d'authentification Page de déconnexion Annexe 3 : interface de l'application Banque IMA on line 1 2 Page indiquant si le transfert a réussi ou non Et en cas d'échec la raison de ce dernier 4
Composants Java de l'application présentation métier Accès aux données Navigateur Servlets Client ClientDAO Pages JSP Compte CompteDAO Serveur d'application Java JDBC SGBD Relationnel Les objets DAO (Data Access Object) isolent tout le code lié à la persistance des données Quand l'application a besoin d'effectuer une opération lié à la persistance elle fait appel à un objet DAO L'interface des objets DAO est indépendante du support de persistance Le reste de l'application utilise les DAO uniquement au travers de leur interface abstraite Par exemple si on change d'implémentation de DAO pour passer d'une base Oracle à des fichiers XML le reste de l'application demeure inchangé. Chaque classe d'objet métier a son propre type de DAO (ClientDAO, CompteDAO) Le même objet DAO peut être utilisé pour les objets d'une même classe d'objet métier 5 Travail à faire Définir la couche métier Les classes Java Client et Compte Définir la couche persistante Les tables de la base de données Définir la couche DAO Opérations CRUD (Create, Retrieve, Update, Delete) liées aux objets métier 6
Modèle conceptuel des données 7 Traduction en modèle relationnel CLIENTS CODE_CLIENT NOM PRENOM ADRESSE... 1234 DUPONT JEAN 12 RUE MACHIN GRENOBLE 1567 DURAND ANNE 2 IMPASSE TRUC ANNECY COMPTES PK PK FK NUMERO SOLDE DEBITMAX DECOUVERTMAX INTITULE TITULAIRE 56787 2567,90 1000 500 COMPTE DEPOT 1234 57890-107,50 1500 1000 COMPTE DEPOT 1567 47891 3000,50 1500 1000 COMPTE DEPOT 1567... PROCURATIONS FK FK CODE_CLIENT NUMERO 1234 57891 1567 56787 1234 47891... 8
Traduction en modèle relationnel Une autre modélisation possible. PK CLIENTS PK COMPTES FK CODE_CLIENT NOM PRENOM ADRESSE NUMERO SOLDE DEBITMAX DECOUVERTMAX INTITULE TITULAIRE 1234 DUPONT JEAN 12 RUE MACHIN GRENOBLE 56787 2567,90 1000 500 COMPTE DEPOT 1234 1567 DURAND ANNE 2 IMPASSE TRUC ANNECY 57890-107,50 1500 1000 COMPTE DEPOT 1567... 47891 3000,50 1500 1000 COMPTE DEPOT 1567... ACCES_COMPTES FK FK CODE_CLIENT NUMERO 1234 56787 V 1234 57891 1567 56787 1234 47891... TITULAIRE F F F Mais la première semble plus facile pour garantir la contrainte qu'un compte à un titulaire et un seul première solution retenue 9 Code SQL de création de la base CREATE TABLE CLIENTS (CODE_CLIENT INTEGER NOT NULL, NOM VARCHAR2(32) NOT NULL, PRENOM VARCHAR2(32) NOT NULL, ADRESSE VARCHAR2(50), PASSWD VARCHAR2(8), PRIMARY KEY (CODE_CLIENT)); CREATE TABLE COMPTES (NUMERO INTEGER NOT NULL, SOLDE FLOAT NOT NULL, DEBITMAX FLOAT NOT NULL, DECOUVERTMAX FLOAT NOT NULL, INTITULE VARCHAR2(32) NOT NULL, TITULAIRE FLOAT NOT NULL, PRIMARY KEY (NUMERO)); ALTER TABLE COMPTES ADD FOREIGN KEY (TITULAIRE) REFERENCES CLIENTS(CODE_CLIENT); CREATE TABLE PROCURATIONS (CODE_CLIENT INTEGER NOT NULL, NUMERO INTEGER NOT NULL); ALTER TABLE PROCURATIONS ADD FOREIGN KEY (CODE_CLIENT) REFERENCES CLIENTS(CODE_CLIENT); ALTER TABLE PROCURATIONS ADD FOREIGN KEY (NUMERO) REFERENCES COMPTES(NUMERO); INSERT INTO CLIENTS (CODE_CLIENT, NOM, PRENOM, ADRESSE, PASSWD) VALUES ('1003', 'LEHERO', 'Toto', '234 Rue Machin GRENOBLE', 'toto1003'); INSERT INTO CLIENTS (CODE_CLIENT, NOM, PRENOM, ADRESSE, PASSWD) VALUES ('1001', 'DUPOND', 'Jean', '23 Rue du Lac GRENOBLE', 'toto1001'); INSERT INTO CLIENTS (CODE_CLIENT, NOM, PRENOM, ADRESSE, PASSWD) VALUES ('1002', 'DURAND', 'Sophie', NULL, 'toto1002'); INSERT INTO COMPTES (NUMERO, SOLDE, DEBITMAX, DECOUVERTMAX, INTITULE, TITULAIRE) VALUES ('5203', '2320', '1000', '1000', 'Compte de dépot', '1002'); INSERT INTO COMPTES (NUMERO, SOLDE, DEBITMAX, DECOUVERTMAX, INTITULE, TITULAIRE) VALUES ('5204', '2199', '1000', '500', 'Livret A', '1002'); INSERT INTO COMPTES (NUMERO, SOLDE, DEBITMAX, DECOUVERTMAX, INTITULE, TITULAIRE) VALUES ('5205', '5500', '1000', '1000', 'Compte de dépot', '1003'); INSERT INTO COMPTES (NUMERO, SOLDE, DEBITMAX, DECOUVERTMAX, INTITULE, TITULAIRE) VALUES ('5201', '1600', '500', '500', 'Compte de dépot', '1001'); INSERT INTO COMPTES (NUMERO, SOLDE, DEBITMAX, DECOUVERTMAX, INTITULE, TITULAIRE) VALUES ('5202', '3100', '1000', '700', 'Livret A', '1001'); INSERT INTO PROCURATIONS (CODE_CLIENT, NUMERO) VALUES ('1002', '5202'); INSERT INTO PROCURATIONS (CODE_CLIENT, NUMERO) VALUES ('1001', '5204'); INSERT INTO PROCURATIONS (CODE_CLIENT, NUMERO) VALUES ('1001', '5205'); 10
Objets métier : la classe Compte Modélisation sans tenir compte l'association avec Client Accesseurs et modifieurs (getters et setters) Opérations "métier" Certaines opérations peuvent lever des exceptions. Définition d'une classe d'exception sur les comptes 11 Objets métier : la classe Compte Prise en compte de l'association avec Client Ajout d'un attribut? private Client titulaire Ajout d'un paramètres au constructeur? Client titulaire Ajout d'un accesseur? Client gettitulaire() Quand un Compte est chargé son titulaire doit-il être chargé? Quand un Client est chargé tous les Comptes auxquels il a accès doiventils être chargés? Risque de créer en cascade beaucoup d'objets inutiles 12
Objets métier : la classe Compte Prise en compte de l'association avec Client Ne pas conserver l'association Compte Client au niveau du modèle objet Ajout de deux attributs private int idtitulaire private String nomtitulaire Ajout de deux paramètres au constructeur int idtitulaire String nomtitulaire Ajout de deux accesseurs int getidtitulaire() String getnomtitulaire() 13 Objets métier : la classe Client 14
Objet DAO pour les Comptes Définir une interface ICompteDAO On pourra avoir ensuite plusieurs implémentations OracleCompteDAO pourr SGB Oracle MySQLCompteDAO pour SGBD MySQL Le code qui utilise les objets DAO utilise l'interface il ne dépend pas des implémentations 15 Objet DAO pour les Comptes interface ICompteDAO opérations CRUD (Create, Retrieve, Update, Delete) pour l'application Banque IMA seules des opérations Retrieve et Update sont nécessaires charger un compte à partir de son numéro public Compte retreive(int numero) enregistrer le solde d'un compte public Compte updatesolde(compte cpt) 16
Objet DAO pour les Comptes interface ICompteDAO les méthodes du DAO effectuent des entrées/sorties (dans notre cas accès à la BD) elles peuvent donc lancer des exceptions (SQLException) public Compte retreive(int numero) throws SQLEXception? public Compte updatesolde(compte cpt) throws SQLEXception? pas une bonne idée : si on veut pouvoir changer facilement de DAO il ne faut pas lier les exceptions à un type de DAO particulier 17 Objet DAO pour les Comptes interface ICompteDAO création d'une classe d'exception indépendante du type de DAO (DAOException) les méthodes d'implémentation des DAO attrapent les exceptions particulières (par exemple SQLException) et relancent des DAOException les exceptions d'origine sont chaînées aux DAOException 18
Objet DAO pour les Comptes Gestion des connexions JDBC Un attribut connexion créé (et donc ouvert) à la création de l'objet DAO? Possibles problèmes de timeout. La connexion peut être fermée automatiquement. Risques d'incohérences si multithreading (par exemple si il y a des transactions). Une connexion ouverte au début de chaque méthode du DAO et fermée à la fin de chaque méthode? Ouverture d'une connexion opération très coûteuse. Une solution : utilisation d'un pool de connexions. 19 Objet DAO pour les Comptes La classe d'implémentation aura un attribut DataSource que cette méthode permet d'initialiser 20
Objet DAO pour les Comptes interface ICompteDAO suite 21 L'API des objets DAO API publique package bima.dao implémentation privée package bima.dao.oracle 22
L'API des objets DAO Fabrique abstraite package bima.dao implémentations packages bima.dao.oracle et bima.dao.mysql 23 La DataSource javax.sql.datasource est une interface. Pas d'implémentation dans JSE typiquement gérée et crée par un conteneur d'application JEE (exemple conteneur web TOMCAT) Comment faire pour tester simplement nos DAO sans déployer un serveur d'application? utilisation d'une classe simulant une DataSource (c.a.d. qui implémente l'interface javax.sql.datasource) classe DataSourceDeTest 24
Travail à effectuer Réalisez une classe OracleCompteDAO qui implémente l'interface ICompteDAO Testez cette classe réfléchir sur la manière de procéder pour la tester Si du temps réfléchir aux problèmes soulevés par l'opération de Transfert? l'api ICompteDAO est-elle adaptée pour celle-ci? Quel enrichissement proposez vous? Implémenter et tester votre nouvelle API. 25 Travail a effectuer Une fois votre classe CompteDAO testée indépendamment la tester dans un serveur Tomcat 1) Créer une application Web sous NetBeans 26
Travail a effectuer 2) configurer cette application de manière à ce qu'elle définisse une source de données JDBC (javax.sql.datasource) qui sera gérée par Tomcat <Context path="/bima"> <Context path="/bima"> <Resource name="jdbc/bima" <Resource name="jdbc/bima" auth="container" auth="container" type="javax.sql.datasource" type="javax.sql.datasource" maxactive="10" maxactive="10" maxidle="3" maxidle="3" maxwait="10000" maxwait="10000" username="genoud" username="genoud" password="xxxxxxx" password="xxxxxxx" driverclassname="oracle.jdbc.oracledriver" driverclassname="oracle.jdbc.oracledriver" url="jdbc:oracle:thin:@hopper.e.ujf-grenoble.fr:1521:ufrima"/> url="jdbc:oracle:thin:@hopper.e.ujf-grenoble.fr:1521:ufrima"/> </Context> </Context> Pour en savoir plus voir le document... <servlet-mapping>... </servlet-mapping> <resource-ref> <res-ref-name>jdbc/bima</res-ref-name> <res-type>javax.sql.datasource</res-type> <res-auth>container</res-auth> </resource-ref>... http://www.inrialpes.fr/helix/people/genoud/ensjava/cours/supportspdf/datasource_2pp.pdf 27 Travail a effectuer 2) dans cette application créer une servlet 28
Travail à effectuer modifier le code de la servlet de manière à ce que : à son initialisation elle récupère dans un variable d'instance la référence de la data source correspondant à votre base de données pour la banque IMA. dans sa méthode de traitement de la requête HTTP elle récupère un paramètre : un numéro de compte en banque elle construit à l'aide de la classe OracleCompteDAO un objet Compte correspondant au numéro récupéré dans la requête HTTP elle renvoie une page HTML présentant les différentes infos liées à ce compte 29 L'application BIMA_V0 POST numero_compte=5201 1 3 CompteServlet 2 Compte création d'un objet Compte à partir des données contenues dans la base construction et renvoi d'un page HTML à partir des données de l'objet Compte 30
Structure du projet BIMA_V0 pages HTML (statiques) correspondant à une maquette de l'application fichiers de configuration de l'application Web package bima.dao : classes et interfaces publiques pour les DAO package bima.dao.mysql : implémentation (privée) des DAO pour une base MySQL (non terminée) package bima.dao.oracle : implémentation (privée) des DAO pour une base Oracle package bima.model : objets "métier" pour les Clients et Comtpes package bima.servlets : servlets de l'application Web 31 Enrichissement de BIMA_V0 Page d'accueil Retour à la page de login en indiquant la cause de l'échec 1 Page liste des comptes échec Authentification de l'utilisateur ok Affiche la liste des comptes accessibles par le client <JSP > accueil.html redirection vers la page d'accueil redirection vers la page d'accueil POST client_id="5000" passwd="monmotdepasse" échec 1 Authentification de l'utilisateur LoginServlet.java Récupérer les paramètres Récupérer les paramètres de la requête de la requête 2 ok 3 redirection vers listecomptes.jsp redirection vers listecomptes.jsp Création à partir de client_id et passwd Création à partir de client_id et passwd d'un objet Client d'un objet Client Enregistrement de ce Client dans la session Enregistrement de ce Client dans la session Client <JSP > listecomptes.jsp 32
Enrichissement de BIMA_V0 Déconnexion LogoutServlet L'utilisateur n'a plus accès à l'application à moins de repasser par la phase d'authentification Rediriger vers la page Bye.jsp en plaçant le nom et Rediriger vers la page Bye.jsp en plaçant le nom et prénom de l'utilisateur comme attributs de la prénom de l'utilisateur comme attributs de la requête requête Terminer la session Terminer la session nom="dupont" prenom="jean" Page de déconnexion <JSP > Bye.jsp 33 Enrichir l'application Web récupérer la maquette HTML de l'application mettre en œuvre le début de l'application login et accès à liste des comptes du client 34