0% ont trouvé ce document utile (0 vote)
40 vues73 pages

10 - Spring @MVC

Transféré par

Ilyas
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)
40 vues73 pages

10 - Spring @MVC

Transféré par

Ilyas
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

© Khalid HADDOUTI

SOMMAIRE

INTRODUCTION 3
CYCLE DE VIE D’UNE REQUETE HTTP 7
CONFIGURATION SPRING MVC 11
DEFINITION DES CONTROLLEURS 14
GESTION DES VUES 18
INTEGRATION DE TILES 23
GESTION DES FORMULAIRES 27
VALIDATION DES FORMULAIRES ET JSR-303 33
GESTION DES ERREURS 43
REST / AJAX 49

© Khalid HADDOUTI 2
3
© Khalid HADDOUTI
INTRODUCTION
Principe MVC

+ Spring MVC est un framework de présentation respectant


le principe Model View Controller

© Khalid HADDOUTI 4
INTRODUCTION
Présentation Spring MVC (1/2)

+ Depuis la version 2.5, Spring MVC se configure via les


annotations
 Nom officiel Spring @MVC.
 Utilisation XML possible : Spring <MVC/>.

+ La hiérarchie de contrôleurs est dépréciée depuis Spring


3.0
 Utilisation de POJO pour les contrôleurs.

+ Cette formation ne traite que des annotations

© Khalid HADDOUTI 5
INTRODUCTION
Présentation Spring MVC (2/2)

+ Spring MVC repose un modèle simple Requête / Réponse


par rapport à un modèle évènementiel
 JSF– cycle de vie des données très complexe.

+ Spring MVC intègre un grand nombre de technologies


pour la vue
 JSP, FreeMarker, Velocity, Excel, PDF, etc…

+ Spring MVC fournit une librairie de tags pour faciliter le


développement des JSPs

© Khalid HADDOUTI 6
7
© Khalid HADDOUTI
CYCLE DE VIE D’UNE REQUETE HTTP
Présentation (1/3)

© Khalid HADDOUTI 8
CYCLE DE VIE D’UNE REQUETE HTTP
Présentation (2/3)

+ Spring MVC s’appui sur les URLs pour déterminer le


mapping à appliquer
 Une URL permet l'appel d'une méthode via l'interface
HandlerMapping.
 BeanNameUrlHandlerMapping est la classe par défaut.

+ Les intercepteurs agissent comme des filtres servlet


 Configuration XML ou par annotations.
 Sont gérés au sein du contexte Spring.
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**" />
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"/>
</mvc:interceptor>
<mvc:interceptors>

© Khalid HADDOUTI 9
CYCLE DE VIE D’UNE REQUETE HTTP
Présentation (3/3)

+ Spring MVC centralise la gestion des exceptions


 Par annotation @ExceptionHandler
 Par des beans implémentant l'interface HandlerExceptionResolver

 Permet l’exécution d’actions spécifiques et la redirection vers les

vues

+ L’inteface ViewResolver détermine la vue à partir d’un


nom logique
InternalResourceViewResolver – redirection vers des JSPs et
Servlets.

+ L’interface View prépare les données du modèle et


effectue le rendue selon la technologie configurée

© Khalid HADDOUTI 10
11
© Khalid HADDOUTI
CONFIGURATION SPRING MVC
Dispatcher Servlet

+ Configuration de la servlet dans le fichier web.xml


<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

</web-app>

 Point d’entrée du framework Spring MVC


 Dispatcher est le contexte web de l’application

© Khalid HADDOUTI 12
CONFIGURATION SPRING MVC
Le contexte servlet

+ La configuration MVC est contenue dans un fichier


spécifique
 Par défaut, portant le nom de <servlet-name>-servlet.xml
 Chargé depuis le répertoire WEB-INF
+ Le nom et le chemin vers le fichier est personnalisable
<servlet>

<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/config/web-application-config.xml</param-value>
</init-param>
</servlet>

+ Contient les définitions de beans relatives à la couche


MVC
Intercepteurs, résolution de la Locale, les fichiers de ressources
des messages à afficher, etc…

© Khalid HADDOUTI 13
CONFIGURATION SPRING MVC
Le contexte applicatif

+ Le contexte applicatif Spring est chargé via un listener


<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/config/web-application-config.xml</param-value>
</context-param>

 Par défaut, Spring MVC charge le fichier WEB-


INF/applicationContext.xml
La balise context-param permet de spécifier le(s) fichier(s) de
contexte à charger

+ Contient les définitions de beans hors contexte MVC


 Couche de service, beans métiers, datasources, etc…

© Khalid HADDOUTI 14
CONFIGURATION SPRING MVC
La hiérarchie des contextes (1/2)

+ Le contexte servlet et applicatif forment une hiérarchie de


contextes

© Khalid HADDOUTI 15
CONFIGURATION SPRING MVC
La hiérarchie des contextes (2/2)

+ La hiérarchie des contextes a des impacts sur la visibilité


des beans
 Les beans définis au sein du contexte servlet voient ceux du
contexte racine.
 L'inverse n'est pas applicable.

+ Un bean service peut être injecté au sein d'un bean


contrôlleur
 Il est par contre impossible d'injecter un bean contrôlleur au sein
d'un bean service.

+ Le partage du contexte racine entre plusieurs


dispatcherServlet est envisageable
 Un dispatcherServlet pour les services REST.

© Khalid HADDOUTI 16
CONFIGURATION SPRING MVC
Namespace « mvc » (1/3)

+ Simplifie la configuration de Spring MVC


<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

 Déclaration dans le fichier de contexte servlet


+ Configuration du modèle de programmation des contrôleurs
<mvc:annotation-driven/>

 Définition par défaut des HandlerMapping et HandlerAdapter.


 Configuration via @RequestMapping
 Support de la validation avec @Valid (dépendance sur JSR-303).
 Support pour la lecture et écriture XML/JSON
 @RequestBody et @ResponseBody.

© Khalid HADDOUTI 17
CONFIGURATION SPRING MVC
Namespace « mvc » (2/3)

+ Mapping et mis en cache des ressources


 Images, CSS, javascript, etc…
<mvc:resources location="classpath:/images/" mapping="/images/**" cache-period="31556926"/>

 “location” indique l’emplacement physique des ressources.


 "mapping" indique l'URL à associer.
 "cache-period" définit la durée de mis en cache (client) des ressources.
 Exemple d'URL:
 http://localhost:8080/springmvc/images/internet.png

+ Redirection vers une vue sans passer par un contrôlleur


<mvc:view-controller path="/" view-name="index"/>

 Affichage par défaut de la page d'index de l'application

© Khalid HADDOUTI 18
CONFIGURATION SPRING MVC
Namespace « mvc » (3/3)

+ Définition d'intercepteurs personnalisés


<mvc:interceptors>
<bean class="com.m2i.spring.mvc.view.interceptor.MyInterceptorImpl"/>
</mvc:interceptors>

 Intercepteur appélée pour toutes les requêtes


<mvc:interceptors>
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" />
<mvc:interceptor>
<mvc:mapping path="/secure/*" />
<bean class="com.m2i.spring.mvc.view.interceptor.MyInterceptorImpl" />
</mvc:interceptor>
</mvc:interceptors>

 Intercepteur "MyInterceptor" appelée pour les URLs contant


"/secure/".

© Khalid HADDOUTI 19
20
© Khalid HADDOUTI
DEFINITION DES CONTRÔLEURS
Les contrôleurs et la gestion du mapping (1/2)

+ Un contrôleur est une classe java (POJO) annotée par


@Controller
 Point d’entrée pour les traitements
 Effectue la redirection vers la vue en fonction du résultat.
+ Activation des annotations
<context:component-scan base-package="com.m2i.spring.mvc.view" />
<mvc:annotation-driven />

+ L’annotation RequestMapping effectue le mapping entre


l’URL et la méthode à exécuter
@Controller
public class UserController {
@RequestMapping("/listUsers")
public String list () {
// Exécutions des traitements
return "next";
}
}

 Exemple d'URL : http://localhost:8080/mvcapp/listUsers

© Khalid HADDOUTI 21
DEFINITION DES CONTRÔLEURS
Les contrôleurs et la gestion du mapping (2/2)

+ @RequestMapping peut etre annotée sur la classe


 En complément de l’annotation sur la méthode.
 Permet une meilleur granularité du mapping.
@Controller
@RequestMapping(value="/users")
public class UtilisateurController {

@RequestMapping(value="/listUsers", method=RequestMethod.GET)
public String list() {
// Exécutions des traitements
return "next";
}

 Exemple d’URL : http://localhost:8080/mvcapp/users/listUsers


 L’emploi de jokers est possible : /users/*/**

+ L’attribut method restreint le verbe HTTP pris en compte


par le mapping

© Khalid HADDOUTI 22
DEFINITION DES CONTRÔLEURS
Paramètres des requêtes (1/3)

+ Les méthodes ont besoin de réceptionner les paramètres


de la requête

+ Spring MVC assigne les paramètres aux arguments de la


méthode via les annotations
 Exemple d’URL :
 http://localhost:8080/mvcapp/users/delete?id=234
@RequestMapping(value="/delete", method=RequestMethod.GET)
public String deleteUtilisateur( @RequestParam("id") int id) {
// Exécution des traitements
return "deleteConfirmed";
}

 @RequestParam extrait le paramètre “id” de la requête.


 Le transtypage est effectué automatiquement.

© Khalid HADDOUTI 23
DEFINITION DES CONTRÔLEURS
Paramètres des requêtes (2/3)

+ Spring MVC extrait également les paramètres suivant le


principe de l’UriTemplate
 Concept partagé par beaucoup de frameworks
 Non spécifique Spring MVC

+ Emploi du token {…} et de l’annotation @PathVariable


 Exemple d’URL :
 http://localhost:8080/mvcapp/users/delete/234
@RequestMapping(value="/delete/{userId}", method=RequestMethod.GET)
public String deleteUtilisateur( @PathVariable("userId") long id) {
// Exécution des traitements
return "deleteConfirmed";
}

 Pas de nom de variable véhiculé dans la requête

© Khalid HADDOUTI 24
DEFINITION DES CONTRÔLEURS
Paramètres des requêtes (3/3)

+ La signature des méthodes n’est pas figée


 Permet une grande souplesse dans la définition des arguments
@RequestMapping("/info")
public void info(@RequestHeader("Accept-Encoding") String encoding,
@RequestHeader("Keep-Alive") long keepAlive) {
...
}

 Exemple appliqué sur les entêtes HTTP

+ Synthèse des annotations Spring MVC


Annotation Description
@PathVariable Récupère une partie de l’url et la place dans le paramètre annoté.
@RequestParam Récupère un paramètre de requête web (GET ou POST) .
@RequestHeader Récupère la valeur d’une entête HTTP.
@RequestBody Accède au corps de la requête.
@PathVariable Récupère un paramètre dans le cadre d’une URL de la forme UriTemplate

© Khalid HADDOUTI 25
26
© Khalid HADDOUTI
GESTION DES VUES
L’interface ViewResolver (1/2)

+ Les contrôleurs sont chargés de retourner le nom logique


d’une vue
 En fonction du résultat du traitement.
 La valeur est transmise au DispatcherServlet.
+ Les contrôleurs peuvent également retourner “void” ou
“null”
 Définition d’un bean d’interface RequestToViewNameTranslator.
 Spring fournit l’implémentation

DefaultRequestToViewNameTranslator.
 Résolution des noms logiques à partir de l’URL.

+ Les contrôleurs sont capables de retourner une valeur


concrête
new JstlView("/WEB-INF/users/list.jsp");

 Cas d’utilisation à proscrire car non flexible.

© Khalid HADDOUTI 27
GESTION DES VUES
L’interface ViewResolver (2/2)

+ Le DispatcherServlet délègue aux implémentations de


l’interface ViewResolver la résolutions des noms de vues
 Un identifiant logique est transmis au gestionnaire de vue.

+ Par défaut, Spring MVC gère les noms logiques comme


des chemins relatifs à l'application Web

+ Définir un bean pour modifier le comportement par défaut


<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>

 InternalResourceViewResolver est utilisé pour les JSPs.


 Les préfixe et suffixe sont paramétrés.
 La combinaison résultante forme un chemin vers la vue.

© Khalid HADDOUTI 28
GESTION DES VUES
Les types de retours (1/2)

+ Spring MVC fournit différents moyens de sélection de la


vue
 Plusieurs type de retours de méthode depuis le contrôleur.

+ Renvoi uniquement du nom logique la vue


@RequestMapping("/helloWorld")
public String helloWorld() {
return "helloWorld";
}

 Pas de données à afficher dans la vue.

+ Renvoi d'un objet encapsulant les données et le nom de la


vue
@RequestMapping("/helloWorld")
public ModelAndView helloWorld() {
ModelAndView mav = new ModelAndView();
mav.setViewName("helloWorld");
mav.addObject("message", "Hello World!");
return mav;
}

© Khalid HADDOUTI 29
GESTION DES VUES
Les types de retours (2/2)

+ Synthèse sur quelques types deretours


Classe/Interface Description
ModelAndView Encapsule le nom logique de la vue et sonmodèle.
Model Encapsule le modèle. Retour sur la vuecourante.
View (Interface) Retourne la vue préparée par l'application.
- Template Freemarker : FreeMarkerView
- Redirection vers une ressource externe (code HTTP 302) : RedirectView
String Fournit le nom logique.

© Khalid HADDOUTI 30
GESTION DES VUES
Les librairies de tag

+ Les taglibs permettent notamment de gérer les données


issues du modèle
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

 Déclaration des taglib en début de la JSP.

+ Affichage d'une liste de personnes


@RequestMapping(method=RequestMethod.GET,value="list")
public ModelAndView listPeople() {
ModelAndView mav = new ModelAndView();
List<Person> people = personDao.getPeople();
mav.addObject("people",people);
mav.setViewName("list");
return mav;
}

 Le contrôleur
<c:forEach items="${people}" var="person">
<a href="edit?id=${person.id}">${person.id} - ${person.firstName} ${person.lastName}</a>
<br/>
</c:forEach>

 Extrait du contenu de la JSP

© Khalid HADDOUTI 31
GESTION DES VUES
Conclusion

+ Diagramme des flux

<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/pages/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>

© Khalid HADDOUTI 32
33
© Khalid HADDOUTI
INTÉGRATION DE TILES
Présentation

+ Tiles est un moteur de template pour vues JSPs


 Définition de fragments JSP (ou Tiles).
 Assemblage de ces fragments pour obtenir une page complète.
+ Favorise la réutilisation des gabarits
+ Renforce le caractère homogène de l'identité visuelle
d'une application web
+ Framework Apache actuellement en version 3.0
 Site officiel : http://tiles.apache.org/
 Anciennement composant intégré à Strusts.
+ Ne pas utiliser la version 2.1.1 ou 2.1.0 à cause d’un bug
de sécurité

© Khalid HADDOUTI 34
INTÉGRATION DE TILES
Configuration dans Spring MVC (1/3)

+ Définitions des chemins vers les gabarits


<bean id="tilesConfigurer"
class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/defs/produit.xml</value>
<value>/WEB-INF/defs/login.xml</value>
<value>/WEB-INF/defs/administrateur.xml</value>
<value>/WEB-INF/defs/client.xml</value>
<value>/WEB-INF/defs/fournisseur.xml</value>
</list>
</property>
</bean>

 Le bean tilesConfigurer définit un conteneur Tiles.


 A configurer dans le fichier Spring de contexte servlet.

+ Un résolveur de vue spécifique Tiles doit être spécifié


<bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.tiles2.TilesView"/>
</bean>

 Récupération d’un des fichiers de définitions en fonction du nom.

© Khalid HADDOUTI 35
INTÉGRATION DE TILES
Configuration dans Spring MVC (2/3)

+ Les gabarits sont définis dans les fichiers XML


<definition name="base.definition" template="/WEB-INF/jsp/layout.jsp">
<put-attribute name="title" value="" />
<put-attribute name="header" value="/WEB-INF/jsp/header.jsp" />
<put-attribute name="menu" value="/WEB-INF/jsp/menu.jsp" />
<put-attribute name="body" value="" />
<put-attribute name="footer" value="/WEB-INF/jsp/footer.jsp" />
</definition>

<definition name="clients" extends="base.definition">


<put-attribute name="title" value="Clients" />
<put-attribute name="body" value="/WEB-INF/jsp/clients.jsp" />
</definition>

 Exemple de contenu pour /WEB-INF/defs/client.xml

© Khalid HADDOUTI 36
INTÉGRATION DE TILES
Configuration dans Spring MVC (3/3)

+ Exemple de redirection au sein d'un contrôlleur


@Controller
public class ClientController {

@RequestMapping("/clients")
public Récupération d’un des fichiers de définitions en fonction du nom
 ModelAndView showContacts() {
return new ModelAndView("clients", "command", new Client());
}

 Le nom de vue "clients" permet de sélectionner le gabarit Tiles.


 Affichage du gabarit "clients" issu de fichier de définition " /WEB-
INF/defs/client.xml”

© Khalid HADDOUTI 37
SPRING MVC
Travaux pratiques

+ Exercice 1
 A partir d’une application web existante
 Effectuer la configuration de base Spring @MVC.
 Définir les garabarits Tiles.

© Khalid HADDOUTI 38
39
© Khalid HADDOUTI
GESTION DES FORMULAIRES
Les taglibs « form »

+ Spring fournit un ensemble de taglibs pour la gestion de


formulaires
 Chaque tag HTML possède son équivalent taglib.
 Intègre les attributs pour la gestion des évènements
 onclick, onchange, onmouseover, etc…
 Facilite la liaison des données entre formulaire et contrôlleur.
 Affiche les erreurs de validation des données de formulaires ou

métiers.
 S'intègre avec Spring @MVC.

+ Déclaration du taglib
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>

© Khalid HADDOUTI 40
CRÉATION DES FORMULAIRES
Définition d’un formulaire (1/2)

+ Soit la classe « Produit » comme modèle métier


public class Produit {

private String nom;


private String reference;

public String getNom() {


return nom;
}

public void setNom(String nom) {


this.nom = nom;
}

public String getReference() {


return reference;
}

public void setReference(String reference) {


this.reference = reference;
}

 Classe pure Javabean

© Khalid HADDOUTI 41
CRÉATION DES FORMULAIRES
Définition d’un formulaire (2/2)

+ Formulaire d’édition d’un produit


<form:form method="post" modelAttribute="produit">

+
<table>
<tr>
<td>Référence</td>
<td><form:input path="reference"/></td>
</tr>
<tr>
<td>Nom</td>
<td><form:input path="nom"/></td>
</tr>
<tr>
<td colspan="2">
<form:button value="Créer">Créer</form:button>
</td>
</tr>
</table>
</form:form>

 L’attribut modelAttribute permet de lier les données du formulaire


avec le modèle.
 Le tag « form » positionne automatiquement l’attribut « action » en

fonction du controlleur.
 Les attributs « form:input » font référence aux attributs du modèle.

© Khalid HADDOUTI 42
CRÉATION DES FORMULAIRES
Le contrôleur

+ Contrôleur gestionnaire de formulaire


@Controller
@RequestMapping("/produit")
public class ProduitController {

@RequestMapping(value = "/create", method = RequestMethod.POST)


public String create( @ModelAttribute("produit") Produit produit) {
// Appel de service de création du produit
return "createProduitSuccess";
}

@RequestMapping(value = "/create", method = RequestMethod.GET)


public ModelAndView create() {
ModelAndView view = new ModelAndView();
view.setViewName("createProduit");
view.addObject("produit", new Produit());
return view;
}

 @ModelAttribute effectue le binding avec les données du


formulaire.
<form:form method="post" modelAttribute="produit"> […] </form:form>

© Khalid HADDOUTI 43
44
© Khalid HADDOUTI
VALIDATION DES FORMULAIRES
JSR-303 (1/3)

+ La JSR 303 fournit un ensemble d’annotations pour la


validation de données

+ La JSR-303 est extensible


 Par la création de nouvelles annotations.
 Par la composition d’annotations existantes :
 @NotNull, @Max, @Size, @Pattern, etc …

+ Spring @MVC n’implémente pas la JSR-303


Hibernate fournit une implémentation utilisable avec Spring
@MVC

+ La JSR-303 n’est pas spécifique à la couche de


présentation

© Khalid HADDOUTI 45
VALIDATION DES FORMULAIRES
JSR-303 (2/3)

+ La classe représentant le modèle est annotée suivant les


contraintes souhaitées
public class Client {

@NotEmpty
private String nom;

@NotEmpty
private String prenom;

@Min(18)
private int age;

[…]

+ Les annotations peuvent s'appliquer sur les méthodes


@Pattern( regexp = ".*\\.jpg|.*\\.jpeg|.*\\.gif",
message=“Seules les images de type JPEG or GIF sont acceptés.")
public String getFileName() {
return fileName;
}

© Khalid HADDOUTI 46
VALIDATION DES FORMULAIRES
JSR-303 (3/3)

+ Validation dans le contrôleur


@RequestMapping(method = RequestMethod.POST)
public String submitForm(
@ModelAttribute("client") @Valid Client client, BindingResult result)) {
if (result.hasErrors()) {
return " clientForm ";
}
else {
clientService.make(client);
return "clientSuccess";
}
}

 L’annotation @Valid portée sur l’objet du modèle active la


validation.
 L’objet BindingResult encapsule les erreurs de validations

survenues.

© Khalid HADDOUTI 47
VALIDATION DES FORMULAIRES
Les messages d’erreurs (1/2)

+ Les messages d’erreurs sont externalisés via l’utilisation


de ResourceBundle
<bean class="org.springframework.context.support.ResourceBundleMessageSource"
id="messageSource">
<property name="basename" value="/resources/messages"/>
</bean>

 Définition d’un bean pour charger un fichier messages.properties


situé dans le classpath.
+ La clé associé aux messages d'erreurs doit respecter une
convention de nomage
<Type d’Annotation>.<identifiant du modèle javaBean>.<champ du bean>=[…]

 Exemple
NotEmpty.client.name = Le nom est requis.
Range.client.age = L’âge est compris entre 1 et 150 ans.

+ Utilisation des taglib "form" pour afficher les messages


dans la page
<td><form:input path="age" /></td>
<td><form:errors path="age" cssClass="error" /></td>

© Khalid HADDOUTI 48
VALIDATION DES FORMULAIRES
Validation par Spring (1/2)

+ Spring fournit l’interface « Validator » pour implémenter la


logique de validation spécifique
public class ClientValidator implements Validator{

public boolean supports(Class clazz) {


return Client.class.isAssignableFrom(clazz);
}

public void validate(Object target, Errors errors) {


ValidationUtils.rejectIfEmptyOrWhitespace(
errors, "nom", "required.nom", "Le nom est requis");
Client client = (Client)target;
if( ! regleTresComplexe(client){
errors.rejectValue("nom", "notmatch.nom");
}
}

 La classe ValidationUtils est une classe de support pour de la


validation simple.
 La méthode "supports" assure que le validateur est utilisable pour

le modèle courant.

© Khalid HADDOUTI 49
VALIDATION DES FORMULAIRES
Validation par Spring (2/2)

+ Le validateur est liée au contrôleur pour être


automatiquement utilisé par Spring
@Controller
public class ClientController {
ClientValidator clientValidator;

@Autowired
@Qualifier("produitValidator")
private Validator produitValidator;

@InitBinder
protected void initBinder(WebDataBinder binder) {
binder.setValidator(this.clientValidator);
}

@RequestMapping(method = RequestMethod.POST)
public String submitForm(
@ModelAttribute("client") @Valid Client client, BindingResult result)) {
if (result.hasErrors()) {
return " clientForm ";
} else {
clientService.make(client);
return "clientSuccess";
}
}

© Khalid HADDOUTI 50
51
© Khalid HADDOUTI
GESTION DES EXCEPTIONS
Présentation

+ Spring @MVC propose une gestion centralisée des


exceptions
 Principe proche des déclarations dans "web.xml".

+ L'approche Spring @MVC offre une plus grande flexibilité


 Exécution de méthodes lors de la levée d'exceptions.
 Redirection vers une vue Spring

+ Spring @MVC permet la défintion des gestionnaires selon


deux modes
 XML – déclaration d’un bean d’implémentation de l’interface
« HandlerExceptionResolver »
 Par annotation – utilisation de @ExceptionHandler

© Khalid HADDOUTI 52
GESTION DES EXCEPTIONS
Approche XML - HandlerExceptionResolver

+ Spring @MVC fournit un certain nombre


d’implémentations
 SimpleMappingExceptionResolver
 DefaultHandlerExceptionResolver (implémentation par défaut),…
+ Exemple avec SimpleMappingExceptionResolver
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<prop key="com.monappli.exception.MonException">NomLogiquePageException</prop>
<prop key="java.lang.Exception">error</prop>
</props>
</property>
</bean>

 Association d’une exception avec la vue à afficher.


 La résolution de la vue est effectuée par le ViewResolver définit

dans le contexte Spring.


 La vue JSP est enrichie d’un bean "exception" qui référence

l'exception levée <h2>${exception.message}</h2>

© Khalid HADDOUTI 53
GESTION DES EXCEPTIONS
Approche par annotation - @ExceptionHandler

+ L’exception est géré au sein d’un contrôleur


@Controller
public class ProduitController {

// Autres méthodes du contrôleur

@ExceptionHandler(IOException.class)
public String handleIOException(IOException ex, HttpServletRequest request) {
return ClassUtils.getShortName(ex.getClass());
}
}

 L'annotation est posée sur une méthode spécifique qui gère


l'exception.
 Les types d’exceptions sont déclarés en argument de l’annotation.
 La méthode possède une signature variable selon les besoins du

développeur.
 La méthode retourne une simple chaîne portant le nom de la vue

ou bien un objet de type "ModelAndView".

© Khalid HADDOUTI 54
GESTION DES EXCEPTIONS
Conclusion

+ Déclaration par XML pour une gestion globale des


exceptions au sein d’une application
 Centralisation des traitements des exceptions.
 Externaliser les traitements associés aux exceptions du code

applicatif.
 Gestionnaire adapté pour les erreurs techniques.

+ Déclaration par annotation pour une gestion spécifique


des exceptions
 Plus grande granularité dans les traitements.
 Gestionnaire d'exception adapté pour les erreurs métiers.

© Khalid HADDOUTI 55
SPRING MVC
Travaux pratiques

+ Exercice 2
 Élaborer une application simple de création de contrat.
 Les points couverts :
 Contrôleur.
 Mapping de requête.
 Validation.
 Messages d’erreurs.
 Formulaire web.

© Khalid HADDOUTI 56
57
© Khalid HADDOUTI
REST
Présentation

+ REST - Representational state transfer


+ Les applications web ne sont pas uniquement utilisées
par les navigateurs

+ Les systèmes automatisés sont aussi capables de se


connecter via HTTP

+ REST est un type d’architecture de web services défini


par Roy Fielding
 HTTP est utilisé en tant que protocole d’application et non plus en
tant que couche de transport

© Khalid HADDOUTI 58
REST
Principes (1/2)

+ Les ressources sont identifiées par des URIs


 Ensemble regroupant les URLs et URNs

+ Utilisation des verbes issue du protocole HTTP


 GET, PUT, DELETE, POST.

+ Protocole de communication du web


 XML, JSON, texte, etc…

+ Architecture stateless
 HttpSession n’est pas utilisé
 Les requêtes de type GET peuvent être mis en cache
 Les clients conservent l’état de la session en cours

© Khalid HADDOUTI 59
REST
Principes (2/2)

+ Les clients REST peuvent demander une représentation


parmi plusieurs possibles
 Les ressources peuvent êtres transmises sous plusieurs formes
 HTML, XML, JSON, etc…

+ Les types MIME sont utilisés pour interagir avec les


ressources

+ Les entêtes et les codes d’état HTTP transportent les


résultats vers les clients

+ Couplage faible entre client et serveur

© Khalid HADDOUTI 60
REST
JAX-RS : Java API for RESTful Web Services

+ JAX-RS est l’implémentation standard Java EE 6 pour la


construction de web services REST

+ Concerne les clients automatisés (programmatique) plus


que les navigateurs Web

+ Plusieurs implémentations sont disponibles


 Apache CXF
 Jersey
 RESTEeasy de Jboss
 Reslet crée par Jérome Louvel (pionnier REST)

+ Pas de standard pour la construction de client

© Khalid HADDOUTI 61
REST
Spring MVC

+ Spring MVC apporte les outils pour la mise en place REST


 Depuis la version 3.0
 S’appui sur le modèle d’architecture Spring
 Spring MVC n’offre pas de support pour JAX-RS

+ Support pour la partie client (web services sur HTTP) et


serveur (RESTful web applications)

+ Spring MVC fournit la classe RestTemplate pour


implémentation d’un client Java

© Khalid HADDOUTI 62
REST
Gestion des requêtes

+ Mapping des méthodes basés sur le verbe HTTP


 Permet d’associer une même URL sur plusieurs méthodes
 Utilisé pour la gestion des formulaires (GET et POST)
 Important pour gérer les URLs des ressources REST
 Incluant PUT et DELETE
@RequestMapping(value="/utilisateurs", method=RequestMethod.GET)
public void listUtilisateur(Model model) {
// Récupération des utilisateurs
// et les placer dans le modèle.
}

@RequestMapping(value="/utilisateurs", method=RequestMethod.POST)
public void createUtilisateur(HttpServletRequest request, Model model) {
// Création de l'utilisateur
}

© Khalid HADDOUTI 63
REST
Gestion des codes erreurs HTTP (1/3)

+ Les applications web utilisent les codes standards HTTP


 200 OK, 404 Not Found, 302/303 pour les redirections et 500 pour
les erreurs internes.

+ L’annotation @ResponseStatus permet de positionner le


code HTTP paramétré au sein de l’instance
« HttpServletResponse »

+ @ResponseStatus permet d’associer un code spécifique


avec une exception

© Khalid HADDOUTI 64
REST
Gestion des codes erreurs HTTP (2/3)

+ Quelques codes HTTP


Code HTTP Description
200 Envoyé après une commande GET ayantaboutie
201 Création d’une nouvelle ressource depuis un POST ouPUT
204 La réponse est vide (après une commande POST ouPUT)
404 La ressource n’existepas
405 La méthode invoquée n’est pas supporté par la ressource
409 Un conflit apparait pendant la modification appliquée sur une ressource
500 Erreur interne grave

 http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

© Khalid HADDOUTI 65
REST
Gestion des codes erreurs HTTP (3/3)

+ Exemple d’envoi d’un code HTTP de création d’une


ressource
@RequestMapping(method=RequestMethod.GET)
@ResponseStatus(HttpStatus.CREATED) // Code HTTP envoyé : 201
public void createUtilisateur(HttpServletRequest request, HttpServletResponse response) {
Utilisateur utilisateur = this.utilisateurService.createUtilisateur();
response.addHeader("Location", getLocationForChildResource(request, utilisateur.getId()));
}

 La méthode ne renvoi pas vers une vue.


 La réponse ne possède pas de contenu.

© Khalid HADDOUTI 66
REST / AJAX
Spring @MVC et JSON – Serveur (1/3)

+ Spring MVC permetde renvoyer du flux de type JSON


 @ResponseBody spécifie le contenu retourné au consommateur.
 Un convertisseur effectue la sérialisation/déssérialisation depuis

un javabean modèle.
 Le convertisseur implémente l’interface HttpMessageConverter.

 JSON – MappingJacksonHttpMessageConverter

+ Spring @MVC d’autres implémentations


 XML – flux XML
 Texte – Chaînes de caractères

+ Un type MIME est défini par défaut pour chaque


convertisseur
 Il est possible de modifier le type MIME

© Khalid HADDOUTI 67
REST / AJAX
Spring @MVC et JSON – Serveur (2/3)

+ Les caractéristiques du service sont annotés sur le


contrôlleur
 Controller
@RequestMapping(value = "/{clientId}", method = RequestMethod.GET)
Public @ResponseBody Client findClient(@PathVariable int clientId) {
return clientService.get(clientId);
}

+ Le modèle est encapsulé au sein d’un JavaBean


import org.codehaus.jackson.annotate.JsonAutoDetect;

@JsonAutoDetect
public class Client {
@NotEmpty
private String nom;
@NotEmpty
private String prenom;
@Min(18)
private int age;
….
}

@JsonAutodetect permet de sélectionner les champs/méthodes à


sérialiser.

© Khalid HADDOUTI 68
REST / AJAX
Spring @MVC et JSON – Serveur (3/3)

+ Les convertisseurs sont déclarés au sein du contexte


servlet
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="jsonConverter" />
</list>
</property>
</bean>

<bean id="jsonConverter"
class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name="supportedMediaTypes" value="application/json" />
</bean>

+ Une librairie d’implémentation de JSON doit être ajouté au


projet.
 Librairie Jackson : http://jackson.codehaus.org/

© Khalid HADDOUTI 69
REST / AJAX
Spring @MVC et JSON – Client (1/2)

+ Spring @MVC fournit la classe RestTemplate pour


interroger les services REST
 Implémente le pattern Template
+ Le bean RestTemplate est déclaré dans le fichier de
contexte applicatif Spring
<bean id="restTemplate" class="org.springframework.web.client.RestTemplate">
<property name="messageConverters">
<list>
<ref bean="jacksonConverter"/>
</list>
</property>
</bean>

 Les convertisseurs sont injectés dans le bean RestTemplate.


<bean id="jacksonConverter"
class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name="supportedMediaTypes" value="application/json" />
</bean>

 Par défaut, Spring @MVC positionne le type MIME


« application/json »

© Khalid HADDOUTI 70
REST / AJAX
Spring @MVC et JSON – Client (2/2)

+ Le bean RestTemplate est injecté et manipulé dans les


classes spécifique
@Component
public class Client {

@Autowired
private RestTemplate restTemplate;

public Contract getClient(int clientId) {


Client c = this.restTemplate.getForObject(
"http://localhost:8080/app/client/{clientId}", Client.class, clientId);
return c;
}

 La classe RestTemplate possède de multiples méthodes pour


 La création de ressources
 La suppression de ressources
 La lecture des entêtes HTTP
 RestTemplate couvre l’ensemble des verbes HTTP.

© Khalid HADDOUTI 71
SPRING MVC
Travaux pratiques

+ Exercice 3
 A partir d’une application web existante
 Mettre en place un web service en s’appuyant sur Spring MVC.
 Utiliser les différentes implémentations REST pour les web services.
 A partir d’une application cliente existante :
 Consommer le web service en s’appuyant sur la classe RestTemplate
et le protocole JSON.

© Khalid HADDOUTI 72
SPRING @MVC

73
© Khalid HADDOUTI

Vous aimerez peut-être aussi