0% ont trouvé ce document utile (0 vote)
72 vues46 pages

J2EE Spring

Ce document décrit l'architecture d'une application J2EE en détaillant ses différentes couches et le rôle du framework Spring dans celles-ci. Il explique également les concepts d'inversion de contrôle et d'injection de dépendances avec Spring pour réduire le couplage entre les classes.

Transféré par

aminekazdari4
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
72 vues46 pages

J2EE Spring

Ce document décrit l'architecture d'une application J2EE en détaillant ses différentes couches et le rôle du framework Spring dans celles-ci. Il explique également les concepts d'inversion de contrôle et d'injection de dépendances avec Spring pour réduire le couplage entre les classes.

Transféré par

aminekazdari4
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

Architecture J2EE

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

Inversion
de Contrôle
MVC
AOP

Web
Remoting Spring services

JDBC Web Flow

JMS/JMX
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…
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..
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
Presentation MetierImpl
1 1 DaoImpl
metier:MetierImpl dao: DaoImpl
main(String[] calcul() : double getValue() : double
a):void
package dao;
package metier; public class DaoImpl {
import dao.DaoImpl; public double getValue(){
public class MetierImpl { return(5);
private DaoImpl dao; }
public MetierImpl() { }
dao=new DaoImpl();
package pres;
}
import metier.MetierImpl;
public double calcul(){
public class Presentation {
double nb=dao.getValue();
private static MetierImpl metier;
return 2*nb;
public static void main(String[]
} args) {
} metier=new MetierImpl();
System.out.println(metier.calcul());
}
}
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.
Exemple de coupage faible
Presentation IMetier
1 1 IDao
metier:IMetier calcul() : double getValue() : double
main(String[]
a):void
MetierImpl
DaoImpl
dao: IDao
package metier; getValue() : double
public interface IMetier { calcul() : double
public double calcul();
}
package dao;
package metier; public interface IDao {
import dao.IDao; public double getValue();
public class MetierImpl }
implements IMetier {
private IDao dao; package dao;
public double calcul() { public class DaoImpl implements IDao
double nb=dao.getValue(); {
return 2*nb; public double getValue() {
} return 5;
// Getters et Setters }
} }
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.
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
d:DaoImpl
dao:
getValue() : double
calcul() : 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(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.
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
Spring MVC
Spring MVC
 Architecture de Spring MVC
Spring MVC Architecture
Spring MVC
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, ...
Application
 Création d’une application web qui permet d’afficher
les utilisateurs d’un département saisi.
Architecture de l’application
WEB
Métier DAO
Contrôleur

Interface

Interface
Classes

Classes
JSP

Modèle
1 1
Controller IMetier IDao
getUsers(String dep):List getUsers(String dep):List
User
idUser : long
login : String
* Pass : String
UserController MetierImpl DaoImpl
metier : IMetier Nom : String
Dao : IDao users : List<User> Dep : String
getUsers(String dep):List // Getters
handleRequest() getUsers(String dep):List // Setters
Structure du projet
Couche DAO

Couche Métier

Spring MVC
Couche DAO
 L’entité User.java
package dao;

public class User {


private Long idUser; private String login;
private String pass; private String nom;
private String departement;

public User() {
}
public User(String login, String pass, String nom, String dep) {
this.login = login;
this.pass = pass;
this.nom = nom;
this.departement = dep;
}
// Getters et Setters
}
Couche DAO
 Interface de la couche DAO
package dao;
import java.util.List;
public interface IDao {
public void addUser(User u);
public List<User> getUsersByDep(String dep);
}
Couche DAO
 Une implémentation DAO
package dao;
import java.util.*;
import org.apache.log4j.Logger;
public class DaoImpl implements IDao {
private List<User> users=new ArrayList<User>();
Logger log=Logger.getLogger(DaoImpl.class);
public void addUser(User u) {
u.setIdUser(new Long(users.size()+1));
users.add(u);
}
public List<User> getUsersByDep(String dep) {
List<User> urs=new ArrayList<User>();
for(User u:users)
if(u.getDepartement().equals(dep))
urs.add(u);
return urs;
}
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étier


package metier;
import java.util.List;
import dao.User;

public interface IMetier {


public void addUser(User u);
public List<User> getUsersByDep(String dep);
}
Couche Métier
 Implémentation de la couche métier
package 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>
Le fichier web.xml
Pour Spring MVC
<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>
Spring MVC
Structure de beans Spring pour l’injection des dépendances:
<?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>
Contrôleur Version XML
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
}
Spring MVC
 application-servlet-config.xml:
 Mapping des URL :

<bean
class="org.springframework.web.servlet.handler.SimpleUrlH
andlerMapping">
<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.BeanNameViewResolver"/>
<!-- les vues -->
<bean id="vueUsers"
class="org.springframework.web.servlet.view.JstlView">
<property name="url">
<value>/Vues/Users.jsp</value>
</property>
</bean>
 La vue : Users.jsp Spring MVC
<%@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 annotations
package web
import …
@Controller
public class UserController {
@Autowired
private 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");
}
}
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>
 La vue : Users.jsp Spring MVC
<%@ 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>
Application2
Correction : Voir Vidéo

Vous aimerez peut-être aussi