• Aucun résultat trouvé

Transparents(PowerPoint

N/A
N/A
Protected

Academic year: 2022

Partager "Transparents(PowerPoint"

Copied!
95
0
0

Texte intégral

(1)

27/02/22 © Robert Godin. Tous droits réser vés.

1

15 Développement d'application de

base de données en Java

(2)

Patron d'architecture en couche (layer)

 Couche présentation

 Couche contrôle (coordonnateur d'application)

 Couche domaine d'application (ou métier)

 Couche de services.

– persistance

– transaction

– communication

– sécurité

– etc.

(3)

27/02/22 © Robert Godin. Tous droits réser vés.

3

15.1 Application Java/JDBC client-serveur

R é s e a u

L o g i c i e l i n t e r m é d i a i r e

P i l o t e d e t é l é c o m m u n i c a t i o n

P r o g r a m m e d 'a p p l i c a t i o n

L o g i c i e l i n t e r m é d i a i r e

P i l o t e d e t é l é c o m m u n i c a t i o n

S G B D

C l i e n t S e r v e u r

B D

P r o g r a m m e d 'a p p l i c a t i o n : - p r é s e n t a t i o n

- c o n t r ô l e

- d o m a i n e d 'a p p l i c a t i o n

S G B D

- p e r s i s t e n c e

- p a r t i e d u d o m a i n e d 'a p p l i c a t i o n ?

C l i e n t S e r v e u r

(4)

Cas d ’utilisation EnregistrerPrêts

Commis au prêt Système

1. Le commis invoque l'écran d'enregistrement du prêt

2. Le système demande la saisie de l'identificateur de l'utilisateur

3. Le commis saisit l'identificateur de l'utilisateur à l'aide de la carte de membre ou manuellement

4. Le système affi che le nombre de prêts en cours et demande de saisir l'identificateur de l'exemplaire.

5. Le commis entre l'identificateur de l'exemplaire à l'aide du lecteur optique ou manuellement

6. Le système enregistre le prêt, affi che un message

d'acquiescement.

(5)

27/02/22 © Robert Godin. Tous droits réser vés.

5

Cas de test pour scénario normal

(6)

Cas d ’exception : nombre maximal

d'emprunts (ici 2) atteint

(7)

27/02/22 © Robert Godin. Tous droits réser vés.

7

Cas d ’exception : exemplaire

non disponible

(8)

Cas d'utilisation et classes métiers concernées

Personne nom : String prénom : String

Membre

téléphoneRésidence : String nbMaxPrêts : Integer = 5 duréeMaxPrêts : Integer = 7

PrêtEnCours Employé

{UNIQUE : codeMatricule}

codeMatricule : String

catégorieEm ployé : enum (b ibliothécaire, co mm is ) catégorieUtilisateur

Exemplaire {UNIQUE: idExemplaire}

idExemplaire : String dateAchat : Date

statut : enum(prêté, disponible, retiré)

Prêt datePrêt : Date

1 0..*

1 0..*

Utilisateur {UNIQUE :idUtilisateur}

idUtilisateur : String

motPasse : String 11 0..*0..*

{disjointe, complète}

{disjointe, complète}

EnregistrerPrêts

(from PackageCasServicePrêt)

(9)

27/02/22 © Robert Godin. Tous droits réser vés.

9

Patron courtier BD : classes du

programme Java et tables concernées

Membre

té léph oneRésidence : String nbMaxPrêts : Integer = 5 duréeMaxPrêts : Integer = 7

PrêtEnCours Utilisateur

idUtilisateur : String m otPasse : String catégorie : String lesPrêts : Vector

CourtierBDUtilisateur

ch erch erVari ables Stati quesDeMem bre() ch erch erUtili sateu rParIdUti lisateur()

Table Utilisateur

Table Mem bre Table Mem breGénéral

Table Prêts EnCours Table Exem plaire

CourtierBDPrêtsEnCou rs chercherLesPrêtsEnCours() insérerPrêtEnCours ()

Courtie rBDExem plaire che rche rExem plai reParId Exem plaire() Prêt

datePrêt : Date

lExem plaire : Exem plaire lUtilisateur : Utilisateur

Exem plaire idExem plaire : String statut : String Person ne

nom : Stri ng préno m : String

Em ployé {UNIQUE : codeMatricule}

codeMatricule : String

catégorieEm ployé : enum (bibliothécaire, com m is)

Table Em p loyé

~ Data Access Object

(DAO) + Domain Data

Transfer Object

(10)

Classe Java pour Personne

package ExemplesJDBC.SyLeRat;

public class Personne { protected String nom;

protected String prénom;

public Personne(String nom,String prénom) { this.nom = nom;

this.prénom = prénom;

}

public String getNom(){return nom;}

public String getPrénom(){return prénom;}

public void setNom(String nom){this.nom = nom;}

public void setPrénom(String prénom){this.prénom = prénom;}

}

Lecteurs/modifieurs pour attributs

(peut en faire un Java Bean)

(11)

27/02/22 © Robert Godin. Tous droits réser vés.

11

Classe Java pour Utilisateur

package ExemplesJDBC.SyLeRat;

import java.util.*;

public class Utilisateur extends Personne { protected String idUtilisateur;

protected String motPasse;

protected String catégorie;

protected Vector lesPrêts; // Association avec Prêt // NB Ce constructeur de crée pas lesPrêts

public Utilisateur(String idUtilisateur, String motPasse, String nom, String prénom, String catégorie){

super(nom,prénom);

this.idUtilisateur = idUtilisateur;

this.motPasse = motPasse;

this.catégorie = catégorie;

}

public String getIdUtilisateur(){return idUtilisateur;}

public String getMotPasse(){return motPasse;}

public String getCatégorie(){return catégorie;}

public Vector getLesPrêts(){return lesPrêts;}

public int getNbPrêtsEnCours(){

Enumeration enumerationPrêts = lesPrêts.elements();

int nbPrêtsEnCours = 0;

while (enumerationPrêts.hasMoreElements()){

Prêt unPrêt = (Prêt)enumerationPrêts.nextElement();

if (unPrêt instanceof PrêtEnCours){

nbPrêtsEnCours++;

} }

return nbPrêtsEnCours;

}

public void setIdUtilisateur(String idUtilisateur){this.idUtilisateur = idUtilisateur;}

public void setMotPasse(String motPasse){this.motPasse = motPasse;}

public void setCatégorie(String catégorie){this.catégorie = catégorie;}

public void setLesPrêts(Vector lesPrêts){this.lesPrêts = lesPrêts;}

}

Lecteur pour donnée dérivée

Lecteurs/modifieurs

pour naviguer les

associations

(12)

Classe Java pour Membre

package ExemplesJDBC.SyLeRat;

import java.util.*;

public class Membre extends Utilisateur { private static int nbMaxPrêts;

private static int duréeMaxPrêt;

private String téléphoneRésidence;

public Membre(String idUtilisateur, String motPasse, String nom, String prénom, String catégorie, String téléphoneRésidence){

super(idUtilisateur, motPasse, nom, prénom, catégorie);

this.téléphoneRésidence = téléphoneRésidence;

}

public static int getNbMaxPrêts(){return nbMaxPrêts;}

public static int getDuréeMaxPrêt(){return duréeMaxPrêt;}

public static void setNbMaxPrêts(int leNbMaxPrêts){nbMaxPrêts = leNbMaxPrêts;}

public static void setDuréeMaxPrêts(int laDuréeMaxPrêt){duréeMaxPrêt = laDuréeMaxPrêt;}

public void setTéléphoneRésidence(String téléphoneRésidence) {this.téléphoneRésidence = téléphoneRésidence;}

public String getTéléphoneRésidence(){return téléphoneRésidence;}

public int getNbRetards(){

Enumeration enumerationPrêts = lesPrêts.elements();

int nbRetards = 0;

Calendar maintenant = Calendar.getInstance(); // Calendrier avec date actuelle // Soustrait ensuite la durée maximale en jours pour obtenir la date minimale // avant laquelle il y a un retard

maintenant.add(Calendar.DATE,-duréeMaxPrêt);

java.sql.Date dateMinSansRetard = new java.sql.Date(maintenant.getTime().getTime());

while (enumerationPrêts.hasMoreElements()){

Prêt unPrêt = (Prêt)enumerationPrêts.nextElement();

if (unPrêt instanceof PrêtEnCours){

if (dateMinSansRetard.after(unPrêt.getDatePrêt())){

nbRetards++;

} } }

return nbRetards;

}

public boolean conditionsPrêtAcceptées(){

Attributs et méthodes

static pour attributs de

classe (ou singleton)

(13)

27/02/22 © Robert Godin. Tous droits réser vés.

13

Classe Java pour Employé

package ExemplesJDBC.GererPrets;

import java.util.*;

public class Employé extends Utilisateur { private String codeMatricule;

private String catégorieEmployé;

public Employé(String idUtilisateur, String motPasse, String nom,

String prénom, String catégorie, String codeMatricule, String catégorieEmployé){

super(idUtilisateur, motPasse, nom, prénom, catégorie);

this.codeMatricule = codeMatricule;

this.catégorieEmployé = catégorieEmployé;

}

public String getCodeMatricule(){return codeMatricule;}

public String getCatégorieEmployé(){return catégorieEmployé;}

public void setCodeMatricule(String codeMatricule) {this.codeMatricule = codeMatricule;}

public void setCatégorieEmployé(String catégorieEmployé) {this.catégorieEmployé = catégorieEmployé;}

}

(14)

Classe Java pour Prêt

package ExemplesJDBC.SyLeRat;

import java.sql.Date;

public class Prêt {

protected Utilisateur lUtilisateur;

protected java.sql.Date datePrêt;

protected Exemplaire lExemplaire;

public Prêt(Utilisateur lUtilisateur,java.sql.Date datePrêt, Exemplaire lExemplaire) { this.lUtilisateur = lUtilisateur;

this.datePrêt = datePrêt;

this.lExemplaire = lExemplaire;

}

public java.sql.Date getDatePrêt(){return datePrêt;}

public String getIdExemplaire(){return lExemplaire.getIdExemplaire();}

public String getIdUtilisateur(){return lUtilisateur.getIdUtilisateur();}

}

(15)

27/02/22 © Robert Godin. Tous droits réser vés.

15

Classe Java pour PrêtEnCours

package ExemplesJDBC.GererPrets;

public class PrêtEnCours extends Prêt {

public PrêtEnCours(Utilisateur lUtilisateur,java.sql.Date datePrêt, Exemplaire lExemplaire) {

super(lUtilisateur,datePrêt,lExemplaire);

}

// Le constructeur suivant ne construit pas le lien vers Exemplaire public PrêtEnCours(Utilisateur lUtilisateur,java.sql.Date datePrêt) { super(lUtilisateur,datePrêt,null);

}

}

(16)

Classe Java pour Exemplaire

package ExemplesJDBC.SyLeRat;

public class Exemplaire {

private String idExemplaire;

private String statut;

public Exemplaire(String idExemplaire,String statut) { this.idExemplaire = idExemplaire;

this.statut = statut;

}

public String getStatut(){return statut;}

public String getIdExemplaire(){return idExemplaire;}

}

(17)

27/02/22 © Robert Godin. Tous droits réser vés.

17

CourtierBDUtilisateur

package ExemplesJDBC.GererPrets;

import java.sql.*;

import java.util.*;

public class CourtierBDUtilisateur{

private Connection uneConnection;

// Constructeur pour connexion passée par le créateur public CourtierBDUtilisateur(Connection laConnection){

this.uneConnection = laConnection;

}

public Utilisateur chercherUtilisateurParIdUtilisateur(String idUtilisateur) // Retourne un objet Membre ou un Employé selon le cas

throws Exception {

// Verrouillage de l'utilisateur pour sérialisabilité (Oracle mode READ COMMITTED) PreparedStatement unEnoncéSQL = uneConnection.prepareStatement

("SELECT motPasse,nom,prénom,catégorieUtilisateur,téléphoneRésidence,codeMatricule,catégorieEmployé "+

"FROM Membre m, Utilisateur u, Employé e WHERE u.idUtilisateur = ? AND "+

"u.idUtilisateur = m.idUtilisateur (+) AND "+

"u.idUtilisateur = e.idUtilisateur (+) FOR UPDATE");

unEnoncéSQL.setString(1,idUtilisateur);

ResultSet résultatSelect = unEnoncéSQL.executeQuery();

if (résultatSelect.next ()){

if (résultatSelect.getString ("catégorieUtilisateur").equals("membre")){

Membre leMembre = new Membre(

idUtilisateur,résultatSelect.getString ("motPasse"),

résultatSelect.getString ("nom"),résultatSelect.getString ("prénom"), résultatSelect.getString ("catégorieUtilisateur"),

résultatSelect.getString ("téléphoneRésidence"));

unEnoncéSQL.close();

return leMembre;

}

else{// Pas un Membre, doit être un Employé

Employé lEmployé = new Employé(idUtilisateur,résultatSelect.getString ("motPasse");

(18)

Diagramme de séquence pour CourtierBDUtilisateur

: ContrôleEnregistrerPrêts : CourtierBDUtilisateur

:java.sql .Connection

:java.sql.Statement

: Membre

: Em pl oyé 2. chercherUtilisateur(idUtilisateur)

1. «create»(uneConnection)

3. prepareStatement()

4. executeQuery()

5. [catégorie = 'membre']«create»

7. unU til isateur

6. [catégorie='employé']«create»

(19)

27/02/22 © Robert Godin. Tous droits réser vés.

19

Classe UsineConnection

package ExemplesJDBC.GererPrets;

import java.sql.*;

public class UsineConnection { public UsineConnection() {}

public Connection getConnectionSansAutoCommit(

String nomPilote, // "oracle.jdbc.driver.OracleDriver" pour Oracle

String URLBD, // exemple : "jdbc:oracle:thin:@localhost:1521:ora817i"

String authorizationID, String password)

throws Exception {

Class.forName (nomPilote);

Connection uneConnection = DriverManager.getConnection (URLBD, authorizationID,password);

uneConnection.setAutoCommit(false);

return uneConnection;

}

public Connection getConnection(

String nomPilote, // "oracle.jdbc.driver.OracleDriver" pour Oracle

String URLBD, // exemple : "jdbc:oracle:thin:@localhost:1521:ora817i"

String authorizationID, String password)

throws Exception {

Class.forName (nomPilote);

Connection uneConnection = DriverManager.getConnection (URLBD, authorizationID,password);

return uneConnection;

}

}

(20)

Courtier CourtierBDPrêtEnCours : chercherLesPrêtsEnCours

package ExemplesJDBC.GererPrets;

import java.sql.*;

import java.util.*;

public class CourtierBDPrêtEnCours { private Connection uneConnection;

public void chercherLesPrêtsEnCours(Utilisateur unUtilisateur) // Dématérialiser les PrêtEnCours d'un Utilisateur

throws Exception{

// Verrouiller la table des prêts en cours pour sérialisabilité // (Oracle mode READ COMMITTED)

PreparedStatement unEnoncéLock = uneConnection.prepareStatement(

"LOCK TABLE PrêtEnCours IN SHARE ROW EXCLUSIVE MODE");

unEnoncéLock.execute();

unEnoncéLock.close();

PreparedStatement unEnoncéSQL = uneConnection.prepareStatement ("SELECT datePrêt,idExemplaire "+

"FROM PrêtEnCours WHERE idUtilisateur = ? " );

String idUtilisateur = unUtilisateur.getIdUtilisateur();

unEnoncéSQL.setString(1,idUtilisateur);

ResultSet résultatSelect = unEnoncéSQL.executeQuery();

// lesPrêts contiendra la collection des objets PrêtEnCours Vector lesPrêts = new Vector();

while (résultatSelect.next ()){

PrêtEnCours unPrêt = new PrêtEnCours(unUtilisateur,résultatSelect.getDate(1));

lesPrêts.addElement(unPrêt);

}

// Faire les références inverses ! unUtilisateur.setLesPrêts(lesPrêts);

unEnoncéSQL.close();

}

… }

(21)

27/02/22 © Robert Godin. Tous droits réser vés.

21

Matérialisation d ’un PrêtEnCours : insérerPrêtEnCours

package ExemplesJDBC.GererPrets;

import java.sql.*;

import java.util.*;

public class CourtierBDPrêtEnCours { private Connection uneConnection;

public void insérerPrêtEnCours (PrêtEnCours unPrêtEnCours) // Matérialise un nouveau PrêtEnCours dans la BD

throws Exception, SQLException {

PreparedStatement unEnoncéSQL = uneConnection.prepareStatement ("INSERT INTO PrêtEnCours(idExemplaire,idUtilisateur)"+

"VALUES(?,?)");

unEnoncéSQL.setString(1,unPrêtEnCours.getIdExemplaire());

unEnoncéSQL.setString(2,unPrêtEnCours.getIdUtilisateur());

//NB la date est générée automatiquement par le serveur de BD (default sysdate) // et le statut est modifié par un TRIGGER

int n = unEnoncéSQL.executeUpdate();

unEnoncéSQL.close();

if (n != 1){throw new Exception("Insertion dans PrêtEnCours a échoué");}

}

}

(22)

Enjeux de la conception des courtiers

 Granularité des courtiers

 Granularité de

matérialisation/dématérialisation

– minimiser les appels au serveur de BD

– limiter le volume de données à

transférer

(23)

27/02/22 © Robert Godin. Tous droits réser vés.

23

Classe de contrôle

ControleEnregistrerPrets

package ExemplesJDBC.GererPrets;

/* Classe de contrôle simple pour EnregistrerPrêts * Interface à l'utilisateur minimaliste

* NB Vérifie les conditions de prêt et le statut de l'exemplaire au niveau du programme client */

import java.sql.*;

import javax.swing.JOptionPane;

import java.util.*;

class ControleEnregistrerPrets {

public static void main (String args []) throws Exception { // Création d'une Connection globale pour l'application UsineConnection uneUsineConnection = new UsineConnection();

Connection uneConnection = uneUsineConnection.getConnectionSansAutoCommit(

"oracle.jdbc.driver.OracleDriver",

"jdbc:oracle:thin:@localhost:1521:ora817i", "clerat","oracle");

try{

// Dématérialiser l'Utilisateur et ses PrêtsEnCours Membre unMembre = null;

String idUtilisateur =

JOptionPane.showInputDialog("Entrez l'identificateur de l'utilisateur: ");

// Création du courtier et dématérialisation de l'Utilisateur

CourtierBDUtilisateur unCourtierBDUtilisateur = new CourtierBDUtilisateur(uneConnection);

Utilisateur unUtilisateur =

unCourtierBDUtilisateur.chercherUtilisateurParIdUtilisateur(idUtilisateur);

//Création du courtier et dématérialisation des PrêtsEnCours

CourtierBDPrêtEnCours unCourtierBDPrêtEnCours = new CourtierBDPrêtEnCours(uneConnection);

unCourtierBDPrêtEnCours.chercherLesPrêtsEnCours(unUtilisateur);

JOptionPane.showMessageDialog(null,

"Nombre de prêts en cours :" + unUtilisateur.getNbPrêtsEnCours());

(24)

uneTransaction

: Commis au prêt :

ContrôleEnregistrerPrêts :

CourtierBDUtilisateur

: CourtierBDPrêtsEnCours

:

CourtierBDExemplaire : Usin eConnection

uneConnection 2. getConnexionSansAutoCommit( )

4. uneConnection

9. «create»(uneConnection) 10 . chercherLesPrêtsEnCours(un Utilisateur )

18. insérerPrêtEnCou rs (unPrêtEnCours) 7. chercherUtilisateur(idUtilisateur)

12. chercherVariablesStatiquesDeMembre( ) 6. «cre ate»(uneConnection)

15. «create»(uneConnection) 16. chercherExem plaire (i dExemplaire )

3. «create»

8. prepareStatement()

11. prepareStatement()

13. prepareStatement()

17. prepareStatement()

20. commit() 21. close() 1. créerNouveauPrêt()

5 . entrer(idUtilisateur)

14. entrer(i dExempl aire)

19. prepapreStatement()

(25)

27/02/22 © Robert Godin. Tous droits réser vés.

25

uneTransaction : Commis au prêt :

ContrôleEnregistrerPrêts : CourtierBDUtilisateur

: CourtierBDPrêtsEnCours

: CourtierBDExemplaire

: Usin eConnection

uneConnection 2. getConnexionSansAutoCommit( )

4. uneConnection

9. «create»(uneConnection) 10 . chercherLesPrêtsEnCours(un Utilisateur )

18. insérerPrêtEn Cours (unPrêtEnCours) 7. chercherUtilisateur(idUtilisateur)

12. chercherVariablesStatiquesDeMembre( ) 6. «cre ate»(uneConnection)

15. «create»(uneConnection) 16. chercherExem plaire (i dExempla ire )

3. «create»

8. prepareStatement()

11. prepareStatement()

13. prepareStatement()

17. prepareStatement()

20. commit() 21. cl ose() 1. créerNouveauPrêt()

5 . entrer(idUtilisateur)

14. entrer(idExemplaire)

19. prepapreStatement()

15.1.1 Enjeux de conception d'une application Java/JDBC

Dépendance

au temps de

réflexion

(26)

Limiter les verrouillages ?

Transaction T

1

Transaction T

2

SQL> SELECT * FROM PrêtEnCours 2 WHERE idUtilisateur = 2;

IDEXEMPLAI DATEPRÊT IDUTILISAT --- --- ---

3 02-03-21 2

SQL> SELECT * FROM PrêtEnCours 2 WHERE idUtilisateur = 2;

IDEXEMPLAI DATEPRÊT IDUTILISAT --- --- ---

4 02-03-21 2

SQL> INSERT INTO

2 PrêtEnCours(idExemplaire,idUtilisateur) 3 VALUES(4,2);

1 row created.

SQL> COMMIT;

Commit complete.

SQL> INSERT INTO

2 PrêtEnCours(idExemplaire,idUtilisateur) 3 VALUES(5,2);

1 row created.

SQL> COMMIT;

Commit complete.

Dépasse la limite du nombre de prêts (maximum 2)

(27)

27/02/22 © Robert Godin. Tous droits réser vés.

27

Limiter la durée des transactions

 Contraintes de sérialisabilité ?

(28)

Vérification des contraintes par le serveur

Transaction T

1

Transaction T

2

SQL> SELECT * FROM PrêtEnCours 2 WHERE idUtilisateur = 2;

IDEXEMPLAI DATEPRÊT IDUTILISAT --- --- ---

3 02-03-21 2

SQL> SELECT * FROM PrêtEnCours 2 WHERE idUtilisateur = 2;

IDEXEMPLAI DATEPRÊT IDUTILISAT --- --- ---

4 02-03-21 2

SQL> INSERT INTO

2 PrêtEnCours(idExemplaire,idUtilisateur) 3 VALUES(4,2);

1 row created.

SQL> COMMIT;

Commit complete.

SQL> INSERT INTO

2 PrêtEnCours(idExemplaire,idUtilisateur) 3 VALUES(5,2);

INSERT INTO

PrêtEnCours(idExemplaire,idUtilisateur) *

ERROR at line 1:

ORA-20101: le nombre maximal d'emprunts est atteint

ORA-06512: at "CLERAT.BIPRÊTENCOURSVÉRIFIER", line 59

ORA-04088: error during execution of trigger 'CLERAT.BIPRÊTENCOURSVÉRIFIER'

Non

sérialisabilité

perçue par T2

(29)

27/02/22 © Robert Godin. Tous droits réser vés.

29

Contrôle de concurrence optimiste par estampillage explicite

 Lecture en une première transaction

– Note l’estampille courante (ou numéro de version, …)

 Écriture en une deuxième transaction distincte

– Vérifie si l’état a changé depuis la lecture

 Si non, met à jour les données et l’estampille

 Si oui, annulation

 Ne bloque pas les objets lus

(30)

Réduire l'interactivité

Nom: EnregistrerPrêtsSimple

Description courte : Enregistrer les prêts en un aller-retour au système Type: Interactif

Description : Ce cas d'utilisation est déclenché par le commis au prêt suite à une requête d'un membre ou d'un employé et lui permet d'enregistrer un prêt en un aller-retour au système.

Exigence d'intégrité : la séquence constitue une transaction Séquence normale d'interaction :

Commis au prêt Système

1. Le commis invoque l'écran d'enregistrement du prêt

2. Le système demande la saisie de l'identificateur de l'utilisateur et de l’exemplaire

3. Le commis saisit l'identificateur de l'utilisateur à l'aide de la carte de membre ou manuellement et entre l'identificateur de l'exemplaire à l'aide du lecteur optique ou manuellement.

4. Le système enregistre le prêt, affi che un message

d'acquiescement.

(31)

27/02/22 © Robert Godin. Tous droits réser vés.

31

ControleEnregistrerPretsSimple

uneTransaction : Commis au prêt :

ContrôleEnregistrerPrêts

: CourtierBDPrêtsEnCours :

UsineConnection

uneConnection 1. créerNouveauPrêt()

5. entrer(idUtilisate ur, idExempl aire)

6. «create»(uneConnection) 7. insérerPrêtEnCours (unPrêtEnCours)

2. getConnexion( )

4. uneConnection 3. «create»

9. close()

8. prepapreStatem ent()

(32)

public typeRetour nomMéthodeCourtier(listeParamètres) throws Exception {

Connection uneConnection = uneUsineConnection.getConnection…

// Utiliser uneConnection

uneConnection.close();

}

Libérer la connexion entre les appels

 Transaction ne peut chevaucher les appels

 Ouverture/fermeture couteuse

– Solution : connection pooling (JDBC 2)

(33)

27/02/22 © Robert Godin. Tous droits réser vés.

33

15.1.2 Gestion de la sécurité

 Qui gère l ’idUtilisateur et le mot de passe ?

– par les données : le SGBD

– par les traitements : le programme

client

(34)

ControleEnrPretsSecuriteParDonnees

package ExemplesJDBC.GererPrets;

/* Classe de contrôle simple pour EnregistrerPrêts * Interface à l'utilisateur minimaliste

* NB Vérifie les conditions de prêt et le statut de l'exemplaire au niveau du programme client

*/ import java.sql.*;

import javax.swing.JOptionPane;

import java.util.*;

class ControleEnrPretsSecuriteParDonnees {

public static void main (String args []) throws Exception { String idCommis =

JOptionPane.showInputDialog("Entrez l'identificateur du commis au prêt: ");

String motDePasse =

JOptionPane.showInputDialog("Entrez le mot de passe : ");

// Création d'une Connection à partir du idCommis et de son motDePasse UsineConnection uneUsineConnection = new UsineConnection();

Connection uneConnection = uneUsineConnection.getConnectionSansAutoCommit(

"oracle.jdbc.driver.OracleDriver",

"jdbc:oracle:thin:@localhost:1521:ora817i", idCommis, motDePasse);

try{

// Dématérialiser l'Utilisateur et ses PrêtsEnCours

// Le reste du code est identique à ControleEnregistrerPrets

(35)

27/02/22 © Robert Godin. Tous droits réser vés.

35

ControleEnrPretsSecuriteParTraitement

package ExemplesJDBC.GererPrets;

/* Classe de contrôle pour EnregistrerPrêts * Sécurité «par les traitements»

* Interface à l'utilisateur minimaliste

* NB Vérifie les conditions de prêt et le statut de l'exemplaire au niveau du programme client */

import java.sql.*;

import javax.swing.JOptionPane;

import java.util.*;

class ControleEnrPretsSecuriteParTraitement {

public static void main (String args []) throws Exception {

// Création d'une Connection avec un authorizationID SQL indépendant du idCommis UsineConnection uneUsineConnection = new UsineConnection();

Connection uneConnection = uneUsineConnection.getConnectionSansAutoCommit(

"oracle.jdbc.driver.OracleDriver",

"jdbc:oracle:thin:@localhost:1521:ora817i", "clerat", "oracle");

try{

// Authentifier le commis au prêt (en utilisant la table Utilisateur) String idCommis =

JOptionPane.showInputDialog("Entrez l'identificateur du commis au prêt: ");

CourtierBDUtilisateur unCourtierBDUtilisateur = new CourtierBDUtilisateur(uneConnection);

Utilisateur lUtilisateur =

unCourtierBDUtilisateur.chercherUtilisateurParIdUtilisateur(idCommis);

if (!(lUtilisateur instanceof Employé)){

JOptionPane.showMessageDialog(null,"Pas un employé :"+idCommis);

}else {

Employé leCommis = (Employé)lUtilisateur;

if (!(leCommis.getCatégorieEmployé().equals("commis"))){

JOptionPane.showMessageDialog(null,"Pas un commis au prêt:"+idCommis);

} else {

String motDePasse =

JOptionPane.showInputDialog("Entrez le mot de passe : ");

if (!(leCommis.getMotPasse().equals(motDePasse))){

JOptionPane.showMessageDialog(null,"Mot de passe invalide:"+motDePasse);

}else{//OK Commis est authentifié

// Dématérialiser l'Utilisateur et ses PrêtsEnCours …

// Le reste du code est identique à ControleEnregistrerPrets

(36)

15.1.3 Façade pour les services de la couche application

Membre PrêtEnCours

Utilisateur

CourtierBDUtilisateur CourtierBDPrêtsEnCours CourtierBDExemplaire Prêt

Exemplaire Personne

ControleEnregistrerPretsAvecFacade

FacadeEnregistrerPrets

UsineConnection Connection

(37)

27/02/22 © Robert Godin. Tous droits réser vés.

37

Diagramme de séquence pour

ControleEnregistrerPretAvecFacade

: ControleEnregistrerPretsAvecFacade : FacadeEnregistrerPrets : UsineConnection uneConnection

3. chercherOTDUtilisateurPrets()

4. getStatutExemplaire()

5. insererPretEnCours( )

6. confirmerTransaction( ) 1. «create»

1.1. getConnexionSansAuto Commit( )

1.1.1. «create»

2. u neConnectio n

7. commit() 8. close()

Dépendance réduite par rapport à la

couche persistence

(38)

Patron d'objet de transfert de données (OTD)

uneClasseControle unOTD uneClasseFacade

1. getOTD()

3. getPropriété1() 4. getPropriété2() 5. getPropriété3() etc.

2. unOTD

(39)

27/02/22 © Robert Godin. Tous droits réser vés.

39

ControleEnregistrerPretsSimpleAvecFacade

:ControleEnregistrerPretsSimpleAvecFacade :FacadeEnregistrerPretsSimple : UsineC onne ction uneConnection 1. «create»

2. insererPretEnCours(idUtilisateur,idExemplaire)

3. getConn ection() 5. uneCon nection

6. close()

4. «create»

Connexion libérée

entre les appels

(40)

15.2 Développement d'applications Web par servlet Java

F u r e t e u r W e b : - p r é s e n t a t i o n

S G B D

- p e r s i s t e n c e

- p a r t i e d u d o m a i n e d 'a p p l i c a t i o n ?

C l i e n t m i n c e S e r v e u r B D

S e r v e u r d 'a p p l i c a t i o n : - c o n t r ô l e

- d o m a i n e d 'a p p l i c a t i o n

S e r v e u r d ' a p p l i c a t i o n

(41)

27/02/22 © Robert Godin. Tous droits réser vés.

41

15.2.1 Principe de base du Web : le protocole HTTP et le langage de

présentation HTML

F u r e t e u r W e b S e r v e u r W e b

R e q u ê t e H T T P

R é p o n s e H T T P

(42)

15.2.2 Développement de servlet Java

S e r v e u r d 'a p p l i c a t i o n ( W e b )

C o n t e n e u r à s e r v l e t

2 . L e s e r v e u r t é l é c h a r g e l a F O R M H T M L

F u r e t e u r W e b

s e r v l e t J a v a

3 . L e f u r e t e u r e n v o i e d e s

p a r a m è t r e s ( H T T P P O S T ) 4 . L e s e r v e u r d é l è g u e l ' a p p e l a u c o n t e n e u r à s e r v l e t 1 . L e f u r e t e u r I n v o q u e l ' é c r a n

d e s a i s i e ( H T T P G E T )

5 . L e c o n t e n e u r à s e r v l e t d é m a r r e u n f i l d e l a s e r v l e t

7 . L a s e r v e l t p r o d u i t l a r é p o n s e H T T P q u i e s t r e t o u r n é e a u f u r e t e u r

S e r v e u r B D

6 . L a s e r v e l t f a i t a p p e l a u

s e r v e u r d e B D B D

F O R M H T M L

(43)

27/02/22 © Robert Godin. Tous droits réser vés.

43

Diagramme de séquence de l'invocation de la servlet

ServletEnregistrerPretSimpleFacade

unFureteur unServeurWeb

: ServletEnregistrerPretSimpleFacade

: FacadeEnregistrerPretSimple 1. requête HTTP POST

2. doPost(HttpServletRequest, HttpServletResponse)

5. HttpServletResponse 6. réponse HTTP (document HTML)

3. insererPretEnCours(idUtilisateur,idExemplaire ) 4. date du prêt

Réutilisation des classes du client-serveur

(44)

<html>

<head>

<title>

Bibliothèque LeRat : Enregistrer un prêt (avec un servlet, interaction simplifiée)

</title>

</head>

<body>

<form action = "servlet/ServletEnregistrerPretsSimpleFacade" method = "post">

<p> Entrez l'identificateur de l'utilisateur et de l'exemplaire et cliquez Soumettre</p>

<table>

<tr>

<td>Identificateur d'utilisateur</td>

<td><input type = "text" name = "idUtilisateur" /></td>

</tr>

<tr>

<td>Identificateur d'exemplaire</td>

<td><input type = "text" name = "idExemplaire" /></td>

</tr>

</table>

<input type = "submit" value = "Soumettre" />

</form>

</body>

</html>

(45)

27/02/22 © Robert Godin. Tous droits réser vés.

45

import javax.servlet.*;

import javax.servlet.http.*;

import java.io.*;

import java.util.*;

import java.sql.*;

public class ServletEnregistrerPretsSimpleFacade extends HttpServlet {

public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{

//Chercher le paramètre idUtilisateur de la FORM HTML et créer un Utilisateur String idUtilisateur = "";

try { idUtilisateur = request.getParameter("idUtilisateur"); } catch (Exception e) { e.printStackTrace(); }

//Chercher le paramètre idExemplaire de la FORM HTML et créer un Exemplaire String idExemplaire = "";

try { idExemplaire = request.getParameter("idExemplaire"); } catch (Exception e) { e.printStackTrace(); }

// Entête de la page de réponse HTML response.setContentType("text/html");

OutputStreamWriter unOutputStreamWriter =

new OutputStreamWriter(response.getOutputStream());

PrintWriter out = new PrintWriter(unOutputStreamWriter);

out.println("<html>");

out.println("<head><title>Réponse de ServletEnregistrerPretsSimpleFacadeEJB</title></head>");

out.println("<body>");

FacadeEnregistrerPretsSimple uneFacadeEnregistrerPretsSimple = null;

try{

uneFacadeEnregistrerPretsSimple = new FacadeEnregistrerPretsSimple();

// Enregistrer le prêt en passant par la façade java.sql.Date datePret =

uneFacadeEnregistrerPretsSimple.insererPretEnCours(idUtilisateur,idExemplaire);

// Message de confirmation du prêt

out.println("Prêt de l'exemplaire " + idExemplaire +

" à l'utilisateur " + idUtilisateur + " confirmé.<br>Date :" + datePret);

}

(46)

15.2.3 Cycle de vie d'une servlet

 Compilation et démarrage à la

première invocation (par conteneur)

init() appelé une fois

 permet d ’initialiser des ressources (e.g.

connexion)

– nouveau fil à chaque invocation d ’une méthode de service (doGet, doPost,…)

destroy() à la fin

 e.g. fermer connexion

(47)

27/02/22 © Robert Godin. Tous droits réser vés.

47

15.2.4 Gestion d'une session HTTP dans une servlet

La FORM

n ’envoie que

le idUtilisateur

(48)

FormIdentificationUtilisateurFacade.html

<html>

<head>

<title> Exemple de session http pour cas Enregistrer Prêts : Identification utilisateur

</title>

</head>

<body>

<form action = "servlet/ServletIdentificationUtilisateurFacade" method = "post">

<p>Entrez l'identifiant de l'utilisateur et cliquez Soumettre</p>

<input type = "text" name = "idUtilisateur" />

<input type = "submit" value = "Soumettre" />

</form>

</body>

</html>

(49)

27/02/22 © Robert Godin. Tous droits réser vés.

49

EnregistrerPrets en deux servlets

unFureteur unServeurWeb

: ServletIdentificationUtilisateurFacade

: ServletTerminerPretFacade uneSession :

HttpSession

uneFacadeEnregistrerPrets : FacadeEnregistrerPrets

uneTransaction 1. requête HTTP POST pour ServletIdentificationUtilisateurFacade

9. réponse HTTP (FormTerminerPret)

2. doPost(HttpServletRequest, HttpServletResponse)

8. HttpServletResponse

15. insererPretEnCours(idUtilisateur,idExemplaire ) 5. chercherOTDUtilisateurPrets()

4. «create»

3. «create»

6. setAttribute('uneFacadeEnregistrerPrets', uneFacadeEnregistrerPrets)

10. requête HTTP POST pour ServletTerminerPretFacade

11. doPost(HttpServletRequest, HttpServletResponse)

14. getStatutExem plaire() 12. getAttribute('uneFacadeEnregistrerPrets')

16. confirm erTransaction( ) 17. HttpServletResponse

18. réponse HTTP (confirmation)

7. setAttribute('idUtilis ateur',idUtilis ateur)

13. getAttribute('idUtilisateur')

(50)

public class ServletIdentificationUtilisateurFacade extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

//Chercher le paramètre idUtilisateur de la form String idUtilisateur = "";

try { idUtilisateur = request.getParameter("idUtilisateur"); } catch (Exception e) { e.printStackTrace(); }

// Créer un objet session si non existant

HttpSession uneSession = request.getSession(true);

// Entête de la page de réponse html response.setContentType("text/html");

try{

// Créer la facade et chercher l'OTDUtilisateurPrets

FacadeEnregistrerPrets uneFacadeEnregistrerPrets = new FacadeEnregistrerPrets();

OTDUtilisateurPrets unOTDUtilisateurPrets =

uneFacadeEnregistrerPrets.chercherOTDUtilisateurPrets(idUtilisateur);

// Affichage de l'idUtilisateur et du nombre de prêts out.println("Utilisateur :" + idUtilisateur);

out.println(" Nombre de prêts en cours :" + unOTDUtilisateurPrets.getNbPretsEnCours()+"<br>");

// Vérifier si les conditions préalables sont violées

}else{

// Sauvegarder les objets du contexte de la session

uneSession.setAttribute("uneFacadeEnregistrerPrets", uneFacadeEnregistrerPrets);

uneSession.setAttribute("idUtilisateur", idUtilisateur);

// Construire la FORM pour saisir l'idExemplaire

out.println("<form action = \"ServletTerminerPretFacade\" method = \"post\">");

out.println("<p>Entrez l'identifiant de l'exemplaire et cliquez Soumettre</p>");

out.println("<input type = \"text\" name = \"idExemplaire\" />");

out.println("<input type = \"submit\" value = \"Soumettre\" />");

out.println("</form>");

} ...

(51)

27/02/22 © Robert Godin. Tous droits réser vés.

51

public class ServletTerminerPretFacade extends HttpServlet {

public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

//Chercher le paramètre idUtilisateur de la form String idExemplaire = "";

try { idExemplaire = request.getParameter("idExemplaire"); } catch (Exception e) { e.printStackTrace(); }

// Chercher l'objet de la session en cours

HttpSession uneSession = request.getSession(false);

// Chercher les objets du contexte de la session en cours FacadeEnregistrerPrets uneFacadeEnregistrerPrets =

(FacadeEnregistrerPrets)uneSession.getAttribute("uneFacadeEnregistrerPrets");

String idUtilisateur = (String)uneSession.getAttribute("idUtilisateur");

// Entête de la page de réponse html

try{

// Vérifier statut de l'exemplaire

String statut = uneFacadeEnregistrerPrets.getStatutExemplaire(idExemplaire);

if (statut.equals("disponible")){

// Enregistrer le prêt en passant par la façade java.sql.Date datePret =

uneFacadeEnregistrerPrets.insererPretEnCours();

finally{

try{

out.println("</body></html>");

out.close();

uneFacadeEnregistrerPrets.confirmerTransaction();

}

catch(Exception lException){

lException.printStackTrace();

} } } }

(52)

15.2.5 DataSource,

ConnectionPoolDataSource et PooledConnection

 Passage par serveur JNDI (Java Naming and Directory Interface)

– e.g. serveur LDAP

– repérage de ressources (e.g. serveur BD)

– accès sécurisé

(53)

27/02/22 © Robert Godin. Tous droits réser vés.

53

Ouverture d ’une Connection en passant par DataSource

package ExemplesJDBC.GererPrets;

import java.sql.*;

import javax.naming.*;

import javax.sql.*;

public class UsineConnection { public UsineConnection() {}

public Connection getConnectionFromDataSource(

String nomDataSource) throws Exception {

InitialContext unContexte = new InitialContext();

DataSource unDataSource =

(DataSource)unContexte.lookup(nomDataSource);

Connection uneConnection = unDataSource.getConnection();

return uneConnection;

}

}

(54)

Enregistrement du DataSource par descripteur de

déploiement XML pour serveur embarqué OC4J de Oracle9i JDevelopper (généré par JDevelopper)

Connection uneConnection =

uneUsineConnection.getConnectionFromDataSource("jdbc/ora9icleratCoreDS");

<?xml version = '1.0' encoding = 'windows-1252'?>

<!DOCTYPE data-sources PUBLIC "Orion data-sources" "http://xmlns.oracle.com/ias/dtds/data-sources.dtd">

<data-sources>

<data-source class="com.evermind.sql.DriverManagerDataSource"

connection-driver="oracle.jdbc.driver.OracleDriver"

ejb-location="jdbc/ora9icleratDS"

inactivity-timeout="30"

location="jdbc/ora9icleratCoreDS"

name="ora9icleratDS"

password="oracle"

pooled-location="jdbc/ora9icleratPooledDS" url="jdbc:oracle:thin:@localhost:1521:ora9i"

username="clerat"

xa-location="jdbc/xa/ora9icleratXADS"/>

</data-sources>

(55)

27/02/22 © Robert Godin. Tous droits réser vés.

55

Partage d'un pool de connexions

package ExemplesJDBC.GererPrets;

import java.sql.*;

import javax.naming.*;

import javax.sql.*;

import oracle.jdbc.pool.*;

public class UsineConnection { public UsineConnection() {}

public Connection getConnectionFromConnectionPoolDataSource(

String nomDataSource) throws Exception {

InitialContext unContexte = new InitialContext();

ConnectionPoolDataSource unDataSource =

(ConnectionPoolDataSource)unContexte.lookup(nomDataSource);

PooledConnection unePooledConnection = unDataSource.getPooledConnection();

Connection uneConnection = unePooledConnection.getConnection();

return uneConnection;

}

}

(56)

15.2.6 Mécanismes de sécurité pour l'accès à un servlet

 Sécurité programmatique

 Sécurité déclarative par le conteneur

– rôles/utilisateurs

– géré par conteneur

(57)

27/02/22 © Robert Godin. Tous droits réser vés.

57

15.3 Architecture pour la persistance transparente

 Persistance gérée par la classe métier

 Transparent au client

 Mécanisme paresseux de

matérialisation/dématérialisation

– gestion de cache transactionnelle

– programmation complexe

 Norme Java Data Objects (JDO)

– http://access1.sun.com/jdo/

– inspirée de ODMG

– outils : http://www.javaskyline.com/database.html

(58)

15.4 Norme EJB de J2EE (http://

java.sun.com/products/ejb/)

 Transparence « extrême »

– persistance

– répartition

– services

 Spécification déclarative de services

– comportement transactionnel

– sécurité

– partage de ressources (CPU, mémoire, serveurs, ...)

 partage transparent d’un bassin d’objets EJB (pooling) entre clients

 Prise en charge des services par le conteneur à EJB

(59)

27/02/22 © Robert Godin. Tous droits réser vés.

59

Séparation propre des responsabilités (rôles)

 Fournisseur de EJB (EnterpriseBean Provider)

– développe les composantes EJB

 Assembleur d'application (Application Assembler) .

– assemble EJB + servlet, JSP, HTML, etc.

 Déployeur (Deployer)

– déploie les EJB dans leur environnement d'exécution

 Fournisseur de serveur EJB (EJB Server Provider).

– serveur EJB : services de bas niveau pour le conteneur EJB

 Fournisseur de conteneur EJB (EJB Container Provider)

– conteneur EJB : environnement de déploiement et d'exécution des EJB

 Administrateur de Système (System Administrator)

– administre serveur et le conteneur EJB

(60)

Catégories de EJB

 EJB session (Session Bean)

– service d ’objet distant

– un seul client à la fois par objet

– partage d’un bassin d’objets entre clients

– état au besoin entre les appels

 stateful/stateless session EJB

– non persistent (perdu suite à une panne)

 EJB entité (Entity Bean)

– services d'objet distant persistent

– objet ~ proxy pour une ligne d'une table

– un objet EJB entité peut être partagé par plusieurs clients

 EJB message (Message Bean)

– service de message

(61)

27/02/22 © Robert Godin. Tous droits réser vés.

61

Codage d ’un EJB

 Interface home

– usine à objet EJB

 Interface à distance (remote)

– accès aux méthodes d'un objet EJB

 Classe bean (bean class)

– implémente les méthodes de

l'objet EJB

(62)

15.4.1 Développement d'un EJB session sans état : FacadeEnrPretSimpleSessionEJB

 Interface home (usine à EJB)

 Interface remote (interface à l’objet EJB)

package ExemplesJDBC.GererPrets;

import javax.ejb.EJBHome;

import java.rmi.RemoteException;

import javax.ejb.CreateException;

public interface FacadeEnrPretSimpleSessionEJBHome extends EJBHome {

FacadeEnrPretSimpleSessionEJB create() throws RemoteException, CreateException;

}

package ExemplesJDBC.GererPrets;

import javax.ejb.EJBObject;

import java.rmi.RemoteException;

import java.sql.Date;

public interface FacadeEnrPretSimpleSessionEJB extends EJBObject {

Date insererPretEnCours(String idUtilisateur, String idExemplaire) throws RemoteException, Exception;

}

(63)

27/02/22 © Robert Godin. Tous droits réser vés.

63

package ExemplesJDBC.GererPrets.impl;

import javax.ejb.SessionBean;

import javax.ejb.SessionContext;

import java.sql.Date;

import ExemplesJDBC.GererPrets.*;

import java.sql.Connection;

import java.util.*;

public class FacadeEnrPretSimpleSessionEJBBean implements SessionBean {

public void ejbCreate(){}

public void ejbActivate(){}

public void ejbPassivate(){}

public void ejbRemove(){}

public void setSessionContext(SessionContext ctx){}

public Date insererPretEnCours(String idUtilisateur, String idExemplaire) throws Exception {

UsineConnection uneUsineConnection = new UsineConnection();

Connection uneConnection =

uneUsineConnection.getConnectionFromDataSource("jdbc/ora9icleratCoreDS");

Utilisateur unUtilisateur = new Utilisateur(idUtilisateur);

Exemplaire unExemplaire = new Exemplaire(idExemplaire);

// Générer la date du jour et l'objet PrêtEnCours

Calendar maintenant = Calendar.getInstance(); // Calendrier avec date actuelle java.sql.Date dateMaintenant = new java.sql.Date(maintenant.getTime().getTime());

PrêtEnCours leNouveauPrêtEnCours =

new PrêtEnCours(unUtilisateur,dateMaintenant,unExemplaire);

// Matérialiser le PrêtEnCours dans la BD CourtierBDPrêtEnCours unCourtierBDPrêtEnCours = new CourtierBDPrêtEnCours(uneConnection);

unCourtierBDPrêtEnCours.insérerPrêtEnCours(leNouveauPrêtEnCours);

// Pas besoin de commit uneConnection.close();

return dateMaintenant;

} }

(64)

Descripteur de

déploiement XML

<?xml version = '1.0' encoding = 'windows-1252'?>

<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 1.1//EN"

"http://java.sun.com/j2ee/dtds/ejb-jar_1_1.dtd">

<ejb-jar>

<enterprise-beans>

<session>

<description>Session Bean ( Stateless )</description>

<display-name>FacadeEnrPretSimpleSessionEJB</display-name>

<ejb-name>FacadeEnrPretSimpleSessionEJB</ejb-name>

<home>ExemplesJDBC.GererPrets.FacadeEnrPretSimpleSessionEJBHome</home>

<remote>ExemplesJDBC.GererPrets.FacadeEnrPretSimpleSessionEJB</remote>

<ejb-class>ExemplesJDBC.GererPrets.impl.FacadeEnrPretSimpleSessionEJBBean</ejb-class>

<session-type>Stateless</session-type>

<transaction-type>Bean</transaction-type>

</session>

</ejb-jar>

(65)

27/02/22 © Robert Godin. Tous droits réser vés.

65

Client du EJB : façade locale qui délègue à la façade EJB distante

(patron Business Delegate)

package ExemplesJDBC.GererPrets;

import java.util.Hashtable;

import javax.naming.Context;

import javax.naming.InitialContext;

import ExemplesJDBC.GererPrets.FacadeEnrPretSimpleSessionEJB;

import ExemplesJDBC.GererPrets.FacadeEnrPretSimpleSessionEJBHome;

// Façade pour le cas d'utilisation EnregistrerPretsSimple

// La façade utilise les services du EJB session FacadeEnrPretSimpleSessionEJB public class FacadeEJBEnregistrerPretsSimple

{

public FacadeEJBEnregistrerPretsSimple()throws Exception {

}

// Insère le prêt et retourne la date d'enregistrement public java.sql.Date insererPretEnCours(

String idUtilisateur, String idExemplaire) throws Exception{

// Chercher une référence au EJB session

FacadeEnrPretSimpleSessionEJB uneFacadeEnrPretSimpleSessionEJB;

Hashtable env = new Hashtable();

env.put(Context.INITIAL_CONTEXT_FACTORY,

"com.evermind.server.rmi.RMIInitialContextFactory");

env.put(Context.SECURITY_PRINCIPAL, "admin");

env.put(Context.SECURITY_CREDENTIALS, "welcome");

env.put(Context.PROVIDER_URL, "ormi://localhost:23893/current-workspace-app");

Context ctx = new InitialContext(env);

FacadeEnrPretSimpleSessionEJBHome facadeEnrPretSimpleSessionEJBHome =

(FacadeEnrPretSimpleSessionEJBHome)ctx.lookup("FacadeEnrPretSimpleSessionEJB");

uneFacadeEnrPretSimpleSessionEJB = facadeEnrPretSimpleSessionEJBHome.create();

// Déléguer l'insertion du PrêtEnCours à la méthode du EJB

return uneFacadeEnrPretSimpleSessionEJB.insererPretEnCours(idUtilisateur,idExemplaire);

} }

(66)

JDevelopper 10g (déploiement

de défaut différent)

(67)

27/02/22 © Robert Godin. Tous droits réser vés.

67

Interposition transparente d ’objets

: Controle Enregi strerPretsSimpleAvecFacadeEJB

: FacadeEJBEnregistrerPretsSimple

ctx : Context

uneFacad eEnrPretSim ple SessionEJB : FacadeEnregistrerPretsSimpleSessionEJB

: FacadeEn regi strerPretsSimpleSessi onEJBBean facadeEnrPretSimpl

eSessionEJBHome

In terposition transparente d'objets générés par le conten eur pour e ffectuer l'envoie de message à l'objet be an Client du EJB

ObjetEJB local qui implémente l'interface remote

Conteneur EJB Poste du client du EJB

1. insererPretEnCours(idUtilisateur,idExemplaire)

7. in sererPretEnCours(idUtil is ateur,idExemplaire)

8. insererPretEnCours(idUtilisateur,idExemplaire) 2. «create»

3. lookup()

4. facadeEnrPretSimpleSessionEJBHome 5. create()

6. uneFacadeEnrPretSimpleSessionEJB Ob jet home

Objet bean

Conteneur

de bean

(68)

Dans ServletEnregistrerPretsSimpleFacade remplacer FacadeEnregistrerPretsSimple par une

FacadeEJBEnregitrerPretSimple

package ExemplesJDBC.GererPrets;

import javax.servlet.*;

import javax.servlet.http.*;

import java.io.*;

import java.util.*;

import java.sql.*;

public class ServletEnregistrerPretsSimpleFacadeEJB extends HttpServlet {

public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{

FacadeEJBEnregistrerPretsSimple uneFacadeEnregistrerPretsSimple = null;

try{

uneFacadeEnregistrerPretsSimple = new FacadeEJBEnregistrerPretsSimple();

}

}

(69)

27/02/22 © Robert Godin. Tous droits réser vés.

69

15.4.2 Développement d'un EJB session avec état

package ExemplesJDBC.GererPrets;

import javax.ejb.EJBHome;

import java.rmi.RemoteException;

import javax.ejb.CreateException;

public interface FacadeEnrPretsSessionEJBHome extends EJBHome {

FacadeEnrPretsSessionEJB create() throws RemoteException, CreateException;

}

package ExemplesJDBC.GererPrets;

import javax.ejb.EJBObject;

import java.rmi.RemoteException;

import java.sql.Date;

public interface FacadeEnrPretsSessionEJB extends EJBObject {

OTDUtilisateurPrets chercherOTDUtilisateurPrets(String idUtilisateur) throws Exception, RemoteException;

void confirmerTransaction() throws Exception, RemoteException;

String getStatutExemplaire(String idExemplaire) throws Exception, RemoteException;

Date insererPretEnCours() throws Exception, RemoteException;

}

(70)

Classe bean

package ExemplesJDBC.GererPrets.impl;

import javax.ejb.SessionBean;

import javax.ejb.SessionContext;

import java.sql.Connection;

import ExemplesJDBC.GererPrets.*;

import java.sql.Date;

import java.util.*;

public class FacadeEnrPretsSessionEJBBean implements SessionBean {

private Connection uneConnection;

private Utilisateur unUtilisateur;

private Exemplaire unExemplaire;

private CourtierBDPrêtEnCours unCourtierBDPretEnCours;

public void ejbCreate()throws Exception{}

public void ejbActivate(){}

public void ejbPassivate(){}

public void ejbRemove(){}

public void setSessionContext(SessionContext ctx) { try {

UsineConnection uneUsineConnection = new UsineConnection();

uneConnection =

uneUsineConnection.getConnectionFromDataSourceSansAutoCommit("jdbc/ora9icleratCoreDS");

}

catch(Exception lException){

lException.printStackTrace();

} }

État maintenu entre les appels Méthode du cycle de vie appelée à la création de l’objet avant ejbCreate()

NB setSessionContext() permet

d’initialiser la connexion au

DataSource (interdit dans

ejbCreate()…)

(71)

27/02/22 © Robert Godin. Tous droits réser vés.

71

Classe Bean (suite) : méthode métier identique à FacadeEnregistrerPrets

public OTDUtilisateurPrets chercherOTDUtilisateurPrets(String idUtilisateur) throws Exception { // Création du courtier et dématérialisation de l'Utilisateur

CourtierBDUtilisateur unCourtierBDUtilisateur = new CourtierBDUtilisateur(uneConnection);

unUtilisateur =

unCourtierBDUtilisateur.chercherUtilisateurParIdUtilisateur(idUtilisateur);

//Création du courtier et dématérialisation des PrêtsEnCours

unCourtierBDPretEnCours = new CourtierBDPrêtEnCours(uneConnection);

unCourtierBDPretEnCours.chercherLesPrêtsEnCours(unUtilisateur);

// Retourner l'objet de transfert de données OTDUtilisateurPrets if (unUtilisateur instanceof Membre){

unCourtierBDUtilisateur.chercherVariablesStatiquesDeMembre();

Membre unMembre = (Membre)unUtilisateur;

return new OTDUtilisateurPrets(

unMembre.getCatégorie(),

unMembre.conditionsPrêtAcceptées(), unMembre.getNbPrêtsEnCours(),

Membre.getNbMaxPrêts(), unMembre.getNbRetards());

} else {

return new OTDUtilisateurPrets(

unUtilisateur.getCatégorie(),true,unUtilisateur.getNbPrêtsEnCours(),0,0);

}

}

(72)

Processus de création d ’un EJB avec état

unClientEJB unEJBHome unObjetEJBl oca l u nSessio nContext unObjetEJBBean 1. create()

2. «create»

3. «create»

4. «create»

5. setSessionContext()

6. ejbCreate()

Références

Documents relatifs

20.8 Traitement d’un document XML avec Java API for XML Processing

– Recommander les items jugés pertinents par les utilisateurs semblables. 

public static void main (String args []) throws Exception { // Création d'une Connection globale pour l'application UsineConnection uneUsineConnection =

public static void main(String[] args) throws Exception { NotePad notes = new NotePad();. Invoker invoke = new

public static void main(String [] args) throws IOException{. ServerSocket serveur =

public static void main(String [] args) throws IOException{. ServerSocket serveur =

public static void main(String[] args) throws Exception { NotePad notes = new NotePad();. Invoker invoke = new

public static void main(String[] args) throws IOException { InputStream in=new FileInputStream(args[0]);.. Et avec