Vous êtes sur la page 1sur 46

Architecture J2EE

M.Youssfi

Architecture J2EE
Serveur dapplication : TOMCAT
Client Lger HTML CSS Couche WEB Couche Mtier Couche DAO

Contrleur Servlet

2 3
Modle 5 Java Beans
STRUTS JSF Spring MVC

Java Script
XML Ajax Flash

HTTP

4
Vue JSP

Mtier

DAO
Donnes Hibernate

Couche service

JDBC

SGBD

Client Lourd AWT SWING

Spring

RMI/EJB/CORBA/SOAP

SWT

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

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

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..

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

MetierImpl
dao: DaoImpl calcul() : double

DaoImpl
getValue() : double

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

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.

Exemple de coupage faible


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

IMetier
calcul() : double

IDao
getValue() : double

MetierImpl dao: IDao

DaoImpl
getValue() : double

calcul() : 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 }

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.

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.

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

Spring MVC

Spring MVC

Architecture de Spring MVC

Spring MVC Architecture

Spring MVC

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, ...

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 * 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

handleRequest()

Structure du projet
Couche DAO

Couche Mtier

Spring MVC

Couche DAO

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

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>

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>

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 }

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>

application-servlet-config.xml (suite)

Spring MVC

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>

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="/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 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>

Application2

Correction : Voir Vido