SSpprriinngg MMVVCC 
Par : Abdelhakim Bachar 
DAVEO
Avant 
 Programmation web : Utilisation des Servlets 
 JSP ou formulaire HTML -> Submit to servlet -> Servlet Processes data -> 
Outputs information 
 Fonctionne très bien pour les petites applications, mais peut rapidement 
devenir hors de contrôle à cause du code HTML, les scrip-lets, java script, 
tag-libraries, l'accès base de données et la logique métier => C’est difficile à 
organiser. 
 En d'autres termes, le manque de structure peut provoquer une «soupe» de 
différentes technologies. 
 Les JSP sont compilées en Servlet
Une meilleure façon ? 
 Séparer les Data Access, Business Logic et Présentation à l'aide d'un 
framework MVC : 
 WebWork 
 Spring MVC 
 Struts 
 JSF 
 Tapisserie 
 …
Les choses ont changé : 
 Struts : est de loin le plus populaire. 
 Webwork : évolué pour Webwork2 
 Tapestry : est présent depuis un certain temps. 
 Spring : Le plus recent des frameworks. S'intègre bien avec n'importe quel 
autre cadre ou avec Spring MVC.
Pour quoi Spring ? 
 Tous frameworks s'intègrent bien avec Spring. 
 Spring offre une structure ouverte et organisée, avec l’injection des 
dépendances. 
 Configuration cohérente 
 S'intègre très bien avec les différents frameworks de mappings O/R comme 
Hibernate 
 Plus facile de tester les applications avec Spring. 
 Moins compliqué que d'autres frameworks. 
 Une communauté tres active.
Vous aimez Microsoft .NET? 
 Essayez Spring Framework .NET 
 http://sourceforge.net/projects/springnet/
Spring est plus qu’un framework de MVC : 
 Spring AMQP 
 Spring for Android 
 Spring Batch 
 Spring Data 
 Spring Framework 
 Spring Gemfire 
 Spring Integration 
 Spring Mobile 
 Spring .NET 
 Spring Roo 
 Spring Security 
 Spring Social 
 Spring Web Flow 
 Spring Web Services
Configuration de Spring MVC 
 Dans votre conteneur Web, les fichiers XML de Spring sont dans le même 
répertoire que votre fichier web.xml avec un “-servlet.xml" à la fin 
webapps 
/tradingapp 
/WEB-INF/spring-mvc-servlet.xml, web.xml) 
/classes 
/lib (all jar files) 
 Le dispatcher est configuré avec le nom spring-mvc donc il va chercher et 
charger le fichier ”spring-mvc-servlet.xml" pour configurer les URL-mapping 
et les controleurs.
Exemple de fichier web.xml 
<web-app> 
<servlet> 
<servlet-name>spring-mvc</servlet-name> 
<servlet-class>DispatcherServlet</servlet-class> 
</servlet> 
<servlet-mapping> 
<servlet-name>spring-mvc</servlet-name> 
<url-pattern>*.htm</url-pattern> 
</servlet-mapping> 
</web-app> 
Toute URL se terminant par le motif “. Htm” est acheminé vers le 
DispatcherServlet, le DispatcherServlet charge le fichier spring-mvc-servlet.xml 
et redérige l'utilisateur vers le bon contrôleur.
DispatcherServlet 
 Dans une architecture MVC les controleurs traitent toutes les requêtes. 
 Spring utilise un DispatcherServlet défini dans le fichier web.xml pour 
analyser la pattern d'URL de la requête, puis passer le contrôle au contrôleur 
approprié à l'aide d'un mapping URL définie dans un fichier de 
configuration Spring.
The DispatcherServlet
Notre formulaire 
 URL : http://localhost:8080/spring-mvc/login.htm
Le fichier spring-mvc-servlet.xml 
 Prenant l’URL /login.htm 
 Cette URL set termine par .htm le DispatcherServlet va charger le fichier 
spring-mvc-servlet.xml le controleur approporié. 
 Le fichier spring-mvc-servlet.xml utilise la classe SimpleUrlHandlerMapping 
pour mapper les URLs à des controleurs, dans notre cas le LoginController
Le fichier spring-mvc-servlet.xml 
<bean id="urlMapping” class="org.springframework.SimpleUrlHandlerMapping"> 
<property name="urlMap"> 
<map> 
<entry key="/login.htm” ref bean=”loginController"/> 
</map> 
</property> 
</bean> 
<bean id="loginController" 
class=”fr.daveo.springmvc.controllers.LoginController"> 
<property name="sessionForm” value=“true” /> 
<property name="commandName” value=“credentials” /> 
<property name="commandClass"> 
<value>fr.daveo.springmvc.model.Credentials</value> 
</property> 
<property name="validator"><ref bean="logonValidator"/></property> 
<property name="formView"><value>logon</value></property> 
<property name="successView"><value>home.htm</value></property> 
</bean>
Le controleur LoginController 
public class LoginController extends SimpleFormController { 
public ModelAndView onSubmit(Object command) throws 
ServletException { 
return new ModelAndView(new 
RedirectView(getSuccessView())); 
} 
} 
Je vous rappel le fichier spring-mvc-servler.xml 
<bean id="logonForm" class="fr.daveo.springmvc.controllers.LoginController"> 
<property name="sessionForm"><value>true</value></property> 
<property name="commandName"><value>credentials</value></property 
<property name="commandClass” value=“com.tradingapp.Credentials” /> 
<property name="validator"><ref bean="logonValidator"/></property> 
<property name="formView"><value>logon</value></property> 
<property name="successView” value=“portfolio.htm” /> 
</bean>
successView /portfolio.htm
Command/Form Backing Bean 
public class Credentials { 
private String username; 
private String password; 
public String getPassword() { 
return password; 
} 
public void setPassword(String password) { 
this.password = password; 
} 
public String getUsername() { 
return username; 
} 
public void setUsername(String username) { 
this.username = username; 
} 
}
Command/Form Backing Bean 
Username: 
Password: 
Le formulaire de login est "backed" au 
bean via la commandName “credentials” 
définies dans les le fichier spring-mvc-servlet. 
xml. “credentials” sera notre 
“command object” nous allons l’utiliser 
pour lier le formulaire au bean. 
public class Credentials { 
private String username; 
private String password; 
public String getPassword() { 
return password; 
} 
public void setPassword(String password) { 
this.password = password; 
} 
public String getUsername() { 
return username; 
} 
public void setUsername(String username) { 
this.username = username; 
} 
}
Messages d'erreurs 
Rappel du fichier de configuration: 
<bean id="logonForm" class="fr.daveo.springmvc.controllers.LoginController"> 
<property name="sessionForm"><value>true</value></property> 
<property name="commandName"><value>credentials</value></property 
<property name="commandClass” value=“com.tradingapp.Credentials” /> 
<property name="validator"><ref bean="logonValidator"/></property> 
<property name="formView"><value>logon</value></property> 
<property name="successView"><value>portfolio.htm</value></property> 
</bean> 
<bean id="loginValidator" class="fr.daveo.springmvc.controllers.LogonValidator"/>
Messages d'erreurs 
public class LogonValidator implements Validator { 
public void validate(Object obj, Errors errors) { 
Credentials credentials = (Credentials) obj; 
if (credentials.getPassword().equals("guest") == 
false) { 
errors.rejectValue("password", 
"error.login.invalid-pass”, 
null, "Incorrect Password."); 
} 
} 
}
Binding du formulaire avec Springs Tag Library 
<%@ taglib prefix="spring" uri="/spring" %> 
<html> 
<head><title>Daveo Login</title></head> 
<body> 
<spring:bind path="credentials.username"> 
<input type="text" name="username" /> 
</spring:bind> 
<spring:bind path="credentials.password"> 
<input type="password" name="password" /> 
</spring:bind> 
</body> 
</html>
Les annotations 
Avec les version 2.5 et 3 de Spring vous pouvez utiliser les annotations 
@Controller and @RequestMapping pour replacer la configuation XML. 
Controller : La classe contrôleur n’a plus besoin d’héiter des contrôleurs 
AbstractController ou SimpleFormController, tout simplement annoter la avec 
une annotation @Controller. 
RequestMapping : Pas plus de déclaration XML pour le mappage comme 
BeanNameUrlHandlerMapping, ControllerClassNameHandlerMapping ou 
SimpleUrlHandlerMapping, tous sont remplacées par une norme annotation 
@RequestMapping.
Autres annotations 
 PathVariable : permet de récupérer une partie de l'URL afin de l'utiliser 
comme paramètre dans le contrôleur 
 RequestParam : Paramètre de la requête dont l’identifiant est celui spécifié 
dans l’annotation. 
 SessionAttributes : Spring offre la possibilité de gérer implicitement le 
stockage, cette annotation permet de spécifier l’identifiant correspondant. 
 ModelAttribute : initialise un formulaire 
 …
Spring MVC & RESTful 
REST est un style d'architecture, pas un standard. Il n'existe donc pas de spécifications de 
REST. Il faut comprendre le style REST et ensuite concevoir des applications ou des services 
Web selon ce style. 
Bien que REST ne soit pas un standard, il utilise des standards. En particulier : 
 URI comme syntaxe universelle pour adresser les ressources, 
 HTTP un protocole sans état (stateless) avec un nombre très limité d'opérations, 
 Des liens hypermedia dans des documents (X)HTML et XML pour représenter à la fois le 
contenu des informations et la transition entre états de l'application, 
 Les types MIME comme text/xml, text/html, image/jpeg, application/pdf, video/mpeg pour 
la représentation des ressources. 
REST concerne l'architecture globale d'un système. Il ne définit pas la manière de réaliser 
dans les détails. En particulier, des services REST peuvent être réalisés en .NET, JAVA, CGI 
ou COBOL.
RESTful : URI Templates 
Spring 3 a introduit l’URI templates via l’annotation @PathVariable, voici un exemple : 
@RequestMapping("/hotels/{hotelId}”) 
public String getHotel(@PathVariable String hotelId, Model model) { 
List<Hotel> hotels = hotelService.getHotels(); 
model.addAttribute("hotels", hotels); 
return "hotels”; 
} 
You can also have more than one path variable, like so: 
@RequestMapping(value="/hotels/{hotel}/bookings/{booking}", method=RequestMethod.GET) 
public String getBooking(@PathVariable("hotel") long hotelId, 
@PathVariable("booking") long bookingId, Model model) { 
Hotel hotel = hotelService.getHotel(hotelId); 
Booking booking = hotel.getBooking(bookingId); 
model.addAttribute("booking", booking); 
return "booking”; 
}
RESTful : Views 
Spring 3 a également ajouté quelques nouvelles Views à Spring MVC, notamment: 
AbstractAtomFeedView et AbstractRssFeedView, qui peut être utilisé pour renvoyer un 
flux Atom et RSS, 
MarshallingView peut être utilisée pour retourner une représentation XML. Cette view 
est basé sur le module de mapping objet / XML du projet Spring Web Services. Ce module 
concerne la technologies XML marshalling telles que JAXB, Castor, JiBX, 
JacksonJsonView, pour l’affichage des objets JSON dans votre modèle. Cette vue fait 
partie du projet Spring Java script 
Évidemment, tous ces vues pouvent être utilsées avec le ContentNegotiatingViewResolver!
RESTful : HTTP Method Conversion 
Alors que HTTP définit ces quatre méthodes, HTML prend en charge que deux: GET et 
POST. Heureusement, il existe deux solutions possibles : 
Vous pouvez soit utiliser JavaScript pour faire votre PUT ou DELETE 
Faire un envoie de formulaire avec la vraie méthode comme paramètre supplémentaire 
<form:form method="delete"> 
<p class="submit"><input type="submit" value="Delete Pet"/></p> 
</form:form> 
@RequestMapping(method = RequestMethod.DELETE) 
public String deletePet(@PathVariable int ownerId, @PathVariable int petId) { 
this.clinic.deletePet(petId); 
return "redirect:/owners/" + ownerId; 
}

Spring MVC

  • 1.
    SSpprriinngg MMVVCC Par: Abdelhakim Bachar DAVEO
  • 2.
    Avant  Programmationweb : Utilisation des Servlets  JSP ou formulaire HTML -> Submit to servlet -> Servlet Processes data -> Outputs information  Fonctionne très bien pour les petites applications, mais peut rapidement devenir hors de contrôle à cause du code HTML, les scrip-lets, java script, tag-libraries, l'accès base de données et la logique métier => C’est difficile à organiser.  En d'autres termes, le manque de structure peut provoquer une «soupe» de différentes technologies.  Les JSP sont compilées en Servlet
  • 3.
    Une meilleure façon?  Séparer les Data Access, Business Logic et Présentation à l'aide d'un framework MVC :  WebWork  Spring MVC  Struts  JSF  Tapisserie  …
  • 4.
    Les choses ontchangé :  Struts : est de loin le plus populaire.  Webwork : évolué pour Webwork2  Tapestry : est présent depuis un certain temps.  Spring : Le plus recent des frameworks. S'intègre bien avec n'importe quel autre cadre ou avec Spring MVC.
  • 5.
    Pour quoi Spring?  Tous frameworks s'intègrent bien avec Spring.  Spring offre une structure ouverte et organisée, avec l’injection des dépendances.  Configuration cohérente  S'intègre très bien avec les différents frameworks de mappings O/R comme Hibernate  Plus facile de tester les applications avec Spring.  Moins compliqué que d'autres frameworks.  Une communauté tres active.
  • 6.
    Vous aimez Microsoft.NET?  Essayez Spring Framework .NET  http://sourceforge.net/projects/springnet/
  • 7.
    Spring est plusqu’un framework de MVC :  Spring AMQP  Spring for Android  Spring Batch  Spring Data  Spring Framework  Spring Gemfire  Spring Integration  Spring Mobile  Spring .NET  Spring Roo  Spring Security  Spring Social  Spring Web Flow  Spring Web Services
  • 8.
    Configuration de SpringMVC  Dans votre conteneur Web, les fichiers XML de Spring sont dans le même répertoire que votre fichier web.xml avec un “-servlet.xml" à la fin webapps /tradingapp /WEB-INF/spring-mvc-servlet.xml, web.xml) /classes /lib (all jar files)  Le dispatcher est configuré avec le nom spring-mvc donc il va chercher et charger le fichier ”spring-mvc-servlet.xml" pour configurer les URL-mapping et les controleurs.
  • 9.
    Exemple de fichierweb.xml <web-app> <servlet> <servlet-name>spring-mvc</servlet-name> <servlet-class>DispatcherServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>spring-mvc</servlet-name> <url-pattern>*.htm</url-pattern> </servlet-mapping> </web-app> Toute URL se terminant par le motif “. Htm” est acheminé vers le DispatcherServlet, le DispatcherServlet charge le fichier spring-mvc-servlet.xml et redérige l'utilisateur vers le bon contrôleur.
  • 10.
    DispatcherServlet  Dansune architecture MVC les controleurs traitent toutes les requêtes.  Spring utilise un DispatcherServlet défini dans le fichier web.xml pour analyser la pattern d'URL de la requête, puis passer le contrôle au contrôleur approprié à l'aide d'un mapping URL définie dans un fichier de configuration Spring.
  • 11.
  • 12.
    Notre formulaire URL : http://localhost:8080/spring-mvc/login.htm
  • 13.
    Le fichier spring-mvc-servlet.xml  Prenant l’URL /login.htm  Cette URL set termine par .htm le DispatcherServlet va charger le fichier spring-mvc-servlet.xml le controleur approporié.  Le fichier spring-mvc-servlet.xml utilise la classe SimpleUrlHandlerMapping pour mapper les URLs à des controleurs, dans notre cas le LoginController
  • 14.
    Le fichier spring-mvc-servlet.xml <bean id="urlMapping” class="org.springframework.SimpleUrlHandlerMapping"> <property name="urlMap"> <map> <entry key="/login.htm” ref bean=”loginController"/> </map> </property> </bean> <bean id="loginController" class=”fr.daveo.springmvc.controllers.LoginController"> <property name="sessionForm” value=“true” /> <property name="commandName” value=“credentials” /> <property name="commandClass"> <value>fr.daveo.springmvc.model.Credentials</value> </property> <property name="validator"><ref bean="logonValidator"/></property> <property name="formView"><value>logon</value></property> <property name="successView"><value>home.htm</value></property> </bean>
  • 15.
    Le controleur LoginController public class LoginController extends SimpleFormController { public ModelAndView onSubmit(Object command) throws ServletException { return new ModelAndView(new RedirectView(getSuccessView())); } } Je vous rappel le fichier spring-mvc-servler.xml <bean id="logonForm" class="fr.daveo.springmvc.controllers.LoginController"> <property name="sessionForm"><value>true</value></property> <property name="commandName"><value>credentials</value></property <property name="commandClass” value=“com.tradingapp.Credentials” /> <property name="validator"><ref bean="logonValidator"/></property> <property name="formView"><value>logon</value></property> <property name="successView” value=“portfolio.htm” /> </bean>
  • 16.
  • 17.
    Command/Form Backing Bean public class Credentials { private String username; private String password; public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } }
  • 18.
    Command/Form Backing Bean Username: Password: Le formulaire de login est "backed" au bean via la commandName “credentials” définies dans les le fichier spring-mvc-servlet. xml. “credentials” sera notre “command object” nous allons l’utiliser pour lier le formulaire au bean. public class Credentials { private String username; private String password; public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } }
  • 19.
    Messages d'erreurs Rappeldu fichier de configuration: <bean id="logonForm" class="fr.daveo.springmvc.controllers.LoginController"> <property name="sessionForm"><value>true</value></property> <property name="commandName"><value>credentials</value></property <property name="commandClass” value=“com.tradingapp.Credentials” /> <property name="validator"><ref bean="logonValidator"/></property> <property name="formView"><value>logon</value></property> <property name="successView"><value>portfolio.htm</value></property> </bean> <bean id="loginValidator" class="fr.daveo.springmvc.controllers.LogonValidator"/>
  • 20.
    Messages d'erreurs publicclass LogonValidator implements Validator { public void validate(Object obj, Errors errors) { Credentials credentials = (Credentials) obj; if (credentials.getPassword().equals("guest") == false) { errors.rejectValue("password", "error.login.invalid-pass”, null, "Incorrect Password."); } } }
  • 21.
    Binding du formulaireavec Springs Tag Library <%@ taglib prefix="spring" uri="/spring" %> <html> <head><title>Daveo Login</title></head> <body> <spring:bind path="credentials.username"> <input type="text" name="username" /> </spring:bind> <spring:bind path="credentials.password"> <input type="password" name="password" /> </spring:bind> </body> </html>
  • 22.
    Les annotations Avecles version 2.5 et 3 de Spring vous pouvez utiliser les annotations @Controller and @RequestMapping pour replacer la configuation XML. Controller : La classe contrôleur n’a plus besoin d’héiter des contrôleurs AbstractController ou SimpleFormController, tout simplement annoter la avec une annotation @Controller. RequestMapping : Pas plus de déclaration XML pour le mappage comme BeanNameUrlHandlerMapping, ControllerClassNameHandlerMapping ou SimpleUrlHandlerMapping, tous sont remplacées par une norme annotation @RequestMapping.
  • 23.
    Autres annotations PathVariable : permet de récupérer une partie de l'URL afin de l'utiliser comme paramètre dans le contrôleur  RequestParam : Paramètre de la requête dont l’identifiant est celui spécifié dans l’annotation.  SessionAttributes : Spring offre la possibilité de gérer implicitement le stockage, cette annotation permet de spécifier l’identifiant correspondant.  ModelAttribute : initialise un formulaire  …
  • 24.
    Spring MVC &RESTful REST est un style d'architecture, pas un standard. Il n'existe donc pas de spécifications de REST. Il faut comprendre le style REST et ensuite concevoir des applications ou des services Web selon ce style. Bien que REST ne soit pas un standard, il utilise des standards. En particulier :  URI comme syntaxe universelle pour adresser les ressources,  HTTP un protocole sans état (stateless) avec un nombre très limité d'opérations,  Des liens hypermedia dans des documents (X)HTML et XML pour représenter à la fois le contenu des informations et la transition entre états de l'application,  Les types MIME comme text/xml, text/html, image/jpeg, application/pdf, video/mpeg pour la représentation des ressources. REST concerne l'architecture globale d'un système. Il ne définit pas la manière de réaliser dans les détails. En particulier, des services REST peuvent être réalisés en .NET, JAVA, CGI ou COBOL.
  • 25.
    RESTful : URITemplates Spring 3 a introduit l’URI templates via l’annotation @PathVariable, voici un exemple : @RequestMapping("/hotels/{hotelId}”) public String getHotel(@PathVariable String hotelId, Model model) { List<Hotel> hotels = hotelService.getHotels(); model.addAttribute("hotels", hotels); return "hotels”; } You can also have more than one path variable, like so: @RequestMapping(value="/hotels/{hotel}/bookings/{booking}", method=RequestMethod.GET) public String getBooking(@PathVariable("hotel") long hotelId, @PathVariable("booking") long bookingId, Model model) { Hotel hotel = hotelService.getHotel(hotelId); Booking booking = hotel.getBooking(bookingId); model.addAttribute("booking", booking); return "booking”; }
  • 26.
    RESTful : Views Spring 3 a également ajouté quelques nouvelles Views à Spring MVC, notamment: AbstractAtomFeedView et AbstractRssFeedView, qui peut être utilisé pour renvoyer un flux Atom et RSS, MarshallingView peut être utilisée pour retourner une représentation XML. Cette view est basé sur le module de mapping objet / XML du projet Spring Web Services. Ce module concerne la technologies XML marshalling telles que JAXB, Castor, JiBX, JacksonJsonView, pour l’affichage des objets JSON dans votre modèle. Cette vue fait partie du projet Spring Java script Évidemment, tous ces vues pouvent être utilsées avec le ContentNegotiatingViewResolver!
  • 27.
    RESTful : HTTPMethod Conversion Alors que HTTP définit ces quatre méthodes, HTML prend en charge que deux: GET et POST. Heureusement, il existe deux solutions possibles : Vous pouvez soit utiliser JavaScript pour faire votre PUT ou DELETE Faire un envoie de formulaire avec la vraie méthode comme paramètre supplémentaire <form:form method="delete"> <p class="submit"><input type="submit" value="Delete Pet"/></p> </form:form> @RequestMapping(method = RequestMethod.DELETE) public String deletePet(@PathVariable int ownerId, @PathVariable int petId) { this.clinic.deletePet(petId); return "redirect:/owners/" + ownerId; }