application web de gestion de comptes en...
TRANSCRIPT
1Philippe GENOUD © UJF Grenoble – janvier 2009
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
2Philippe GENOUD © UJF Grenoble – janvier 2009
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
3Philippe GENOUD © UJF Grenoble – janvier 2009
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
4Philippe GENOUD © UJF Grenoble – janvier 2009
Authentificationde l'utilisateur
Retour à la page de login en indiquant la cause de l'échec
Réalisation dutransfert
Page indiquant si le transfert a réussi ou nonEt en cas d'échec la raison de ce dernier
Affiche la liste des comptes accessibles par le client
Permet de sélectionnerle compte source et le compte destinationet le montant du transfert
Page d'accueilPage liste des comptes
Page affichage desrésultats du transfert
Page pour effectuer un transfert
Page de déconnexion
1111
2222
1111
2222
2222
ok
échec
1111
An
nex
e 3 : in
terface d
e l'ap
plica
tion
Ban
qu
e IMA
on
line
Déconnexion
L'utilisateur n'a plus accès à l'application à moins de repasser par la phase d'authentification
Interface et fonctionnement de l'application
5Philippe GENOUD © UJF Grenoble – janvier 2009
Composants Java de l'application
SGBDRelationnelNavigateur
Serveur d'application Java
présentation métier Accèsaux données
Servlets
Pages JSP
Client
Compte
ClientDAO
CompteDAO
• 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
JD
BC
6Philippe GENOUD © UJF Grenoble – janvier 2009
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
7Philippe GENOUD © UJF Grenoble – janvier 2009
Modèle conceptuel des données
8Philippe GENOUD © UJF Grenoble – janvier 2009
Traduction en modèle relationnel
NUMERO SOLDE DEBITMAX DECOUVERTMAX
56787 2567,90 1000 500 COMPTE DEPOT 1234
57890 -107,50 1500 1000 COMPTE DEPOT 1567
INTITULE
47891 3000,50 1500 1000 COMPTE DEPOT 1567
TITULAIRE
... … … … … …
COMPTESCODE_CLIENT NOM PRENOM ADRESSE
1234 DUPONT JEAN 12 RUE MACHIN GRENOBLE
1567 DURAND ANNE 2 IMPASSE TRUC ANNECY
... …… …
CLIENTS
CODE_CLIENT NUMERO
1234 57891
1567 56787
1234 47891
PROCURATIONS
PK PK FK
FKFK
... …
9Philippe GENOUD © UJF Grenoble – janvier 2009
Traduction en modèle relationnel
CODE_CLIENT NOM PRENOM ADRESSE
1234 DUPONT JEAN 12 RUE MACHIN GRENOBLE
1567 DURAND ANNE 2 IMPASSE TRUC ANNECY
... …… …
... … … … … …
CLIENTSPK
NUMERO SOLDE DEBITMAX DECOUVERTMAX
56787 2567,90 1000 500 COMPTE DEPOT 1234
57890 -107,50 1500 1000 COMPTE DEPOT 1567
INTITULE
47891 3000,50 1500 1000 COMPTE DEPOT 1567
TITULAIRE
COMPTESPK FK
CODE_CLIENT NUMERO
1234 57891
1567 56787
... …
1234 47891
ACCES_COMPTESFK
FK
1234 56787 V
F
F
F
TITULAIRE
Une autre modélisation possible.
Mais la première semble plus facile pour garantir la contrainte qu'un compte à un titulaire et un seul
���� première solution retenue
10Philippe GENOUD © UJF Grenoble – janvier 2009
Code SQL de création de la baseCREATE 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');
11Philippe GENOUD © UJF Grenoble – janvier 2009
Objets métier : la classe Compte
Accesseurs et modifieurs
(getters et setters)
Opérations "métier"
Modélisation sans tenir compte l'association avec Client
Certaines opérations peuvent lever des exceptions. Définition d'une classe d'exception sur les comptes
12Philippe GENOUD © UJF Grenoble – janvier 2009
Objets métier : la classe ComptePrise 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 doivent-ils être chargés ? Risque de créer en cascade beaucoup d'objets inutiles
13Philippe GENOUD © UJF Grenoble – janvier 2009
Objets métier : la classe ComptePrise 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 constructeurint idTitulaire
String nomTitulaire
Ajout de deux accesseursint getIdTitulaire()
String getNomTitulaire()
14Philippe GENOUD © UJF Grenoble – janvier 2009
Objets métier : la classe Client
15Philippe GENOUD © UJF Grenoble – janvier 2009
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
16Philippe GENOUD © UJF Grenoble – janvier 2009
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)
17Philippe GENOUD © UJF Grenoble – janvier 2009
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)
public Compte updateSolde(Compte cpt)
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
throws SQLEXception ?
throws SQLEXception ?
18Philippe GENOUD © UJF Grenoble – janvier 2009
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
19Philippe GENOUD © UJF Grenoble – janvier 2009
Objet DAO pour les Comptes
• Gestion des connexions JDBC
– Un attribut connexion créé (et donc ouvert) à la
création de l'objet DAO ?
– Une connexion ouverte au début de chaque méthode
du DAO et fermée à la fin de chaque méthode ?
– …
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).
Ouverture d'une connexion opération très coûteuse.
Une solution : utilisation d'un pool de connexions.
20Philippe GENOUD © UJF Grenoble – janvier 2009
Objet DAO pour les Comptes
La classe d'implémentationaura un attribut DataSourceque cette méthode permet d'initialiser
21Philippe GENOUD © UJF Grenoble – janvier 2009
Objet DAO pour les Comptes
interface ICompteDAO … suite …
22Philippe GENOUD © UJF Grenoble – janvier 2009
L'API des objets DAO
API publique
packagebima.dao
implémentation privée
packagebima.dao.oracle
23Philippe GENOUD © UJF Grenoble – janvier 2009
L'API des objets DAO
Fabrique abstraite
packagebima.dao
implémentations
packagesbima.dao.oracle
etbima.dao.mysql
24Philippe GENOUD © UJF Grenoble – janvier 2009
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
25Philippe GENOUD © UJF Grenoble – janvier 2009
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.
26Philippe GENOUD © UJF Grenoble – janvier 2009
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
27Philippe GENOUD © UJF Grenoble – janvier 2009
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
...
<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>
...
<Context path="/BIMA">
<Resource name="jdbc/BIMA"
auth="Container"
type="javax.sql.DataSource"
maxActive="10"
maxIdle="3"
maxWait="10000"
username="genoud"
password="xxxxxxx"
driverClassName="oracle.jdbc.OracleDriver"
url="jdbc:oracle:thin:@hopper.e.ujf-grenoble.fr:1521:ufrima"/>
</Context>
<Context path="/BIMA">
<Resource name="jdbc/BIMA"
auth="Container"
type="javax.sql.DataSource"
maxActive="10"
maxIdle="3"
maxWait="10000"
username="genoud"
password="xxxxxxx"
driverClassName="oracle.jdbc.OracleDriver"
url="jdbc:oracle:thin:@hopper.e.ujf-grenoble.fr:1521:ufrima"/>
</Context>
Pour en savoir plus voir le document
http://www.inrialpes.fr/helix/people/genoud/ENSJAVA/cours/supportsPDF/DataSource_2pp.pdf
28Philippe GENOUD © UJF Grenoble – janvier 2009
Travail a effectuer
2) dans cette application créer une servlet
29Philippe GENOUD © UJF Grenoble – janvier 2009
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
30Philippe GENOUD © UJF Grenoble – janvier 2009
CompteServlet
POSTnumero_compte=52011
2Compte
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
3
L'application BIMA_V0
31Philippe GENOUD © UJF Grenoble – janvier 2009
pages HTML (statiques) correspondant à une maquette de l'application
package bima.dao : classes et interfaces publiques pour les DAO
package bima.dao.oracle : implémentation (privée) des DAO pour une base Oracle
package bima.dao.mysql :implémentation (privée) des DAO pour une base MySQL (non terminée)
package bima.model : objets "métier" pour les Clients et Comtpes
fichiers de configuration del'application Web
package bima.servlets : servletsde l'application Web
Structure du projet BIMA_V0
32Philippe GENOUD © UJF Grenoble – janvier 2009
Authentificationde l'utilisateur
Retour à la page de login en indiquant la cause de l'échec
Affiche la liste des comptes accessibles par le client
Page d'accueilPage liste des comptes1111
ok
échec
POST
client_id="5000"
passwd="monMotDePasse"
Authentificationde l'utilisateur
Création à partir de client_id et passwdd'un objet ClientEnregistrement de ce Client dans la session
Création à partir de client_id et passwdd'un objet ClientEnregistrement de ce Client dans la session
listeComptes.jspaccueil.html
LoginServlet.java
redirection vers la page d'accueilredirection vers la page d'accueil
Récupérer les paramètresde la requête
Récupérer les paramètresde la requête
<JSP …>…
<JSP …>…
échec ok
redirection vers listeComptes.jspredirection vers listeComptes.jsp
12
3
Client
Enrichissement de BIMA_V0
33Philippe GENOUD © UJF Grenoble – janvier 2009
Page de déconnexion
Déconnexion
L'utilisateur n'a plus accès à l'application à moins de repasser par la phase d'authentification
Bye.jsp
<JSP …>…
<JSP …>…
LogoutServlet Rediriger vers la page Bye.jsp en plaçant le nom et prénom de l'utilisateur comme attributs de la requêteTerminer la session
Rediriger vers la page Bye.jsp en plaçant le nom et prénom de l'utilisateur comme attributs de la requêteTerminer la session
nom="DUPONT"
prenom="Jean"
Enrichissement de BIMA_V0
34Philippe GENOUD © UJF Grenoble – janvier 2009
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