46
Architecture J2EE M.Youssfi

J2EE Spring

Embed Size (px)

Citation preview

Page 1: J2EE Spring

Architecture J2EE

M.Youssfi

Page 2: J2EE Spring

Serveur d’application : TOMCAT

Couche WEB Couche Métier

Couche DAO

Architecture J2EE

SGBD

DonnéesMétier

ContrôleurServlet

VueJSP

ModèleJava Beans

12

34

56

Client Léger

• HTML

• CSS

• Java Script

• XML

•Ajax

•Flash

DAO

Hibernate

JDBC

HTTP

Client Lourd

•AWT

•SWING

•SWT

RMI/EJB/CORBA/SOAP

STRUTSJSFSpring MVC

Spring

Couche service

Page 3: J2EE Spring

Architecture d’une application La couche [dao] s'occupe de l'accès aux données, le plus

souvent des données persistantes au sein d'un SGBD. Mais cela peut être aussi des données qui proviennent de capteurs, du réseau, ...

La couche [metier] implémente les algorithmes " métier " de l'application. Cette couche est indépendante de toute forme d'interface avec l'utilisateur. C'est généralement la couche la plus stable de l'architecture. Elle ne change pas si on change l'interface utilisateur ou la façon

d'accéder aux données nécessaires au fonctionnement de l'application.

La couche [Présentation] qui est l'interface (graphique souvent) qui permet à l'utilisateur de piloter l'application et d'en recevoir des informations.

Page 4: J2EE Spring

Spring FrameWork

Page 5: J2EE Spring

Projets Spring

Spring

Inversion de Contrôle

Inversion de Contrôle

MVCAOP

JDBC

JMS/JMX

Web Flow

RemotingWeb

services

Page 6: J2EE Spring

Rôle de Spring Spring est un framework qui peut intervenir dans les différentes

parties d’une projet J2EE : Spring IOC: permet d’assurer l’injection des dépendances entres

les différentes couches de votre application (Inversion du contrôle), de façon à avoir un faible couplage entre les différentes parties de votre application.

Spring MVC: Implémenter le modèle MVC d’une application web au même titre que STRUTS et JSF

Spring AOP: permet de faire la programmation orientée Aspect. Peut être utilisé au niveau de la couche métier pour la gestion des

transactions. Spring JDBC: Peut être exploiter au niveau de la couche d’accès

aux bases de données Spring Remoting : offre un support qui permet de faciliter l’accès à

un objet distant RMI ou EJB. Spring Web Services : permet de faciliter la création et l’accès aux

web services Etc…

Page 7: J2EE Spring

Spring IOC

Inversion de Contrôle

Page 8: J2EE Spring

Rappels de quelque principes de conception Une application qui n’évolue pas meurt. Une application doit être fermée à la modification et

ouverte à l’extension. Une application doit s’adapter aux changements Efforcez-vous à coupler faiblement vos classes. Programmer une interface et non une

implémentation Etc..

Page 9: J2EE Spring

Couplage fort Quand une classe A est lié à une classe B, on dit

que la classe A est fortement couplée à la classe B. La classe A ne peut fonctionner qu’en présence de

la classe B. Si une nouvelle version de la classe B (soit B2), est

crée, on est obligé de modifier dans la classe A. Modifier une classe implique:

Il faut disposer du code source. Il faut recompiler, déployer et distribuer la nouvelle

application aux clients. Ce qui engendre un cauchemar au niveau de la

maintenance de l’aplication

Page 10: J2EE Spring

Exemple de couplage fort

package dao;public class DaoImpl { public double getValue(){ return(5); }}

MetierImpl

dao: DaoImpl

calcul() : double

DaoImpl

getValue() : double

1

package metier;import dao.DaoImpl;public class MetierImpl { private DaoImpl dao; public MetierImpl() { dao=new DaoImpl(); }public double calcul(){ double nb=dao.getValue(); return 2*nb;}}

package pres;import metier.MetierImpl;public class Presentation {private static MetierImpl metier;public static void main(String[] args)

{metier=new MetierImpl();System.out.println(metier.calcul());}}

Presentation

metier:MetierImpl

main(String[] a):void

1

Page 11: J2EE Spring

Problèmes du couplage fort Dans l’exemple précédent, les classes MetierImpl et DaoImpl

sont liées par un couplage fort. De même pour les classe Presentation et MetierImpl

Ce couplage fort n’a pas empêché de résoudre le problème au niveau fonctionnel.

Mais cette conception nous ne a pas permis de créer une application fermée à la modification et ouverte à l’extension.

En effet, la création d’une nouvelle version de la méthode getValue() de la classe DaoImpl, va nous obliger d’éditer le code source de l’application aussi bien au niveau de DaoImpl et aussi MetierImpl.

De ce fait nous avons violé le principe « une application doit être fermée à la modification et ouverte à l’exetension»

Nous allons voir que nous pourrons faire mieux en utilisant le couplage faible.

Page 12: J2EE Spring

Couplage Faible.

Pour utiliser le couplage faible, nous devons utiliser les interfaces.

Considérons une classe A qui implémente une interface IA, et une classe B qui implémente une interface IB.

Si la classe A est liée à l’interface IB par une association, on dit que le classe A et la classe B sont liées par un couplage faible.

Cela signifie que la classe B peut fonctionner avec n’importe quelle classe qui implémente l’interface IA.

En effet la classe B ne connait que l’interface IA. De ce fait n’importe quelle classe implémentant cette interface peut être associée à la classe B, sans qu’il soit nécéssaire de modifier quoi que se soit dans la classe B.

Avec le couplage faible, nous pourrons créer des application fermée à la modification et ouvertes à l’extension.

Page 13: J2EE Spring

Exemple de coupage faible

package dao;public class DaoImpl implements IDao {public double getValue() { return 5;}}

MetierImpl

dao: IDao

calcul() : double

DaoImpl

getValue() : double

1 IDao

getValue() : double

package dao;public interface IDao {public double getValue();}

package metier;import dao.IDao;public class MetierImpl

implements IMetier { private IDao dao;public double calcul() {double nb=dao.getValue(); return 2*nb;}// Getters et Setters}

IMetier

calcul() : double

Presentation

metier:IMetier

main(String[] a):void

1

package metier;public interface IMetier { public double calcul();}

Page 14: J2EE Spring

Injection des dépendances avec Spring. L’injection des dépendance, ou l’inversion de

contrôle est un concept qui intervient généralement au début de l’exécution de l’application.

Spring IOC commence par lire un fichier XML qui déclare quelles sont différentes classes à instancier et d’assurer les dépendances entre les différentes instances.

Quand on a besoin d’intégrer une nouvelle implémentation à une application, il suffirait de la déclarer dans le fichier xml de beans spring.

Page 15: J2EE Spring

Injection des dépendances dans une application java standard

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN"

"http://www.springframework.org/dtd/spring-beans-2.0.dtd" >

<beans> <bean id="d" class="dao.DaomImpl2"></bean> <bean id="metier" class="metier.MetierImpl"> <property name="dao" ref="d"></property> </bean></beans>

metier:MetierImpl

dao:

calcul() : double

d:DaoImpl

getValue() : double

Page 16: J2EE Spring

Injection des dépendances dans une application java standard

package pres;import metier.IMetier;import org.springframework.beans.factory.xml.XmlBeanFactory;import org.springframework.core.io.ClassPathResource;public class Presentation {public static void main(String[] args) {

XmlBeanFactory bf=new XmlBeanFactory(new ClassPathResource("spring-beans.xml"));

IMetier m=(IMetier) bf.getBean("metier"); System.out.println(m.calcul());}}

Pour une application java classique, le fichier « spring-beans.xml » devrait être enregistré dans la racine du classpath. C’est-à-dire le dossier src.

Page 17: J2EE Spring

Structure du projet

Page 18: J2EE Spring

Injection des dépendances dans une application web Dans une application web, SpringIOC est appelé au démarrage du

serveur en déclarant le listener ContextLoaderListener dans le fichier web.xml

<context-param><param-name>contextConfigLocation</param-name><param-value>/WEB-INF/spring-beans.xml</param-value>

</context-param><listener>

<listener-class> org.springframework.web.context.ContextLoaderListener

</listener-class></listener> Dans cette déclaration, CotextLoaderListener est appelé par Tomcat au

moment du démarrage de l’application. Ce listener cherchera le fichier de beans spring « spring-beans.xml » stocké dans le dossier WEB-INF. ce qui permet de faire l’injection des dépendances entre MetierImpl et DaoImpl

Page 19: J2EE Spring

Spring MVC

Page 20: J2EE Spring

Spring MVC

Architecture de Spring MVC

Page 21: J2EE Spring

Spring MVC Architecture

Page 22: J2EE Spring

Spring MVC

Page 23: J2EE Spring

Spring MVC 1- le client fait une demande au contrôleur. Celui-ci voit

passer toutes les demandes des clients. C'est la porte d'entrée de l'application. C'est le C de MVC. Ici le contrôleur est assuré par une servlet générique : org.springframework.web.servlet.DispatcherServlet

2- le contrôleur principal [DispatcherServlet] fait exécuter l'action demandée par l'utilisateur par une classe implémentant l'interface : org.springframework.web.servlet.mvc.Controller A cause du nom de l'interface, nous appellerons une telle classe un

contrôleur secondaire pour le distinguer du contrôleur principal [DispatcherServlet] ou simplement contrôleur lorsqu'il n'y a pas d'ambiguïté.

3- le contrôleur [Controller] traite une demande particulière de l'utilisateur. Pour ce faire, il peut avoir besoin de l'aide de la couche métier. Une fois la demande du client traitée, celle-ci peut appeler diverses réponses. Un exemple classique est : une page d'erreurs si la demande n'a pu être traitée correctement une page de confirmation sinon

Page 24: J2EE Spring

Spring MVC 4- Le contrôleur choisit la réponse (= vue) à envoyer au client. Choisir

la réponse à envoyer au client nécessite plusieurs étapes : choisir l'objet qui va générer la réponse. C'est ce qu'on appelle la vue V, le

V de MVC. Ce choix dépend en général du résultat de l'exécution de l'action demandée par l'utilisateur.

lui fournir les données dont il a besoin pour générer cette réponse. En effet, celle-ci contient le plus souvent des informations calculées par la couche métier ou le contrôleur lui-même. Ces informations forment ce qu'on appelle le modèle M de la vue, le M de MVC. Spring MVC fournit ce modèle sous la forme d'un dictionnaire de type java.util.Map.

Cette étape consiste donc en le choix d'une vue V et la construction du modèle M nécessaire à celle-ci.

5- Le contrôleur DispatcherServlet demande à la vue choisie de s'afficher. Il s'agit d'une classe implémentant l'interface org.springframework.web.servlet.View Spring MVC propose différentes implémentations de cette interface pour

générer des flux HTML, Excel, PDF, ... 6. le générateur de vue View utilise le modèle Map préparé par le

contrôleur Controller pour initialiser les parties dynamiques de la réponse qu'il doit envoyer au client.

7. la réponse est envoyée au client. La forme exacte de celle-ci dépend du générateur de vue. Ce peut être un flux HTML, XML, PDF, Excel, ...

Page 25: J2EE Spring

Application

Création d’une application web qui permet d’afficher les utilisateurs d’un département saisi.

Page 26: J2EE Spring

Architecture de l’applicationC

on

trô

leu

r

JS

P

Inte

rfac

e

Cla

sse

s

Inte

rfac

e

Cla

sse

s

WEBMétier DAO

UseridUser : longlogin : StringPass : StringNom : StringDep : String// Getters// Setters

IDaogetUsers(String dep):List

DaoImplusers : List<User>getUsers(String dep):List

IMetiergetUsers(String dep):List

MetierImplDao : IDao

getUsers(String dep):List

1

Modèle

*

Controller

UserControllermetier : IMetier

handleRequest()

1

Page 27: J2EE Spring

Structure du projet

Couche DAO

Couche Métier

Spring MVC

Page 28: J2EE Spring

Couche DAO

Page 29: J2EE Spring

Couche DAO

Interface de la couche DAOpackage dao;

import java.util.List;

public interface IDao {

public void addUser(User u);

public List<User> getUsersByDep(String dep);

}

Page 30: J2EE Spring

Couche DAO

Page 31: J2EE Spring

Couche DAO DaoImpl (Suite)

public void init(){

this.addUser(new User("root", "123", "Alpha","math"));

this.addUser(new User("user", "432", "Gamma","math"));

this.addUser(new User("toto", "123", "wild","math"));

this.addUser(new User("admin", "admin", "Mandour","info"));

this.addUser(new User("user1", "user1", "Gamma","info"));

log.info("Création de 5 Utilisateurs");

}

}

Page 32: J2EE Spring

Couche Métier

Interface de la couche métierpackage metier;

import java.util.List;

import dao.User;

public interface IMetier {

public void addUser(User u);

public List<User> getUsersByDep(String dep);

}

Page 33: J2EE Spring

Couche Métier Implémentation de la couche métierpackage metier;

import java.util.List;

import dao.IDao;

import dao.User;

public class MetierIpml implements IMetier {

private IDao dao;

public void setDao(IDao dao) {

this.dao = dao;

}

public void addUser(User u) {

dao.addUser(u);

}

public List<User> getUsersByDep(String dep) {

return dao.getUsersByDep(dep);

} }

Page 34: J2EE Spring

Le fichier web.xml

Pour L’injection des dépendances :

<context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring-beans.xml</param-value> </context-param> <listener>

<listener-class>org.springframework.web.context.ContextLoaderListener

</listener-class></listener>

Page 35: J2EE Spring

Le fichier web.xml

<servlet> <servlet-name>action</servlet-name> <servlet-class>

org.springframework.web.servlet.DispatcherServlet </servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/application-servlet-config.xml</param-value> </init-param></servlet><servlet-mapping> <servlet-name>action</servlet-name> <url-pattern>*.html</url-pattern></servlet-mapping>

Pour Spring MVC

Page 36: J2EE Spring

Spring MVC

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"> <bean class="dao.DaoImpl" id="dao" init-method="init"> </bean> <bean id="metier" class="metier.MetierIpml"> <property name="dao" ref="dao"></property> </bean> </beans>

Structure de beans Spring pour l’injection des dépendances:

Page 37: J2EE Spring

Contrôleur Version XML

Page 38: J2EE Spring

Spring MVC Le Contrôleur:UserController.java

package web;import ………public class UserController implements Controller {

private IMetier metier;public ModelAndView handleRequest(

HttpServletRequest request,HttpServletResponse response) throws Exception {

String dep=request.getParameter("departement");Map modele=new HashMap();modele.put("dep", dep);List<User> users=metier.getUsersByDep(dep);modele.put("users", users);return new ModelAndView("vueUsers",modele);

}// Getters et Setters}

Page 39: J2EE Spring

Spring MVC application-servlet-config.xml:

Mapping des URL : <bean

class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <prop key="chercheUser.html">userController</prop> </props> </property> </bean>

Page 40: J2EE Spring

Spring MVC application-servlet-config.xml (suite)

Déclaration du contrôleur :<!-- LES CONTROLEURS --> <bean id="userController" class="web.UserController"> <property name="metier"> <ref bean="metier"/> </property> </bean> Déclaration du résolveur de vues: <!-- le résolveur de vues --> <bean class=

"org.springframework.web.servlet.view.BeanNameViewResolver"/> <!-- les vues --> <bean id="vueUsers"

class="org.springframework.web.servlet.view.JstlView"> <property name="url"> <value>/Vues/Users.jsp</value> </property> </bean>

Page 41: J2EE Spring

Spring MVC

La vue : Users.jsp<%@taglib uri="/WEB-INF/c.tld" prefix="c" %><html> <body> <form action="chercheUser.html" method="post"> Département :<input type="text" name="departement" value="${dep}"> <input type="submit" name="action" value="Chercher"> <table border="1" width="80%"> <tr> <th>ID</th><th>Login</th><th>Pass</th> <th>Nom</th><th>Département</th> </tr> <c:forEach items="${users}" var="u"> <tr> <td><c:out value="${u.idUser}"/></td> <td><c:out value="${u.login}"/></td> <td><c:out value="${u.pass}"/></td> <td><c:out value="${u.nom}"/></td> <td><c:out value="${u.departement}"/></td> </tr> </c:forEach> </table> </form> </body></html>

Page 42: J2EE Spring

Utilisation des annotationspackage web

import …

@Controllerpublic class UserController {

@Autowiredprivate IMetier metier;

@RequestMapping(value="/chercher")public String chercher(){

return("VueUsers");

}

@RequestMapping(value="/chercheUsers")public String chercheUsers(@RequestParam String dep, Model model){

model.addAttribute("dep",dep);

model.addAttribute("users", metier.getUsersByDep(dep));

return("VueUsers");

}

}

Page 43: J2EE Spring

Spring MVC Quand on utilise les annotations, le contenu du fichier application-

servlet-config.xml est réduit au code xml suivant:

<!-- Spécifier les packages où Spring devrait chercher les contrôleurs au démarrage-->

<context:component-scan base-package="web"/><!-- Utiliser un résolveur de vues simple qui suppose que

toutes les vues se terminent par .jsp et que qu’elles sont stockées dans le dossier Vues-->

<bean class= "org.springframework.web.servlet.view.InternalResourceViewResolver">

<property name="prefix" value="/Vues/"/> <property name="suffix" value=".jsp"/></bean>

Page 44: J2EE Spring

Spring MVC

La vue : Users.jsp<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>

<html>

<body>

<form action="chercheUsers.html" method="get">

Département:<input type="text" name="dep" value="${dep}">

<input type="submit" value="OK">

</form>

<table width="80%" border="1">

<tr>

<th>ID</th><th>Login</th><th>Pass</th><th>Nom</th><th>DEp</th>

</tr>

<c:forEach var="u" items="${users}">

<tr>

<td>${u.idUser}</td><td>${u.nom}</td><td>${u.pass}</td>

<td>${u.nom}</td><td>${u.departement}</td>

</tr>

</c:forEach>

</table>

</body>

</html>

Page 45: J2EE Spring

Application2

Page 46: J2EE Spring

Correction : Voir Vidéo