Vous êtes sur la page 1sur 23

J2EE : Par M.

Youssfi

Architecture J2EE

M.Youssfi

Architecture J2EE
Serveur dapplication : TOMCAT
Client Lger HTML CSS Java Script XML Ajax Flash HTTP Couche WEB Couche Mtier Couche DAO

Contrleur Servlet

2 3
Modle

4
Vue JSP

5 Java
Beans
STRUTS JSF Spring MVC

Mtier

DAO
Donnes Hibernate

Couche service

JDBC

SGBD

Client Lourd AWT SWING SWT

Spring

RMI/EJB/CORBA/SOAP

J2EE : Par M.Youssfi

Architecture dune application


La couche [dao] s'occupe de l'accs aux donnes, le plus souvent des donnes persistantes au sein d'un SGBD. Mais cela peut tre aussi des donnes qui proviennent de capteurs, du rseau, ... La couche [metier] implmente les algorithmes " mtier " de l'application. Cette couche est indpendante de toute forme d'interface avec l'utilisateur.
C'est gnralement la couche la plus stable de l'architecture. Elle ne change pas si on change l'interface utilisateur ou la faon d'accder aux donnes ncessaires au fonctionnement de l'application.

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

Spring FrameWork

J2EE : Par M.Youssfi

Projets Spring
Inversion de Contrle MVC AOP

Remoting

Spring
JDBC JMS/JMX

Web services

Web Flow

Rle de Spring
Spring est un framework qui peut intervenir dans les diffrentes parties dune projet J2EE :
Spring IOC: permet dassurer linjection des dpendances entres les diffrentes couches de votre application (Inversion du contrle), de faon avoir un faible couplage entre les diffrentes parties de votre application. Spring MVC: Implmenter le modle MVC dune application web au mme titre que STRUTS et JSF Spring AOP: permet de faire la programmation oriente Aspect. Peut tre utilis au niveau de la couche mtier pour la gestion des transactions. Spring JDBC: Peut tre exploiter au niveau de la couche daccs aux bases de donnes Spring Remoting : offre un support qui permet de faciliter laccs un objet distant RMI ou EJB. Spring Web Services : permet de faciliter la cration et laccs aux web services Etc

J2EE : Par M.Youssfi

Spring IOC

Inversion de Contrle

Rappels de quelque principes de conception


Une application qui nvolue pas meurt. Une application doit tre ferme la modification et ouverte lextension. Une application doit sadapter aux changements Efforcez-vous coupler faiblement vos classes. Programmer une interface et non une implmentation Etc..

J2EE : Par M.Youssfi

Couplage fort
Quand une classe A est li une classe B, on dit que la classe A est fortement couple la classe B. La classe A ne peut fonctionner quen prsence de la classe B. Si une nouvelle version de la classe B (soit B2), est cre, on est oblig de modifier dans la classe A. Modifier une classe implique:
Il faut disposer du code source. Il faut recompiler, dployer et distribuer la nouvelle application aux clients. Ce qui engendre un cauchemar au niveau de la maintenance de laplication

Exemple de couplage fort


Presentation metier:MetierImpl main(String[] a):void 1 MetierImpl dao: DaoImpl calcul() : double
getValue() : double

DaoImpl

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 dao; public class DaoImpl { public double getValue(){ return(5); } }


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

J2EE : Par M.Youssfi

Problmes du couplage fort


Dans lexemple prcdent, les classes MetierImpl et DaoImpl sont lies par un couplage fort. De mme pour les classe Presentation et MetierImpl Ce couplage fort na pas empch de rsoudre le problme au niveau fonctionnel. Mais cette conception nous ne a pas permis de crer une application ferme la modification et ouverte lextension. En effet, la cration dune nouvelle version de la mthode getValue() de la classe DaoImpl, va nous obliger dditer le code source de lapplication aussi bien au niveau de DaoImpl et aussi MetierImpl. De ce fait nous avons viol le principe une application doit tre ferme la modification et ouverte lexetension 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. Considrons une classe A qui implmente une interface IA, et une classe B qui implmente une interface IB. Si la classe A est lie linterface IB par une association, on dit que le classe A et la classe B sont lies par un couplage faible. Cela signifie que la classe B peut fonctionner avec nimporte quelle classe qui implmente linterface IA. En effet la classe B ne connait que linterface IA. De ce fait nimporte quelle classe implmentant cette interface peut tre associe la classe B, sans quil soit ncssaire de modifier quoi que se soit dans la classe B. Avec le couplage faible, nous pourrons crer des application ferme la modification et ouvertes lextension.

J2EE : Par M.Youssfi

Exemple de coupage faible


Presentation metier:IMetier main(String[] a):void MetierImpl
package metier; public interface IMetier { public double calcul(); }

IMetier
calcul() : double

IDao
getValue() : double

dao: IDao calcul() : double

DaoImpl
getValue() : double

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 }

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

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

Injection des dpendances avec Spring.


Linjection des dpendance, ou linversion de contrle est un concept qui intervient gnralement au dbut de lexcution de lapplication. Spring IOC commence par lire un fichier XML qui dclare quelles sont diffrentes classes instancier et dassurer les dpendances entre les diffrentes instances. Quand on a besoin dintgrer une nouvelle implmentation une application, il suffirait de la dclarer dans le fichier xml de beans spring.

J2EE : Par M.Youssfi

Injection des dpendances 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-beans2.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 dpendances 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. Cest--dire le dossier src.

J2EE : Par M.Youssfi

Structure du projet

Injection des dpendances dans une application web


Dans une application web, SpringIOC est appel au dmarrage du serveur en dclarant 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 dclaration, CotextLoaderListener est appel par Tomcat au moment du dmarrage de lapplication. Ce listener cherchera le fichier de beans spring spring-beans.xml stock dans le dossier WEB-INF. ce qui permet de faire linjection des dpendances entre MetierImpl et DaoImpl

J2EE : Par M.Youssfi

Spring MVC

Spring MVC
Architecture de Spring MVC

J2EE : Par M.Youssfi

Spring MVC Architecture

Spring MVC

J2EE : Par M.Youssfi

Spring MVC
1- le client fait une demande au contrleur. Celui-ci voit passer toutes les demandes des clients. C'est la porte d'entre de l'application. C'est le C de MVC. Ici le contrleur est assur par une servlet gnrique : org.springframework.web.servlet.DispatcherServlet 2- le contrleur principal [DispatcherServlet] fait excuter l'action demande par l'utilisateur par une classe implmentant l'interface : org.springframework.web.servlet.mvc.Controller
A cause du nom de l'interface, nous appellerons une telle classe un contrleur secondaire pour le distinguer du contrleur principal [DispatcherServlet] ou simplement contrleur lorsqu'il n'y a pas d'ambigut.

3- le contrleur [Controller] traite une demande particulire de l'utilisateur. Pour ce faire, il peut avoir besoin de l'aide de la couche mtier. Une fois la demande du client traite, celle-ci peut appeler diverses rponses. Un exemple classique est :
une page d'erreurs si la demande n'a pu tre traite correctement une page de confirmation sinon

Spring MVC
4- Le contrleur choisit la rponse (= vue) envoyer au client. Choisir la rponse envoyer au client ncessite plusieurs tapes :
choisir l'objet qui va gnrer la rponse. C'est ce qu'on appelle la vue V, le V de MVC. Ce choix dpend en gnral du rsultat de l'excution de l'action demande par l'utilisateur. lui fournir les donnes dont il a besoin pour gnrer cette rponse. En effet, celle-ci contient le plus souvent des informations calcules par la couche mtier ou le contrleur lui-mme. Ces informations forment ce qu'on appelle le modle M de la vue, le M de MVC. Spring MVC fournit ce modle 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 modle M ncessaire celle-ci.

5- Le contrleur DispatcherServlet demande la vue choisie de s'afficher. Il s'agit d'une classe implmentant l'interface org.springframework.web.servlet.View
Spring MVC propose diffrentes implmentations de cette interface pour gnrer des flux HTML, Excel, PDF, ...

6. le gnrateur de vue View utilise le modle Map prpar par le contrleur Controller pour initialiser les parties dynamiques de la rponse qu'il doit envoyer au client. 7. la rponse est envoye au client. La forme exacte de celle-ci dpend du gnrateur de vue. Ce peut tre un flux HTML, XML, PDF, Excel, ...

J2EE : Par M.Youssfi

Application
Cration dune application web qui permet dafficher les utilisateurs dun dpartement saisi.

Architecture de lapplication
WEB Mtier DAO

Contrleur

Interface

Interface
1

Classes

Modle Controller
1

IMetier
getUsers(String dep):List

IDao
getUsers(String dep):List

Classes

JSP

User UserController
metier : IMetier handleRequest() * idUser : long login : String Pass : String Nom : String Dep : String // Getters // Setters

MetierImpl
Dao : IDao getUsers(String dep):List

DaoImpl
users : List<User> getUsers(String dep):List

J2EE : Par M.Youssfi

Structure du projet
Couche DAO

Couche Mtier

Spring MVC

Couche DAO

J2EE : Par M.Youssfi

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

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("Cration de 5 Utilisateurs"); } }

Couche Mtier
Interface de la couche mtier
package metier; import java.util.List; import dao.User; public interface IMetier { public void addUser(User u); public List<User> getUsersByDep(String dep); }

J2EE : Par M.Youssfi

Couche Mtier
Implmentation de la couche mtier
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 Linjection des dpendances :
<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>

J2EE : Par M.Youssfi

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 linjection des dpendances:
<?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>

J2EE : Par M.Youssfi

Contrleur Version XML

Spring MVC
Le Contrleur: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 }

J2EE : Par M.Youssfi

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)
Dclaration du contrleur :
<!-- LES CONTROLEURS --> <bean id="userController" class="web.UserController"> <property name="metier"> <ref bean="metier"/> </property> </bean>

Dclaration du rsolveur de vues:


<!-- le rsolveur 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>

J2EE : Par M.Youssfi

La vue : Users.jsp

<%@taglib uri="/WEB-INF/c.tld" prefix="c" %> <html> <body> <form action="chercheUser.html" method="post"> Dpartement :<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>Dpartement</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>

Spring MVC

Utilisation des annotations


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

J2EE : Par M.Youssfi

Spring MVC
Quand on utilise les annotations, le contenu du fichier applicationservlet-config.xml est rduit au code xml suivant:
<!-- Spcifier les packages o Spring devrait chercher les contrleurs au dmarrage-->

<context:component-scan base-package="web"/>
<!-- Utiliser un rsolveur de vues simple qui suppose que toutes les vues se terminent par .jsp et que quelles sont stockes 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"> Dpartement:<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>

J2EE : Par M.Youssfi

Application2

Correction : Voir Vido