23
J2EE : Par M.Youssfi Architecture J2EE M.Youssfi Serveur d’application : TOMCAT Couche WEB Couche Métier Couche DAO Architecture J2EE SGBD Données Métier Contrôleur Servlet Vue JSP Modèle Java Beans 1 2 3 4 5 6 Client Léger • HTML • CSS • Java Script • XML •Ajax •Flash DAO Hibernate JDBC HTTP Client Lourd •AWT •SWING •SWT RMI/EJB/CORBA/SOAP STRUTS JSF Spring MVC Spring Couche service

JEE Spring MVC

Embed Size (px)

Citation preview

Page 1: JEE  Spring MVC

J2EE : Par M.Youssfi

Architecture J2EE

M.Youssfi

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 2: JEE  Spring MVC

J2EE : Par M.Youssfi

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.

Spring FrameWork

Page 3: JEE  Spring MVC

J2EE : Par M.Youssfi

Projets Spring

Spring

Inversion de Contrôle

Inversion de Contrôle

MVCAOP

JDBC

JMS/JMX

Web Flow

RemotingWeb

services

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 4: JEE  Spring MVC

J2EE : Par M.Youssfi

Spring IOC

Inversion de Contrôle

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 5: JEE  Spring MVC

J2EE : Par M.Youssfi

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

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 6: JEE  Spring MVC

J2EE : Par M.Youssfi

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.

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 7: JEE  Spring MVC

J2EE : Par M.Youssfi

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();}

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 8: JEE  Spring MVC

J2EE : Par M.Youssfi

Injection des dépendances dans une application java standard

<?xml version ="1.0" encoding ="UTF-8"?><! DOCTYPEbeans 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

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( newClassPathResource( "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 9: JEE  Spring MVC

J2EE : Par M.Youssfi

Structure du projet

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 10: JEE  Spring MVC

J2EE : Par M.Youssfi

Spring MVC

Spring MVC

� Architecture de Spring MVC

Page 11: JEE  Spring MVC

J2EE : Par M.Youssfi

Spring MVC Architecture

Spring MVC

Page 12: JEE  Spring MVC

J2EE : Par M.Youssfi

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

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 13: JEE  Spring MVC

J2EE : Par M.Youssfi

Application

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

Architecture de l’application

Con

trôl

eur

JSP

Inte

rfac

e

Cla

sses

Inte

rfac

e

Cla

sses

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 14: JEE  Spring MVC

J2EE : Par M.Youssfi

Structure du projet

Couche DAO

Couche Métier

Spring MVC

Couche DAO

Page 15: JEE  Spring MVC

J2EE : Par M.Youssfi

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);

}

Couche DAO

Page 16: JEE  Spring MVC

J2EE : Par M.Youssfi

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");

}}

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 17: JEE  Spring MVC

J2EE : Par M.Youssfi

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);}

� }

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 18: JEE  Spring MVC

J2EE : Par M.Youssfi

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

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/schem a/context"xsi:schemaLocation="http://www.springframework.org/ schema/beans

http://www.springframework.org/schema/beans/spring- beans-2.5.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx- 2.5.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/sprin g-context- 2.5.xsd">

<bean class="dao.DaoImpl" id="dao" init-method="ini t"></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 19: JEE  Spring MVC

J2EE : Par M.Youssfi

Contrôleur Version XML

Spring MVC

� Le Contrôleur:UserController.javapackage 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 20: JEE  Spring MVC

J2EE : Par M.Youssfi

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 >

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.BeanNameViewR esolver" /><!-- les vues -->

<bean id ="vueUsers" class ="org.springframework.web.servlet.view.JstlView" >

<property name="url" ><value >/Vues/Users.jsp </ value >

</ property ></ bean >

Page 21: JEE  Spring MVC

J2EE : Par M.Youssfi

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 >

Utilisation des annotationspackage web

import …

@Controller

public class UserController {

@Autowired

private IMetier metier ;

@RequestMapping(value= "/chercheUsers" )

public String chercheUsers(@RequestParam String dep, Model model){

model.addAttribute( "dep" ,dep);

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

return ( "VueUsers" );

}

@RequestMapping(value= "/chercher" )

public String chercher(){

return ( "VueUsers" );

}

}

Page 22: JEE  Spring MVC

J2EE : Par M.Youssfi

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 cherche r les contrôleurs au démarrage-->

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

toutes les vues se terminent par .jsp et que qu’ell es 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>

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 23: JEE  Spring MVC

J2EE : Par M.Youssfi

Application2

Correction : Voir Vidéo