TP3-Passage vers Spring.pdf

13

Click here to load reader

description

TP3-Passage vers Spring

Transcript of TP3-Passage vers Spring.pdf

Page 1: TP3-Passage vers Spring.pdf

[email protected] Page 1

Passage vers Spring

Cycle de Formations Technologique avancées : Framework : Spring

M. Belhassen OUESLATI

Ingénieur Java/J2EE

Travaux pratique TP N°4 Passage vers Spring

Objectifs Développer un premier exemple de composants liés Détecter le besoin d'Ioc

Pré-requis

TP N°2 : HIBERNATE : RECHERCHE D’UN OBJECT DANS LA SESSION

Page 2: TP3-Passage vers Spring.pdf

[email protected] Page 2

Passage vers Spring

1. Cas pratique : « Gestion des contacts » (cahier technique)

1.1 Sujet

Le but de cet exercice est de créer une application permettant de gérer une

liste de contacts.

On doit pouvoir lister, ajouter, supprimer, modifier, rechercher ces contacts.

1.2 Analyse

Dans un premier temps, avant l’écriture des premières lignes de codes, nous

allons définir les entités et les fonctionnalités requises pour notre application.

1.2.1 Définition des entités

D’après le sujet, on a besoin de "gérer une liste de contacts".

Cela signifie donc que l’on doit créer une classe Contact qui aura pour

attributs toutes les informations d’un contact : nom, prénom, …

1.2.2 Définition des fonctionnalités

On a besoin d’ajouter, lister, supprimer nos contacts.

Cas d’utilisation « Ajouter un contact »

1. Entrée des informations du contact.

2. Validation des entrées.

a. Vérification de la conformité des informations (nom, prénom, …).

i. Si les données sont conformes, le programme ajoute le contact et

indique un message positif au client.

ii. Si les données ne sont pas conformes, le programme renvoie une

erreur à l’utilisateur.

Page 3: TP3-Passage vers Spring.pdf

[email protected] Page 3

Passage vers Spring

Cas d’utilisation « Lister les contacts »

1. Récupération de l’ensemble des informations du support de stockage.

a. Si la récupération s’est bien passée :

i. S’il existe au moins un contact dans le support de stockage, le

programme affiche la liste des contacts (nom, prénom, adresse,

email…).

ii. S’il n’existe aucun contact dans la base de données, le programme

affiche un message indiquant qu’aucun contact n’a été trouvé.

b. Si la récupération s’est mal passée, le programme renvoie au client un

message d’erreur logicielle.

Cas d’utilisation « Supprimer un contact »

1. Liste des contacts affichée dans la console avec le numéro Id

correspondant.

2. Choix du numéro Id du contact à supprimer.

3. Le programme vérifie que le contact existe bien :

o Si le contact existe bien, le programme tente de supprimer le contact

demandé :

Si la suppression a échoué, le programme renvoie à l’utilisateur

une erreur lui indiquant une erreur logicielle.

Si la suppression a réussi, le programme renvoie à l’utilisateur un

message de confirmation de suppression du contact.

o Si le contact n’existe pas, le programme renvoie un message indiquant

l’absence de ce contact dans le support de stockage.

Page 4: TP3-Passage vers Spring.pdf

[email protected] Page 4

Passage vers Spring

2. Architecture technique

Nous allons séparer au maximum les différents types de traitement de

l’application en tenant compte des explications du cours (Présentation,

métiers/Service, Dao, Persistance).

2.1 Table contact

Table contact

CREATE TABLE "DEV"."CONTACT" ( "NUM_MAT_CNT" VARCHAR2(10 BYTE) NOT NULL ENABLE, "NOM_NOM_CNT" VARCHAR2(120 BYTE) NOT NULL ENABLE, "NOM_PRN_CNT" VARCHAR2(120 BYTE) NOT NULL ENABLE, "NUM_GSM_CNT" VARCHAR2(8 BYTE) NOT NULL ENABLE, "ADR_EMAIL_CNT" VARCHAR2(120 BYTE) NOT NULL ENABLE, CONSTRAINT "CONTACT__PK" PRIMARY KEY ("NUM_MAT_CNT") ENABLE ) ;

2.2 Nouveau projet de type Dynamic Web : TP_SPRING

Créer un nouveau projet de type dynamic web qui porte le nom : TP_SPRING

2.3 Configuration de la connexion

Voir TP N°2

2.4 Couche Objets persistance : Classe Contact

Cette couche est composée d'objets Java simples qui représentent les

données persistantes de l'application comme par exemple un client ou une

facture.

Pour cette partie, nous utilisons la technologie Hibernate qui va permettre de

mapper ces objets avec la base de données.

Nous y ajoutons la classe Contact avec, pour variables d’instances :

o String nomNomCnt;

o String nomPrnCnt;

o ….

Ces variables doivent évidemment être déclarées en privées et des

getter/setter sont implémentés.

Page 5: TP3-Passage vers Spring.pdf

[email protected] Page 5

Passage vers Spring

Implémentation de la classe persistante Contact

Utiliser la méthode de génération de code avec la perspective Hibernate (Voir TP N°2)

package com.model; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name = "CONTACT") public class Contact implements java.io.Serializable { private String numMatCnt; private String nomNomCnt; private String nomPrnCnt; private String numGsmCnt; private String adrEmailCnt; public Contact() { } public Contact(String numMatCnt, String nomNomCnt, String nomPrnCnt, String numGsmCnt, String adrEmailCnt) { this.numMatCnt = numMatCnt; this.nomNomCnt = nomNomCnt; this.nomPrnCnt = nomPrnCnt; this.numGsmCnt = numGsmCnt; this.adrEmailCnt = adrEmailCnt;

} + getter/setter

}

Note : Hibernate permet une certaine indépendance vis à vis du SGBD qu'on

souhaite utiliser avec l'application développée.

Page 6: TP3-Passage vers Spring.pdf

[email protected] Page 6

Passage vers Spring

2.5 Couche Dao : Classe ContactDaoImp

Cette couche a pour objectif d'encapsuler et d'abstraire l'accès aux données.

Concrètement, les développeurs vont utiliser cette couche pour récupérer,

mettre à jour, supprimer ou insérer des nouvelles données. L'utilité de cette

couche est que le développeur va utiliser des fonctions simples qui vont

masquer toute la complexité sous jacente.

Le développeur utilisateur de ces fonctions n'aura même pas à connaitre les

détails de l'implémentation, il ne saura même pas si la technologie utilisée est

Hibernate, SQL ou EJB3. Il ne verra que de simples fonctions Java.

Nous ajoutons par ailleurs l’interface GenericDao

Interface GenericDao package com.dao; import java.io.Serializable; import java.util.List; import org.hibernate.criterion.Criterion; public interface GenericDao { public void saveOrUpdate(Object entity); public void delete(Object entity); public List<Object> findAll(Class clazz); public List findByCriteria(Class clazz, Criterion critere); public Object findById(Class clazz, Serializable id); }

Page 7: TP3-Passage vers Spring.pdf

[email protected] Page 7

Passage vers Spring

Nous ajoutons par ailleurs la classe GenericDaoImp

Implémentation de l’interface GenericDao package com.dao.impl; // import… public class GenericDaoImpl implements GenericDao { private Session hibernateSession; private Transaction tx; public GenericDaoImpl() { hibernateSession = HibernateUtil.currentSession(); } @Override public void saveOrUpdate(Object entity) { try { startOperation(); hibernateSession.saveOrUpdate(entity); tx.commit(); } catch (HibernateException e) { handleException(e); } finally { hibernateSession.close(); } } @Override public void delete(Object entity) { try { startOperation(); hibernateSession.delete(entity); tx.commit(); } catch (HibernateException e) { handleException(e); } finally { hibernateSession.close(); } } @Override public List<Object> findAll(Class clazz) { List objects = null; try { startOperation(); Query query = hibernateSession.createQuery("from " + clazz.getName());

Page 8: TP3-Passage vers Spring.pdf

[email protected] Page 8

Passage vers Spring

objects = query.list(); } catch (HibernateException e) { handleException(e); } finally { hibernateSession.close(); } return objects; } @Override public List findByCriteria(Class clazz, Criterion critere) { List objects = null; try { startOperation(); Criteria crit = hibernateSession.createCriteria(clazz).add(critere); objects = crit.list(); } catch (HibernateException e) { handleException(e); } finally { hibernateSession.close(); } return objects; } @Override public Object findById(Class clazz, Serializable id) { Object obj = null; try { startOperation(); obj = hibernateSession.load(clazz, id); } catch (HibernateException e) { handleException(e); } finally { hibernateSession.close(); } return obj; } protected void startOperation() throws HibernateException { hibernateSession = HibernateUtil.currentSession(); tx = hibernateSession.beginTransaction(); } protected void handleException(HibernateException e) throws DataAccessLayerException { tx.rollback(); throw new DataAccessLayerException(e); } }

Page 9: TP3-Passage vers Spring.pdf

[email protected] Page 9

Passage vers Spring

Classe DataAccessLayerException

package com.dao.impl; public class DataAccessLayerException extends RuntimeException { public DataAccessLayerException() { } public DataAccessLayerException(String message) { super(message); } public DataAccessLayerException(Throwable cause) { super(cause); } public DataAccessLayerException(String message, Throwable cause) { super(message, cause); } }

Nous ajoutons par ailleurs l’interface ContactDao implémentée par la classe

ContactDaoImp.

Interface ContactDao

package com.dao; public interface ContactDao extends GenericDao { }

Implémentation de l’interface ContactDao

package com.dao.impl; import com.dao.ContactDao; public class ContactDaoImp extends GenericDaoImpl implements ContactDao { }

Note : Comme vous vous en doutez, les développeurs ne verront jamais

l'implémentation, ils se contenteront d'utiliser l'interface ContactDAO.

En cas de changement de technologie, il suffira de réécrire seulement

l'implémentation, tout le reste du code n'aura pas à être migré.

Page 10: TP3-Passage vers Spring.pdf

[email protected] Page 10

Passage vers Spring

2.6 Couche Business : Classe ContactBusiness

Cette couche contient le logique métier de l'application.

Voici un exemple qui illustre la différence entre couche DAO et couche

service :

Dans la couche DAO, la méthode delete(Object entity) supprime un

contact quel qu’il soit.

Dans la couche business, la méthode supprimerContact(String numero)

ajoute le code qui va gérer les règles particulières de l'application, par

exemple, nous allons peut être tester que le contact n'est pas un

administrateur, dans le cas où s'en est un, nous allons déclencher une

exception qui indiquera qu'une règle interdit la suppression de cet

utilisateur particulier.

Ce qu'il faut bien saisir avec cet exemple, c'est que les DAO se chargent de

gérer la persistance des données de manière basique, la couche business

elle y ajoute la logique liée au métier.

Interface ContactBusiness: package com.business; import java.util.List; import org.hibernate.criterion.Criterion; import com.model.Contact; public interface ContactBusiness { public void ajouterContact(Contact contact); public Contact recupererContactByCriteria(Criterion critere); public void supprimerContact(String numero); public List<Contact> recupererListContacts(); }

Page 11: TP3-Passage vers Spring.pdf

[email protected] Page 11

Passage vers Spring

Implémentation de l’interface ContactBusiness package com.business.impl; // import … public class ContactBusinessImp implements ContactBusiness { ContactDao ctDAO = new ContactDaoImp(); @Override public void ajouterContact(Contact contact) { if (contact != null) { ctDAO.saveOrUpdate(contact); } } @Override public Contact recupererContactByCriteria(Criterion criterion) { Session session = HibernateUtil.currentSession(); Criteria crit = session.createCriteria(Contact.class); crit.add(criterion); crit.setMaxResults(1); List<Contact> result = crit.list(); Contact ct = result.get(0); session.close(); return ct; } @Override Public void supprimerContact(String numero) { Contact ct = (Contact) ctDAO.findById(Contact.class, numero); ctDAO.delete(ct); } @Override public List<Contact> recupererListContacts() { List result = ctDAO.findAll(Contact.class); return result; } }

Page 12: TP3-Passage vers Spring.pdf

[email protected] Page 12

Passage vers Spring

2.7 Réaliser l'exemple

Exécuter la classe TestPassageVersSpring.java

Implémentation de la classe TestPassageVersSpring package com.util; // import …. public class TestPassageVersSpring { public static void main(String[] args) { ContactBusiness ctBusiness = new ContactBusinessImp(); // création d'un nouveau Contact Contact ct = new Contact(); ct.setNumMatCnt("4822"); ct.setNomNomCnt("Mhamed"); ct.setNomPrnCnt("Ben Saleh"); ct.setNumGsmCnt("99731434"); ct.setAdrEmailCnt("[email protected]"); ctBusiness.ajouterContact(ct); // Suppression d'un Contact Criterion criterion = Restrictions.like("nomNomCnt", "Mohamed%"); ctBusiness.recupererContactByCriteria(criterion); Contact ct = ctBusiness.recupererContactByCriteria(criterion); List<Contact> results = new ArrayList(); results.add(ct); displayList(results); ctBusiness.supprimerContact(ct.getNumMatCnt()); // Recuperation de ts ls Contact List results = ctBusiness.recupererListContacts(); displayList(results); } static public void displayList(List list) { Iterator iter = list.iterator(); if (!iter.hasNext()) { System.out.println("La lsite est vide"); return; } while (iter.hasNext()) { Contact ct = (Contact) iter.next(); System.out.println("Matricule :" + ct.getNumMatCnt() + " Nom :" + ct.getNomNomCnt() + " Prénom :" + ct.getNomPrnCnt()); } } }

Page 13: TP3-Passage vers Spring.pdf

[email protected] Page 13

Passage vers Spring

2.8 Question ?

Qu'est ce qu'on remarque ?

Si on veut utiliser une autre implémentation de ContactDao, qu'est ce qu'il faut

faire?