JEE Spring MVC
-
Author
sabati-abdo -
Category
Documents
-
view
227 -
download
19
Embed Size (px)
Transcript of 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

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

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…

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

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

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.

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.

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.

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

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

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

J2EE : Par M.Youssfi
Structure du projet
Couche DAO
Couche Métier
Spring MVC
Couche DAO

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

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

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>

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:

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}

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 >

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

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>

J2EE : Par M.Youssfi
Application2
Correction : Voir Vidéo